diff --git a/verilog/tools/ls/BUILD b/verilog/tools/ls/BUILD
index fe67b55..8e9260f 100644
--- a/verilog/tools/ls/BUILD
+++ b/verilog/tools/ls/BUILD
@@ -62,16 +62,23 @@
     ],
 )
 
+cc_library(
+    name = "verilog-language-server",
+    srcs = ["verilog-language-server.cc"],
+    hdrs = ["verilog-language-server.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":verible-lsp-adapter",
+        "//common/lsp:message-stream-splitter",
+    ],
+)
+
 cc_binary(
     name = "verible-verilog-ls",
     srcs = ["verilog_ls.cc"],
     visibility = ["//visibility:public"],
     deps = [
-        ":lsp-parse-buffer",
-        ":verible-lsp-adapter",
-        "//common/lsp:json-rpc-dispatcher",
-        "//common/lsp:lsp-protocol",
-        "//common/lsp:message-stream-splitter",
+        ":verilog-language-server",
         "//common/util:init_command_line",
     ],
 )
diff --git a/verilog/tools/ls/verilog-language-server.cc b/verilog/tools/ls/verilog-language-server.cc
new file mode 100644
index 0000000..8422e55
--- /dev/null
+++ b/verilog/tools/ls/verilog-language-server.cc
@@ -0,0 +1,165 @@
+// Copyright 2021-2022 The Verible Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "verilog/tools/ls/verilog-language-server.h"
+
+namespace verilog {
+
+VerilogLanguageServer::VerilogLanguageServer(const WriteFun &write_fun)
+    : dispatcher_(write_fun), buffers_(&dispatcher_) {
+  // All bodies the stream splitter extracts are pushed to the json dispatcher
+  stream_splitter_.SetMessageProcessor(
+      [this](absl::string_view header, absl::string_view body) {
+        return dispatcher_.DispatchMessage(body);
+      });
+
+  // Whenever there is a new parse result ready, use that as an opportunity
+  // to send diagnostics to the client.
+  buffers_.SetChangeListener(parsed_buffers_.GetSubscriptionCallback());
+  parsed_buffers_.SetChangeListener(
+      [this](const std::string &uri,
+             const verilog::BufferTracker &buffer_tracker) {
+        SendDiagnostics(uri, buffer_tracker);
+      });
+  SetRequestHandlers();
+}
+
+void VerilogLanguageServer::SetRequestHandlers() {
+  // Exchange of capabilities.
+  dispatcher_.AddRequestHandler("initialize",
+                                [this](const nlohmann::json &params) {
+                                  return InitializeRequestHandler(params);
+                                });
+
+  dispatcher_.AddRequestHandler(  // Provide diagnostics on request
+      "textDocument/diagnostic",
+      [this](const verible::lsp::DocumentDiagnosticParams &p) {
+        return verilog::GenerateDiagnosticReport(
+            parsed_buffers_.FindBufferTrackerOrNull(p.textDocument.uri), p);
+      });
+
+  dispatcher_.AddRequestHandler(  // Provide autofixes
+      "textDocument/codeAction",
+      [this](const verible::lsp::CodeActionParams &p) {
+        return verilog::GenerateLinterCodeActions(
+            parsed_buffers_.FindBufferTrackerOrNull(p.textDocument.uri), p);
+      });
+
+  dispatcher_.AddRequestHandler(  // Provide document outline/index
+      "textDocument/documentSymbol",
+      [this](const verible::lsp::DocumentSymbolParams &p) {
+        return verilog::CreateDocumentSymbolOutline(
+            parsed_buffers_.FindBufferTrackerOrNull(p.textDocument.uri), p);
+      });
+
+  dispatcher_.AddRequestHandler(  // Highlight related symbols under cursor
+      "textDocument/documentHighlight",
+      [this](const verible::lsp::DocumentHighlightParams &p) {
+        return verilog::CreateHighlightRanges(
+            parsed_buffers_.FindBufferTrackerOrNull(p.textDocument.uri), p);
+      });
+
+  dispatcher_.AddRequestHandler(  // format range of file
+      "textDocument/rangeFormatting",
+      [this](const verible::lsp::DocumentFormattingParams &p) {
+        return verilog::FormatRange(
+            parsed_buffers_.FindBufferTrackerOrNull(p.textDocument.uri), p);
+      });
+  dispatcher_.AddRequestHandler(  // format entire file
+      "textDocument/formatting",
+      [this](const verible::lsp::DocumentFormattingParams &p) {
+        return verilog::FormatRange(
+            parsed_buffers_.FindBufferTrackerOrNull(p.textDocument.uri), p);
+      });
+  // The client sends a request to shut down. Use that to exit our loop.
+  dispatcher_.AddRequestHandler("shutdown", [this](const nlohmann::json &) {
+    shutdown_requested_ = true;
+    return nullptr;
+  });
+}
+
+absl::Status VerilogLanguageServer::Run(const ReadFun &read_fun) {
+  shutdown_requested_ = false;
+  absl::Status status = absl::OkStatus();
+  while (status.ok() && !shutdown_requested_) {
+    status = stream_splitter_.PullFrom(read_fun);
+  }
+  return status;
+}
+
+void VerilogLanguageServer::PrintStatistics() const {
+  if (shutdown_requested_) {
+    std::cerr << "Shutting down due to shutdown request." << std::endl;
+  }
+
+  std::cerr << "Statistics" << std::endl;
+  std::cerr << "Largest message seen: "
+            << stream_splitter_.StatLargestBodySeen() / 1024 << " kiB "
+            << std::endl;
+  for (const auto &stats : dispatcher_.GetStatCounters()) {
+    fprintf(stderr, "%30s %9d\n", stats.first.c_str(), stats.second);
+  }
+}
+
+verible::lsp::InitializeResult VerilogLanguageServer::InitializeRequestHandler(
+    const nlohmann::json &params) const {
+  // Ignore passed client capabilities from params right now,
+  // just announce what we do.
+  verible::lsp::InitializeResult result;
+  result.serverInfo = {
+      .name = "Verible Verilog language server.",
+      .version = GetVersionNumber(),
+  };
+  result.capabilities = {
+      {
+          "textDocumentSync",
+          {
+              {"openClose", true},  // Want open/close events
+              {"change", 2},        // Incremental updates
+          },
+      },
+      {"codeActionProvider", true},               // Autofixes for lint errors
+      {"documentSymbolProvider", true},           // Symbol-outline of file
+      {"documentRangeFormattingProvider", true},  // Format selection
+      {"documentFormattingProvider", true},       // Full file format
+      {"documentHighlightProvider", true},        // Highlight same symbol
+      {"diagnosticProvider",                      // Pull model of diagnostics.
+       {
+           {"interFileDependencies", false},
+           {"workspaceDiagnostics", false},
+       }},
+  };
+
+  return result;
+}
+
+void VerilogLanguageServer::SendDiagnostics(
+    const std::string &uri, const verilog::BufferTracker &buffer_tracker) {
+  // TODO(hzeller): Cache result and rate-limit.
+  // This should not send anything if the diagnostics we're about to
+  // send would be exactly the same as last time.
+  verible::lsp::PublishDiagnosticsParams params;
+
+  // For the diagnostic notification (that we send somewhat unsolicited), we
+  // limit the number of diagnostic messages. In the
+  // textDocument/diagnostic RPC request, we send all of them.
+  // Arbitrary limit here. Maybe set with flag ?
+  static constexpr int kDiagnosticLimit = 500;
+  params.uri = uri;
+  params.diagnostics =
+      verilog::CreateDiagnostics(buffer_tracker, kDiagnosticLimit);
+  dispatcher_.SendNotification("textDocument/publishDiagnostics", params);
+}
+
+};  // namespace verilog
diff --git a/verilog/tools/ls/verilog-language-server.h b/verilog/tools/ls/verilog-language-server.h
new file mode 100644
index 0000000..7e7e32c
--- /dev/null
+++ b/verilog/tools/ls/verilog-language-server.h
@@ -0,0 +1,75 @@
+// Copyright 2021-2022 The Verible Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef VERILOG_TOOLS_LS_LS_WRAPPER_H
+#define VERILOG_TOOLS_LS_LS_WRAPPER_H
+
+#include <functional>
+
+#include "absl/status/status.h"
+#include "absl/strings/string_view.h"
+#include "common/lsp/json-rpc-dispatcher.h"
+#include "common/lsp/lsp-protocol.h"
+#include "common/lsp/message-stream-splitter.h"
+#include "verilog/tools/ls/verible-lsp-adapter.h"
+
+namespace verilog {
+
+// Class implementing the Language Server for Verilog
+class VerilogLanguageServer {
+ public:
+  using ReadFun = verible::lsp::MessageStreamSplitter::ReadFun;
+  using WriteFun = verible::lsp::JsonRpcDispatcher::WriteFun;
+
+  static std::string GetVersionNumber() { return "0.0 alpha"; }
+
+  // Constructor preparing the callbacks for Language Server requests
+  VerilogLanguageServer(const WriteFun &write_fun);
+
+  // Runs the Language Server
+  absl::Status Run(const ReadFun &read_fun);
+
+  // Prints statistics of the current Language Server session
+  void PrintStatistics() const;
+
+ private:
+  // Creates callbacks for requests from Language Server Client
+  void SetRequestHandlers();
+
+  // The "initialize" method requests server capabilities.
+  verible::lsp::InitializeResult InitializeRequestHandler(
+      const nlohmann::json &params) const;
+
+  // Publish a diagnostic sent to the server.
+  void SendDiagnostics(const std::string &uri,
+                       const verilog::BufferTracker &buffer_tracker);
+
+  // Stream splitter splits the input stream into messages (header/body).
+  verible::lsp::MessageStreamSplitter stream_splitter_;
+
+  // Parser for JSON messages from LS client
+  verible::lsp::JsonRpcDispatcher dispatcher_;
+
+  // Object for keeping track of updates in opened buffers on client's side
+  verible::lsp::BufferCollection buffers_;
+
+  // Tracks changes in buffers from BufferCollection and parses their contents
+  verilog::BufferTrackerContainer parsed_buffers_;
+
+  // A flag for indicating "shutdown" request
+  bool shutdown_requested_ = false;
+};
+
+};      // namespace verilog
+#endif  // VERILOG_TOOLS_LS_LS_WRAPPER_H
diff --git a/verilog/tools/ls/verilog_ls.cc b/verilog/tools/ls/verilog_ls.cc
index 3656850..0702a3e 100644
--- a/verilog/tools/ls/verilog_ls.cc
+++ b/verilog/tools/ls/verilog_ls.cc
@@ -1,4 +1,4 @@
-// Copyright 2021 The Verible Authors.
+// Copyright 2021-2022 The Verible Authors.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -13,17 +13,13 @@
 // limitations under the License.
 //
 
