protected UserDashboard GetDefaultDashboard(DashboardContext ctx)
		{			
			//user didn't have a dashboard
			//return the default settings and default selected widgets
			UserDashboard defaultDashboard = new UserDashboard();

			defaultDashboard.Id = 0;

			//use anonymous, we won't save this to the db
			defaultDashboard.Username = "******";
							
			defaultDashboard.Layout = "layout2";

			var defaultWidgets = from w in ctx.Widgets
									where w.DefaultSelection == true
									select w;

			foreach (Widget widget in defaultWidgets)
			{
				DashboardWidget myWidget = new DashboardWidget(widget);
				defaultDashboard.SelectedWidgets.Add(myWidget);
			}

			return defaultDashboard;			
		}
		// GET api/<controller>
		public DashboardResult Get()
		{
			using (var ctx = new DashboardContext())
			{
				ctx.Configuration.ProxyCreationEnabled = false;
								
				UserDashboard dashboard = null;

				string username = "";

				if (this.User.Identity.IsAuthenticated && !string.IsNullOrEmpty(this.User.Identity.Name))
				{
					//demo was written using windows authentication so we need to remove the prefixed domain from the username
					username = User.Identity.Name.Split(new char[] { '/', '\\' }).Last();
				
					//find the saved settings and selected widgets
					//if it's not there we'll get the defaults later
					dashboard = (from d in ctx.UserDashboards.Include("SelectedWidgets.Widget")
								 where d.Username == username
								 orderby d.Id descending
								 select d).FirstOrDefault();
					if (dashboard != null && dashboard.SelectedWidgets.Count > 0)
						dashboard.SelectedWidgets.OrderBy(x => x.ColumnOrder);
				}
				
				if (dashboard == null)
				{
					//user didn't have a dashboard, they could be anonymous
					//return the default settings and default selected widgets
					dashboard = GetDefaultDashboard(ctx);

					if (!string.IsNullOrEmpty(username))
						dashboard.Username = username;
				}
				
				//TODO: Add some security to the available widgets
				//by updating the linq statement
				var availableWidgets = from w in ctx.Widgets
									   orderby w.Title
									   select w;

				DashboardResult result = new DashboardResult(dashboard, availableWidgets.ToList());

				return result;
			}
		}
		//// POST api/<controller>
		//public void Post([FromBody]string value)
		//{
		//}

		// PUT api/<controller>
		/// <summary>
		/// 
		/// </summary>
		/// <param name="updatedDashboard"></param>
		/// <returns>Dashboard Id</returns>
		public int Put(DashboardResult updatedDashboard)
		{
			string username = "";

			if (this.User.Identity.IsAuthenticated && !string.IsNullOrEmpty(this.User.Identity.Name))
			{
				//demo was written using windows authentication so we need to remove the prefixed domain from the username
				username = User.Identity.Name.Split(new char[] { '/', '\\' }).Last();
			}
			else
			{	
				HttpResponseMessage msg = Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "User not authenticated.");
				throw new HttpResponseException(msg);				
			}

			using (var ctx = new DashboardContext())
			{
				ctx.Configuration.ProxyCreationEnabled = false;

				var existingDashboard = (from d in ctx.UserDashboards.Include("SelectedWidgets.Widget")
										 where d.Username == username
										 orderby d.Id descending
										 select d).FirstOrDefault();

				//the user doesn't have a CUSTOMIZED dashboard yet, 
				//make a new one
				if (existingDashboard == null)
				{
					existingDashboard = GetDefaultDashboard(ctx);
					
					existingDashboard.Username = username;

					//save it
					ctx.UserDashboards.Add(existingDashboard);
					ctx.SaveChanges();					
				}
				
				//set the layout
				existingDashboard.Layout = updatedDashboard.Layout;	

				
				//reset the widgets:
				
				//go through the existing list
				//		- remove widgets that are not in the updated list
				//		- update widgets with new settings
				List<DashboardWidget> widgetsToRemove = new List<DashboardWidget>();
				foreach (DashboardWidget existingWidget in existingDashboard.SelectedWidgets)
				{
					var matchedWidget = updatedDashboard.Widgets.FirstOrDefault(x => x.Id == existingWidget.Widget.Id);

					if (matchedWidget != null)
					{
						//exists in new selection

						//update existing widgets with new settings							
						existingWidget.SetColumnName(matchedWidget.ColumnName);
						existingWidget.ColumnOrder = matchedWidget.ColumnOrder;
						existingWidget.SetWindowState(matchedWidget.Open);
						existingWidget.MetaData = matchedWidget.MetaData;
					}
					else
					{
						//was removed from the user's selection
						widgetsToRemove.Add(existingWidget);
					}
				}
				foreach(DashboardWidget oldWidget in widgetsToRemove)
				{					
					existingDashboard.SelectedWidgets.Remove(oldWidget);
					ctx.DashboardWidgets.Remove(oldWidget);
				}

				//find widgets in the new list that haven't been added yet and create a record
				foreach(WidgetResult updatedWidget in updatedDashboard.Widgets)
				{
					//make sure the widget has a valid widget id
					if(string.IsNullOrEmpty(updatedWidget.Id))
						continue;// skip it, check the others

					if (updatedWidget.IsSelected == false)
					{
						existingDashboard.SelectedWidgets.RemoveAll(x => x.Widget.Id == updatedWidget.Id);
						continue;
					}

					if (existingDashboard.SelectedWidgets.Exists(x => x.Widget.Id == updatedWidget.Id) == false)
					{
						//check if it's a valid widget
						var widget = (from realWidget in ctx.Widgets
									  where realWidget.Id == updatedWidget.Id
									  select realWidget).FirstOrDefault();

						if (widget == null)
							continue;// no such widget, check the others

						DashboardWidget newDashboardWidget = new DashboardWidget();

						newDashboardWidget.Widget = widget;
						newDashboardWidget.SetColumnName(updatedWidget.ColumnName);
						newDashboardWidget.ColumnOrder = updatedWidget.ColumnOrder;
						newDashboardWidget.MetaData = updatedWidget.MetaData;
						
						existingDashboard.SelectedWidgets.Add(newDashboardWidget);
					}
				}

				ctx.SaveChanges();

				return existingDashboard.Id;
			}			
		}