public static SupportedPlatforms Platforms(RemotingProtocol protocol)
            {
                SupportedPlatforms platforms = 0;

                switch (protocol)
                {
                    case RemotingProtocol.inProcess:
                        platforms |= SupportedPlatforms.All;
                        break;
                    case RemotingProtocol.ipcAuto:
                        platforms |= SupportedPlatforms.Win;
                        break;
                    default:
                        throw new NotImplementedException(protocol.ToString());
                }

                return platforms;
            }
            /*
            public static string PortName(int port)
            {
                return string.Format("FluidEarthEngineServer_{0}", port.ToString());
            }
            */
            public static XDocument ServerConfigXml(RemotingProtocol protocol, string objectUri, string portName, int port, string serverType)
            {
                XElement channel;

                switch (protocol)
                {
                    case RemotingProtocol.ipcAuto:
                    case RemotingProtocol.ipc:
                        channel =
                            new XElement("channel",
                                new XAttribute("ref", "ipc"),
                                new XAttribute("portName", portName));
                        break;
                    case RemotingProtocol.tcp:
                        channel =
                            new XElement("channel",
                                new XAttribute("ref", "tcp"),
                                new XAttribute("port", port));
                        break;
                    case RemotingProtocol.http:
                        channel =
                            new XElement("channel",
                                new XAttribute("ref", "http"),
                                new XAttribute("port", port));
                        break;
                    default:
                        throw new NotImplementedException(protocol.ToString());
                }

                XElement xml = new XElement("configuration",
                    new XElement("system.runtime.remoting",
                        new XElement("application",
                            new XAttribute("name", "FluidEarth2 Engine Server"),
                            new XElement("service",
                                new XElement("wellknown",
                                    new XAttribute("type", serverType),
                                    new XAttribute("objectUri", objectUri),
                                    new XAttribute("mode", "Singleton"))),
                            new XElement("channels", channel))));

                return new XDocument(
                    new XDeclaration("1.0", "utf-8", "yes"),
                    xml);
            }
        /// <summary>
        /// Start server
        /// </summary>
        /// <param name="args">Server Args</param>
        public static void Main(string[] a)
        {
            try
            {
                Trace.Listeners.Clear();
                //Trace.Listeners.Add(new TextWriterTraceListener(Console.Out));
                //Trace.AutoFlush = true;

                var sdkUri = new Uri(Assembly.GetAssembly(typeof(RemotingServerEngineTime)).CodeBase);

                Console.WriteLine(
                    "\r\n##########################################" +
                    "\r\n FluidEarth2.Sdk.RemotingServerEngineTime" +
                    "\r\n##########################################" +
                    "\r\n\t" + DateTime.Now.ToString("u"));

                _args.AddRange(Environment.GetCommandLineArgs());

                foreach (string arg in _args)
                    Trace.TraceInformation(string.Format("Arg: {0}", arg));

                if (_args.Count < 4)
                {
                    Console.WriteLine("Minimum of 3 arguments required");
                    Console.WriteLine();
                    Console.Write(CommandLineArgs());
                    return;
                }

                // First argument must be RemotingProtocol

                _protocol = (RemotingProtocol)Enum.Parse(typeof(RemotingProtocol), _args[1]);

                // second argument objectUri

                _objectUri = _args[2];

                if (!_objectUri.EndsWith(".rem") && !_objectUri.EndsWith(".soap"))
                    throw new Exception("objectUri must end in either .rem or .soap");

                // third argument is either portName if IPC or port number

                switch (_protocol)
                {
                    case RemotingProtocol.ipcAuto:
                    case RemotingProtocol.ipc:
                        _portName = _args[3];
                        break;
                    case RemotingProtocol.tcp:
                    case RemotingProtocol.http:
                        _port = int.Parse(_args[3]);
                        break;
                    default:
                        throw new NotImplementedException(_protocol.ToString());
                }

                if (_args.Contains("launchDebugger"))
                {
                    Trace.TraceWarning("Launching debugger");
                    bool launched = Debugger.Launch();
                    Trace.TraceInformation("Launched debugger " + launched.ToString());
                }

                _ensureSecurity = _args.Contains("ensureSecurity");
                _traceEngine = _args.Contains("traceEngine");

                Trace.TraceInformation(string.Format("\r\n" +
                    "\tProtocol: {0}\r\n" +
                    "\tObjectUri: {1} (With extension .rem or .soap)\r\n" +
                    "\tPortName: {2} (Only required if protocol is IPC)\r\n" +
                    "\tPort: {3} (Only required if protocol not IPC)\r\n" +
                    "\tEnsure Security: {4}\r\n" +
                    "\tTrace Engine: {5}\r\n",
                    _protocol, _objectUri, _portName, _port, _ensureSecurity, _traceEngine
                    ));

                ResolveDependancies();

                _assemblyLoader = AssemblyLoader.New("RemotingServerEngineTime");

                var sdkFile = new FileInfo(sdkUri.LocalPath);

                _configFilename = Path.Combine(sdkFile.DirectoryName, "FluidEarth2_Sdk_RemotingServerEngineTime.cfg");

                if (File.Exists(_configFilename))
                {
                    Trace.TraceInformation(string.Format(
                        "Using local remoting config \"{0}\"\r\n\r\n{1}",
                        _configFilename, File.ReadAllText(_configFilename)));
                }
                else
                {
                    _configFilenameTmp = true;
                    _configFilename = Path.GetTempFileName();

                    Console.WriteLine("_configFilename: " + _configFilename);

                    var serverType = "FluidEarth2.Sdk.RemotingServerEngineTime, FluidEarth2_Sdk";

                    var config = Utilities.Remoting.ServerConfigXml(
                        _protocol, _objectUri, _portName, _port, serverType);

                    config.Save(_configFilename);

                    Trace.TraceInformation(string.Format(
                        "Saved remoting config to \"{0}\"\r\n\r\n{1}",
                        _configFilename, config.ToString()));
                }

                Trace.TraceInformation("Configuring server ...");
            #if MONO
                RemotingConfiguration.Configure(_configFilename);
            #else
                RemotingConfiguration.Configure(_configFilename, _ensureSecurity);
            #endif
                Trace.TraceInformation(string.Format(
                    "Configured server\r\n{0}\r\n{1}\r\n{2}",
                    Utilities.Remoting.InfoRemotingConfiguration(),
                    Utilities.Remoting.InfoRegisteredChannels(),
                    "\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~" +
                    "\r\n Server awaiting requests" +
                    "\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~"
                    ));

                if (_protocol != RemotingProtocol.ipcAuto)
                {
                    Trace.TraceInformation("Hit return to exit");
                    Console.ReadLine();
                }
                else
                {
                    while (!_finished)
                        Thread.Sleep(_sleep);

                    Trace.TraceWarning("Engine Finished");
                }
            }
            catch (System.Exception e)
            {
                _lastException = new Exception("Engine Server Initialisation Catch", e);

                Trace.TraceError(_lastException.ToString());
            }
            finally
            {
                if (_configFilenameTmp
                    && _configFilename != null
                    && File.Exists(_configFilename))
                {
                    File.Delete(_configFilename);

                    Trace.TraceInformation("Deleted " + _configFilename);
                }

                Trace.TraceInformation(
                    "\r\n#####################################" +
                    "\r\n FLUID EARTH ENGINE SERVER SHUT DOWN" +
                    "\r\n#####################################" +
                    "\r\n\t" + DateTime.Now.ToString("u"));
            }
        }