Scott Hanselman

Everything's broken and nobody's upset

September 17, '12 Comments [296] Posted in Musings
Sponsored By

Train Wreck Wikipedia CommonsSoftware doesn't work. I'm shocked at how often we put up with it. Here's just a few issues - literally off the top of my head - that I personally dealt with last week.

  • My iPhone 4s has 3 gigs of "OTHER" taking up space, according to iTunes. No one has any idea what other is and all the suggestions are to reset it completely or "delete and re-add your mail accounts." Seems like a problem to me when I have only 16 total gigs on the device!
  • The Windows Indexing Service on my desktop has been running for 3 straight days. The answer? Delete and rebuild the index. That only took a day.
  • I have 4 and sometimes 5 Contacts for every one Actual Human on my iPhone. I've linked them all, but duplicates still show up.
  • My iMessage has one guy who chats me and the message will show up in any one of three guys with the same name. Whenever he chats me I have to back out and see which "him" it is coming from.
  • I don't think Microsoft Outlook has ever "shut down cleanly."
  • The iCloud Photo stream is supposed to show the last 1000 pictures across all my iOS devices. Mine shows 734. Dunno why. The answer? Uninstall, reinstall, stop, start, restart.
  • Where's that email I sent you? Likely stuck in my Outlook Outbox.
  • Gmail is almost as slow as Outlook now. Word is I should check for rogue apps with access to my Gmail via OAuth. There are none.
    • UPDATE: Yes, I know how OAuth works, I've implemented versions of the spec. A Gmail engineer suggested that perhaps other authenticated clients (GMVault, Boomerang, or IMAP clients, etc) were getting in line and forcing synchronous access to my Gmail account. Gabriel Weinberg has blogged about Gmail slowness as well.
  • I use Microsoft Lync (corporate chat) on my Desktops, two laptops, iPhone and iPad as well as in a VM or two. A few days back two of the Lync instances got into a virtual fight and started a loop where they'd log each other in and out declaring "you are logged into Lync from too many places." So basically, "Doctor, it hurts when I do this." "Don't do that."
  • Final Cut Pro crashes when you scroll too fast while saving.
  • My Calendar in Windows 8 is nothing but birthdays. Hundreds of useless duplicate birthdays of people I don't know.
  • iPhoto is utterly unusable with more than a few thousand photos.
  • Don't even get me started about iTunes.
  • And Skype. Everything about the Skype UI. Especially resizing columns in Skype on a Mac.
  • Google Chrome after version 19 or so changed the way it registers itself on Windows as the default browser and broke a half dozen apps (like Visual Studio) who look for specific registry keys that every other browser writes.
  • I should get an Xbox achievement for every time I press "Clear" in the iPhone notification window.
  • I've got two Microsoft Word documents that I wrote in Word that I can no longer open in Word as Word says "Those aren't Word documents."
  • Three of my favorite websites lock up IE9 regularly. Two lock up Chrome. I never remember which is which.
  • AdBlock stopped my Gmail for working for three days with JavaScript errors until I figured it out and added an exclusion.

All of this happened with a single week of actual work. There are likely a hundred more issues like this. Truly, it's death by a thousand paper cuts.

I work for Microsoft, have my personal life in Google, use Apple devices to access it and it all sucks.

Alone or in a crowd, no one cares.

Here's the worst part, I didn't spend any time on the phone with anyone about these issues. I didn't file bugs, send support tickets or email teams. Instead, I just Googled around and saw one of two  possible scenarios for each issue.

  1. No one has ever seen this issue. You're alone and no one cares.
  2. Everyone has seen this issue. No one from the company believes everyone. You're with a crowd and no one cares.

Sadly, both of these scenarios ended in one feeling. Software doesn't work and no one cares.

How do we fix it?

Here we are in 2012 in a world of open standards on an open network, with angle brackets and curly braces flying at gigabit speeds and it's all a mess. Everyone sucks, equally and completely.

  • Is this a speed problem? Are we feeling we have to develop too fast and loose?
  • Is it a quality issue? Have we forgotten the art and science of Software QA?
  • Is it a people problem? Are folks just not passionate about their software enough to fix it?
  • UPDATE: It is a communication problem? Is it easy for users to report errors and annoyances?