+#include <functional>
 #include <iomanip>  // Only needed for json debugging right now
 #include <iostream>
 
-#include "common/lsp/json-rpc-dispatcher.h"
-#include "common/lsp/lsp-protocol.h"
-#include "common/lsp/message-stream-splitter.h"
 #include "common/util/init_command_line.h"
-#include "verilog/tools/ls/lsp-parse-buffer.h"
-#include "verilog/tools/ls/verible-lsp-adapter.h"
+#include "verilog/tools/ls/verilog-language-server.h"
 
-// Windows specific implementation of read()
 #ifndef _WIN32
 #include <unistd.h>
 #else
@@ -34,187 +30,32 @@
 #define read(fd, buf, size) _read(fd, buf, size)
 #endif
 
-using nlohmann::json;
-using verible::lsp::BufferCollection;
-using verible::lsp::InitializeResult;
-using verible::lsp::JsonRpcDispatcher;
-using verible::lsp::MessageStreamSplitter;
-
-static std::string GetVersionNumber() {
-  return "0.0 alpha";  // TODO(hzeller): once ready, extract from build version
-}
-
-// The "initialize" method requests server capabilities.
-static InitializeResult InitializeServer(const nlohmann::json &params) {
-  // Ignore passed client capabilities from params right now,
-  // just announce what we do.
-  InitializeResult result;
-  result.serverInfo = {
-      .name = "Verible Verilog language server.",
-      .version = GetVersionNumber(),
-  };
-  result.capabilities = {
-      {
-          "textDocumentSync",
-          {
-              {"openClose", true},  // Want open/close events
-              {"change", 2},        // Incremental updates
-          },
-      },
-      {"codeActionProvider", true},               // Autofixes for lint errors
-      {"documentSymbolProvider", true},           // Symbol-outline of file
-      {"documentRangeFormattingProvider", true},  // Format selection
-      {"documentFormattingProvider", true},       // Full file format
-      {"documentHighlightProvider", true},        // Highlight same symbol
-      {"diagnosticProvider",                      // Pull model of diagnostics.
-       {
-           {"interFileDependencies", false},
-           {"workspaceDiagnostics", false},
-       }},
-  };
-
-  return result;
-}
-
-// Publish a diagnostic sent to the server.
-static void SendDiagnostics(const std::string &uri,
-                            const verilog::BufferTracker &buffer_tracker,
-                            JsonRpcDispatcher *dispatcher) {
-  // TODO(hzeller): Cache result and rate-limit.
-  // This should not send anything if the diagnostics we're about to
-  // send would be exactly the same as last time.
-  verible::lsp::PublishDiagnosticsParams params;
-
-  // For the diagnostic notification (that we send somewhat unsolicited), we
-  // limit the number of diagnostic messages. In the
-  // textDocument/diagnostic RPC request, we send all of them.
-  // Arbitrary limit here. Maybe set with flag ?
-  static constexpr int kDiagnosticLimit = 500;
-  params.uri = uri;
-  params.diagnostics =
-      verilog::CreateDiagnostics(buffer_tracker, kDiagnosticLimit);
-  dispatcher->SendNotification("textDocument/publishDiagnostics", params);
+static void FormatHeaderBodyReply(absl::string_view reply) {
+  // Output formatting as header/body chunk as required by LSP spec.
+  std::cout << "Content-Length: " << reply.size() << "\r\n\r\n";
+  std::cout << reply << std::flush;
 }
 
 int main(int argc, char *argv[]) {
   verible::InitCommandLine(argv[0], &argc, &argv);
 
+  std::cerr << "Verible Alpha Language Server "
+            << verilog::VerilogLanguageServer::GetVersionNumber() << std::endl;
+
+  // Input and output is stdin and stdout
+  constexpr int in_fd = 0;  // STDIN_FILENO
+
 #ifdef _WIN32
   _setmode(_fileno(stdin), _O_BINARY);
   _setmode(_fileno(stdout), _O_BINARY);
 #endif
 
-  std::cerr << "Verible Alpha Language Server " << GetVersionNumber()
-            << std::endl;
+  verilog::VerilogLanguageServer server(FormatHeaderBodyReply);
 
-  // Input and output is stdin and stdout
-  static constexpr int in_fd = 0;  // STDIN_FILENO
-  JsonRpcDispatcher::WriteFun write_fun = [](absl::string_view reply) {
-    // Output formatting as header/body chunk as required by LSP spec.
-    std::cout << "Content-Length: " << reply.size() << "\r\n\r\n";
-    std::cout << reply << std::flush;
-  };
-
-  // Stream splitter splits the input stream into messages (header/body).
-  MessageStreamSplitter stream_splitter;
-  JsonRpcDispatcher dispatcher(write_fun);
-
-  // All bodies the stream splitter extracts are pushed to the json dispatcher
-  stream_splitter.SetMessageProcessor(
-      [&dispatcher](absl::string_view /*header*/, absl::string_view body) {
-        return dispatcher.DispatchMessage(body);
-      });
-
-  // The buffer collection keeps track of all the buffers opened in the editor.
-  // It registers callbacks to receive the relevant events on the dispatcher.
-  BufferCollection buffers(&dispatcher);
-
-  // The parsed buffers convert the raw text into the SystemVerilog parsed
-  // representation, basis for all high-level features we provide from it.
-  // Subscribe them to text edit updates to trigger parse.
-  verilog::BufferTrackerContainer parsed_buffers;
-  buffers.SetChangeListener(parsed_buffers.GetSubscriptionCallback());
-
-  // Whenever there is a new parse result ready, use that as an opportunity
-  // to send diagnostics to the client.
-  parsed_buffers.SetChangeListener(
-      [&dispatcher](const std::string &uri,
-                    const verilog::BufferTracker &buffer_tracker) {
-        SendDiagnostics(uri, buffer_tracker, &dispatcher);
-      });
-
-  // -- Register JSON RPC callbacks
-
-  // Exchange of capabilities.
-  dispatcher.AddRequestHandler("initialize", InitializeServer);
-
-  dispatcher.AddRequestHandler(  // Provide diagnostics on request
-      "textDocument/diagnostic",
-      [&parsed_buffers](const verible::lsp::DocumentDiagnosticParams &p) {
-        return verilog::GenerateDiagnosticReport(
-            parsed_buffers.FindBufferTrackerOrNull(p.textDocument.uri), p);
-      });
-
-  dispatcher.AddRequestHandler(  // Provide autofixes
-      "textDocument/codeAction",
-      [&parsed_buffers](const verible::lsp::CodeActionParams &p) {
-        return verilog::GenerateLinterCodeActions(
-            parsed_buffers.FindBufferTrackerOrNull(p.textDocument.uri), p);
-      });
-
-  dispatcher.AddRequestHandler(  // Provide document outline/index
-      "textDocument/documentSymbol",
-      [&parsed_buffers](const verible::lsp::DocumentSymbolParams &p) {
-        return verilog::CreateDocumentSymbolOutline(
-            parsed_buffers.FindBufferTrackerOrNull(p.textDocument.uri), p);
-      });
-
-  dispatcher.AddRequestHandler(  // Highlight related symbols under cursor
-      "textDocument/documentHighlight",
-      [&parsed_buffers](const verible::lsp::DocumentHighlightParams &p) {
-        return verilog::CreateHighlightRanges(
-            parsed_buffers.FindBufferTrackerOrNull(p.textDocument.uri), p);
-      });
-
-  dispatcher.AddRequestHandler(  // format range of file
-      "textDocument/rangeFormatting",
-      [&parsed_buffers](const verible::lsp::DocumentFormattingParams &p) {
-        return verilog::FormatRange(
-            parsed_buffers.FindBufferTrackerOrNull(p.textDocument.uri), p);
-      });
-  dispatcher.AddRequestHandler(  // format entire file
-      "textDocument/formatting",
-      [&parsed_buffers](const verible::lsp::DocumentFormattingParams &p) {
-        return verilog::FormatRange(
-            parsed_buffers.FindBufferTrackerOrNull(p.textDocument.uri), p);
-      });
-
-  // The client sends a request to shut down. Use that to exit our loop.
-  bool shutdown_requested = false;
-  dispatcher.AddRequestHandler("shutdown",
-                               [&shutdown_requested](const nlohmann::json &) {
-                                 shutdown_requested = true;
-                                 return nullptr;
-                               });
-
-  absl::Status status = absl::OkStatus();
-  while (status.ok() && !shutdown_requested) {
-    status = stream_splitter.PullFrom([](char *buf, int size) -> int {  //
-      return read(in_fd, buf, size);
-    });
-  }
+  absl::Status status = server.Run(
+      [](char *buf, int size) -> int { return read(in_fd, buf, size); });
 
   std::cerr << status.message() << std::endl;
 
-  if (shutdown_requested) {
-    std::cerr << "Shutting down due to shutdown request." << std::endl;
-  }
-
-  std::cerr << "Statistics" << std::endl;
-  std::cerr << "Largest message seen: "
-            << stream_splitter.StatLargestBodySeen() / 1024 << " kiB "
-            << std::endl;
-  for (const auto &stats : dispatcher.GetStatCounters()) {
-    fprintf(stderr, "%30s %9d\n", stats.first.c_str(), stats.second);
-  }
+  server.PrintStatistics();
 }
