/// <summary>
		/// Executes the worker.
		/// </summary>
		/// <param name="info">The worker information.</param>
		public void ExecuteWorker(ExtensionInfo info)
		{
			Logger.Info("Creating worker with configuration set {0}", info.Name);
			IWorker worker = CreateWorker(info.AssemblyPath, info.ClassName);
			ConfigureCommonValues(worker);
			info.Configure(worker);
			ExecuteWorker(worker);
		}
		/// <summary>
		/// Starts the assembly.
		/// </summary>
		/// <param name="info">The information.</param>
		/// <returns>
		///   <c>true</c> if the worker was successfully started, otherwise <c>false</c>
		/// </returns>
		public static bool StartWorker(ExtensionInfo info)
		{
			Logger.Info("Starting worker with name: {0}", info.Name);

			if (!File.Exists(Path.GetFullPath(info.AssemblyPath)))
			{
				Logger.Warn("Unable to start worker '{0}', the assembly {1} could not be found.", info.Name, Path.GetFileName(info.AssemblyPath));
				return false;
			}

			WorkerProcess process = null;

			if (_executingProcesses.ContainsKey(Path.GetFullPath(info.AssemblyPath)))
			{
				Logger.Debug("Executing domain for assembly '{0}' found, executing worker '{1}' in existing domain.", Path.GetFileName(info.AssemblyPath), info.Name);
				process = _executingProcesses[info.AssemblyPath];
			}
			else
			{
				Logger.Debug("Creating domain for assembly '{0}'", info.AssemblyPath);
				Type           remoteType = typeof(WorkerProcess);
				AppDomainSetup domainInfo = new AppDomainSetup();

				// Prepares a different domain for extension assemblies search. This isolates the loaded assemblies from the application domain.
				domainInfo.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;

				AppDomain     domain  = AppDomain.CreateDomain(Guid.NewGuid().ToString().GetHashCode().ToString("x"), null, domainInfo);
				process = (WorkerProcess)domain.CreateInstanceAndUnwrap(remoteType.Assembly.FullName, remoteType.FullName);

				domain.UnhandledException += OnWorkerDomainUnhandledException;
				_executingDomains[Path.GetFullPath(info.AssemblyPath)]   = domain;
				_executingProcesses[Path.GetFullPath(info.AssemblyPath)] = process;
			}

			process.ExecuteWorker(info);
			return true;
		}
		/// <summary>
		/// Creates a new object that is a copy of the current instance.
		/// </summary>
		/// <returns>A new object that is a copy of this instance.</returns>
		public object Clone()
		{
			ExtensionInfo result = new ExtensionInfo();

			result.name                     = (string)this.name.Clone();
			result.assembly                 = (string)this.assembly.Clone();
			result.token                    = (string)this.token.Clone();
			result.klass                    = (string)this.klass.Clone();
			result.properties               = (PropertiesCollection)this.properties.Clone();

			return result;
		}