static void wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            ICollection ic = downloadQueue as ICollection;

            //
            lock (ic.SyncRoot)
            {
                DownloadQueueItem qi = Array.Find <DownloadQueueItem>(downloadQueue.ToArray(),
                                                                      x => x.ConnectionPoint == sender);
                //
                if (e.Error != null)
                {
                    //
                    if (qi != null)
                    {
                        Log.WriteError(String.Format("Could not download app {0}", qi.ItemKey), e.Error);
                    }
                    else
                    {
                        Log.WriteError(e.Error);
                    }
                }
                //
                downloadQueue.Remove(qi);
            }
        }
        public static int GetApplicationDownloadProgress(string appName)
        {
            int appProgress = 0;
            //
            bool appInQueue = IsApplicationInDownloadQueue(appName);

            //
            if (appInQueue)
            {
                ICollection ic = downloadQueue as ICollection;
                //
                lock (ic.SyncRoot)
                {
                    DownloadQueueItem qi = Array.Find <DownloadQueueItem>(downloadQueue.ToArray(),
                                                                          x => x.ItemKey == appName.ToLower());
                    //
                    if (qi.Progress != null)
                    {
                        appProgress = qi.Progress.ProgressPercentage;
                    }
                }
            }
            //
            return(appProgress);
        }
        //
        public static void StartApplicationDownload(string appName, string packageUrl, string localPathToStore)
        {
            //
            bool appInQueue = IsApplicationInDownloadQueue(appName);

            //
            if (!appInQueue)
            {
                ICollection ic = downloadQueue as ICollection;
                //
                lock (ic.SyncRoot)
                {
                    //
                    DownloadQueueItem qi = new DownloadQueueItem
                    {
                        ItemKey         = appName.ToLower(),
                        ConnectionPoint = new WebClient(),
                        Progress        = null
                    };
                    //
                    qi.DownloadItemURI      = packageUrl;
                    qi.LocalFilePathToStore = localPathToStore;
                    qi.ConnectionPoint.Headers.Add(HttpRequestHeader.UserAgent, WebApplicationGallery.WEB_PI_USER_AGENT_HEADER);
                    qi.ConnectionPoint.DownloadFileCompleted   += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
                    qi.ConnectionPoint.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
                    //
                    downloadQueue.Add(qi);
                    // Start async download (10 attempts)
                    int numOfAttempt = 0;
                    do
                    {
                        try
                        {
                            bool success = ThreadPool.QueueUserWorkItem(
                                new WaitCallback(qi.StartItemDownloadAsync));
                            // Exit the loop if the item successfuly queued
                            if (success)
                            {
                                break;
                            }
                        }
                        catch (Exception ex)
                        {
                            numOfAttempt++;
                            // Log an exception
                            Log.WriteError(String.Format("Could not start distibutive download from the following URI: {0}", qi.DownloadItemURI), ex);
                        }
                    }while (numOfAttempt <= 10);
                }
            }
        }
        static void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            ICollection ic = downloadQueue as ICollection;

            //
            lock (ic.SyncRoot)
            {
                DownloadQueueItem qi = Array.Find <DownloadQueueItem>(downloadQueue.ToArray(),
                                                                      x => x.ConnectionPoint == sender);

                if (qi != null)
                {
                    qi.Progress = e;
                }
            }
        }
		//
		public static void StartApplicationDownload(string appName, string packageUrl, string localPathToStore)
		{
			//
			bool appInQueue = IsApplicationInDownloadQueue(appName);
			//
			if (!appInQueue)
			{
				ICollection ic = downloadQueue as ICollection;
				//
				lock (ic.SyncRoot)
				{
					//
					DownloadQueueItem qi = new DownloadQueueItem
					{
						ItemKey = appName.ToLower(),
						ConnectionPoint = new WebClient(),
						Progress = null
					};
					//
					qi.DownloadItemURI = packageUrl;
					qi.LocalFilePathToStore = localPathToStore;
					qi.ConnectionPoint.Headers.Add(HttpRequestHeader.UserAgent, String.Format(WebApplicationGallery.WEB_PI_USER_AGENT_HEADER, Environment.OSVersion));
					qi.ConnectionPoint.DownloadFileCompleted += new System.ComponentModel.AsyncCompletedEventHandler(wc_DownloadFileCompleted);
					qi.ConnectionPoint.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
					//
					downloadQueue.Add(qi);
					// Start async download (10 attempts)
					int numOfAttempt = 0;
					do
					{
						try
						{
							bool success = ThreadPool.QueueUserWorkItem(
								new WaitCallback(qi.StartItemDownloadAsync));
							// Exit the loop if the item successfuly queued 
							if (success)
								break;
						}
						catch (Exception ex)
						{
							numOfAttempt++;
							// Log an exception
							Log.WriteError(String.Format("Could not start distibutive download from the following URI: {0}", qi.DownloadItemURI), ex);
						}
					}
					while (numOfAttempt <= 10);
				}
			}
		}