diff --git a/CMakeLists.txt b/CMakeLists.txt
index cb8e9f4..54a69bf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -734,6 +734,7 @@
                       quickstep_cli_LineReader
                       quickstep_cli_LocalIO
                       quickstep_cli_PrintToScreen
+                      quickstep_cli_SocketIO
                       quickstep_parser_ParseStatement
                       quickstep_parser_SqlParserWrapper
                       quickstep_queryexecution_ForemanSingleNode
diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt
index 03c5408..d90de95 100644
--- a/cli/CMakeLists.txt
+++ b/cli/CMakeLists.txt
@@ -65,6 +65,9 @@
                     NetworkCli.proto)
 endif()
 
+# Sub-directories:
+add_subdirectory(simple_socket)
+
 # Declare micro-libs and link dependencies:
 add_library(quickstep_cli_CommandExecutor CommandExecutor.cpp CommandExecutor.hpp)
 add_library(quickstep_cli_CommandExecutorUtil CommandExecutorUtil.cpp CommandExecutorUtil.hpp)
@@ -74,6 +77,7 @@
 add_library(quickstep_cli_Flags Flags.cpp Flags.hpp)
 add_library(quickstep_cli_IOInterface ../empty_src.cpp IOInterface.hpp)
 add_library(quickstep_cli_InputParserUtil InputParserUtil.cpp InputParserUtil.hpp)
