Scott Hanselman

Facebook's privacy settings are too complex for ANYONE to use - Change these settings today

April 13, '12 Comments [19] Posted in Blogging
Sponsored By

The Friends privacy setting on status updates extends to tagged friends and their friends

My wife is quite a bit smarter than I am. She is also more educated that I am. Frankly, I'm happy she talks to me at all.

She put a photo on Facebook last week of she and a friend and was careful to double-check that the photo was set to "Friends only."

A few days later she rushed in and told me that she thought the photo was public even though it was set as Friends only.


"Because random people that I don't know are commented on this photo! Like, who is this guy? I don't want him to see this - I don't know him! Why did they let non-friends see it?"

I looked for a minute and noticed that she had "tagged" her other friend in the photo as in this example photo below:

A photo in Facebook with 4 people "tagged"

In this photo there are four people tagged. When you tag someone they are notified that they've been tagged and they can remove the tag which removes it from their "photos of me" list. The photo above is totally public but let's say it was posted by me and I tagged my three friends and marked as "friends only."

Who can see the photo of me and my 3 friends? Who can see the photo of my wife and her friend when the photo is marked Friends?

Who sees the photo? The union of all our friends!

Answer: The union of all the friends of everyone tagged in the photo. If someone else sees the photo and tags some more people, the circle of visibility for that photo or post expands.

This may seem obvious to a software engineer or someone with a background in set theory but it's not obvious even to smart regular folks. It certainly surprised my wife although she gets it now. Here's the thing, though. Now she says she really is less likely to put photos on Facebook and certainly less likely to tag folks in photos.

Confused a little? There's more. Recently my programmer man crush and favorite Canadian Reginald Braithwaite wrote a post called When you share personal data with Facebook friends, you're sharing your personal data with every app your friends use. Read that title again.

Remember that when you aren't paying for something (like Facebook), someone is paying. The advertisers are paying and you, your friends and all your info are the product.

Reginald points out that when you grant an application (Farmville, etc) in Facebook access to your profile you are often granting that application access to your friends personal information. That means that your annoying friend who is always pushing the Mob Wars invites has likely granted an application access to your information by proxy.

UPDATE: When you are sharing something note that you can pull down the privacy dropdown, select custom and make changes then hover your mouse over the gear to get a plain English tooltip showing the resulting visibility of this update:

The Tooltip will show the resulting visiblity of the post

Your Homework - and pass it on

Go log into Facebook and in the upper right corner click Privacy Settings:

Privacy settings in Facebook is in the upper right corner

Then, spend some time in these two areas of Settings. Timeline and Tagging and Apps and Websites.

Update your facebook privacy settings

Under tagging you can choose what happens when someone tags you and tags that friends add to your own posts or photos. You can also control tag suggestions. You can lock this down as much as you want.

Check your Timeline and Tagging settings in Facebook

Next, click on Apps and Websites and freak out when you see how many you (or your teen) has added. You can remove them as you like. Most importantly, click on "How people bring your info into apps they use."

Review the "Apps you use" at Facebook

How much of this info to you want your friends sharing with their applications? Turn this stuff off.

Uncheck all the checkboxes at "How people bring your info info apps they use."

And finally, check out the Public Search option. Do you want Facebook and your public timeline to show up when someone Googles for you  or your child? If not, turn this OFF.

Turn off your Facebook public search settings

You can also go back in time and "limit old posts." This will take posts from years ago when you didn't know this information and make them visible to friends only.

Limit the visiblity of old posts

Facebook will likely try to talk you out of it. Use your judgment.


Now, for a fun over-dinner exercise try explaining this to your 14 year old and why everyone should be careful about information leakage. Seriously. At least try.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Big Glossary of Open Source JavaScript and Web Frameworks with Cool Names

April 13, '12 Comments [38] Posted in ASP.NET | Javascript | Open Source
Sponsored By