I think it's all of the above. We need to care and we need the collective will to fix it. What do you think?

P.S. If you think I'm just whining, let me just say this. I'm am complaining not because it sucks, but because I KNOW we can do better.

Related Posts in this Three Part series on Software Quality

  1. Everything's broken and nobody's upset
  2. A Bug Report is a Gift
  3. Help your users record and report bugs with the Problem Steps Recorder

Sponsor: Thanks to DevExpress for sponsoring this week's feed. Multi-channel experiences made easy: Discover DXTREME. Delight your users with apps designed expressly for their device. DXTREME, multi-channel tools build stunning apps across devices & optimize for the best of each platform, from Win8 to the iPhone. And, the powerful HTML5, CSS and JavaScript tools in DXTREME also build interactive web apps.

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

Dick and Jane: Jedi Masters

September 15, '12 Comments [27] Posted in Musings
Sponsored By

Dick and Jane: Jedi MastersMy 6 year old started First Grade this last week. We've been reading to him and his brother, without fail, every night for their entire lives. It's been awesome to start seeing their little brains firing as they are starting to read on their own.

My wife picked up a copy of the classic 1950s Dick and Jane series since it's what her parents used and how she learned to read. We only made it a few pages in when both boys declared "this is boring!"

"Why is it boring?"

"There are no light sabers! Dick and Jane don't DOOOOOO anything."

So before dinner this afternoon the 6 year old and the 4 year old - the same little boys for whom I wrote The Nerd Parent's Guide: When and how to introduce your kids to Star Wars - and I proceeded to sit down and create Dick and Jane: Jedi Master.

The boys not only wrote all the text but also made all the decisions about the pictures. You can blame me for the poor Photoshop work but the kids get the credit for everything else. We printed it on glossy inkjet paper and stapled it and the boys are THRILLED.

Have fun. PDF at the bottom, thumbnails here.

NOTE: This is a parody, it's not for sale. Don't sue me. Just playin'.


Jump, Sally. Jump up. Flip, Sally. Flip up!Force push, Sally! Force push Tim. Fly, Tim, fly!

Use the Force, Dick. Use the Force, JaneThere is no try, Jane. There is only do. Do, Jane, Do.

We had so much fun doing this. I hope my kids end up feeling empowered to create and remix.

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

FREE: Visual Studio Express 2012 for Windows Desktop

September 13, '12 Comments [32] Posted in Open Source | VS2012
Sponsored By

