public static IAdapterNativeLibraryDouble AddDiagnostics(ParametersDiagnosticsNative diagnostics, IAdapterNativeLibraryDouble engine, out Stream stream, bool isServer)
            {
                Contract.Requires(diagnostics != null, "diagnostics != null");
                Contract.Requires(engine != null, "engine != null");

                stream = null;

                if (diagnostics.To == WriteTo.None)
                    return engine;

                var log = diagnostics.Log;

                if (isServer && !diagnostics.LogServer)
                    log = null;

                if (log != null)
                {
                    try
                    {
                        if (!Path.IsPathRooted(log.FullName))
                            throw new Exception("Filename NOT rooted.");

                        if (isServer)
                        {
                            // Adapt from Client path

                            var n = log.FullName.Length - log.Extension.Length;
                            var s = log.FullName.Insert(n, "_Server");

                            log = new FileInfo(s);
                        }

                        if (File.Exists(log.FullName))
                            log.Delete();

                        stream = new BufferedStream(log.OpenWrite(), 20000);
                    }
                    catch (System.Exception e)
                    {
                        throw new Exception("Invalid Log fileName: " + log.FullName, e);
                    }
                }

                var intercepts = new List<IIntercept>();

                if (diagnostics.IncludeStatistics)
                    intercepts.Add(new InterceptCallReturnValues(diagnostics));

                if (diagnostics.IncludeCalls)
                    intercepts.Add(new InterceptCallArguments(diagnostics));

                if (diagnostics.IncludeTimings)
                    intercepts.Add(new InterceptCallTimer(diagnostics));

                if (stream != null)
                    foreach (var i in intercepts)
                        i.Streams.Add(stream);

                return new InterceptionAdapterNativeLibraryDouble(engine, intercepts, true);
            }
        public void Initialise(string initialisingXml, IDocumentAccessor accessor)
        {
            try
            {
                _initialisingXml = XElement.Parse(initialisingXml);

                var arguments = Persistence.Arguments
                    .Parse(_initialisingXml, accessor);

                var remotingId = BaseComponentWithEngine.GetArgumentIdentity(
                    BaseComponentWithEngine.ArgsWithEngine.Remoting).Id;
                var diagnosticsId = BaseComponentWithEngine.GetArgumentIdentity(
                    BaseComponentWithEngine.ArgsWithEngine.Diagnostics).Id;

                var remoting = arguments
                    .Where(a => a.Id == remotingId)
                    .Single();

                var diagnostics = arguments
                    .Where(a => a.Id == diagnosticsId)
                    .Single();

                _remotingData = new ParametersRemoting();
                _remotingData.ValueAsString = remoting.ValueAsString;

                _diagnostics = new ParametersDiagnosticsNative();
                _diagnostics.ValueAsString = diagnostics.ValueAsString;

                if (_remotingData.Protocol == RemotingProtocol.ipcAuto)
                {
                    string args = string.Format(
                        "ipcAuto {0} {1}", _remotingData.ObjectUri, _remotingData.PortName);

                    if (_remotingData.ServerLaunchDebugger)
                        args += " launchDebugger";
                    if (_remotingData.EnsureSecurity)
                        args += " ensureSecurity";
                    if (_remotingData.ServerTraceEngine)
                        args += " traceEngine";

                    var serverType = new ExternalType(typeof(RemotingServerEngineTime));

                    WriteLine("IPC Auto Process");
                    WriteLine("\tServer: " + serverType.Url.LocalPath, false);
                    WriteLine("\tArgs: " + args, false);
                    WriteLine("\tRedirect Standard Output (if true could be VERY slow): "
                        + _remotingData.IpcAutoRedirectStdOut.ToString(), false);

                    _process = new RemotingProcess("RemotingServerEngineTime");
                    _process.Start(serverType.Url.LocalPath, args, _remotingData.IpcAutoRedirectStdOut);

                    WriteLine("Process started");
                }

                WriteLine(_remotingData.Details());

                switch (_remotingData.Protocol)
                {
                    case RemotingProtocol.ipc:
                    case RemotingProtocol.ipcAuto:
                        WriteLine("IPC Connection");
                        _connection = new RemotingConnectionIpc();
                        break;
                    case RemotingProtocol.tcp:
                        WriteLine("TCP Connection");
                        _connection = new RemotingConnectionTcp();
                        break;
                    case RemotingProtocol.http:
                        WriteLine("HTTP Connection");
                        _connection = new RemotingConnectionHttp();
                        break;
                    case RemotingProtocol.inProcess:
                    default:
                        throw new NotImplementedException(_remotingData.Protocol.ToString());
                }

                WriteLine("\tClient Uri: " + _remotingData.ClientUri, false);
                WriteLine("\tEnsure Security: " + _remotingData.EnsureSecurity, false);
                WriteLine("\tConnection TimeOut: " + _remotingData.ConnectionTimeOut, false);

                _connection.Start(_remotingData.ClientUri, _remotingData.EnsureSecurity, _remotingData.ConnectionTimeOut, typeof(IEngine));

                WriteLine("\tConnection started.", false);
                WriteLine(string.Format("... pause {0} seconds before pinging engine ...", _remotingData.ConnectionSleep / 1000.0));

                Thread.Sleep(_remotingData.ConnectionSleep);

                string ping = EngineProxy.Ping();

                WriteLine("Engine Ping: " + ping);

                WriteLine("Engine Initialising ...");
                EngineProxy.Initialise(_initialisingXml.ToString());
                WriteLine("\tInitialised.", false);
            }
            catch (System.Exception e)
            {
                throw EngineMethodCatch("Initialise", e);
            }
        }