Photo via Dmitry Baranovskiy and used under Creative Commons -'s getting to the point where there are so many cool open source projects that I can't keep up. When you add in the currently battle royale of JavaScript projects that are basically just hip sounding words with ".js" added to the end, it's a little overwhelming. Seriously, just pick a word out of the dictionary at random and that's the name of an up and coming JavaScript library.

JavaScript MVC Frameworks and Libraries

This is an area that is very interesting but also very not-yet-baked. In the DOM manipulation and CSS selector space, jQuery won. That fight is over. The next big question is client side MVC frameworks. It seems everyone wants to make the next "Rails" framework on JavaScript and while there are some contenders, there's still lots of room for someone to "win."

DOM manipulation libraries like jQuery are important, but it's clear that making large and rich web applications requires more than just jQuery. More and more applications want smart asynchrony and dynamic loading.

(Reminder: All this IS overwhelming. That doesn't mean you need to know all these frameworks or feel bad that you don't know them all. Just accept that you DON'T know them all. Be OK with that.)

Here's the major players and ones you might want to be familiar with. Remember, these are client side libraries and while they often mention server-side frameworks like node or rails, these are things written in JavaScript that anyone can use.

  • Ember.js - Attempts to remove tedious boilerplate code. Includes a templating engine (no one will agree on just one), encourages an architecture where the browser does most of the work, supports state-management out of the box. Focus on computed properties, and templates that update themselves.
  • Underscore .js - A library of more than 60 functions to make JavaScript more fun and easier to use. Provides a layer that will use a modern browser's native implementation of a method while still supporting older browsers. Has iterators like each, map, reduce, etc. In a way, it's like LINQ for JavaScript.
  • JavaScriptMVC - A jQuery-friendly framework that adds functional testing, MVC plugins, documentation generation, dependancy management and build tools.
  • Spine.js - Seems like less than a Backbone (these libraries all play with each other's names). Introduces models and controllers, but for views, requires you use your own template engine. Intends to be super lightweight.
  • Backbone.js - Everyone loves Backbone. It's the one you'll hear about the most. There's a large community supporting it. Folks have said that large applications can get a little hairy and difficult to manage, though. Lots of great docs and examples.
  • Knockout.js - MVVM on the client rather than MVC. Lots of interesting client-side data-bind expressions. Rich documentation.
    • And, wait for it, Knockback.js, a library that bridges the gaps between Knockout and Backbone and encourages you to use both effectively.
  • Sammy.js - A very small core library that brings in other adapters and plugins to give you just the parts you need. Focused on developer happiness. Works well with apps that are sitting on top of RESTful JSON server sides.
  • Angular.js - Includes templates, two-way data-binding and MVC, again, all on the client. Very small and starting to make a splash.
  • SproutCore - SproutCore seems to be very complete and more prescriptive than other frameworks. It also has a focus on making apps on tablets and other devices. The NPR for Chrome app used them.
  • Cappuccino - If you like and think in Objective-C, you'll like Cappuccino and Objective-J. Cappuccino is kinda of Cocoa (Mac APIs) for the web.
  • Google Closure - Almost doesn't belong in the list as it's a very complete toolkit with a whole worldview, rich library, templates, and lots of extras. You can choose how much you want to embrace, though.
  • ExtJS4 - This is a Sencha product and now on its fourth major release. It includes not only a framework and architecture but also widgets and charts.
  • PureMVC - Another MVC on the client side implementation, but this one was ported from ActionScript. It was originally used on Adobe Air and the like.
  • Batman.js - Bonus points for the best name. Explicitly embraces CoffeeScript as well as JavaScript. Only 2000 lines and very few extras. Very Rails friendly, prescriptive without being oppressive.
  • Require.js - A JavaScript file and module loader.
  • PrefixFree.js - A nice library that expands all your CSS to use the explosion of vendor prefixes correctly.
  • Lawnchair.js - Client-side storage and persistence. Less than a couch, but smaller and outside.
  • Mustache - Templates for views, explicitly without logic.
var view = {
title: "Joe",
calc: function () {
return 2 + 4;

var output = Mustache.render("{{title}} spends {{calc}}", view);
  • Handlebars.js - An superset of the Mustache template concept with extra features. A fancier mustache. Ahem, "Handlebar Mustache."

Also checkout Gordon Hempton's excellent "consumer reports" table on his blog that covers which JavaScript frameworks support which features.

ASP.NET Libraries, Frameworks and Open Source Projects

You may have heard that ASP.NET MVC 4, ASP.NET Web API and ASP.NET Web Pages v2 (Razor) are all now open source with contributions. They are up on CodePlex using Git. I thought I'd mention some interesting ASP.NET/CLR server side libraries here also as that's the area I work in.  There are thousands of Open Source projects in the .NET space, but I wanted to take a moment and feature these as they are all related and all emerging.

Just like the JavaScript projects above, these .NET projects are all trying to innovate...trying to make something new and modern and compelling without sacrificing the good things about the past.

  • OWIN - This is the "open web interface for .net." It represents the "spec" of the web app function signature. It serves the same purpose as Rack spec on Ruby or WSGI on Python. "The goal of the OWIN interface is to decouple server and application, encourage the development of simple modules for .NET web development, and, by being an open standard, stimulate the open source ecosystem of .NET web development tools."
  • Gate - An OWIN Reference implementation of utilities, host handlers, and web framework adapters for OWIN. This is essentially glue code, with things like Gate.Hosts.Kayak.dll on one hand, and Gate.Adapters.Nancy.dll on the other, to fit together your stack, e.g. "Kayak->Owin->Nancy"
  • Nancy - A "Sinatra" inspired framework. "Nancy is a lightweight, low-ceremony, framework for building HTTP based services on .Net and Mono. The goal of the framework is to stay out of the way as much as possible and provide a super-duper-happy-path to all interactions."
  • Kayak - A 100% C# HTTP Server assembly that can be embedded in your project. "Kayak is an asynchronous HTTP server written in C#. It has been designed to be easy to embed into a variety of applications. Kayak natively supports the OWIN 1.0 Draft specification."
  • Firefly - Another 100% C# HTTP server assembly.
  • Manos - A 100% C# HTTP server in an assembly that is a part of a larger Manos web server + web framework bundle.
    (web frameworks with owin adapters:)
  • AspNetWebApi - A framework optimized for HTTP APIs and services. Part of the open source ASP.NET Web Stack.
  • SignalR -  A message bus that supports realtime communication over Web Sockets, long polling, forever frame, or server sent events. JavaScript and Server-side components.
  • Fubu - A MVC-inspired framework with the beginnings of some OWIN support.
  • OpenRasta - A development framework for building web-based applications and services. Focused on being RESTful.

There is no question that I've missed some. Leave them in the comments and I'll keep this post updated. Projects for this list should be of some renown and be pushing the envelope in some notable way.

Big thanks to Louis DeJardin for his help and bootstrapping the list.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

My car ships with crapware

April 10, '12 Comments [97] Posted in Musings
Sponsored By

Toyota Entune In Dash computerThere are few things sadder than the software that ships with your car's in dash computer. it's 2012 and we have hybrids that can regenerate power from inertia but the car manufacturers haven't figured out that we just want the in-dash car screen to be powered by our smartphone. Sure, there's a few products in the space like the hobbyist-grade "Mimics" from MP3Car and some weird hybrids like AppRadio from Pioneer but they are all aftermarket and a little Frankenstein's Monster.

The Toyota Prius V that we just bought comes with a system called Entune. This is a little computer in the dash itself that includes Applications (yes, applications) like Bing Search, Pandora, Traffic and others. I've got a dual-core internet connected super-computer in my pocket and you can get one yourself for $99 at AT&T but my new car includes an underpowered, low-resolution, low-memory tiny computer of its own. It would have made far too much sense for them to spend the money on an awesome 6" or 7" screen that mirrored the phone.

Think about this. My car has Pandora. Yay, right?

To use Pandora on my new car I have to:

  • Register for an Entune account at - This is a required step.
  • Link my existing Pandora account with my Entune account. Note that this can't be done on your phone. Gotta use a PC. Didn't work on the iPad either.
  • Pair my phone with my car using Bluetooth.
  • Have a phone that supports Tethering via Bluetooth
  • Pay for a tethering account from my phone provider (Personal Hotspot from AT&T, for example)
  • Perform a second pairing to authorize the car to use my phone for Internet
  • Enter my Entune password into my car using their touch screen. It then uses my phone to talk to Entune (I hope it's using SSL!)
  • Run Pandora on my car which uses Bluetooth to my phone over tethering which uses 3G/4G to talk to the internet.
  • Send a check to Rube Goldberg to pay for royalties given this is a complete rip-off of his best contraptions.

Seriously friends, drink that in for a moment. My car has a crappy computer that runs a version of Pandora that talks to my phone to use its internet to get music from Pandora.

Here's a thought. Why don't I just run Pandora on my phone?

Do you think that my car will ever get a new version of Pandora? Do I need to get on the app update treadmill with my car's appstore?

Will my Entune system update? No.

Well, let's see. The Entune FAQ says that I should "check back often for updates."

Check back often for updates? Ok, so the answer is NO. This Pandora application will never be updated, ever. I have a pale shadow of a tablet PC in my new car that requires tethering from my super-powered and often updated internet connected phone with a thriving app store. It would have made far too much sense to use the phone as the heart of this system.

In ten years my car will still be running. AOL was hot 10 years ago. Will Pandora even exist in 10 years?

Will Toyota put out a user-serviceable update to my car's system to remove the Pandora icon or will it remain on my dash for eternity, a lonely symbol of a dead company reminding me each ignition of a bubble long past?

The phone connectivity ecosystem is so messy right now that there are actually wizards to walk you through the complexities. Toyota's Connect site will show you which of the 150 features their in-dash Entune system will support given your phone and car and phone carrier. We're doing Cartesian products here to find out if I can listen to streaming audio?

This is a ridiculous table that shows that my iphone supports SOME of the features of my car, but not all

Here's the final irony. I have the latest and greatest and fanciest fruit-based smartphone with the latest hardware and software. It doesn't support 30% of the things my car does. In fact, no phone does. I was thrilled to see that the car supports text messaging, a sync'ed calendar and more (when stopped.) Does my phone support that? No. A Blackberry does though. And I'm sure they'll be around in the future.

May I just point out, as a final hilarious indignity that this system has won awards?

I know this is ranty and if you worked on this system and show up in the comments, forgive me. I'm not trying to pick on the trench developers of these things but rather the architects/designers/planners. I wish they'd show some foresight and create future-proofed systems that use and embrace open specs and protocols. VNC anyone? The fact that I can place calls and stream Bluetooth audio in this car is great. But it'd be nice if with all this dancing back and forth and tethering and pairing that the maps and navigation would just use Google or Bing maps for always updated high-res, high quality maps. Do they? Nope, that would make too much sense.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

It's not what you read, it's what you ignore - Video of Scott Hanselman's Personal Productivity Tips

April 9, '12 Comments [55] Posted in Productivity | Speaking
Sponsored By

I've done a number of talks on Productivity in the past. Lots of folks ask me what my tips are for being productive. I've taken all those tips as well as tips from Kathy Sierra, Stephen Covey, David Allen, The Pomodoro Technique and many more and aggregated them into a system that works well for me. I talk about how to effectively handle large amounts email, sorting your personal data stream, how to conserve your keystrokes, the "one email rule" that you need to be effective

I'm giving this talk in a few places in the coming months like StirTrek in Ohio, DevCon in Russia, and possibly "That Conference" in Wisconsin. If you will be attending one of these events, you might want to wait and see it in person. ;)

There's a few jokes in the beginning of the talk that refer back to some discussion about Gamification and a funny back and forth that Kathy Sierra and I had. If they don't make sense, that's the context.

I hope you enjoy it. It's about 42 minutes long. There's lots of other great talks from WebStock '12 up at their event site. Do check them out. I particularly like Lauren Beuke's talk on Kinking Reality, Matthew Inman (The Oatmeal) and his talk on getting people to read what you write, Adam Lisagor (the world's quietest pitchman) and Rob Malda on the Rise and Fall of Slashdot.

Of course, feel free to share this post with your friends. I hope it helps them.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Back to Basics: Dynamic Image Generation, ASP.NET Controllers, Routing, IHttpHandlers, and runAllManagedModulesForAllRequests

April 7, '12 Comments [33] Posted in ASP.NET | ASP.NET MVC | Back to Basics | Learning .NET
Sponsored By

Warning, this is long but full of info. Read it all.

Often folks want to dynamically generate stuff with ASP.NET. The want to dynamically generate PDFs, GIFs, PNGs, CSVs, and lots more. It's easy to do this, but there's a few things to be aware of if you want to keep things as simple and scalable as possible.

You need to think about the whole pipeline as any HTTP request comes in. The goal is to have just the minimum number of things run to do the job effectively and securely, but you also need to think about "who sees the URL and when."

A timeline representation of the ASP.NET pipeline


This diagram isn't meant to be exhaustive, but rather give a general sense of when things happen.

Modules can see any request if they are plugged into the pipeline. There are native modules written in C++ and managed modules written in .NET. Managed modules are run anytime a URL ends up being processed by ASP.NET or if "RAMMFAR" is turned on.

RAMMFAR means "runAllManagedModulesForAllRequests" and refers to this optional setting in your web.config.

<modules runAllManagedModulesForAllRequests="true" />

You want to avoid having this option turned on if your configuration and architecture can handle it. This does exactly what it says. All managed modules will run for all requests. That means *.* folks. PNGs, PDFs, everything including static files ends up getting seen by ASP.NET and the full pipeline. If you can let IIS handle a request before ASP.NET sees it, that's better.

Remember that the key to scaling is to do as little as possible. You can certainly make a foo.aspx in ASP.NET Web Forms page and have it dynamically generate a graphic, but there's some non-zero amount of overhead involved in the creation of the page and its lifecycle. You can make a MyImageController in ASP.NET MVC but there's some overhead in the Routing that chopped up the URL and decided to route it to the Controller. You can create just an HttpHandler or ashx. The result in all these cases is that an image gets generated but if you can get in and get out as fast as you can it'll be better for everyone. You can route the HttpHandler with ASP.NET Routing or plug it into web.config directly.

Works But...Dynamic Images with RAMMFAR and ASP.NET MVC

A customer wrote me who was using ASP.NET Routing (which is an HttpModule) and a custom routing handler to generate images like this:

routes.Add(new Route("images/mvcproducts/{ProductName}/default.png", 
new CustomPNGRouteHandler()));

Then they have a IRouteHandler that just delegates to an HttpHandler anyway:

public class CustomPNGRouteHandler : IRouteHandler
public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
return new CustomPNGHandler(requestContext);

Note the {ProductName} route data in the route there. The customer wants to be able to put anything in that bit. if I visit http://localhost:9999/images/mvcproducts/myproductname/default.png I see this image...

A dynamically generated PNG from ASP.NET Routing, routed to an IHttpHandler

Generated from this simple HttpHandler:

public class CustomPNGHandler : IHttpHandler
public bool IsReusable { get { return false; } }
protected RequestContext RequestContext { get; set; }

public CustomPNGHandler():base(){}

public CustomPNGHandler(RequestContext requestContext)
this.RequestContext = requestContext;

public void ProcessRequest(HttpContext context)
using (var rectangleFont = new Font("Arial", 14, FontStyle.Bold))
using (var bitmap = new Bitmap(320, 110, PixelFormat.Format24bppRgb))
using (var g = Graphics.FromImage(bitmap))
g.SmoothingMode = SmoothingMode.AntiAlias;
var backgroundColor = Color.Bisque;
g.DrawString("This PNG was totally generated", rectangleFont, SystemBrushes.WindowText, new PointF(10, 40));
context.Response.ContentType = "image/png";
bitmap.Save(context.Response.OutputStream, ImageFormat.Png);

The benefits of using MVC is that handler is integrated into your routing table. The bad thing is that doing this simple thing requires RAMMFAR to be on. Every module sees every request now so you can generate your graphic. Did you want that side effect? The bold is to make you pay attention, not scare you. But you do need to know what changes you're making that might affect the whole application pipeline.

(As an aside, if you're a big site doing dynamic images, you really should have your images on their own cookieless subdomain in the cloud somewhere with lots of caching, but that's another article).

So routing to an HttpHandler (or an MVC Controller) is an OK solution but it's worth exploring to see if there's an easier way that would involve fewer moving parts. In this case the they really want the file to have the extension *.png rather than *.aspx (page) or *.ashx (handler) as it they believe it affects their image's SEO in Google Image search.

Better: Custom HttpHandlers

Remember that HttpHandlers are targeted to a specific path, file or wildcard and HttpModules are always watching. Why not use an HttpHandler directly and plug it in at the web.config level and set runAllManagedModulesForAllRequests="false"?

<add name="pngs" verb="*" path="images/handlerproducts/*/default.png"
type="DynamicPNGs.CustomPNGHandler, DynamicPNGs" preCondition="managedHandler"/>
<modules runAllManagedModulesForAllRequests="false" />

Note how I have a * there in part of the URL? Let's try hitting http://localhost:37865/images/handlerproducts/myproductname/default.png. It still works.

A dynamically generated PNG from an ASP.NET IHttpHandler

This lets us not only completely bypass the managed ASP.NET Routing system but also remove RAMMFAR so fewer modules are involved for other requests. By default, managed modules will only run for requests that ended up mapped to the managed pipeline and that's almost always requests with an extension. You may need to be aware of routing if you have a "greedy route" that might try to get ahold of your URL. You might want an IgnoreRoute. You also need to be aware of modules earlier in the process that have a greedy BeginRequest.

The customer could setup ASP.NET and IIS to route request for *.png to ASP.NET, but why not be as specific as possible so that the minimum number of requests is routed through the managed pipeline? Don't do more work than you need to.

What about extensionless URLs?

Getting extensionless URLs working on IIS6 was tricky before and lots of been written on it. Early on in IIS6 and ASP.NET MVC you'd map everything *.* to managed code. ASP.NET Routing used to require RAMFARR set to true until the Extensionless URL feature was created.

Extentionless URLs support was added in this KB and ships with ASP.NET MVC 4. If you have ASP.NET MVC 4, you have Extentionless URLs on your development machine. But your server may not. You may need to install this hotfix, or turn on RAMMFAR. I would rather you install the update than turn on RAMMFAR if you can avoid it. The Run All Modules options is really a wildcard mapping.

Extensionless URLs exists so you can have URLs like /home/about and not /home/about.aspx. It exists to get URLs without extensions to be seen be the managed pipelines while URLs with extensions are not seen any differently. The performance benefits of Extensionless URLs over RAMMFAR are significant.

If you have static files like CSS, JS and PNG files you really want those to be handled by IIS (and HTTP.SYS) for speed. Don't let your static files get mapped to ASP.NET if you can avoid it.


When you're considering any solution within the ASP.NET stack (or "One ASP.NET" as I like to call it)...

The complete ASP.NET stack with MVC, Web Pages, Web Forms and more called out in a stack of boxes

...remember that it's things like IHttpHandler that sit at the bottom and serve one request (everything comes from IHttpHandler) while it's IHttpModule that's always watching and can see every request.

In other words, and HttpHandler sees the ExecuteRequestHandler event which is just one event in the pipeline, while HttpModules can see every event they subscribe to.

HttpHandlers and Modules are at the bottom of the stack

I hope this helps!

Sponsor: Thank you to my friends at Axosoft for sponsoring the Hanselman feed this week. Do check out their product! Imagine agile project management software that is brilliantly easy to use, blazingly fast, totally customizable, and just $7 per user. With OnTime Scrum, you won't have to imagine. Get started free.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.