/// <summary>
		/// Add a file to the collection
		/// </summary>
		/// <param name="filename">The path of the file</param>
		/// <param name="scanMetaData">Whether to scan the tracks meta data as well</param>
		/// <param name="callback">A function that will be sent along with the SourceModified event</param>
		/// <param name="callbackParams">The parameters for the callback function</param>
		private static void AddFile(String filename, bool scanMetaData = false, ScannerCallback callback = null, object callbackParams = null)
		{
			List<KeyValuePair<ScannerCallback, object>> callbacks = new List<KeyValuePair<ScannerCallback, object>>();
			if (callback != null)
				callbacks.Add(new KeyValuePair<ScannerCallback,object>(callback, callbackParams));
			AddFile(filename, scanMetaData, callbacks);
		}
		/// <summary>
		/// Remove a file from the collection
		/// </summary>
		/// <param name="filename">The path of the file</param>
		/// <param name="callback">A function that will be sent along with the SourceModified event</param>
		/// <param name="callbackParams">The parameters for the callback function</param>
		private static void RemoveFile(String filename, ScannerCallback callback = null, object callbackParams = null)
		{
			List<KeyValuePair<ScannerCallback, object>> callbacks = new List<KeyValuePair<ScannerCallback, object>>();
			if (callback != null)
				callbacks.Add(new KeyValuePair<ScannerCallback,object>(callback, callbackParams));
			RemoveFile(filename, callbacks);
		}
		/// <summary>
		/// Scan a path for files and synchronize its content with our collection
		/// </summary>
		/// <param name="path">The path to scan</param>
		/// <param name="tree">The tree that is either the path itself or the parent</param>
		/// <param name="removeIgnored">Whether or not we should remove any paths that we find which is set to ignore</param>
		/// <param name="callback">The callback which will be sent along with the SourceModified event</param>
		private static void ScanPath(String path, SourceTree tree, bool removeIgnored = true, ScannerCallback callback = null, object callbackParams = null)
		{
			List<KeyValuePair<ScannerCallback, object>> callbacks = new List<KeyValuePair<ScannerCallback, object>>();
			if (callback != null)
				callbacks.Add(new KeyValuePair<ScannerCallback,object>(callback, callbackParams));
			ScanPath(path, tree, removeIgnored, callbacks);
		}
		/// <summary>
		/// Scan all folders in the collection for supported music tracks
		/// </summary>
		/// <param name="callback">A function that will be sent along with the SourceModified event</param>
		/// <param name="callbackParams">The parameters for the callback function</param>
		public static void ScanSources(ScannerCallback callback = null, object callbackParams = null)
		{
			List<KeyValuePair<ScannerCallback, object>> callbacks = new List<KeyValuePair<ScannerCallback, object>>();
			if (callback != null)
				callbacks.Add(new KeyValuePair<ScannerCallback,object>(callback, callbackParams));
			ScanSources(callbacks);
		}
		/// <summary>
		/// Scans the sources after a slight delay with buffering of callbacks and their parameters.
		/// </summary>
		/// <param name="callback">The callback to be called after scan is complete</param>
		/// <param name="callbackParams">Parameters for the callback</param>
		public static void ScanSourcesWithDelay(ScannerCallback callback = null, object callbackParams = null)
		{
			if (scanDelay != null)
				scanDelay.Dispose();

			if (callback != null)
				scanDelayCallbacks.Add(new KeyValuePair<ScannerCallback,object>(callback, callbackParams));

			scanDelay = new Timer(DoScanSources, null, 400, 3600000);
		}
		/// <summary>
		/// Add a source to the collection
		/// </summary>
		/// <param name="source">The source to be added</param>
		/// <param name="callback">A function that will be sent along with the SourceModified event</param>
		/// <param name="callbackParams">The parameters for the callback function</param>
		public static void AddSource(SourceData source, ScannerCallback callback = null, object callbackParams = null)
		{
			U.L(LogLevel.Information, "FILESYSTEM", String.Format("{0} the {1} {2}", 
				(source.Include ? "Adding" : "Ignoring"), source.Type, source.Data));

			SourceTree s = GetSourceTree(source.Data, sourceForest);

			if (s != null)
			{
				U.L(LogLevel.Warning, "FILESYSTEM", String.Format("Removing currently {0} {1} {2}",
					(source.Include ? "added" : "ignored"), source.Type, source.Data));
				RemoveSource(source);
			}

			DispatchSourceAdded(source);
			ScanSourcesWithDelay(callback, callbackParams);
		}
		/// <summary>
		/// Add a source to the collection
		/// </summary>
		/// <param name="path">The path of source to be added</param>
		/// <param name="callback">A function that will be sent along with the SourceModified event</param>
		/// <param name="callbackParams">The parameters for the callback function</param>
		public static void AddSource(string path, ScannerCallback callback = null, object callbackParams = null)
		{
			SourceData s = null;
			if (File.Exists(path))
			{
				s = new SourceData()
				{
					Data = path,
					Type = SourceType.File,
					Icon = "pack://application:,,,/Platform/Windows 7/GUI/Images/Icons/FileAudio.ico",
					Include = true
				};
			}
			else if (Directory.Exists(path))
			{
				s = new SourceData()
				{
					Data = path,
					Type = SourceType.Folder,
					Icon = "pack://application:,,,/Platform/Windows 7/GUI/Images/Icons/Folder.ico",
					Include = true
				};
			}
			else
			{
				s = new SourceData()
				{
					Data = path,
					Type = SourceType.Library,
					Icon = "pack://application:,,,/Platform/Windows 7/GUI/Images/Icons/Library.ico",
					Include = true
				};
			}
			if (s != null)
				AddSource(s, callback, callbackParams);
		}