async Task RunServer()
        {
            Serilog.Log.Logger = new LoggerConfiguration()
                                 .Enrich.FromLogContext()
                                 .WriteTo.File(LogFile(), rollingInterval: RollingInterval.Day, flushToDiskInterval: new TimeSpan(0, 0, 10))
                                 .CreateLogger();

            Serilog.Log.Information("Deltinteger Language Server");

            DocumentHandler = new DocumentHandler(this);
            FileGetter      = new FileGetter(DocumentHandler);
            ConfigurationHandler configurationHandler = new ConfigurationHandler(this);
            CompletionHandler    completionHandler    = new CompletionHandler(this);
            SignatureHandler     signatureHandler     = new SignatureHandler(this);
            DefinitionHandler    definitionHandler    = new DefinitionHandler(this);
            HoverHandler         hoverHandler         = new HoverHandler(this);
            RenameHandler        renameHandler        = new RenameHandler(this);

            Server = await OmniSharp.Extensions.LanguageServer.Server.LanguageServer.From(options => options
                                                                                          .WithInput(Console.OpenStandardInput())
                                                                                          .WithOutput(Console.OpenStandardOutput())
                                                                                          .ConfigureLogging(x => x
                                                                                                            .AddSerilog()
                                                                                                            .AddLanguageServer()
                                                                                                            .SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug))
                                                                                          .WithHandler <DocumentHandler>(DocumentHandler)
                                                                                          .WithHandler <CompletionHandler>(completionHandler)
                                                                                          .WithHandler <SignatureHandler>(signatureHandler)
                                                                                          .WithHandler <ConfigurationHandler>(configurationHandler)
                                                                                          .WithHandler <DefinitionHandler>(definitionHandler)
                                                                                          .WithHandler <HoverHandler>(hoverHandler)
                                                                                          .WithHandler <RenameHandler>(renameHandler));

            await Server.WaitForExit;
        }
        private LanguageServerOptions AddRequests(LanguageServerOptions options)
        {
            // Pathmap creation is seperated into 2 requests, 'pathmapFromClipboard' and 'pathmapApply'.
            // Pathmap generation request.
            options.OnRequest <object, string>("pathmapFromClipboard", _ => Task <string> .Run(() =>
            {
                // Create the error handler for pathmap parser.
                ServerPathmapHandler error = new ServerPathmapHandler();

                // Get the pathmap. 'map' will be null if there is an error.
                try
                {
                    Pathmap map = Pathmap.ImportFromCSV(Clipboard.GetText(), error);

                    if (map == null)
                    {
                        return(error.Message);
                    }
                    else
                    {
                        lastMap = map;
                        return("success");
                    }
                }
                catch (Exception ex)
                {
                    return(ex.Message);
                }
            }));

            // Pathmap save request.
            options.OnRequest <Newtonsoft.Json.Linq.JToken>("pathmapApply", uriToken => Task.Run(() =>
            {
                // Save 'lastMap' to a file.
                string result = lastMap.ExportAsJSON();
                string output = uriToken["path"].ToObject <string>().Trim('/');
                using (var stream = new StreamWriter(output))
                    stream.Write(result);
            }));

            // Pathmap editor request.
            options.OnRequest <PathmapDocument, bool>("pathmapEditor", (editFileToken) => Task <bool> .Run(() =>
            {
                DeltinScript compile;
                if (editFileToken.Text == null)
                {
                    string editor = Extras.CombinePathWithDotNotation(null, "!PathfindEditor.del");
                    compile       = new DeltinScript(new TranslateSettings(editor)
                    {
                        OutputLanguage = ConfigurationHandler.OutputLanguage
                    });
                }
                else
                {
                    compile = Editor.Generate(editFileToken.File, Pathmap.ImportFromText(editFileToken.Text), ConfigurationHandler.OutputLanguage);
                }

                Clipboard.SetText(compile.WorkshopCode);

                return(true);
            }));

            // semantic tokens
            options.OnRequest <Newtonsoft.Json.Linq.JToken, SemanticToken[]>("semanticTokens", (uriToken) => Task <SemanticToken[]> .Run(async() =>
            {
                await DocumentHandler.WaitForParse();
                SemanticToken[] tokens = LastParse?.ScriptFromUri(new Uri(uriToken["fsPath"].ToObject <string>()))?.GetSemanticTokens();
                return(tokens ?? new SemanticToken[0]);
            }));

            // debugger start
            options.OnRequest <object>("debugger.start", args => Task.Run(() =>
            {
                _debugger.Start();
                return(new object());
            }));

            // debugger stop
            options.OnRequest <object>("debugger.stop", args => Task.Run(() =>
            {
                _debugger.Stop();
                return(new object());
            }));

            // debugger scopes
            options.OnRequest <ScopesArgs, DBPScope[]>("debugger.scopes", args => Task <DBPScope[]> .Run(() =>
            {
                try
                {
                    if (_debugger.VariableCollection != null)
                    {
                        return(_debugger.VariableCollection.GetScopes(args));
                    }
                }
                catch (Exception ex)
                {
                    DebuggerException(ex);
                }
                return(new DBPScope[0]);
            }));

            // debugger variables
            options.OnRequest <VariablesArgs, DBPVariable[]>("debugger.variables", args => Task <DBPVariable[]> .Run(() =>
            {
                try
                {
                    if (_debugger.VariableCollection != null)
                    {
                        return(_debugger.VariableCollection.GetVariables(args));
                    }
                }
                catch (Exception ex)
                {
                    DebuggerException(ex);
                }
                return(new DBPVariable[0]);
            }));

            // debugger evaluate
            options.OnRequest <EvaluateArgs, EvaluateResponse>("debugger.evaluate", args => Task <EvaluateResponse> .Run(() =>
            {
                try
                {
                    return(_debugger.VariableCollection?.Evaluate(args));
                }
                catch (Exception ex)
                {
                    DebuggerException(ex);
                    return(EvaluateResponse.Empty);
                }
            }));

            // Decompile insert
            options.OnRequest <DecompileResult>("decompile.insert", () => Task <DecompileResult> .Run(() =>
            {
                try
                {
                    var tte      = new ConvertTextToElement(Clipboard.GetText());
                    var workshop = tte.Get();
                    var code     = new WorkshopDecompiler(workshop, new OmitLobbySettingsResolver(), new CodeFormattingOptions()).Decompile();
                    return(new DecompileResult(tte, code));
                }
                catch (Exception ex)
                {
                    return(new DecompileResult(ex));
                }
            }));

            // Decompile file
            options.OnRequest <DecompileFileArgs, DecompileResult>("decompile.file", args => Task.Run <DecompileResult>(() =>
            {
                try
                {
                    // Parse the workshop code.
                    var tte      = new ConvertTextToElement(Clipboard.GetText());
                    var workshop = tte.Get();

                    // Decompile the parsed workshop code.
                    var workshopToCode = new WorkshopDecompiler(workshop, new FileLobbySettingsResolver(args.File, workshop.LobbySettings), new CodeFormattingOptions());
                    var code           = workshopToCode.Decompile();

                    var result = new DecompileResult(tte, code);

                    // Only create the decompile was successful.
                    if (result.Success)
                    {
                        // Create the file.
                        using (var writer = File.CreateText(args.File))
                            // Write the code to the file.
                            writer.Write(code);
                    }

                    return(result);
                }
                catch (Exception ex)
                {
                    return(new DecompileResult(ex));
                }
            }));

            return(options);
        }