private void OnMessage(ObjectStreamConnection <CompilerMessage, CompilerMessage> connection, CompilerMessage message)
        {
            Func <string, bool> func = null;

            if (message == null)
            {
                Interface.Oxide.NextTick(() => {
                    this.OnCompilerFailed(string.Concat("compiler version ", PluginCompiler.CompilerVersion, " disconnected"));
                    this.DependencyTrace();
                    this.Shutdown();
                });
                return;
            }
            switch (message.Type)
            {
            case CompilerMessageType.Assembly:
            {
                Compilation item = this.compilations[message.Id];
                if (item == null)
                {
                    Interface.Oxide.LogWarning("Compiler compiled an unknown assembly", Array.Empty <object>());
                    return;
                }
                item.endedAt = Interface.Oxide.Now;
                string extraData = (string)message.ExtraData;
                if (extraData != null)
                {
                    string[] strArrays = extraData.Split(new char[] { '\r', '\n' });
                    for (int i = 0; i < (int)strArrays.Length; i++)
                    {
                        string str   = strArrays[i];
                        Match  match = this.fileErrorRegex.Match(str.Trim());
                        for (int j = 1; j < match.Groups.Count; j++)
                        {
                            string value = match.Groups[j].Value;
                            if (value.Trim() != string.Empty)
                            {
                                string           str1             = value.Basename(null);
                                string           str2             = str1.Substring(0, str1.Length - 3);
                                CompilablePlugin compilablePlugin = item.plugins.SingleOrDefault <CompilablePlugin>((CompilablePlugin pl) => pl.ScriptName == str2);
                                if (compilablePlugin != null)
                                {
                                    HashSet <string>    requires = compilablePlugin.Requires;
                                    Func <string, bool> func1    = func;
                                    if (func1 == null)
                                    {
                                        Func <string, bool> func2 = (string name) => !item.IncludesRequiredPlugin(name);
                                        Func <string, bool> func3 = func2;
                                        func  = func2;
                                        func1 = func3;
                                    }
                                    IEnumerable <string> strs = requires.Where <string>(func1);
                                    if (!strs.Any <string>())
                                    {
                                        string str3                   = str.Trim();
                                        string pluginDirectory        = Interface.Oxide.PluginDirectory;
                                        char   directorySeparatorChar = Path.DirectorySeparatorChar;
                                        compilablePlugin.CompilerErrors = str3.Replace(string.Concat(pluginDirectory, directorySeparatorChar.ToString()), string.Empty);
                                    }
                                    else
                                    {
                                        compilablePlugin.CompilerErrors = string.Concat("Missing dependencies: ", strs.ToSentence <string>());
                                    }
                                }
                                else
                                {
                                    Interface.Oxide.LogError(string.Concat("Unable to resolve script error to plugin: ", str), Array.Empty <object>());
                                }
                            }
                        }
                    }
                }
                item.Completed((byte[])message.Data);
                this.compilations.Remove(message.Id);
                Oxide.Core.Libraries.Timer.TimerInstance timerInstance1 = this.idleTimer;
                if (timerInstance1 != null)
                {
                    timerInstance1.Destroy();
                }
                else
                {
                }
                if (!PluginCompiler.AutoShutdown)
                {
                    return;
                }
                Interface.Oxide.NextTick(() => {
                        Oxide.Core.Libraries.Timer.TimerInstance timerInstance = this.idleTimer;
                        if (timerInstance != null)
                        {
                            timerInstance.Destroy();
                        }
                        else
                        {
                        }
                        if (PluginCompiler.AutoShutdown)
                        {
                            this.idleTimer = Interface.Oxide.GetLibrary <Oxide.Core.Libraries.Timer>(null).Once(60f, new Action(this.Shutdown), null);
                        }
                    });
                return;
            }

            case CompilerMessageType.Compile:
            case CompilerMessageType.Exit:
            {
                return;
            }

            case CompilerMessageType.Error:
            {
                Interface.Oxide.LogError("Compilation error: {0}", new object[] { message.Data });
                this.compilations[message.Id].Completed(null);
                this.compilations.Remove(message.Id);
                Oxide.Core.Libraries.Timer.TimerInstance timerInstance2 = this.idleTimer;
                if (timerInstance2 != null)
                {
                    timerInstance2.Destroy();
                }
                else
                {
                }
                if (!PluginCompiler.AutoShutdown)
                {
                    return;
                }
                Interface.Oxide.NextTick(() => {
                        Oxide.Core.Libraries.Timer.TimerInstance timerInstance = this.idleTimer;
                        if (timerInstance != null)
                        {
                            timerInstance.Destroy();
                        }
                        else
                        {
                        }
                        this.idleTimer = Interface.Oxide.GetLibrary <Oxide.Core.Libraries.Timer>(null).Once(60f, new Action(this.Shutdown), null);
                    });
                return;
            }

            case CompilerMessageType.Ready:
            {
                connection.PushMessage(message);
                if (this.ready)
                {
                    return;
                }
                this.ready = true;
                while (this.messageQueue.Count > 0)
                {
                    connection.PushMessage(this.messageQueue.Dequeue());
                }
                return;
            }

            default:
            {
                return;
            }
            }
        }
        private void OnMessage(ObjectStreamConnection <CompilerMessage, CompilerMessage> connection, CompilerMessage message)
        {
            if (message == null)
            {
                Interface.Oxide.NextTick(() =>
                {
                    OnCompilerFailed($"compiler version {CompilerVersion} disconnected");
                    DependencyTrace();
                    Shutdown();
                });
                return;
            }

            switch (message.Type)
            {
            case CompilerMessageType.Assembly:
                Compilation compilation = compilations[message.Id];
                if (compilation == null)
                {
                    Interface.Oxide.LogWarning("Compiler compiled an unknown assembly");     // TODO: Any way to clarify this?
                    return;
                }
                compilation.endedAt = Interface.Oxide.Now;
                string stdOutput = (string)message.ExtraData;
                if (stdOutput != null)
                {
                    foreach (string line in stdOutput.Split('\r', '\n'))
                    {
                        Match match = fileErrorRegex.Match(line.Trim());
                        for (int i = 1; i < match.Groups.Count; i++)
                        {
                            string value = match.Groups[i].Value;
                            if (value.Trim() == string.Empty)
                            {
                                continue;
                            }

                            string           fileName         = value.Basename();
                            string           scriptName       = fileName.Substring(0, fileName.Length - 3);
                            CompilablePlugin compilablePlugin = compilation.plugins.SingleOrDefault(pl => pl.ScriptName == scriptName);
                            if (compilablePlugin == null)
                            {
                                Interface.Oxide.LogError($"Unable to resolve script error to plugin: {line}");
                                continue;
                            }
                            IEnumerable <string> missingRequirements = compilablePlugin.Requires.Where(name => !compilation.IncludesRequiredPlugin(name));
                            if (missingRequirements.Any())
                            {
                                compilablePlugin.CompilerErrors = $"Missing dependencies: {missingRequirements.ToSentence()}";
                            }
                            else
                            {
                                compilablePlugin.CompilerErrors = line.Trim().Replace(Interface.Oxide.PluginDirectory + Path.DirectorySeparatorChar, string.Empty);
                            }
                        }
                    }
                }
                compilation.Completed((byte[])message.Data);
                compilations.Remove(message.Id);
                idleTimer?.Destroy();
                if (AutoShutdown)
                {
                    Interface.Oxide.NextTick(() =>
                    {
                        idleTimer?.Destroy();
                        if (AutoShutdown)
                        {
                            idleTimer = Interface.Oxide.GetLibrary <Core.Libraries.Timer>().Once(60, Shutdown);
                        }
                    });
                }
                break;

            case CompilerMessageType.Error:
                Interface.Oxide.LogError("Compilation error: {0}", message.Data);
                compilations[message.Id].Completed();
                compilations.Remove(message.Id);
                idleTimer?.Destroy();
                if (AutoShutdown)
                {
                    Interface.Oxide.NextTick(() =>
                    {
                        idleTimer?.Destroy();
                        idleTimer = Interface.Oxide.GetLibrary <Core.Libraries.Timer>().Once(60, Shutdown);
                    });
                }
                break;

            case CompilerMessageType.Ready:
                connection.PushMessage(message);
                if (!ready)
                {
                    ready = true;
                    while (messageQueue.Count > 0)
                    {
                        connection.PushMessage(messageQueue.Dequeue());
                    }
                }
                break;
            }
        }