+add_library(quickstep_cli_SocketIO SocketIO.cpp SocketIO.hpp)
 
 if(USE_LINENOISE)
   add_library(quickstep_cli_LineReader
@@ -178,7 +182,8 @@
                       quickstep_storage_StorageConstants
                       ${GFLAGS_LIB_NAME})
 target_link_libraries(quickstep_cli_IOInterface
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 target_link_libraries(quickstep_cli_InputParserUtil
                       glog
                       quickstep_utility_Macros
@@ -203,7 +208,8 @@
 target_link_libraries(quickstep_cli_LocalIO
                       quickstep_cli_LineReader
                       quickstep_cli_IOInterface
-                      quickstep_utility_Macros)
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
 if (ENABLE_NETWORK_CLI)
   target_link_libraries(quickstep_cli_NetworkCli_proto
                         ${GRPCPLUSPLUS_LIBRARIES}
@@ -226,6 +232,7 @@
                         quickstep_threading_SpinSharedMutex
                         quickstep_utility_Macros
                         quickstep_utility_MemStream
+                        quickstep_utility_StringUtil
                         quickstep_utility_ThreadSafeQueue)
 endif()
 target_link_libraries(quickstep_cli_PrintToScreen
@@ -241,6 +248,17 @@
                       quickstep_types_Type
                       quickstep_types_TypedValue
                       quickstep_utility_Macros)
+target_link_libraries(quickstep_cli_SocketIO
+                      glog
+                      quickstep_cli_IOInterface
+                      quickstep_cli_LineReaderBuffered
+                      quickstep_cli_simplesocket_SimpleSocketConnection
+                      quickstep_cli_simplesocket_SimpleSocketContent
+                      quickstep_cli_simplesocket_SimpleSocketServer
+                      quickstep_utility_Macros
+                      quickstep_utility_MemStream
+                      quickstep_utility_StringUtil
+                      quickstep_utility_ThreadSafeQueue)
 
 # Module all-in-one library:
 add_library(quickstep_cli ../empty_src.cpp CliModule.hpp)
@@ -257,7 +275,8 @@
                       quickstep_cli_LineReader
                       quickstep_cli_LineReaderBuffered
                       quickstep_cli_LocalIO
-                      quickstep_cli_PrintToScreen)
+                      quickstep_cli_PrintToScreen
+                      quickstep_cli_SocketIO)
 if (ENABLE_NETWORK_CLI)
   target_link_libraries(quickstep_cli
                         quickstep_cli_NetworkCli_proto
diff --git a/cli/IOInterface.hpp b/cli/IOInterface.hpp
index b9b36e1..2648e55 100644
--- a/cli/IOInterface.hpp
+++ b/cli/IOInterface.hpp
@@ -22,8 +22,10 @@
 
 #include <cstdio>
 #include <string>
+#include <vector>
 
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 namespace quickstep {
 
@@ -42,7 +44,7 @@
   /**
    * @return Input data.
    */
-  virtual const std::string* data() const = 0;
+  virtual StringPiece data() const = 0;
 
   /**
    * @return A file handle for standard output.
@@ -54,7 +56,7 @@
    */
   virtual FILE* err() = 0;
 
-  virtual std::string getCommand() const = 0;
+  virtual std::vector<std::string> getCommands() const = 0;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(IOHandle);
diff --git a/cli/LocalIO.hpp b/cli/LocalIO.hpp
index 06fa014..86ee2bd 100644
--- a/cli/LocalIO.hpp
+++ b/cli/LocalIO.hpp
@@ -34,6 +34,7 @@
 typedef quickstep::LineReaderDumb LineReaderImpl;
 #endif
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 namespace quickstep {
 
@@ -46,8 +47,8 @@
 
   ~LocalIOHandle() override {}
 
-  const std::string* data() const override {
-    return nullptr;
+  StringPiece data() const override {
+    return StringPiece(nullptr, 0);
   }
 
   FILE *out() override {
@@ -58,8 +59,8 @@
     return stderr;
   }
 
-  std::string getCommand() const override {
-    return command_;
+  std::vector<std::string> getCommands() const override {
+    return {command_};
   }
 
  private:
diff --git a/cli/NetworkIO.hpp b/cli/NetworkIO.hpp
index f8129b5..3098c08 100644
--- a/cli/NetworkIO.hpp
+++ b/cli/NetworkIO.hpp
@@ -26,6 +26,7 @@
 #include <iostream>
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "cli/IOInterface.hpp"
 #include "cli/NetworkCli.grpc.pb.h"
@@ -34,6 +35,7 @@
 #include "threading/SpinSharedMutex.hpp"
 #include "utility/Macros.hpp"
 #include "utility/MemStream.hpp"
+#include "utility/StringUtil.hpp"
 #include "utility/ThreadSafeQueue.hpp"
 
 #include "gflags/gflags.h"
@@ -223,8 +225,9 @@
     request_state_->responseReady(out_stream_.str(), err_stream_.str());
   }
 
-  const std::string* data() const override {
-    return &request_state_->getRequest().data();
+  StringPiece data() const override {
+    const std::string &data = request_state_->getRequest().data();
+    return StringPiece(data.c_str(), data.length());
   }
 
   FILE* out() override {
@@ -235,8 +238,8 @@
     return err_stream_.file();
   }
 
-  std::string getCommand() const override {
-    return request_state_->getRequest().query();
+  std::vector<std::string> getCommands() const override {
+    return {request_state_->getRequest().query()};
   }
 
  private:
diff --git a/cli/QuickstepCli.cpp b/cli/QuickstepCli.cpp
index 37e366a..8588fe5 100644
--- a/cli/QuickstepCli.cpp
+++ b/cli/QuickstepCli.cpp
@@ -46,6 +46,7 @@
 #include "cli/NetworkIO.hpp"
 #endif
 #include "cli/PrintToScreen.hpp"
+#include "cli/SocketIO.hpp"
 #include "parser/ParseStatement.hpp"
 #include "parser/SqlParserWrapper.hpp"
 #include "query_execution/ForemanSingleNode.hpp"
@@ -290,6 +291,8 @@
 #else
     LOG(FATAL) << "Quickstep must be compiled with '-D ENABLE_NETWORK_CLI=true' to use this feature.";
 #endif
+  } else if (quickstep::FLAGS_mode == "socket") {
+    io.reset(new quickstep::SocketIO);
   } else if (quickstep::FLAGS_mode == "local") {
     io.reset(new quickstep::LocalIO);
   } else {
@@ -302,158 +305,161 @@
 #ifdef QUICKSTEP_ENABLE_GOOGLE_PROFILER
   bool started_profiling = false;
 #endif
-  for (;;) {
-    string *command_string = new string();
+  bool quitting = false;
+  while (!quitting) {
     std::unique_ptr<quickstep::IOHandle> io_handle(io->getNextIOHandle());
     ScopedReassignment<FILE*> reassign_stdout(&stdout, io_handle->out());
-//    ScopedReassignment<FILE*> reassign_stderr(&stderr, io_handle->err());
+    ScopedReassignment<FILE*> reassign_stderr(&stderr, io_handle->err());
 
-    *command_string = io_handle->getCommand();
-    LOG(INFO) << "Command received: " << *command_string;
-    if (command_string->size() == 0) {
-      delete command_string;
-      break;
-    }
+    const std::vector<std::string> cmds = io_handle->getCommands();
+    for (const std::string &cmd : cmds) {
+      string *command_string = new string(cmd);
+      LOG(INFO) << "Command received: " << *command_string;
+      if (command_string->size() == 0) {
+        delete command_string;
+        quitting = true;
+        break;
+      }
 
-    if (quickstep::FLAGS_print_query) {
-      fprintf(io_handle->out(), "\n%s\n", command_string->c_str());
-    }
+      if (quickstep::FLAGS_print_query) {
+        fprintf(io_handle->out(), "\n%s\n", command_string->c_str());
+      }
 
-    parser_wrapper->feedNextBuffer(command_string);
+      parser_wrapper->feedNextBuffer(command_string);
 
-    bool quitting = false;
-    // A parse error should reset the parser. This is because the thrown quickstep
-    // SqlError does not do the proper reset work of the YYABORT macro.
-    bool reset_parser = false;
-    for (;;) {
-      ParseResult result = parser_wrapper->getNextStatement();
-      const ParseStatement &statement = *result.parsed_statement;
-      if (result.condition == ParseResult::kSuccess) {
-        if (statement.getStatementType() == ParseStatement::kQuit) {
-          quitting = true;
-          break;
-        } else if (statement.getStatementType() == ParseStatement::kCommand) {
+      // A parse error should reset the parser. This is because the thrown quickstep
+      // SqlError does not do the proper reset work of the YYABORT macro.
+      bool reset_parser = false;
+      for (;;) {
+        ParseResult result = parser_wrapper->getNextStatement();
+        const ParseStatement &statement = *result.parsed_statement;
+        if (result.condition == ParseResult::kSuccess) {
+          if (statement.getStatementType() == ParseStatement::kQuit) {
+            quitting = true;
+            break;
+          } else if (statement.getStatementType() == ParseStatement::kCommand) {
+            try {
+              quickstep::cli::executeCommand(
+                  statement,
+                  *(query_processor->getDefaultDatabase()),
+                  main_thread_client_id,
+                  foreman.getBusClientID(),
+                  &bus,
+                  &storage_manager,
+                  query_processor.get(),
+                  io_handle->out());
+            } catch (const quickstep::SqlError &sql_error) {
+              fprintf(io_handle->err(), "%s",
+                      sql_error.formatMessage(*command_string).c_str());
+              reset_parser = true;
+              break;
+            }
+            continue;
+          }
+          // Here the statement is presumed to be a query.
+          const std::size_t query_id = query_processor->query_id();
+          const CatalogRelation *query_result_relation = nullptr;
+          std::unique_ptr<quickstep::ExecutionDAGVisualizer> dag_visualizer;
+
           try {
-            quickstep::cli::executeCommand(
-                statement,
-                *(query_processor->getDefaultDatabase()),
+            auto query_handle = std::make_unique<QueryHandle>(query_id,
+                                                              main_thread_client_id,
+                                                              statement.getPriority());
+            query_handle->setMemData(io_handle->data());
+            query_processor->generateQueryHandle(statement, query_handle.get());
+            DCHECK(query_handle->getQueryPlanMutable() != nullptr);
+
+            if (quickstep::FLAGS_visualize_execution_dag) {
+              dag_visualizer =
+                  std::make_unique<quickstep::ExecutionDAGVisualizer>(query_handle->getQueryPlan());
+            }
+
+            query_result_relation = query_handle->getQueryResultRelation();
+
+            start = std::chrono::steady_clock::now();
+            QueryExecutionUtil::ConstructAndSendAdmitRequestMessage(
                 main_thread_client_id,
                 foreman.getBusClientID(),
-                &bus,
-                &storage_manager,
-                query_processor.get(),
-                io_handle->out());
+                query_handle.release(),
+                &bus);
           } catch (const quickstep::SqlError &sql_error) {
-            fprintf(io_handle->err(), "%s",
-                    sql_error.formatMessage(*command_string).c_str());
+            switch (statement.getStatementType()) {
+              case ParseStatement::kDropTable:
+                // Quick hack for QuickGrail for cleaner log information
+                // since we don't have DROP TABLE IF EXISTS yet.
+                break;
+              default:
+                fprintf(io_handle->err(), "%s",
+                        sql_error.formatMessage(*command_string).c_str());
+            }
             reset_parser = true;
             break;
           }
-          continue;
-        }
-        // Here the statement is presumed to be a query.
-        const std::size_t query_id = query_processor->query_id();
-        const CatalogRelation *query_result_relation = nullptr;
-        std::unique_ptr<quickstep::ExecutionDAGVisualizer> dag_visualizer;
 
-        try {
-          auto query_handle = std::make_unique<QueryHandle>(query_id,
-                                                            main_thread_client_id,
-                                                            statement.getPriority());
-          query_handle->setMemData(io_handle->data());
-          query_processor->generateQueryHandle(statement, query_handle.get());
-          DCHECK(query_handle->getQueryPlanMutable() != nullptr);
+          try {
+            QueryExecutionUtil::ReceiveQueryCompletionMessage(
+                main_thread_client_id, &bus);
+            end = std::chrono::steady_clock::now();
 
-          if (quickstep::FLAGS_visualize_execution_dag) {
-            dag_visualizer =
-                std::make_unique<quickstep::ExecutionDAGVisualizer>(query_handle->getQueryPlan());
+            if (query_result_relation) {
+              PrintToScreen::PrintRelation(*query_result_relation,
+                                           &storage_manager,
+                                           io_handle->out());
+              PrintToScreen::PrintOutputSize(
+                  *query_result_relation,
+                  &storage_manager,
+                  io_handle->err());
+
+              DropRelation::Drop(*query_result_relation,
+                                 query_processor->getDefaultDatabase(),
+                                 &storage_manager);
+            }
+
+            query_processor->saveCatalog();
+            if (quickstep::FLAGS_display_timing) {
+              std::chrono::duration<double, std::milli> time_ms = end - start;
+              fprintf(io_handle->out(), "Time: %s ms\n",
+                     quickstep::DoubleToStringWithSignificantDigits(
+                         time_ms.count(), 3).c_str());
+            }
+            if (quickstep::FLAGS_profile_and_report_workorder_perf) {
+              // TODO(harshad) - Allow user specified file instead of stdout.
+              foreman.printWorkOrderProfilingResults(query_id, stdout);
+            }
+            if (quickstep::FLAGS_visualize_execution_dag) {
+              const auto *profiling_stats =
+                  foreman.getWorkOrderProfilingResults(query_id);
+              if (profiling_stats) {
+                dag_visualizer->bindProfilingStats(*profiling_stats);
+              }
+              std::cerr << "\n" << dag_visualizer->toDOT() << "\n";
+            }
+          } catch (const std::exception &e) {
+            fprintf(io_handle->err(), "QUERY EXECUTION ERROR: %s\n", e.what());
+            break;
           }
-
-          query_result_relation = query_handle->getQueryResultRelation();
-
-          start = std::chrono::steady_clock::now();
-          QueryExecutionUtil::ConstructAndSendAdmitRequestMessage(
-              main_thread_client_id,
-              foreman.getBusClientID(),
-              query_handle.release(),
-              &bus);
-        } catch (const quickstep::SqlError &sql_error) {
-          switch (statement.getStatementType()) {
-            case ParseStatement::kDropTable:
-              // Quick hack for QuickGrail for cleaner log information
-              // since we don't have DROP TABLE IF EXISTS yet.
-              break;
-            default:
-              fprintf(io_handle->err(), "%s",
-                      sql_error.formatMessage(*command_string).c_str());
+        } else {
+          if (result.condition == ParseResult::kError) {
+            fprintf(io_handle->err(), "%s", result.error_message.c_str());
           }
           reset_parser = true;
           break;
         }
-
-        try {
-          QueryExecutionUtil::ReceiveQueryCompletionMessage(
-              main_thread_client_id, &bus);
-          end = std::chrono::steady_clock::now();
-
-          if (query_result_relation) {
-            PrintToScreen::PrintRelation(*query_result_relation,
-                                         &storage_manager,
-                                         io_handle->out());
-            PrintToScreen::PrintOutputSize(
-                *query_result_relation,
-                &storage_manager,
-                io_handle->err());
-
-            DropRelation::Drop(*query_result_relation,
-                               query_processor->getDefaultDatabase(),
-                               &storage_manager);
-          }
-
-          query_processor->saveCatalog();
-          if (quickstep::FLAGS_display_timing) {
-            std::chrono::duration<double, std::milli> time_ms = end - start;
-            fprintf(io_handle->out(), "Time: %s ms\n",
-                   quickstep::DoubleToStringWithSignificantDigits(
-                       time_ms.count(), 3).c_str());
-          }
-          if (quickstep::FLAGS_profile_and_report_workorder_perf) {
-            // TODO(harshad) - Allow user specified file instead of stdout.
-            foreman.printWorkOrderProfilingResults(query_id, stdout);
-          }
-          if (quickstep::FLAGS_visualize_execution_dag) {
-            const auto *profiling_stats =
-                foreman.getWorkOrderProfilingResults(query_id);
-            if (profiling_stats) {
-              dag_visualizer->bindProfilingStats(*profiling_stats);
-            }
-            std::cerr << "\n" << dag_visualizer->toDOT() << "\n";
-          }
-        } catch (const std::exception &e) {
-          fprintf(io_handle->err(), "QUERY EXECUTION ERROR: %s\n", e.what());
-          break;
+  #ifdef QUICKSTEP_ENABLE_GOOGLE_PROFILER
+        // Profile only if profile_file_name flag is set
+        if (!started_profiling && !quickstep::FLAGS_profile_file_name.empty()) {
+          started_profiling = true;
+          ProfilerStart(quickstep::FLAGS_profile_file_name.c_str());
         }
-      } else {
-        if (result.condition == ParseResult::kError) {
-          fprintf(io_handle->err(), "%s", result.error_message.c_str());
-        }
-        reset_parser = true;
+  #endif
+      }
+
+      if (quitting) {
         break;
+      } else if (reset_parser) {
+        parser_wrapper.reset(new SqlParserWrapper());
+        reset_parser = false;
       }
-#ifdef QUICKSTEP_ENABLE_GOOGLE_PROFILER
-      // Profile only if profile_file_name flag is set
-      if (!started_profiling && !quickstep::FLAGS_profile_file_name.empty()) {
-        started_profiling = true;
-        ProfilerStart(quickstep::FLAGS_profile_file_name.c_str());
-      }
-#endif
-    }
-
-    if (quitting) {
-      break;
-    } else if (reset_parser) {
-      parser_wrapper.reset(new SqlParserWrapper());
-      reset_parser = false;
     }
   }
 
diff --git a/cli/SocketIO.cpp b/cli/SocketIO.cpp
new file mode 100644
index 0000000..ea94e06
--- /dev/null
+++ b/cli/SocketIO.cpp
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "cli/SocketIO.hpp"
+
+#include "gflags/gflags.h"
+#include "glog/logging.h"
+
+namespace quickstep {
+
+DEFINE_int32(cli_socket_port, 3000,
+             "Listens for TCP connections on this port when socket mode is enabled. "
+             "This is only used if the cli is set to use the socket mode (-mode=socket).");
+
+DEFINE_string(cli_socket_ip, "0.0.0.0",
+              "The ip address which the cli should open a connection on. "
+              "This is only used if the cli is set to use the network mode (-mode=socket). "
+              "Defaults to the address of localhost.");
+
+}  // namespace quickstep
diff --git a/cli/SocketIO.hpp b/cli/SocketIO.hpp
new file mode 100644
index 0000000..1570e92
--- /dev/null
+++ b/cli/SocketIO.hpp
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 QUICKSTEP_CLI_SOCKET_IO_HPP_
+#define QUICKSTEP_CLI_SOCKET_IO_HPP_
+
+#include <cstdio>
+#include <iostream>
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "cli/IOInterface.hpp"
+#include "cli/LineReaderBuffered.hpp"
+#include "cli/simple_socket/SimpleSocketConnection.hpp"
+#include "cli/simple_socket/SimpleSocketContent.hpp"
+#include "cli/simple_socket/SimpleSocketServer.hpp"
+#include "utility/Macros.hpp"
+#include "utility/MemStream.hpp"
+#include "utility/StringUtil.hpp"
+#include "utility/ThreadSafeQueue.hpp"
+
+#include "gflags/gflags.h"
+#include "glog/logging.h"
+
+namespace quickstep {
+
+DECLARE_int32(cli_socket_port);
+DECLARE_string(cli_socket_ip);
+
+class SocketIOHandle final : public IOHandle {
+ public:
+  explicit SocketIOHandle(SimpleSocketConnection *conn)
+      : conn_(conn),
+        request_(conn_->getRequest()) {
+    const auto *it = request_.get("query");
+    CHECK(it != nullptr);
+    LineReaderBuffered line_reader;
+    line_reader.setBuffer(std::string(it->first, it->second));
+    while (!line_reader.bufferEmpty()) {
+      std::string command = line_reader.getNextCommand();
+      if (!command.empty()) {
+        commands_.emplace_back(std::move(command));
+      }
+    }
+  }
+
+  ~SocketIOHandle() override {
+    conn_->sendResponse(out_stream_.str(), err_stream_.str());
+  }
+
+  StringPiece data() const override {
+    const StringPiece *entry = request_.get("data");
+    return entry == nullptr ? StringPiece(nullptr, 0) : *entry;
+  }
+
+  FILE* out() override {
+    return out_stream_.file();
+  }
+
+  FILE* err() override {
+    return err_stream_.file();
+  }
+
+  std::vector<std::string> getCommands() const override {
+    return commands_;
+  }
+
+ private:
+  std::unique_ptr<SimpleSocketConnection> conn_;
+  const SimpleSocketContent &request_;
+  MemStream out_stream_, err_stream_;
+  std::vector<std::string> commands_;
+
+  DISALLOW_COPY_AND_ASSIGN(SocketIOHandle);
+};
+
+/**
+ * A network interface that uses native socket to accept commands.
+ */
+class SocketIO final : public IOInterface {
+ public:
+  SocketIO()
+      : server_(FLAGS_cli_socket_port) {
+    server_.start();
+  }
+
+  ~SocketIO() override {
+    server_.stop();
+  }
+
+  IOHandle* getNextIOHandle() override {
+    return new SocketIOHandle(server_.waitForConnection());
+  }
+
+ private:
+  SimpleSocketServer server_;
+
+  DISALLOW_COPY_AND_ASSIGN(SocketIO);
+};
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_CLI_SOCKET_IO_HPP_
diff --git a/cli/quickstep/NetworkCliOuterClass.java b/cli/quickstep/NetworkCliOuterClass.java
deleted file mode 100644
index 6f4e833..0000000
--- a/cli/quickstep/NetworkCliOuterClass.java
+++ /dev/null
@@ -1,1388 +0,0 @@
-// Generated by the protocol buffer compiler.  DO NOT EDIT!
-// source: NetworkCli.proto
-
-package quickstep;
-
-public final class NetworkCliOuterClass {
-  private NetworkCliOuterClass() {}
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistryLite registry) {
-  }
-
-  public static void registerAllExtensions(
-      com.google.protobuf.ExtensionRegistry registry) {
-    registerAllExtensions(
-        (com.google.protobuf.ExtensionRegistryLite) registry);
-  }
-  public interface QueryRequestOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:quickstep.QueryRequest)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>string query = 1;</code>
-     */
-    java.lang.String getQuery();
-    /**
-     * <code>string query = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getQueryBytes();
-
-    /**
-     * <code>string data = 2;</code>
-     */
-    java.lang.String getData();
-    /**
-     * <code>string data = 2;</code>
-     */
-    com.google.protobuf.ByteString
-        getDataBytes();
-  }
-  /**
-   * Protobuf type {@code quickstep.QueryRequest}
-   */
-  public  static final class QueryRequest extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:quickstep.QueryRequest)
-      QueryRequestOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use QueryRequest.newBuilder() to construct.
-    private QueryRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private QueryRequest() {
-      query_ = "";
-      data_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private QueryRequest(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownFieldProto3(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 10: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              query_ = s;
-              break;
-            }
-            case 18: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              data_ = s;
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              quickstep.NetworkCliOuterClass.QueryRequest.class, quickstep.NetworkCliOuterClass.QueryRequest.Builder.class);
-    }
-
-    public static final int QUERY_FIELD_NUMBER = 1;
-    private volatile java.lang.Object query_;
-    /**
-     * <code>string query = 1;</code>
-     */
-    public java.lang.String getQuery() {
-      java.lang.Object ref = query_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        query_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>string query = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getQueryBytes() {
-      java.lang.Object ref = query_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        query_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int DATA_FIELD_NUMBER = 2;
-    private volatile java.lang.Object data_;
-    /**
-     * <code>string data = 2;</code>
-     */
-    public java.lang.String getData() {
-      java.lang.Object ref = data_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        data_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>string data = 2;</code>
-     */
-    public com.google.protobuf.ByteString
-        getDataBytes() {
-      java.lang.Object ref = data_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        data_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (!getQueryBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, query_);
-      }
-      if (!getDataBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, data_);
-      }
-      unknownFields.writeTo(output);
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getQueryBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, query_);
-      }
-      if (!getDataBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, data_);
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
-      }
-      if (!(obj instanceof quickstep.NetworkCliOuterClass.QueryRequest)) {
-        return super.equals(obj);
-      }
-      quickstep.NetworkCliOuterClass.QueryRequest other = (quickstep.NetworkCliOuterClass.QueryRequest) obj;
-
-      boolean result = true;
-      result = result && getQuery()
-          .equals(other.getQuery());
-      result = result && getData()
-          .equals(other.getData());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
-      }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + QUERY_FIELD_NUMBER;
-      hash = (53 * hash) + getQuery().hashCode();
-      hash = (37 * hash) + DATA_FIELD_NUMBER;
-      hash = (53 * hash) + getData().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryRequest parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(quickstep.NetworkCliOuterClass.QueryRequest prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code quickstep.QueryRequest}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:quickstep.QueryRequest)
-        quickstep.NetworkCliOuterClass.QueryRequestOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                quickstep.NetworkCliOuterClass.QueryRequest.class, quickstep.NetworkCliOuterClass.QueryRequest.Builder.class);
-      }
-
-      // Construct using quickstep.NetworkCliOuterClass.QueryRequest.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        query_ = "";
-
-        data_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryRequest_descriptor;
-      }
-
-      public quickstep.NetworkCliOuterClass.QueryRequest getDefaultInstanceForType() {
-        return quickstep.NetworkCliOuterClass.QueryRequest.getDefaultInstance();
-      }
-
-      public quickstep.NetworkCliOuterClass.QueryRequest build() {
-        quickstep.NetworkCliOuterClass.QueryRequest result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public quickstep.NetworkCliOuterClass.QueryRequest buildPartial() {
-        quickstep.NetworkCliOuterClass.QueryRequest result = new quickstep.NetworkCliOuterClass.QueryRequest(this);
-        result.query_ = query_;
-        result.data_ = data_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder clone() {
-        return (Builder) super.clone();
-      }
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return (Builder) super.setField(field, value);
-      }
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
-      }
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
-      }
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
-      }
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
-      }
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof quickstep.NetworkCliOuterClass.QueryRequest) {
-          return mergeFrom((quickstep.NetworkCliOuterClass.QueryRequest)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(quickstep.NetworkCliOuterClass.QueryRequest other) {
-        if (other == quickstep.NetworkCliOuterClass.QueryRequest.getDefaultInstance()) return this;
-        if (!other.getQuery().isEmpty()) {
-          query_ = other.query_;
-          onChanged();
-        }
-        if (!other.getData().isEmpty()) {
-          data_ = other.data_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        quickstep.NetworkCliOuterClass.QueryRequest parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (quickstep.NetworkCliOuterClass.QueryRequest) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object query_ = "";
-      /**
-       * <code>string query = 1;</code>
-       */
-      public java.lang.String getQuery() {
-        java.lang.Object ref = query_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          query_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>string query = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getQueryBytes() {
-        java.lang.Object ref = query_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          query_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>string query = 1;</code>
-       */
-      public Builder setQuery(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        query_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string query = 1;</code>
-       */
-      public Builder clearQuery() {
-        
-        query_ = getDefaultInstance().getQuery();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string query = 1;</code>
-       */
-      public Builder setQueryBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        query_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object data_ = "";
-      /**
-       * <code>string data = 2;</code>
-       */
-      public java.lang.String getData() {
-        java.lang.Object ref = data_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          data_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>string data = 2;</code>
-       */
-      public com.google.protobuf.ByteString
-          getDataBytes() {
-        java.lang.Object ref = data_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          data_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>string data = 2;</code>
-       */
-      public Builder setData(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        data_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string data = 2;</code>
-       */
-      public Builder clearData() {
-        
-        data_ = getDefaultInstance().getData();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string data = 2;</code>
-       */
-      public Builder setDataBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        data_ = value;
-        onChanged();
-        return this;
-      }
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFieldsProto3(unknownFields);
-      }
-
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:quickstep.QueryRequest)
-    }
-
-    // @@protoc_insertion_point(class_scope:quickstep.QueryRequest)
-    private static final quickstep.NetworkCliOuterClass.QueryRequest DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new quickstep.NetworkCliOuterClass.QueryRequest();
-    }
-
-    public static quickstep.NetworkCliOuterClass.QueryRequest getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<QueryRequest>
-        PARSER = new com.google.protobuf.AbstractParser<QueryRequest>() {
-      public QueryRequest parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-          return new QueryRequest(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<QueryRequest> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<QueryRequest> getParserForType() {
-      return PARSER;
-    }
-
-    public quickstep.NetworkCliOuterClass.QueryRequest getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface QueryResponseOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:quickstep.QueryResponse)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>string query_result = 1;</code>
-     */
-    java.lang.String getQueryResult();
-    /**
-     * <code>string query_result = 1;</code>
-     */
-    com.google.protobuf.ByteString
-        getQueryResultBytes();
-
-    /**
-     * <code>string error_result = 2;</code>
-     */
-    java.lang.String getErrorResult();
-    /**
-     * <code>string error_result = 2;</code>
-     */
-    com.google.protobuf.ByteString
-        getErrorResultBytes();
-  }
-  /**
-   * Protobuf type {@code quickstep.QueryResponse}
-   */
-  public  static final class QueryResponse extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:quickstep.QueryResponse)
-      QueryResponseOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use QueryResponse.newBuilder() to construct.
-    private QueryResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private QueryResponse() {
-      queryResult_ = "";
-      errorResult_ = "";
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private QueryResponse(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            default: {
-              if (!parseUnknownFieldProto3(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-            case 10: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              queryResult_ = s;
-              break;
-            }
-            case 18: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              errorResult_ = s;
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_descriptor;
-    }
-
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              quickstep.NetworkCliOuterClass.QueryResponse.class, quickstep.NetworkCliOuterClass.QueryResponse.Builder.class);
-    }
-
-    public static final int QUERY_RESULT_FIELD_NUMBER = 1;
-    private volatile java.lang.Object queryResult_;
-    /**
-     * <code>string query_result = 1;</code>
-     */
-    public java.lang.String getQueryResult() {
-      java.lang.Object ref = queryResult_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        queryResult_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>string query_result = 1;</code>
-     */
-    public com.google.protobuf.ByteString
-        getQueryResultBytes() {
-      java.lang.Object ref = queryResult_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        queryResult_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    public static final int ERROR_RESULT_FIELD_NUMBER = 2;
-    private volatile java.lang.Object errorResult_;
-    /**
-     * <code>string error_result = 2;</code>
-     */
-    public java.lang.String getErrorResult() {
-      java.lang.Object ref = errorResult_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        errorResult_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>string error_result = 2;</code>
-     */
-    public com.google.protobuf.ByteString
-        getErrorResultBytes() {
-      java.lang.Object ref = errorResult_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        errorResult_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private byte memoizedIsInitialized = -1;
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (!getQueryResultBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, queryResult_);
-      }
-      if (!getErrorResultBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, errorResult_);
-      }
-      unknownFields.writeTo(output);
-    }
-
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getQueryResultBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, queryResult_);
-      }
-      if (!getErrorResultBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, errorResult_);
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
-      }
-      if (!(obj instanceof quickstep.NetworkCliOuterClass.QueryResponse)) {
-        return super.equals(obj);
-      }
-      quickstep.NetworkCliOuterClass.QueryResponse other = (quickstep.NetworkCliOuterClass.QueryResponse) obj;
-
-      boolean result = true;
-      result = result && getQueryResult()
-          .equals(other.getQueryResult());
-      result = result && getErrorResult()
-          .equals(other.getErrorResult());
-      result = result && unknownFields.equals(other.unknownFields);
-      return result;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
-      }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + QUERY_RESULT_FIELD_NUMBER;
-      hash = (53 * hash) + getQueryResult().hashCode();
-      hash = (37 * hash) + ERROR_RESULT_FIELD_NUMBER;
-      hash = (53 * hash) + getErrorResult().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static quickstep.NetworkCliOuterClass.QueryResponse parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(quickstep.NetworkCliOuterClass.QueryResponse prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code quickstep.QueryResponse}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:quickstep.QueryResponse)
-        quickstep.NetworkCliOuterClass.QueryResponseOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                quickstep.NetworkCliOuterClass.QueryResponse.class, quickstep.NetworkCliOuterClass.QueryResponse.Builder.class);
-      }
-
-      // Construct using quickstep.NetworkCliOuterClass.QueryResponse.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-        }
-      }
-      public Builder clear() {
-        super.clear();
-        queryResult_ = "";
-
-        errorResult_ = "";
-
-        return this;
-      }
-
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return quickstep.NetworkCliOuterClass.internal_static_quickstep_QueryResponse_descriptor;
-      }
-
-      public quickstep.NetworkCliOuterClass.QueryResponse getDefaultInstanceForType() {
-        return quickstep.NetworkCliOuterClass.QueryResponse.getDefaultInstance();
-      }
-
-      public quickstep.NetworkCliOuterClass.QueryResponse build() {
-        quickstep.NetworkCliOuterClass.QueryResponse result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      public quickstep.NetworkCliOuterClass.QueryResponse buildPartial() {
-        quickstep.NetworkCliOuterClass.QueryResponse result = new quickstep.NetworkCliOuterClass.QueryResponse(this);
-        result.queryResult_ = queryResult_;
-        result.errorResult_ = errorResult_;
-        onBuilt();
-        return result;
-      }
-
-      public Builder clone() {
-        return (Builder) super.clone();
-      }
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return (Builder) super.setField(field, value);
-      }
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return (Builder) super.clearField(field);
-      }
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return (Builder) super.clearOneof(oneof);
-      }
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return (Builder) super.setRepeatedField(field, index, value);
-      }
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return (Builder) super.addRepeatedField(field, value);
-      }
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof quickstep.NetworkCliOuterClass.QueryResponse) {
-          return mergeFrom((quickstep.NetworkCliOuterClass.QueryResponse)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(quickstep.NetworkCliOuterClass.QueryResponse other) {
-        if (other == quickstep.NetworkCliOuterClass.QueryResponse.getDefaultInstance()) return this;
-        if (!other.getQueryResult().isEmpty()) {
-          queryResult_ = other.queryResult_;
-          onChanged();
-        }
-        if (!other.getErrorResult().isEmpty()) {
-          errorResult_ = other.errorResult_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        quickstep.NetworkCliOuterClass.QueryResponse parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (quickstep.NetworkCliOuterClass.QueryResponse) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object queryResult_ = "";
-      /**
-       * <code>string query_result = 1;</code>
-       */
-      public java.lang.String getQueryResult() {
-        java.lang.Object ref = queryResult_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          queryResult_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>string query_result = 1;</code>
-       */
-      public com.google.protobuf.ByteString
-          getQueryResultBytes() {
-        java.lang.Object ref = queryResult_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          queryResult_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>string query_result = 1;</code>
-       */
-      public Builder setQueryResult(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        queryResult_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string query_result = 1;</code>
-       */
-      public Builder clearQueryResult() {
-        
-        queryResult_ = getDefaultInstance().getQueryResult();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string query_result = 1;</code>
-       */
-      public Builder setQueryResultBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        queryResult_ = value;
-        onChanged();
-        return this;
-      }
-
-      private java.lang.Object errorResult_ = "";
-      /**
-       * <code>string error_result = 2;</code>
-       */
-      public java.lang.String getErrorResult() {
-        java.lang.Object ref = errorResult_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          errorResult_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>string error_result = 2;</code>
-       */
-      public com.google.protobuf.ByteString
-          getErrorResultBytes() {
-        java.lang.Object ref = errorResult_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          errorResult_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>string error_result = 2;</code>
-       */
-      public Builder setErrorResult(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        errorResult_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string error_result = 2;</code>
-       */
-      public Builder clearErrorResult() {
-        
-        errorResult_ = getDefaultInstance().getErrorResult();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string error_result = 2;</code>
-       */
-      public Builder setErrorResultBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        errorResult_ = value;
-        onChanged();
-        return this;
-      }
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFieldsProto3(unknownFields);
-      }
-
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:quickstep.QueryResponse)
-    }
-
-    // @@protoc_insertion_point(class_scope:quickstep.QueryResponse)
-    private static final quickstep.NetworkCliOuterClass.QueryResponse DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new quickstep.NetworkCliOuterClass.QueryResponse();
-    }
-
-    public static quickstep.NetworkCliOuterClass.QueryResponse getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<QueryResponse>
-        PARSER = new com.google.protobuf.AbstractParser<QueryResponse>() {
-      public QueryResponse parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-          return new QueryResponse(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<QueryResponse> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<QueryResponse> getParserForType() {
-      return PARSER;
-    }
-
-    public quickstep.NetworkCliOuterClass.QueryResponse getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_quickstep_QueryRequest_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_quickstep_QueryRequest_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_quickstep_QueryResponse_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_quickstep_QueryResponse_fieldAccessorTable;
-
-  public static com.google.protobuf.Descriptors.FileDescriptor
-      getDescriptor() {
-    return descriptor;
-  }
-  private static  com.google.protobuf.Descriptors.FileDescriptor
-      descriptor;
-  static {
-    java.lang.String[] descriptorData = {
-      "\n\020NetworkCli.proto\022\tquickstep\"+\n\014QueryRe" +
-      "quest\022\r\n\005query\030\001 \001(\t\022\014\n\004data\030\002 \001(\t\";\n\rQu" +
-      "eryResponse\022\024\n\014query_result\030\001 \001(\t\022\024\n\014err" +
-      "or_result\030\002 \001(\t2N\n\nNetworkCli\022@\n\tSendQue" +
-      "ry\022\027.quickstep.QueryRequest\032\030.quickstep." +
-      "QueryResponse\"\000b\006proto3"
-    };
-    com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
-        new com.google.protobuf.Descriptors.FileDescriptor.    InternalDescriptorAssigner() {
-          public com.google.protobuf.ExtensionRegistry assignDescriptors(
-              com.google.protobuf.Descriptors.FileDescriptor root) {
-            descriptor = root;
-            return null;
-          }
-        };
-    com.google.protobuf.Descriptors.FileDescriptor
-      .internalBuildGeneratedFileFrom(descriptorData,
-        new com.google.protobuf.Descriptors.FileDescriptor[] {
-        }, assigner);
-    internal_static_quickstep_QueryRequest_descriptor =
-      getDescriptor().getMessageTypes().get(0);
-    internal_static_quickstep_QueryRequest_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_quickstep_QueryRequest_descriptor,
-        new java.lang.String[] { "Query", "Data", });
-    internal_static_quickstep_QueryResponse_descriptor =
-      getDescriptor().getMessageTypes().get(1);
-    internal_static_quickstep_QueryResponse_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_quickstep_QueryResponse_descriptor,
-        new java.lang.String[] { "QueryResult", "ErrorResult", });
-  }
-
-  // @@protoc_insertion_point(outer_class_scope)
-}
diff --git a/cli/simple_socket/CMakeLists.txt b/cli/simple_socket/CMakeLists.txt
new file mode 100644
index 0000000..d021a61
--- /dev/null
+++ b/cli/simple_socket/CMakeLists.txt
@@ -0,0 +1,35 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+
+# Declare micro-libs:
+add_library(quickstep_cli_simplesocket_SimpleSocketConnection ../../empty_src.cpp SimpleSocketConnection.hpp)
+add_library(quickstep_cli_simplesocket_SimpleSocketContent ../../empty_src.cpp SimpleSocketContent.hpp)
+add_library(quickstep_cli_simplesocket_SimpleSocketServer ../../empty_src.cpp SimpleSocketServer.hpp)
+
+# Link dependencies:
+target_link_libraries(quickstep_cli_simplesocket_SimpleSocketConnection
+                      glog
+                      quickstep_cli_simplesocket_SimpleSocketContent
+                      quickstep_utility_Macros)
+target_link_libraries(quickstep_cli_simplesocket_SimpleSocketContent
+                      quickstep_utility_Macros
+                      quickstep_utility_StringUtil)
+target_link_libraries(quickstep_cli_simplesocket_SimpleSocketServer
+                      glog
+                      quickstep_cli_simplesocket_SimpleSocketConnection
+                      quickstep_utility_Macros
+                      quickstep_utility_ThreadSafeQueue)
diff --git a/cli/simple_socket/SimpleSocketConnection.hpp b/cli/simple_socket/SimpleSocketConnection.hpp
new file mode 100644
index 0000000..111db6a
--- /dev/null
+++ b/cli/simple_socket/SimpleSocketConnection.hpp
@@ -0,0 +1,159 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_CONNECTION_HPP_
+#define QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_CONNECTION_HPP_
+
+#include <sys/socket.h>
+
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "cli/simple_socket/SimpleSocketContent.hpp"
+#include "utility/Macros.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class SimpleSocketConnection {
+ public:
+  explicit SimpleSocketConnection(const int socket_fd)
+      : socket_fd_(socket_fd),
+        request_data_(nullptr) {
+    receiveRequest();
+  }
+
+  ~SimpleSocketConnection() {
+    if (request_data_ != nullptr) {
+      std::free(request_data_);
+      request_data_ = nullptr;
+      shutdown(socket_fd_, SHUT_RDWR);
+      close(socket_fd_);
+    }
+  }
+
+  const SimpleSocketContent& getRequest() const {
+    return request_;
+  }
+
+  void sendResponse(const std::string &stdout_str,
+                    const std::string &stderr_str) const {
+    SimpleSocketContent response;
+    response.setField("stdout", stdout_str);
+    response.setField("stderr", stderr_str);
+    sendResponse(response);
+  }
+
+ private:
+  void receiveRequest() {
+    request_data_length_ = receiveUInt64();
+    request_data_ = std::malloc(request_data_length_);
+    receiveData(request_data_, request_data_length_);
+
+    // Decode request data.
+    const std::uint64_t *size_ptr =
+        static_cast<const std::uint64_t*>(request_data_);
+    const std::uint64_t num_fields = ntohll(*size_ptr++);
+
+    std::vector<std::pair<std::uint64_t, std::uint64_t>> field_sizes;
+    for (std::size_t i = 0; i < num_fields; ++i) {
+      const std::uint64_t key_size = ntohll(*size_ptr++);
+      const std::uint64_t value_size = ntohll(*size_ptr++);
+      field_sizes.emplace_back(key_size, value_size);
+    }
+
+    const char *data_ptr = reinterpret_cast<const char*>(size_ptr);
+    for (std::size_t i = 0; i < num_fields; ++i) {
+      const auto &fs = field_sizes[i];
+      const std::uint64_t key_size = fs.first;
+      const std::uint64_t value_size = fs.second;
+      const char *key = data_ptr;
+      const char *value = data_ptr + key_size;
+      request_.setField(key, key_size, value, value_size);
+      data_ptr += key_size + value_size;
+    }
+
+    CHECK_EQ(static_cast<const char*>(request_data_) + request_data_length_,
+             data_ptr);
+  }
+
+  inline void receiveData(void *dst, std::size_t bytes) const {
+    while (bytes != 0) {
+      const std::size_t bytes_read = read(socket_fd_, dst, bytes);
+      CHECK(bytes_read != 0);
+      bytes -= bytes_read;
+      dst = static_cast<char*>(dst) + bytes_read;
+    }
+  }
+
+  inline std::uint64_t receiveUInt64() const {
+    std::uint64_t code;
+    receiveData(&code, sizeof(std::uint64_t));
+    return ntohll(code);
+  }
+
+  inline void writeUInt64(const std::uint64_t value) const {
+    const uint64_t code = htonll(value);
+    write(socket_fd_, &code, sizeof(std::uint64_t));
+  }
+
+  void sendResponse(const SimpleSocketContent &response) const {
+    // Calculate field sizes.
+    std::uint64_t total_size = 0;
+    std::vector<std::pair<const char*, const char*>> field_ptrs;
+    std::vector<std::pair<std::uint64_t, std::uint64_t>> field_sizes;
+    for (const auto &it : response.fields()) {
+      const std::string &key = it.first;
+      const StringPiece &value = it.second;
+      field_ptrs.emplace_back(key.data(), value.first);
+      field_sizes.emplace_back(key.length(), value.second);
+      total_size += key.length() + value.second;
+    }
+
+    const std::size_t num_fields = field_ptrs.size();
+    total_size += sizeof(std::uint64_t) * (1 + 2 * num_fields);
+
+    writeUInt64(total_size);
+    writeUInt64(num_fields);
+    for (const auto &it : field_sizes) {
+      writeUInt64(it.first);
+      writeUInt64(it.second);
+    }
+    for (std::size_t i = 0; i < num_fields; ++i) {
+      const auto &fp = field_ptrs[i];
+      const auto &fs = field_sizes[i];
+      write(socket_fd_, fp.first, fs.first);
+      write(socket_fd_, fp.second, fs.second);
+    }
+  }
+
+  const int socket_fd_;
+  std::uint64_t request_data_length_;
+  void *request_data_;
+  SimpleSocketContent request_;
+
+  DISALLOW_COPY_AND_ASSIGN(SimpleSocketConnection);
+};
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_CONNECTION_HPP_
diff --git a/cli/simple_socket/SimpleSocketContent.hpp b/cli/simple_socket/SimpleSocketContent.hpp
new file mode 100644
index 0000000..2cfb7a8
--- /dev/null
+++ b/cli/simple_socket/SimpleSocketContent.hpp
@@ -0,0 +1,75 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_CONTENT_HPP_
+#define QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_CONTENT_HPP_
+
+#include <cstddef>
+#include <iostream>
+#include <list>
+#include <string>
+#include <unordered_map>
+#include <utility>
+
+#include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
+
+namespace quickstep {
+
+class SimpleSocketContent {
+ public:
+  SimpleSocketContent() {}
+
+  bool contains(const std::string &key) const {
+    return fields_.find(key) != fields_.end();
+  }
+
+  const StringPiece* get(const std::string &key) const {
+    const auto it = fields_.find(key);
+    return it == fields_.end() ? nullptr : &it->second;
+  }
+
+  void setField(const std::string &key, const std::string &value) {
+    storage_.emplace_back(value);
+    const std::string &sv = storage_.back();
+    fields_.emplace(key, StringPiece(sv.c_str(), sv.length()));
+  }
+
+  const std::unordered_map<std::string, StringPiece>& fields() const {
+    return fields_;
+  }
+
+ private:
+  void setField(const char *key, const std::size_t key_size,
+                const char *value, const std::size_t value_size) {
+    fields_.emplace(std::string(key, key_size),
+                    StringPiece(value, value_size));
+  }
+
+  std::unordered_map<std::string, StringPiece> fields_;
+  std::list<std::string> storage_;
+
+  friend class SimpleSocketConnection;
+
+  DISALLOW_COPY_AND_ASSIGN(SimpleSocketContent);
+};
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_CONTENT_HPP_
diff --git a/cli/simple_socket/SimpleSocketServer.hpp b/cli/simple_socket/SimpleSocketServer.hpp
new file mode 100644
index 0000000..d2f5dfe
--- /dev/null
+++ b/cli/simple_socket/SimpleSocketServer.hpp
@@ -0,0 +1,115 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_SERVER_HPP_
+#define QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_SERVER_HPP_
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <cstring>
+#include <iostream>
+#include <memory>
+#include <thread>
+
+#include "cli/simple_socket/SimpleSocketConnection.hpp"
+#include "utility/Macros.hpp"
+#include "utility/ThreadSafeQueue.hpp"
+
+#include "glog/logging.h"
+
+namespace quickstep {
+
+class SimpleSocketServer {
+ public:
+  SimpleSocketServer(const int port)
+      : port_(port) {}
+
+  ~SimpleSocketServer() {
+    stop();
+  }
+
+  void start() {
+    CHECK(main_loop_thread_ == nullptr);
+    CHECK(connections_.empty());
+    main_loop_thread_ = std::make_unique<std::thread>([this] {
+      this->mainLoop(this->port_);
+    });
+  }
+
+  void stop() {
+    if (main_loop_thread_ != nullptr) {
+      main_loop_thread_ = nullptr;
+    }
+  }
+
+  SimpleSocketConnection* waitForConnection() {
+    return connections_.popOne().release();
+  }
+
+ private:
+  void mainLoop(const int port) {
+    main_socket_fd_ = socket(AF_INET, SOCK_STREAM, 0);
+    int option = 1;
+    setsockopt(main_socket_fd_,
+               SOL_SOCKET, SO_REUSEADDR,
+               &option,
+               sizeof(option));
+    CHECK(main_socket_fd_ >= 0) << "Error opening socket";
+
+    constexpr socklen_t sockaddr_size = sizeof(sockaddr_in);
+    sockaddr_in server_address;
+    std::memset(&server_address, 0, sockaddr_size);
+
+    server_address.sin_family = AF_INET;
+    server_address.sin_addr.s_addr = INADDR_ANY;
+    server_address.sin_port = htons(port);
+
+    const int bind_retval =
+        bind(main_socket_fd_,
+             reinterpret_cast<const sockaddr*>(&server_address),
+             sockaddr_size);
+    CHECK(bind_retval >= 0) << "Error binding socket";
+
+    const int listen_retval = listen(main_socket_fd_, 32);
+    CHECK(listen_retval >= 0) << "Error listening to socket connection";
+
+    while (true) {
+      socklen_t client_addr_len = sockaddr_size;
+      sockaddr_in client_address;
+      const int client_socket_fd =
+          accept(main_socket_fd_,
+                 reinterpret_cast<sockaddr*>(&client_address),
+                 &client_addr_len);
+      CHECK(client_socket_fd >= 0) << "Error accepting socket connection";
+      connections_.push(std::make_unique<SimpleSocketConnection>(client_socket_fd));
+    }
+  }
+
+  const int port_;
+  std::unique_ptr<std::thread> main_loop_thread_;
+  int main_socket_fd_;
+  ThreadSafeQueue<std::unique_ptr<SimpleSocketConnection>> connections_;
+
+  DISALLOW_COPY_AND_ASSIGN(SimpleSocketServer);
+};
+
+}  // namespace quickstep
+
+#endif  // QUICKSTEP_CLI_SIMPLE_SOCKET_SIMPLE_SOCKET_SERVER_HPP_
diff --git a/query_optimizer/CMakeLists.txt b/query_optimizer/CMakeLists.txt
index 5e0db44..1c5d669 100644
--- a/query_optimizer/CMakeLists.txt
+++ b/query_optimizer/CMakeLists.txt
@@ -148,6 +148,7 @@
                       quickstep_relationaloperators_UpdateOperator
                       quickstep_relationaloperators_WindowAggregationOperator
                       quickstep_storage_AggregationOperationState_proto
+                      quickstep_storage_Flags
                       quickstep_storage_HashTableFactory
                       quickstep_storage_HashTable_proto
                       quickstep_storage_InsertDestination_proto
@@ -248,6 +249,7 @@
                       quickstep_queryexecution_QueryContext_proto
                       quickstep_queryoptimizer_QueryPlan
                       quickstep_utility_Macros
+                      quickstep_utility_StringUtil
                       tmb)
 target_link_libraries(quickstep_queryoptimizer_QueryPlan
                       quickstep_relationaloperators_RelationalOperator
diff --git a/query_optimizer/QueryHandle.hpp b/query_optimizer/QueryHandle.hpp
index 9b83074..2063f2a 100644
--- a/query_optimizer/QueryHandle.hpp
+++ b/query_optimizer/QueryHandle.hpp
@@ -31,6 +31,7 @@
 #include "query_optimizer/QueryOptimizerConfig.h"  // For QUICKSTEP_DISTRIBUTED.
 #include "query_optimizer/QueryPlan.hpp"
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 #include "tmb/id_typedefs.h"
 
@@ -90,7 +91,7 @@
         analyze_query_info_(analyze_query_info),
         query_plan_(new QueryPlan()),
         query_result_relation_(nullptr),
-        mem_data_(nullptr) {}
+        mem_data_(nullptr, 0) {}
 
   ~QueryHandle() {}
 
@@ -180,11 +181,11 @@
     query_result_relation_ = relation;
   }
 
-  const std::string* getMemData() const {
+  const StringPiece& getMemData() const {
     return mem_data_;
   }
 
-  void setMemData(const std::string *mem_data) {
+  void setMemData(const StringPiece &mem_data) {
     mem_data_ = mem_data;
   }
 
@@ -224,7 +225,7 @@
   //             and deleted by the Cli shell.
   const CatalogRelation *query_result_relation_;
 
-  const std::string *mem_data_;
+  StringPiece mem_data_;
 
 #ifdef QUICKSTEP_DISTRIBUTED
   // Indicate whether the query should be executed on the default Shiftboss for
diff --git a/relational_operators/CMakeLists.txt b/relational_operators/CMakeLists.txt
index 7b9ed96..1a4311f 100644
--- a/relational_operators/CMakeLists.txt
+++ b/relational_operators/CMakeLists.txt
@@ -532,6 +532,8 @@
                       quickstep_utility_BulkIoConfiguration
                       quickstep_utility_Glob
                       quickstep_utility_Macros
+                      quickstep_utility_ScopedBuffer
+                      quickstep_utility_StringUtil
                       tmb)
 if (QUICKSTEP_HAVE_FILE_MANAGER_HDFS)
   target_link_libraries(quickstep_relationaloperators_TextScanOperator
@@ -626,6 +628,7 @@
                       quickstep_relationaloperators_WorkOrder_proto
                       quickstep_storage_StorageBlockInfo
                       quickstep_utility_Macros
+                      quickstep_utility_StringUtil
                       quickstep_utility_lipfilter_LIPFilterUtil
                       tmb)
 target_link_libraries(quickstep_relationaloperators_WorkOrder_proto
diff --git a/relational_operators/TextScanOperator.cpp b/relational_operators/TextScanOperator.cpp
index 86712aa..ef7da22 100644
--- a/relational_operators/TextScanOperator.cpp
+++ b/relational_operators/TextScanOperator.cpp
@@ -125,11 +125,11 @@
     std::vector<std::size_t> file_sizes;
 
     if (file_pattern_ == "$stdin") {
-      if (mem_data_ == nullptr) {
+      if (mem_data_.first == nullptr) {
         container->addNormalWorkOrder(
             new TextScanWorkOrder(query_id_,
                                   file_pattern_,
-                                  nullptr /* mem_data */,
+                                  mem_data_,
                                   0,
                                   -1 /* text_segment_size */,
                                   options_->getDelimiter(),
@@ -143,7 +143,7 @@
         return true;
       }
       files.emplace_back(file_pattern_);
-      file_sizes.emplace_back(mem_data_->size());
+      file_sizes.emplace_back(mem_data_.second);
     } else {
       DCHECK_EQ('@', file_pattern_.front());
       files = utility::file::GlobExpand(file_pattern_.substr(1));
@@ -282,7 +282,7 @@
 void TextScanWorkOrder::execute() {
   DCHECK(!filename_.empty());
   if (filename_ == "$stdin") {
-    if (mem_data_ == nullptr) {
+    if (mem_data_.first == nullptr) {
       executeInputStream();
     } else {
       executeMemData();
@@ -512,7 +512,7 @@
   bool is_faulty;
 
   // Locate the first newline character.
-  const char *row_ptr = mem_data_->c_str() + text_offset_;
+  const char *row_ptr = mem_data_.first + text_offset_;
   const char *segment_end = row_ptr + text_segment_size_;
   if (text_offset_ != 0) {
     while (row_ptr < segment_end && *row_ptr != '\n') {
@@ -558,7 +558,7 @@
     }
   }
   // Process the tuple that is right after the last newline character.
-  const char *data_end = mem_data_->c_str() + mem_data_->size();
+  const char *data_end = mem_data_.first + mem_data_.second;
   while (end_ptr < data_end && *end_ptr != '\n') {
     ++end_ptr;
   }
diff --git a/relational_operators/TextScanOperator.hpp b/relational_operators/TextScanOperator.hpp
index dfedb2b..09b7f2d 100644
--- a/relational_operators/TextScanOperator.hpp
+++ b/relational_operators/TextScanOperator.hpp
@@ -35,6 +35,7 @@
 #include "types/containers/Tuple.hpp"
 #include "utility/BulkIoConfiguration.hpp"
 #include "utility/Macros.hpp"
+#include "utility/StringUtil.hpp"
 
 #include "glog/logging.h"
 
@@ -127,7 +128,7 @@
    **/
   TextScanOperator(const std::size_t query_id,
                    const std::string &file_pattern,
-                   const std::string *mem_data,
+                   const StringPiece &mem_data,
                    const BulkIoConfigurationPtr &options,
                    const CatalogRelation &output_relation,
                    const QueryContext::insert_destination_id output_destination_index)
@@ -138,7 +139,7 @@
         options_(options),
         output_relation_(output_relation),
         output_destination_index_(output_destination_index),
-        serial_bulk_insert_(mem_data != nullptr),
+        serial_bulk_insert_(mem_data.first != nullptr),
         num_remaining_chunks_(0),
         serial_worker_ready_(true),
         work_generated_(false) {}
@@ -177,7 +178,7 @@
                                                  const std::size_t text_segment_size);
 
   const std::string file_pattern_;
-  const std::string *mem_data_;
+  const StringPiece mem_data_;
   const BulkIoConfigurationPtr options_;
 
   const CatalogRelation &output_relation_;
@@ -215,7 +216,7 @@
   TextScanWorkOrder(
       const std::size_t query_id,
       const std::string &filename,
-      const std::string *mem_data,
+      const StringPiece &mem_data,
       const std::size_t text_offset,
       const std::size_t text_segment_size,
       const char field_terminator,
@@ -360,7 +361,7 @@
   }
 
   const std::string filename_;
-  const std::string *mem_data_;
+  const StringPiece mem_data_;
   const std::size_t text_offset_;
   const std::size_t text_segment_size_;
   const char field_terminator_;
diff --git a/relational_operators/WorkOrderFactory.cpp b/relational_operators/WorkOrderFactory.cpp
index 9eeac9e..df839ef 100644
--- a/relational_operators/WorkOrderFactory.cpp
+++ b/relational_operators/WorkOrderFactory.cpp
@@ -55,6 +55,7 @@
 #include "relational_operators/WindowAggregationOperator.hpp"
 #include "relational_operators/WorkOrder.pb.h"
 #include "storage/StorageBlockInfo.hpp"
+#include "utility/StringUtil.hpp"
 #include "utility/lip_filter/LIPFilterUtil.hpp"
 
 #include "glog/logging.h"
@@ -554,7 +555,7 @@
       return new TextScanWorkOrder(
           query_id,
           proto.GetExtension(serialization::TextScanWorkOrder::filename),
-          nullptr /* TODO */,
+          StringPiece(nullptr, 0) /* TODO */,
           proto.GetExtension(serialization::TextScanWorkOrder::text_offset),
           proto.GetExtension(serialization::TextScanWorkOrder::text_segment_size),
           proto.GetExtension(serialization::TextScanWorkOrder::field_terminator),
diff --git a/relational_operators/tests/TextScanOperator_unittest.cpp b/relational_operators/tests/TextScanOperator_unittest.cpp
index aacc70c..caaebfa 100644
--- a/relational_operators/tests/TextScanOperator_unittest.cpp
+++ b/relational_operators/tests/TextScanOperator_unittest.cpp
@@ -42,6 +42,7 @@
 #include "types/TypeID.hpp"
 #include "utility/BulkIoConfiguration.hpp"
 #include "utility/MemStream.hpp"
+#include "utility/StringUtil.hpp"
 
 #include "gflags/gflags.h"
 #include "glog/logging.h"
@@ -200,7 +201,7 @@
   std::unique_ptr<TextScanOperator> text_scan_op(
       new TextScanOperator(kQueryId,
                            input_filename,
-                           nullptr /* mem_data */,
+                           StringPiece(nullptr, 0) /* mem_data */,
                            BulkIoConfigurationPtr(options.release()),
                            *relation_,
                            output_destination_index));
diff --git a/utility/StringUtil.hpp b/utility/StringUtil.hpp
index abda8f3..747d31d 100644
--- a/utility/StringUtil.hpp
+++ b/utility/StringUtil.hpp
@@ -20,9 +20,11 @@
 #ifndef QUICKSTEP_UTILITY_STRING_UTIL_HPP_
 #define QUICKSTEP_UTILITY_STRING_UTIL_HPP_
 
+#include <cstddef>
 #include <cstdint>
 #include <sstream>
 #include <string>
+#include <utility>
 #include <vector>
 
 namespace quickstep {
@@ -120,6 +122,8 @@
 DoubleToStringWithSignificantDigits(double val,
                                     std::uint64_t significant_digits);
 
+typedef std::pair<const char*, std::size_t> StringPiece;
+
 /** @} */
 
 }  // namespace quickstep
diff --git a/utility/ThreadSafeQueue.hpp b/utility/ThreadSafeQueue.hpp
index 440f8a7..dbbe63d 100644
--- a/utility/ThreadSafeQueue.hpp
+++ b/utility/ThreadSafeQueue.hpp
@@ -126,7 +126,7 @@
       queue_nonempty_condition_->await();
     }
     num_waiters_.fetch_sub(initially_empty, std::memory_order_relaxed);
-    T popped_value(internal_queue_.front());
+    T popped_value(std::move(internal_queue_.front()));
     internal_queue_.pop();
     return popped_value;
   }
