Adds, and downloads if required, a mod to the mod manager.
Inheritance: BackgroundTask, IDisposable
		/// <summary>
		/// Adds a task to the monitor.
		/// </summary>
		/// <param name="p_tskTask">The task to monitor.</param>
		public void AddActivity(AddModTask p_tskTask)
		{
			p_tskTask.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(Task_PropertyChanged);
			m_oclTasks.Add(p_tskTask);
			if (p_tskTask.IsActive)
				m_setActiveTasks.Add(p_tskTask);
		}
		/// <summary>
		/// Removes a task from the monitor.
		/// </summary>
		/// <remarks>
		/// Tasks can only be removed if they are not running.
		/// </remarks>
		/// <param name="p_tskTask">The task to remove.</param>
		public void RemoveDownload(AddModTask p_tskTask)
		{
			if (CanRemove(p_tskTask))
			{
				p_tskTask.PropertyChanged -= new System.ComponentModel.PropertyChangedEventHandler(Task_PropertyChanged);
				m_oclTasks.Remove(p_tskTask);
				m_setActiveTasks.Remove(p_tskTask);
			}
		}
		/// <summary>
		/// Removes the given task.
		/// </summary>
		/// <param name="p_tskTask">IBackgroundTask task to remove.</param>
		public void RemoveTask(AddModTask p_tskTask)
		{
			if (DownloadMonitor.CanRemove(p_tskTask))
				DownloadMonitor.RemoveDownload(p_tskTask);
		}
			/// <summary>
			/// Adds the specified mod to the queue.
			/// </summary>
			/// <remarks>
			/// The specified mod is downloaded, and then added to the mod manager.
			/// </remarks>
			/// <param name="p_uriPath">The URL of the mod to add to the manager.</param>
			/// <param name="p_cocConfirmOverwrite">The delegate to call to resolve conflicts with existing files.</param>
			public IBackgroundTask AddMod(Uri p_uriPath, ConfirmOverwriteCallback p_cocConfirmOverwrite)
			{
				AddModTask amtModAdder = null;
				
				if (p_uriPath.Scheme.ToLowerInvariant().ToString() == "nxm")
				{
					if (m_dicActiveTasks.ContainsKey(p_uriPath))
						return m_dicActiveTasks[p_uriPath];
					Trace.TraceInformation(String.Format("[{0}] Adding Mod to AddModQueue", p_uriPath.ToString()));
					amtModAdder = new AddModTask(m_mmgModManager.GameMode, m_mmgModManager.ReadMeManager, m_mmgModManager.EnvironmentInfo, m_mmgModManager.ManagedModRegistry, m_mmgModManager.FormatRegistry, m_mmgModManager.ModRepository, p_uriPath, p_cocConfirmOverwrite);
					amtModAdder.TaskEnded += new EventHandler<TaskEndedEventArgs>(ModAdder_TaskEnded);
					amtModAdder.IsRemote = true;
					m_dicActiveTasks[p_uriPath] = amtModAdder;
					m_mmgModManager.DownloadMonitor.AddActivity(amtModAdder);
					amtModAdder.AddMod(false);
				}
				else
				{
					if (m_dicActiveTasks.ContainsKey(p_uriPath))
						return m_dicActiveTasks[p_uriPath];
					Trace.TraceInformation(String.Format("[{0}] Adding Mod to AddModQueue", p_uriPath.ToString()));
					amtModAdder = new AddModTask(m_mmgModManager.GameMode, m_mmgModManager.ReadMeManager, m_mmgModManager.EnvironmentInfo, m_mmgModManager.ManagedModRegistry, m_mmgModManager.FormatRegistry, m_mmgModManager.ModRepository, p_uriPath, p_cocConfirmOverwrite);
					amtModAdder.TaskEnded += new EventHandler<TaskEndedEventArgs>(ModAdder_TaskEnded);
					amtModAdder.IsRemote = false;
					m_dicActiveTasks[p_uriPath] = amtModAdder;
					m_mmgModManager.DownloadMonitor.AddActivity(amtModAdder);

					if (LocalTaskCount > 1)
						amtModAdder.AddMod(true);
					else
						amtModAdder.AddMod(false);
				}
				return amtModAdder;
			}
		/// <summary>
		/// A simple constructor that initializes the object with the given values.
		/// </summary>
		/// <param name="p_tskTask">The task whose status is to be displayed by this list
		/// view item.</param>
		public DownloadListViewItem(AddModTask p_tskTask)
		{
			Task = p_tskTask;

			ListViewSubItem lsiSubItem = SubItems[0];
			lsiSubItem.Name = ObjectHelper.GetPropertyName(() => p_tskTask.OverallMessage);
			lsiSubItem.Text = p_tskTask.OverallMessage;

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = ObjectHelper.GetPropertyName(() => p_tskTask.OverallProgress);
			if (p_tskTask.ShowOverallProgressAsMarquee)
				lsiSubItem.Text = "Working...";
			else
			{
				lsiSubItem.Text = "";
			}

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = ObjectHelper.GetPropertyName(() => p_tskTask.Status);
			if (p_tskTask.Status == TaskStatus.Running)
				{
				if (p_tskTask.IsRemote)
					lsiSubItem.Text = "Downloading";
				else
					lsiSubItem.Text = "Moving";
			}
			else
				lsiSubItem.Text = p_tskTask.Status.ToString();

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = ObjectHelper.GetPropertyName(() => p_tskTask.ItemMessage);
			if (p_tskTask.ShowItemProgress)
				lsiSubItem.Text = p_tskTask.ItemMessage;
			else
				lsiSubItem.Text = "";

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = "Fileserver";
			lsiSubItem.Text = "";

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = "ETA";
			lsiSubItem.Text = "";

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = ObjectHelper.GetPropertyName(() => p_tskTask.ItemProgress);
			if (p_tskTask.ShowItemProgress)
			{
				if (p_tskTask.ShowItemProgressAsMarquee)
					lsiSubItem.Text = "Working...";
				else
				{
					lsiSubItem.Text = "";
				}
			}

			lsiSubItem = SubItems.Add(new ListViewSubItem());
			lsiSubItem.Name = ObjectHelper.GetPropertyName(() => p_tskTask.InnerTaskStatus);

			p_tskTask.PropertyChanged += new PropertyChangedEventHandler(Task_PropertyChanged);
		}
		/// <summary>
		/// Updates the list view item to display the changed property.
		/// </summary>
		/// <param name="p_tskTask">The task whose property has changed.</param>
		/// <param name="p_strPropertyName">The name of the propety that has changed.</param>
		private void HandleChangedTaskProperty(AddModTask p_tskTask, string p_strPropertyName)
		{
			if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.OverallMessage)))
			{
				SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.OverallMessage)].Text = p_tskTask.OverallMessage;
			}
			else if ((p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ETA_Seconds))) || (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ETA_Minutes))))
			{
				if (Task.Status == TaskStatus.Running)
					SubItems["ETA"].Text = String.Format("{0:00}:{1:00}", p_tskTask.ETA_Minutes, p_tskTask.ETA_Seconds);
				else
					SubItems["ETA"].Text = String.Empty;
			}
			else if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.FileServer)))
			{
				if (Task.Status == TaskStatus.Running)
					SubItems["Fileserver"].Text = p_tskTask.FileServer;
				else
					SubItems["Fileserver"].Text = String.Empty;
			}
			else if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.TaskSpeed)))
			{
				SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemMessage)].Text = String.Format("{0:} kb/s", p_tskTask.TaskSpeed.ToString());
			}
			else if ((p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.DownloadProgress))) || (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.DownloadMaximum))))
			{
				SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.OverallProgress)].Text = String.Format("{0}kb / {1}kb", p_tskTask.DownloadProgress, p_tskTask.DownloadMaximum);
			}
			else if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ActiveThreads)))
			{
				if (Task.Status == TaskStatus.Running)
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress)].Text = p_tskTask.ActiveThreads.ToString();
				else
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress)].Text = String.Empty;
			}
			else if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress))
					|| p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgressMaximum))
					|| p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgressMinimum))
					|| p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ShowItemProgress))
					|| p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.ShowItemProgressAsMarquee)))
			{
				if (p_tskTask.ShowItemProgress)
				{
					if (p_tskTask.ShowItemProgressAsMarquee)
						SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress)].Text = "Working...";
				}
				else
				{
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemMessage)].Text = null;
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress)].Text = null;
				}
			}
			else if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.Status)))
			{
				if (p_tskTask.Status == TaskStatus.Running)
				{
					if (p_tskTask.IsRemote)
						SubItems[p_strPropertyName].Text = "Downloading";
					else
						SubItems[p_strPropertyName].Text = "Moving";
				}
				else
				{
					SubItems[p_strPropertyName].Text = p_tskTask.Status.ToString();
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemMessage)].Text = "";
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress)].Text = "";
					if (!(p_tskTask.Status.ToString() == "Paused"))
						SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.OverallProgress)].Text = "";
					SubItems["ETA"].Text = "";
				}
			}
			else if (p_strPropertyName.Equals(ObjectHelper.GetPropertyName<AddModTask>(x => x.InnerTaskStatus)))
			{
				if ((p_tskTask.InnerTaskStatus.ToString() == "Retrying") && ((p_tskTask.Status != TaskStatus.Paused) && (p_tskTask.Status != TaskStatus.Queued)))
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.Status)].Text = p_tskTask.InnerTaskStatus.ToString();
				else if (p_tskTask.InnerTaskStatus.ToString() == "Running")
				{
					if(p_tskTask.IsRemote)
						SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.Status)].Text = "Downloading";
					else
						SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.Status)].Text = "Moving";
				}
					
				else
				{
					SubItems["ETA"].Text = "";
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemMessage)].Text = "";
					SubItems[ObjectHelper.GetPropertyName<AddModTask>(x => x.ItemProgress)].Text = "";
				}
			}
		}
		/// <summary>
		/// Adds the given <see cref="IBackgroundTask"/> to the view's list. If the <see cref="IBackgroundTask"/>
		/// already exists in the list, nothing is done.
		/// </summary>
		/// <param name="p_tskTask">The <see cref="IBackgroundTask"/> to add to the view's list.</param>
		protected void AddTaskToList(AddModTask p_tskTask)
		{
			foreach (DownloadListViewItem lviExisitingDownload in lvwTasks.Items)
				if (lviExisitingDownload.Task == p_tskTask)
					return;
			p_tskTask.PropertyChanged -= new PropertyChangedEventHandler(Task_PropertyChanged);
			p_tskTask.PropertyChanged += new PropertyChangedEventHandler(Task_PropertyChanged);
			DownloadListViewItem lviDownload = new DownloadListViewItem(p_tskTask);
			lvwTasks.Items.Add(lviDownload);
		}