Visual Studio Express 2012 for Windows DesktopWhen the Visual Studio 2012 free versions were originally announced the first thing I noticed was that they had switched from a language-specific model (C# Express, VB Express, etc) to a target-specific model (Windows 8, Web). However, I was very surprised (and disappointed) that there was no free way to make Console Apps, or Windows Forms apps, or anything for the Windows Desktop. I wasn't the only one who thought this was a problem. Shortly thereafter (with a lot of people pushing) Soma announced there would be a "Windows Desktop" Express version for free. He said:

...we heard from our community that developers want to have for Windows desktop development the same great experience and access to the latest Visual Studio 2012 features at the Express level.

Today, I’m happy to announce that we will add Visual Studio Express 2012 for Windows Desktop to the Visual Studio 2012 family. This will bring to the Visual Studio Express family significant new capabilities that we’ve made available in Visual Studio 2012 for building great desktop applications.

I'm glad folks realized that no-cost desktop software development is important. Open Source projects need free tools like the Express SKUs. Even better that the the Express Desktop SKU gets the new 2012 features as well.

Today Visual Studio has made Visual Studio Express 2012 for Windows Desktop available and you can go download it now free. The best part is that this one SKU supports C++, C#, and Visual Basic together. With this one free version you can make WinForms, WPF, Console or Class Libraries with any or all of Visual Basic, C#, as well as Win32 projects, class libraries, and CLR apps using C++. You can also, of course, combine projects over multiple languages into a single solution. You can target both .NET 4.0 and 4.5.

NOTE: You might wonder, what about a free F#? Why isn't F# included? We've got a free download to add F# support to the free Visual Studio Express 2012 for Web!

Related Links

While Express SKUs don't allow arbitrary add-ins (you need Pro for that) the free SKU does include Unit Testing, Code Analysis, as well as the NuGet package manager. It's a bit of a nice coup for my little group that NuGet is now included in ALL Visual Studio 2012 SKUs, even Express ones. Package management is finally happening in .NET.

In the screenshot below I've added a C++ Console app, a Window Forms C# app and a C# Console to a single solution in VS2012 using Express for Windows Desktop.


Just to illustrate one of the reasons I think a free "Desktop" SKU is so important, I wanted to share a cool open source project I found recently called Topshelf. It's a library for making Windows Services easier to write using .NET. It's up on GitHub under an Apache license. The easiest way to get Topshelf is with NuGet with simply "install-package Topshelf". Topshelf has some impressive documentation as well, especially for an open source project!

Here's a simple Windows Service with a basic heartbeat timer using Topshelf:

public class TownCrier
readonly Timer _timer;
public TownCrier()
_timer = new Timer(1000) {AutoReset = true};
_timer.Elapsed += (sender, eventArgs) => Console.WriteLine("It is {0} an all is well", DateTime.Now);
public void Start() { _timer.Start(); }
public void Stop() { _timer.Stop(); }

public class Program
public static void Main()
HostFactory.Run(x => //1
x.Service<TownCrier>(s => //2
s.ConstructUsing(name=> new TownCrier()); //3
s.WhenStarted(tc => tc.Start()); //4
s.WhenStopped(tc => tc.Stop()); //5
x.RunAsLocalSystem(); //6

x.SetDescription("Sample Topshelf Host"); //7
x.SetDisplayName("Stuff"); //8
x.SetServiceName("stuff"); //9
}); //10

Topshelf even has nice Log4net and NLog integration. Anyway, this is just the kind of powerful, useful, and interesting open source library that could be helped by a free Express SKU for Desktop. I'm not involved directly (yet ;) ) in making decisions this high up, but I (and many, many others) inside and out continue to advocate for balance. In this case I'm very glad that the decision was made to ship this SKU and I hope you all find it useful whether you work in open source or in education.

There's more details over at the Visual Studio blog and the team is watching the comments.

This week's sponsor: Be part of GENERATION APP. Your Idea. Your App. 30 Days. Begin your 30-day journey to create a Windows Store style app and talk 1-on-1 with a Windows 8 app development pro. Get started today.

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

ASP.NET Web Forms DynamicData FieldTemplates for DbGeography Spatial Types (plus Model Binders and Friendly URLs)

September 11, '12 Comments [16] Posted in ASP.NET | ASP.NET MVC | Javascript | Open Source | VS2012
Sponsored By

Did you enjoy my recent post on ASP.NET MVC DisplayTemplate and EditorTemplates for Entity Framework DbGeography Spatial Types and it's associated GIANT URL?

Modeling Binding and EditorTemplates...for ASP.NET Web Forms?

DisplayTemplates and EditorTemplates are a great way in ASP.NET MVC to keep things DRY (Don't Repeat Yourself.) That means I can just write EditorFor() calls like this:

@Html.EditorFor(model => model.Location)   

See how I didn't say "TextBoxFor" or "MapFor"? You say EditorFor and it makes the right choice. If the type is called DbGeography then it will look for a Editor Template at ~/Shared/EditorTemplates/DbGeography.cshtml. It's a nice feature of ASP.NET MVC that folks don't use enough.

Now, remember ASP.NET Dynamic Data? You might think that idea "died" or was "retired" when actually the concepts are built into ASP.NET itself. That means that ASP.NET Web Forms developers can have "Editor Templates" as well. They are called FieldTemplates in ASP.NET Web Forms parlance, and making sure we have feature parity like this is part of the larger move towards One ASP.NET. We'll take the ASP.NET MVC sample using DbGeography and make it work for Web Forms in a very similar way.

<%--  Let's not do this: <asp:TextBox ID="location" runat="server" Text="<%# BindItem.Location %>"></asp:TextBox>--%>
<asp:DynamicControl runat="server" ID="Location" DataField="Location" Mode="Insert" />

When we do a POST, ModelBinders handle the boring work of digging types out of the HTTP POST. These work in not just MVC but also Web Forms and Web API now. Rather that Request["this"] and Request["that"] a model binder can be registered to do the work of populating a type from the Request. Even better, we can populate objects not only from the POST but also anywhere that provides values including Cookies, QueryStrings and more.

Let's walk through this one by one and at the end we'll have a complete sample that has:

  • ASP.NET Web Forms and AS.NET MVC in one application, living together.
  • FriendlyURLs for Web Forms and Routing for MVC
  • 90% Shared Model Binding Code between Web Forms and MVC
    • Spatial types custom DbGeography Model Binder
  • Simple CRUD (Create, Read, Update, Delete) to the same database in both Web Forms and MVC using the same model.

The goal is to continue to move towards a cleaner, more unified platform...One ASP.NET. This is an example. Thanks to Pranav for his help!

Related Links

DbGeography FieldTemplates for ASP.NET Web Forms

Here's a FormView in ASP.NET Web Forms. Notice the ItemType is set, rather than using Eval(). We're also using SelectMethod rather than an ObjectDataSource.

<asp:FormView runat="server" ItemType="TouristAttraction" ID="attractionDetails"
<asp:DynamicControl DataField="name" runat="server" ClientIDMode="Static" /><br />
<asp:DynamicControl DataField="location" runat="server" /><br />
<a id="A1" href='<%# FriendlyUrl.Href("~/WebForms/Edit", Item.TouristAttractionId ) %>'>Edit</a> |
<a id="A1" href='<%# FriendlyUrl.Href("~/WebForms") %>'>Back To List</a>

The FormView doesn't specify what a location or name should look like, but since we know the model...

public class TouristAttraction
public int TouristAttractionId { get; set; }
public string Name { get; set; }
public DbGeography Location { get; set; }
} will dynamically figure out the controls (hence, DynamicControl) and find FieldTemplates in the DynamicData folder:

Dynamic Data Field Templates called DbGeography.ascx

Those templates are simple. Here's the Edit example.

<%@ Control Language="C#" CodeBehind="DbGeography_Edit.ascx.cs" Inherits="MvcApplication2.DynamicData.FieldTemplates.DbGeography_EditField" %>

<asp:TextBox runat="server" ID="location" CssClass="editor-for-dbgeography" />

You might say, hang on, this is just a text box! I thought we weren't using TextBoxes? The point is that we have control in a single place over what a DbGeography - or any type - looks like when it's being edited, or when it's read-only. In this example, I AM using a Textbox BUT I've added a CssClass that I will use to create a Google Map using obtrusive JavaScript thanks to my recent refactoring from Dave Ward. If I wanted I could change this FieldTemplate to be a 3rd party control or whatever custom markup I want.

If you have an object called Foo, then make a Foo.ascx and Foo_Edit.ascx and put them in ~/DynamicData/FieldTemplates and they'll be used by DynamicControl.

Model Binding for ASP.NET Web Forms

I did 13 short videos recently on new features in ASP.NET 4.5 including one on Model Binding for ASP.NET Web Forms. Here's the Model Binding one.

Let me first say that Model Binding between ASP.NET Web Forms, MVC and Web API isn't unified. I want more unification and I am continuing to push the One ASP.NET vision internally and many people share that goal.

In the previous blog post on ASP.NET MVC, Model Binding and DbGeography I already had a good Model Binder that I want to reuse between MVC and Web Forms. I can do it, although the ModelBinderProvider stuff isn't very well unified.

First, here's the unified Model Binder for DbGeography that is used for both MVC and Web Forms. We implement two interfaces and use one implementation. Not ideal, but it works.

public class DbGeographyModelBinder : IMvcModelBinder, IWebFormsModelBinder
public object BindModel(ControllerContext controllerContext, MvcModelBindingContext bindingContext)
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
return BindModelImpl(valueProviderResult != null ? valueProviderResult.AttemptedValue : null);

public bool BindModel(ModelBindingExecutionContext modelBindingExecutionContext, WebFormsModelBindingContext bindingContext)
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
bindingContext.Model = BindModelImpl(valueProviderResult != null ? valueProviderResult.AttemptedValue : null);
return bindingContext.Model != null;

private DbGeography BindModelImpl(string value)
if (value == null)
return (DbGeography)null;
string[] latLongStr = value.Split(',');
// TODO: More error handling here, what if there is more than 2 pieces or less than 2?
// Are we supposed to populate ModelState with errors here if we can't conver the value to a point?
string point = string.Format("POINT ({0} {1})", latLongStr[1], latLongStr[0]);
//4326 format puts LONGITUDE first then LATITUDE
DbGeography result = DbGeography.FromText(point, 4326);
return result;

Part of the "trick" are these namespace aliases:

using IMvcModelBinder = System.Web.Mvc.IModelBinder;
using IWebFormsModelBinder = System.Web.ModelBinding.IModelBinder;

using MvcModelBindingContext = System.Web.Mvc.ModelBindingContext;
using WebFormsModelBindingContext = System.Web.ModelBinding.ModelBindingContext;

I'd love to see unification of the Model Binding stack at some point.

In Web Forms we could register a single model binder for a single type like this:

ModelBinderProviders.Providers.RegisterBinderForType(typeof(DbGeography), new DbGeographyModelBinder());

Or collect a collection of like types into a Provider of Binders and add them like this:

ModelBinderProviders.Providers.Insert(0,new EFModelBinderProviderWebForms());

I only have one Model Binder but here's how I'd register a provider for both Web Forms and MVC and have them use my same binder if I wanted:

public class EFModelBinderProviderMvc : System.Web.Mvc.IModelBinderProvider
public IMvcModelBinder GetBinder(Type modelType)
if (modelType == typeof(DbGeography))
return new DbGeographyModelBinder();
return null;

public class EFModelBinderProviderWebForms : System.Web.ModelBinding.ModelBinderProvider
public override IWebFormsModelBinder GetBinder(ModelBindingExecutionContext modelBindingExecutionContext, WebFormsModelBindingContext bindingContext)
if (bindingContext.ModelType == typeof(DbGeography))
return new DbGeographyModelBinder();
return null;

Now, to finish the CRUD.


The team released an alpha build of ASP.NET FriendlyUrls that includes cleaner URLs, easier Routing, and Mobile Views for ASP.NET Web Forms yesterday. I wanted to use them in this project as well, and have WebForms and MVC together in the same app.

I could certainly register a bunch of Web Forms routes manually like this:

RouteTable.Routes.MapPageRoute("Attraction", "WF/Attraction", "~/WebForms/Default.aspx");
RouteTable.Routes.MapPageRoute("AttractionNew", "WF/Attraction/Create", "~/WebForms/Create.aspx");
RouteTable.Routes.MapPageRoute("AttractionEdit", "WF/Attraction/Edit/{id}", "~/WebForms/Edit.aspx");
...and more...

Or I could enable FriendlyUrls after my MVC routes like this:

//MVC will be for MVC, while WebForms is under /WebForms/ using Friendly URLs
name: "Default",
url: "MVC/{controller}/{action}/{id}",
defaults: new { controller = "Attraction", action = "Index", id = UrlParameter.Optional }


Here's what my site looks like now. Notice the /MVC and /WebForms URLs. I can call /WebForms/Create or /MVC/Create..

MVC and Web Forms together in one app

I generate the FriendlyUrls like this in Web Forms:

<a href='<%# FriendlyUrl.Href("~/WebForms/Edit", Item.TouristAttractionId ) %>'>Edit</a>
| <a href='<%# FriendlyUrl.Href("~/WebForms/Delete", Item.TouristAttractionId ) %>'>Delete</a>
| <a href='<%# FriendlyUrl.Href("~/WebForms/Details", Item.TouristAttractionId ) %>'>Details</a>

and like this in MVC

@Html.RouteLink("Edit", "Default",new {Controller="Attraction", action="Edit",id=item.TouristAttractionId}) |
@Html.RouteLink("Details", "Default",new {Controller="Attraction", action="Details",id=item.TouristAttractionId})|
@Html.RouteLink("Delete", "Default",new {Controller="Attraction", action="Delete",id=item.TouristAttractionId})

If this was a larger app I would write better helper methods for both, perhaps using an open source helper library.

UPDATE: One thing I forgot to mention was how to get the values out of the FriendlyURL. You can use things like [Form] and [QueryString] to model bind in WebForms. Now you can add [FriendlyUrlSegments] to get data out, like the ID in this example:

public TouristAttraction attractionsForm_GetItem([FriendlyUrlSegments]int? id)
TouristAttraction touristattraction = db.TouristAttractions.Find(id);
return touristattraction;

Both sections talk to the same database and use the same shared Google Maps JavaScript.

MVC and Web Forms together in one app

I chose not to try to share the _Layout.cshtml and Site.Master, although I could share Razor views and Web Forms.

I've updated the my playground repository with a single project that contains all this. Hope it helps.

Related Links

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

Automatically Backup your Gmail account on a schedule with GMVault and Windows Task Scheduler

September 10, '12 Comments [32] Posted in Tools
Sponsored By

It's nice to have your things backed up to the cloud, but you really need to have local backups as well. I have two 1TB pocket hard drives that I rotate between my home and the bank. They are labeled Offsite Backup A and Offsite Backup B. You can encrypt them with either Bitlocker To Go or TrueCrypt, and I do.

Related Links

I've got years and years of email in my only personal email account, powered by Gmail. I've recently started backing up my WHOLE gmail account with a wonderful free tool called GMVault. Setup requires a little attention to detail but once it's done, it's done.

Once installed, you run GMVault-Shell and type "gmvault sync" The first backup will take HOURS and on Windows will put thousands and thousands of files in your C:\Users\YOURNAME\gmvault-db directory. You can move this directory if you want. My email backup was over 350,000 emails so I moved it to my larger D drive by using the -d option on the command line.

After this multi-hour sync was finally done, I wanted to make sure I updated the archive every week or so with backups of new emails.

Create a Scheduled Gmail Backup with Task Scheduler

Go to your start menu and type "Task" and run the Task Scheduler. Some folks don't even know this exists!

On the right side click "Create Basic Task."

Create Basic Task Wizard - Task Name

Make it weekly or monthly or whatever makes you happy.

Create Basic Task Wizard - Setting time

Your action is Start a Program

Create Basic Task Wizard - Start a program

Make the Program like this and check your path first.


Under Arguments, use sync -t quick like this. Be sure to use the -t quick or you'll get ALL your email again!

sync -t quick 

optionally you can point to a specific backup directory like this. If there is a space in your path, use quotes around it.

sync -t quick -d D:\gmvault-db

I also made my task start in the same directory as GmVault, so "C:\Users\YOURNAME\AppData\Local\gmvault"

Create a Basic Task - final screen with all options set

My scheduled task ended up with command line arguments like this:

sync -t quick -d D:\gmvault-db

You can test it by right clicking on it in the Task Scheduler list and clicking "Run." If you need to debug it or if it just starts and then quickly disappears, go into your gmvault.bat and add a "pause" command before the "exit" command to keep the window open long enough to see any errors.

Here's my automatic Gmail backup in action:

GMVault automatically backing up my email

Hope this helps you!

This week's sponsor: Be part of GENERATION APP. Your Idea. Your App. 30 Days. Begin your 30-day journey to create a Windows Store style app and talk 1-on-1 with a Windows 8 app development pro. Get started today.

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.