/// <summary>
    /// The main entry point for the MP2 server application.
    /// </summary>
    public static void Main(params string[] args)
    {
      // Parse command line options
      var mpOptions = new CommandLineOptions();
      var parser = new CommandLine.Parser(with => with.HelpWriter = Console.Out);
      parser.ParseArgumentsStrict(args, mpOptions, () => Environment.Exit(1));

      if (mpOptions.RunAsConsoleApp)
        new ApplicationLauncher(mpOptions.DataDirectory).RunAsConsole();
      else
      {
        ServiceBase[] servicesToRun = new ServiceBase[] { new WindowsService() };
        ServiceBase.Run(servicesToRun);
      }
    }
    /// <summary>
    /// The main entry point for the MP 2 server application.
    /// </summary>
    private static void Main(params string[] args)
    {
      Thread.CurrentThread.Name = "Main";

      // Parse Command Line options
      CommandLineOptions mpArgs = new CommandLineOptions();
      ICommandLineParser parser = new CommandLineParser(new CommandLineParserSettings(Console.Error));
      if (!parser.ParseArguments(args, mpArgs, Console.Out))
        Environment.Exit(1);

#if !DEBUG
      string logPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), @"Team MediaPortal\MP2-Server\Log");
#endif

      Application.ThreadException += Application_ThreadException;
      AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;


      SystemStateService systemStateService = new SystemStateService();
      ServiceRegistration.Set<ISystemStateService>(systemStateService);
      systemStateService.SwitchSystemState(SystemState.Initializing, false);

      try
      {
        ILogger logger = null;
        try
        {
          // Check if user wants to override the default Application Data location.
          ApplicationCore.RegisterCoreServices(mpArgs.DataDirectory);
          logger = ServiceRegistration.Get<ILogger>();

#if !DEBUG
          IPathManager pathManager = ServiceRegistration.Get<IPathManager>();
          logPath = pathManager.GetPath("<LOG>");
#endif

          BackendExtension.RegisterBackendServices();
        }
        catch (Exception e)
        {
          if (logger != null)
            logger.Critical("Error starting application", e);
          systemStateService.SwitchSystemState(SystemState.ShuttingDown, true);
          ServiceRegistration.IsShuttingDown = true;

          BackendExtension.DisposeBackendServices();
          ApplicationCore.DisposeCoreServices();

          throw;
        }

        // Start the core
        logger.Debug("ApplicationLauncher: Starting core");

        try
        {
          IMediaAccessor mediaAccessor = ServiceRegistration.Get<IMediaAccessor>();
          IPluginManager pluginManager = ServiceRegistration.Get<IPluginManager>();
          pluginManager.Initialize();
          pluginManager.Startup(false);
          ApplicationCore.StartCoreServices();

          BackendExtension.StartupBackendServices();
          ApplicationCore.RegisterDefaultMediaItemAspectTypes(); // To be done after backend services are running

          mediaAccessor.Initialize();

          systemStateService.SwitchSystemState(SystemState.Running, true);
          BackendExtension.ActivateImporterWorker(); // To be done after default media item aspect types are present and when the system is running (other plugins might also install media item aspect types)

          Application.Run(new MainForm());

          systemStateService.SwitchSystemState(SystemState.ShuttingDown, true);
          ServiceRegistration.IsShuttingDown = true; // Block ServiceRegistration from trying to load new services in shutdown phase

          mediaAccessor.Shutdown();

          pluginManager.Shutdown();

          BackendExtension.ShutdownBackendServices();
          ApplicationCore.StopCoreServices();
        }
        catch (Exception e)
        {
          logger.Critical("Error executing application", e);
          systemStateService.SwitchSystemState(SystemState.ShuttingDown, true);
          ServiceRegistration.IsShuttingDown = true;
        }
        finally
        {
          BackendExtension.DisposeBackendServices();
          ApplicationCore.DisposeCoreServices();
          systemStateService.SwitchSystemState(SystemState.Ending, false);
        }
      }
      catch (Exception ex)
      {
#if DEBUG
        ConsoleLogger log = new ConsoleLogger(LogLevel.All, false);
        log.Error(ex);
#else
        ServerCrashLogger crash = new ServerCrashLogger(logPath);
        crash.CreateLog(ex);
#endif
        systemStateService.SwitchSystemState(SystemState.Ending, false);
        Application.Exit();
      }
    }