private void Server_OnProjectsUpdated(object sender, BuildQueryEventArgs e)
        {
            if (e == null)
            {
                return;
            }

            Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
                {
                    TeamProject project = sender as TeamProject;
                    if (project != null)
                    {
                        lock (buildContent)
                        {
                            //Get current build item list
                            Dictionary<string, BuildDetail> currentBuilds = new Dictionary<string, BuildDetail>();
                            foreach (BuildDetail item in buildContent)
                            {
                                currentBuilds.Add(item.BuildDefinitionUri, item);
                            }
                            //Get updated builds
                            var query = from buildQueryItem in e.BuildQueryResults
                                        where buildQueryItem.Builds.Count() > 0
                                        orderby buildQueryItem.Builds[0].BuildNumber
                                        select buildQueryItem;

                            foreach (BuildQueryResult buildQuery in query)
                            {
                                foreach (BuildDetail item in buildQuery.Builds)
                                {
                                    //If the item doesnt exist or needs updating
                                    if ((currentBuilds.ContainsKey(item.BuildDefinitionUri) && (buildUpdates[item.BuildDefinitionUri] < item.LastChangedOn))
                                        || (!currentBuilds.ContainsKey(item.BuildDefinitionUri)))
                                    {
                                        //Update the last time
                                        if (buildUpdates.ContainsKey(item.BuildDefinitionUri))
                                        {
                                            buildUpdates[item.BuildDefinitionUri] = item.LastChangedOn;
                                        }
                                        else
                                        {
                                            buildUpdates.Add(item.BuildDefinitionUri, item.LastChangedOn);
                                        }

                                        //Add if doesn't exist
                                        if (!currentBuilds.ContainsKey(item.BuildDefinitionUri))
                                        {
                                            currentBuilds.Add(item.BuildDefinitionUri, item);
                                            buildContent.Add(item);

                                            //Add to view if not hidden
                                            if (!HiddenBuilds.Contains(item.BuildDefinitionUri))
                                            {
                                                buildContentView.Add(item);
                                            }
                                        }
                                        else //Update the item
                                        {
                                            currentBuilds[item.BuildDefinitionUri].Status = item.Status;
                                            currentBuilds[item.BuildDefinitionUri].RequestedFor = item.RequestedFor;
                                            currentBuilds[item.BuildDefinitionUri].LogLocation = item.LogLocation;
                                        }

                                        //If the icon is green and a build is failing, set it to red, only if visible
                                        if (!HiddenBuilds.Contains(item.BuildDefinitionUri))
                                        {
                                            if ((currentIconColour != IconColour.Amber) &&
                                                (item.Status == BuildStatus.Failed))
                                            {
                                                SetIcon(IconColour.Red);
                                            }
                                            else if (currentIconColour == IconColour.Grey)
                                            {
                                                SetIcon(IconColour.Green);
                                            }
                                        }

                                        //Update the name to a friendly name
                                        foreach (TeamServer server in servers)
                                        {
                                            string buildName = server.GetDefinitionByUri(item.BuildDefinitionUri).GetFriendlyName();
                                            if (!String.IsNullOrEmpty(buildName))
                                            {
                                                currentBuilds[item.BuildDefinitionUri].BuildNumber = buildName;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //Send alerts for changes
                        AlertChanges(e);
                    }
                }));
        }
        private void AlertChanges(BuildQueryEventArgs buildQueryEventArgs)
        {
            bool iconChanged = false;
            IconColour mainIconColour = IconColour.Green;

            //Cleanup history
            CleanupIds();

            //Find in progress builds
            foreach (BuildQueueQueryResult queueResult in buildQueryEventArgs.BuildQueueQueryResults)
            {
                //Check for cancelled builds
                IconColour? iconColour = CheckCancelledBuilds(queueResult);
                if (iconColour.HasValue)
                {
                    mainIconColour = iconColour.Value;
                    iconChanged = true;
                }

                //Loop through builds with active histories
                foreach (QueuedBuild build in queueResult.Builds.OrderBy(item => item.Id))
                {
                    //Check if build is hidden
                    if (HiddenBuilds.Contains(build.BuildDefinitionUri))
                    {
                        continue;
                    }

                    //Get the friendly names
                    string buildName = GetFriendlyName(build.BuildDefinitionUri);

                    //Adding builds while the tray is running can cause it to fail, only builds which have atleast 1 successfull build will be displayed.
                    if (!String.IsNullOrEmpty(buildName))
                    {
                        //Check if this is an "In Progress" status and has not been displayed before
                        if ((!buildIdsAlertedInProgress.Contains(build.Id)) && (build.Status == QueueStatus.InProgress))
                        {
                            StatusMessage message = new StatusMessage
                                                        {
                                                            EventDate = DateTime.Now,
                                                            BuildStatus = IconColour.Amber,
                                                            Message =
                                                                String.Format(CultureInfo.CurrentUICulture,
                                                                              ResourcesMain.NotifierWindow_InProgress,
                                                                              build.RequestedBy, buildName)
                                                        };

                            statusMessages.Enqueue(message);
                            mainIconColour = IconColour.Amber;
                            iconChanged = true;
                            buildIdsAlertedInProgress.Add(build.Id);
                            buildIdUris.Add(build.Id, build.BuildDefinitionUri);
                            NotifyIconMainIcon.Text = ResourcesMain.MainWindow_Title + " - Building";

                            UpdateMainWindowItem(build.BuildDefinitionUri, BuildStatus.InProgress, build.RequestedBy);
                        } //Check if this is an "Queued" status and has not been displayed before
                        else if ((!buildIdsAlertedQueued.Contains(build.Id)) && (build.Status == QueueStatus.Queued))
                        {
                            StatusMessage message = new StatusMessage
                                                        {
                                                            EventDate = DateTime.Now,
                                                            BuildStatus = IconColour.Amber,
                                                            Message =
                                                                String.Format(CultureInfo.CurrentUICulture,
                                                                              ResourcesMain.NotifierWindow_Queued,
                                                                              build.RequestedBy, buildName)
                                                        };
                            statusMessages.Enqueue(message);
                            buildIdsAlertedQueued.Add(build.Id);
                        }//Check if this is an "Completed" status and has not been displayed before
                        else if ((!buildIdsAlertedDone.Contains(build.Id)) && (build.Status == QueueStatus.Completed))
                        {
                            StatusMessage message = new StatusMessage
                                                        {
                                                            EventDate = DateTime.Now
                                                        };

                            buildIdsAlertedInProgress.Remove(build.Id);
                            buildIdUris.Remove(build.Id);

                            //Get the status from the build log
                            foreach (BuildDetail item in buildContent)
                            {
                                if (item.BuildDefinitionUri == build.BuildDefinitionUri)
                                {
                                    switch (item.Status)
                                    {
                                        case BuildStatus.Succeeded:
                                            message.BuildStatus = IconColour.Green;
                                            message.Message = String.Format(CultureInfo.CurrentUICulture,
                                                                            ResourcesMain.NotifierWindow_BuildPassed,
                                                                            buildName);
                                            break;
                                        case BuildStatus.PartiallySucceeded:
                                            message.BuildStatus = IconColour.Red;
                                            message.Message = String.Format(CultureInfo.CurrentUICulture,
                                ResourcesMain.NotifierWindow_BuildPartial,
                                buildName);
                                            break;
                                        default:
                                            message.BuildStatus = IconColour.Red;
                                            message.Message = String.Format(CultureInfo.CurrentUICulture,
                                                                            ResourcesMain.NotifierWindow_FailedBuild,
                                                                            build.RequestedFor, buildName);
                                            break;
                                    }

                                    message.HyperlinkUri = new Uri(item.LogLocation);
                                    mainIconColour = message.BuildStatus;
                                    iconChanged = true;
                                    break;
                                }
                            }

                            NotifyIconMainIcon.Text = ResourcesMain.MainWindow_Title;

                            statusMessages.Enqueue(message);
                            buildIdsAlertedDone.Add(build.Id);

                        }
                    }
                }
            }

            //Only pop up if new messages
            if (statusMessages.Count > 0)
            {
                lastStatusMessage = statusMessages.Dequeue();
                MessageWindow.Show(lastStatusMessage, 3000);
            }
            //Only update the main icon if its a valid status change
            if (iconChanged)
            {
                SetIcon(mainIconColour);
            }
        }