int __fastcall Console(TConsoleMode Mode)
{
  DebugAssert(Mode != cmNone);
  TProgramParams * Params = TProgramParams::Instance();
  int Result = RESULT_SUCCESS;
  TConsole * Console = NULL;
  TConsoleRunner * Runner = NULL;
  TStrings * ScriptCommands = new TStringList();
  TStrings * ScriptParameters = new TStringList();
  try
  {
    UnicodeString ConsoleInstance;
    // First check for /consoleinstance as /console is always used by winscp.com
    if (Params->FindSwitch(L"consoleinstance", ConsoleInstance))
    {
      Configuration->Usage->Inc(L"ConsoleExternal");
      Console = new TExternalConsole(ConsoleInstance, Params->FindSwitch(L"nointeractiveinput"));
    }
    else if (Params->FindSwitch(L"Console") || (Mode != cmScripting))
    {
      Configuration->Usage->Inc(L"ConsoleOwn");
      Console = TOwnConsole::Instance();
    }
    else
    {
      Configuration->Usage->Inc(L"ConsoleNull");
      Console = new TNullConsole();
    }

    SetNoGUI();

    if (Mode == cmHelp)
    {
      Configuration->Usage->Inc(L"UsageShown");
      Usage(Console);
    }
    else if (Mode == cmBatchSettings)
    {
      if (CheckSafe(Params))
      {
        Configuration->Usage->Inc(L"BatchSettings");
        Result = BatchSettings(Console, Params);
      }
    }
    else if (Mode == cmKeyGen)
    {
      if (CheckSafe(Params))
      {
        Configuration->Usage->Inc(L"KeyGen");
        Result = KeyGen(Console, Params);
      }
    }
    else if (Mode == cmFingerprintScan)
    {
      if (CheckSafe(Params))
      {
        Configuration->Usage->Inc(L"FingerprintScan");
        Result = FingerprintScan(Console, Params);
      }
    }
    else if (Mode == cmDumpCallstack)
    {
      Result = DumpCallstack(Console, Params);
    }
    else if (Mode == cmInfo)
    {
      Result = Info(Console);
    }
    else if (Mode == cmComRegistration)
    {
      if (CheckSafe(Params))
      {
        Result = ComRegistration(Console);
      }
    }
    else
    {
      Runner = new TConsoleRunner(Console);

      try
      {
        if (CheckSafe(Params))
        {
          UnicodeString Value;
          if (Params->FindSwitch(SCRIPT_SWITCH, Value) && !Value.IsEmpty())
          {
            Configuration->Usage->Inc(L"ScriptFile");
            LoadScriptFromFile(Value, ScriptCommands);
          }
          Params->FindSwitch(COMMAND_SWITCH, ScriptCommands);
          if (ScriptCommands->Count > 0)
          {
            Configuration->Usage->Inc(L"ScriptCommands");
          }
          Params->FindSwitch(L"parameter", ScriptParameters);
          if (ScriptParameters->Count > 0)
          {
            Configuration->Usage->Inc(L"ScriptParameters");
          }
        }

        UnicodeString Session;
        if (Params->ParamCount >= 1)
        {
          Session = Params->Param[1];
          if (Params->ParamCount > 1)
          {
            Runner->PrintMessage(LoadStr(SCRIPT_CMDLINE_PARAMETERS));
          }
        }

        CheckLogParam(Params);
        CheckXmlLogParam(Params);

        Result = Runner->Run(Session, Params,
          (ScriptCommands->Count > 0 ? ScriptCommands : NULL),
          ScriptParameters);
      }
      catch(Exception & E)
      {
        Runner->ShowException(&E);
        Result = RESULT_ANY_ERROR;
      }
    }
  }
  __finally
  {
    delete Runner;
    delete Console;
    delete ScriptCommands;
    delete ScriptParameters;
  }

  return Result;
}