diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8f84ebc54..4e3eba504 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -361,7 +361,7 @@ set(memgraph_src_files
     ${src_dir}/query/stripper.cpp
     ${src_dir}/query/console.cpp
     ${src_dir}/query/frontend/ast/cypher_main_visitor.cpp
-    ${src_dir}/query/backend/cpp/typed_value.cpp
+    ${src_dir}/query/typed_value.cpp
     ${src_dir}/query/frontend/logical/operator.cpp
     ${src_dir}/query/frontend/logical/planner.cpp
     ${src_dir}/query/frontend/semantic/symbol_generator.cpp
diff --git a/src/communication/bolt/v1/decoder/decoder.hpp b/src/communication/bolt/v1/decoder/decoder.hpp
index 62ff42555..5bb1bf92e 100644
--- a/src/communication/bolt/v1/decoder/decoder.hpp
+++ b/src/communication/bolt/v1/decoder/decoder.hpp
@@ -4,7 +4,7 @@
 #include "database/graph_db_accessor.hpp"
 #include "logging/default.hpp"
 #include "logging/logger.hpp"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
 #include "utils/bswap.hpp"
 #include "utils/underlying_cast.hpp"
 
@@ -19,7 +19,7 @@ namespace communication::bolt {
 struct DecodedVertex {
   int64_t id;
   std::vector<std::string> labels;
-  std::map<std::string, TypedValue> properties;
+  std::map<std::string, query::TypedValue> properties;
 };
 
 /**
@@ -31,7 +31,7 @@ struct DecodedEdge {
   int64_t from;
   int64_t to;
   std::string type;
-  std::map<std::string, TypedValue> properties;
+  std::map<std::string, query::TypedValue> properties;
 };
 
 /**
@@ -57,7 +57,7 @@ class Decoder : public Loggable {
    * @returns true if data has been written to the data pointer,
    *          false otherwise
    */
-  bool ReadTypedValue(TypedValue *data) {
+  bool ReadTypedValue(query::TypedValue *data) {
     uint8_t value;
 
     logger.trace("[ReadTypedValue] Start");
@@ -124,7 +124,7 @@ class Decoder : public Loggable {
    * @returns true if data has been written to the data pointer and the type
    *          matches the expected type, false otherwise
    */
-  bool ReadTypedValue(TypedValue *data, TypedValue::Type type) {
+  bool ReadTypedValue(query::TypedValue *data, query::TypedValue::Type type) {
     if (!ReadTypedValue(data)) {
       logger.debug("[ReadTypedValue] ReadTypedValue call failed!");
       return false;
@@ -146,7 +146,7 @@ class Decoder : public Loggable {
    */
   bool ReadVertex(DecodedVertex *data) {
     uint8_t value[2];
-    TypedValue tv;
+    query::TypedValue tv;
 
     logger.trace("[ReadVertex] Start");
 
@@ -166,21 +166,21 @@ class Decoder : public Loggable {
     }
 
     // read ID
-    if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
       logger.debug("[ReadVertex] Couldn't read ID!");
       return false;
     }
     data->id = tv.Value<int64_t>();
 
     // read labels
-    if (!ReadTypedValue(&tv, TypedValue::Type::List)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::List)) {
       logger.debug("[ReadVertex] Couldn't read labels!");
       return false;
     }
-    std::vector<TypedValue> &labels = tv.Value<std::vector<TypedValue>>();
+    auto &labels = tv.Value<std::vector<query::TypedValue>>();
     data->labels.resize(labels.size());
     for (size_t i = 0; i < labels.size(); ++i) {
-      if (labels[i].type() != TypedValue::Type::String) {
+      if (labels[i].type() != query::TypedValue::Type::String) {
         logger.debug("[ReadVertex] Label has wrong type!");
         return false;
       }
@@ -188,11 +188,11 @@ class Decoder : public Loggable {
     }
 
     // read properties
-    if (!ReadTypedValue(&tv, TypedValue::Type::Map)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::Map)) {
       logger.debug("[ReadVertex] Couldn't read properties!");
       return false;
     }
-    data->properties = tv.Value<std::map<std::string, TypedValue>>();
+    data->properties = tv.Value<std::map<std::string, query::TypedValue>>();
 
     logger.trace("[ReadVertex] Success");
 
@@ -209,7 +209,7 @@ class Decoder : public Loggable {
    */
   bool ReadEdge(DecodedEdge *data) {
     uint8_t value[2];
-    TypedValue tv;
+    query::TypedValue tv;
 
     logger.trace("[ReadEdge] Start");
 
@@ -229,39 +229,39 @@ class Decoder : public Loggable {
     }
 
     // read ID
-    if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
       logger.debug("[ReadEdge] couldn't read ID!");
       return false;
     }
     data->id = tv.Value<int64_t>();
 
     // read from
-    if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
       logger.debug("[ReadEdge] Couldn't read from_id!");
       return false;
     }
     data->from = tv.Value<int64_t>();
 
     // read to
-    if (!ReadTypedValue(&tv, TypedValue::Type::Int)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::Int)) {
       logger.debug("[ReadEdge] Couldn't read to_id!");
       return false;
     }
     data->to = tv.Value<int64_t>();
 
     // read type
-    if (!ReadTypedValue(&tv, TypedValue::Type::String)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::String)) {
       logger.debug("[ReadEdge] Couldn't read type!");
       return false;
     }
     data->type = tv.Value<std::string>();
 
     // read properties
-    if (!ReadTypedValue(&tv, TypedValue::Type::Map)) {
+    if (!ReadTypedValue(&tv, query::TypedValue::Type::Map)) {
       logger.debug("[ReadEdge] Couldn't read properties!");
       return false;
     }
-    data->properties = tv.Value<std::map<std::string, TypedValue>>();
+    data->properties = tv.Value<std::map<std::string, query::TypedValue>>();
 
     logger.trace("[ReadEdge] Success");
 
@@ -272,28 +272,28 @@ class Decoder : public Loggable {
   Buffer &buffer_;
 
  private:
-  bool ReadNull(const Marker &marker, TypedValue *data) {
+  bool ReadNull(const Marker &marker, query::TypedValue *data) {
     logger.trace("[ReadNull] Start");
     debug_assert(marker == Marker::Null, "Received invalid marker!");
-    *data = TypedValue::Null;
+    *data = query::TypedValue::Null;
     logger.trace("[ReadNull] Success");
     return true;
   }
 
-  bool ReadBool(const Marker &marker, TypedValue *data) {
+  bool ReadBool(const Marker &marker, query::TypedValue *data) {
     logger.trace("[ReadBool] Start");
     debug_assert(marker == Marker::False || marker == Marker::True,
                  "Received invalid marker!");
     if (marker == Marker::False) {
-      *data = TypedValue(false);
+      *data = query::TypedValue(false);
     } else {
-      *data = TypedValue(true);
+      *data = query::TypedValue(true);
     }
     logger.trace("[ReadBool] Success");
     return true;
   }
 
-  bool ReadInt(const Marker &marker, TypedValue *data) {
+  bool ReadInt(const Marker &marker, query::TypedValue *data) {
     uint8_t value = underlying_cast(marker);
     bool success = true;
     int64_t ret;
@@ -338,13 +338,13 @@ class Decoder : public Loggable {
       return false;
     }
     if (success) {
-      *data = TypedValue(ret);
+      *data = query::TypedValue(ret);
       logger.trace("[ReadInt] Success");
     }
     return success;
   }
 
-  bool ReadDouble(const Marker marker, TypedValue *data) {
+  bool ReadDouble(const Marker marker, query::TypedValue *data) {
     uint64_t value;
     double ret;
     logger.trace("[ReadDouble] Start");
@@ -355,7 +355,7 @@ class Decoder : public Loggable {
     }
     value = bswap(value);
     ret = *reinterpret_cast<double *>(&value);
-    *data = TypedValue(ret);
+    *data = query::TypedValue(ret);
     logger.trace("[ReadDouble] Success");
     return true;
   }
@@ -397,7 +397,7 @@ class Decoder : public Loggable {
     }
   }
 
-  bool ReadString(const Marker &marker, TypedValue *data) {
+  bool ReadString(const Marker &marker, query::TypedValue *data) {
     logger.trace("[ReadString] Start");
     auto size = ReadTypeSize(marker, MarkerString);
     if (size == -1) {
@@ -409,31 +409,31 @@ class Decoder : public Loggable {
       logger.debug("[ReadString] Missing data!");
       return false;
     }
-    *data = TypedValue(std::string(reinterpret_cast<char *>(ret.get()), size));
+    *data = query::TypedValue(std::string(reinterpret_cast<char *>(ret.get()), size));
     logger.trace("[ReadString] Success");
     return true;
   }
 
-  bool ReadList(const Marker &marker, TypedValue *data) {
+  bool ReadList(const Marker &marker, query::TypedValue *data) {
     logger.trace("[ReadList] Start");
     auto size = ReadTypeSize(marker, MarkerList);
     if (size == -1) {
       logger.debug("[ReadList] Couldn't get size!");
       return false;
     }
-    std::vector<TypedValue> ret(size);
+    std::vector<query::TypedValue> ret(size);
     for (int64_t i = 0; i < size; ++i) {
       if (!ReadTypedValue(&ret[i])) {
         logger.debug("[ReadList] Couldn't read element {}", i);
         return false;
       }
     }
-    *data = TypedValue(ret);
+    *data = query::TypedValue(ret);
     logger.trace("[ReadList] Success");
     return true;
   }
 
-  bool ReadMap(const Marker &marker, TypedValue *data) {
+  bool ReadMap(const Marker &marker, query::TypedValue *data) {
     logger.trace("[ReadMap] Start");
     auto size = ReadTypeSize(marker, MarkerMap);
     if (size == -1) {
@@ -441,15 +441,15 @@ class Decoder : public Loggable {
       return false;
     }
 
-    TypedValue tv;
+    query::TypedValue tv;
     std::string str;
-    std::map<std::string, TypedValue> ret;
+    std::map<std::string, query::TypedValue> ret;
     for (int64_t i = 0; i < size; ++i) {
       if (!ReadTypedValue(&tv)) {
         logger.debug("[ReadMap] Couldn't read index {}", i);
         return false;
       }
-      if (tv.type() != TypedValue::Type::String) {
+      if (tv.type() != query::TypedValue::Type::String) {
         logger.debug("[ReadMap] Index {} isn't a string!", i);
         return false;
       }
@@ -466,7 +466,7 @@ class Decoder : public Loggable {
       return false;
     }
 
-    *data = TypedValue(ret);
+    *data = query::TypedValue(ret);
     logger.trace("[ReadMap] Success");
     return true;
   }
diff --git a/src/communication/bolt/v1/encoder/base_encoder.hpp b/src/communication/bolt/v1/encoder/base_encoder.hpp
index 831916835..54ab18bdd 100644
--- a/src/communication/bolt/v1/encoder/base_encoder.hpp
+++ b/src/communication/bolt/v1/encoder/base_encoder.hpp
@@ -4,7 +4,7 @@
 #include "database/graph_db_accessor.hpp"
 #include "logging/default.hpp"
 #include "logging/logger.hpp"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
 #include "utils/bswap.hpp"
 
 #include <string>
@@ -115,12 +115,12 @@ class BaseEncoder : public Loggable {
     WriteRAW(value.c_str(), value.size());
   }
 
-  void WriteList(const std::vector<TypedValue> &value) {
+  void WriteList(const std::vector<query::TypedValue> &value) {
     WriteTypeSize(value.size(), MarkerList);
     for (auto &x : value) WriteTypedValue(x);
   }
 
-  void WriteMap(const std::map<std::string, TypedValue> &value) {
+  void WriteMap(const std::map<std::string, query::TypedValue> &value) {
     WriteTypeSize(value.size(), MarkerMap);
     for (auto &x : value) {
       WriteString(x.first);
@@ -193,36 +193,36 @@ class BaseEncoder : public Loggable {
     // TODO: this isn't implemented in the backend!
   }
 
-  void WriteTypedValue(const TypedValue &value) {
+  void WriteTypedValue(const query::TypedValue &value) {
     switch (value.type()) {
-      case TypedValue::Type::Null:
+      case query::TypedValue::Type::Null:
         WriteNull();
         break;
-      case TypedValue::Type::Bool:
+      case query::TypedValue::Type::Bool:
         WriteBool(value.Value<bool>());
         break;
-      case TypedValue::Type::Int:
+      case query::TypedValue::Type::Int:
         WriteInt(value.Value<int64_t>());
         break;
-      case TypedValue::Type::Double:
+      case query::TypedValue::Type::Double:
         WriteDouble(value.Value<double>());
         break;
-      case TypedValue::Type::String:
+      case query::TypedValue::Type::String:
         WriteString(value.Value<std::string>());
         break;
-      case TypedValue::Type::List:
-        WriteList(value.Value<std::vector<TypedValue>>());
+      case query::TypedValue::Type::List:
+        WriteList(value.Value<std::vector<query::TypedValue>>());
         break;
-      case TypedValue::Type::Map:
-        WriteMap(value.Value<std::map<std::string, TypedValue>>());
+      case query::TypedValue::Type::Map:
+        WriteMap(value.Value<std::map<std::string, query::TypedValue>>());
         break;
-      case TypedValue::Type::Vertex:
+      case query::TypedValue::Type::Vertex:
         WriteVertex(value.Value<VertexAccessor>());
         break;
-      case TypedValue::Type::Edge:
+      case query::TypedValue::Type::Edge:
         WriteEdge(value.Value<EdgeAccessor>());
         break;
-      case TypedValue::Type::Path:
+      case query::TypedValue::Type::Path:
         // TODO: this is not implemeted yet!
         WritePath();
         break;
diff --git a/src/communication/bolt/v1/encoder/encoder.hpp b/src/communication/bolt/v1/encoder/encoder.hpp
index e2ff18623..44b68dc9d 100644
--- a/src/communication/bolt/v1/encoder/encoder.hpp
+++ b/src/communication/bolt/v1/encoder/encoder.hpp
@@ -39,7 +39,7 @@ class Encoder : private BaseEncoder<Buffer> {
    *
    * @param values the fields list object that should be sent
    */
-  void MessageRecord(const std::vector<TypedValue> &values) {
+  void MessageRecord(const std::vector<query::TypedValue> &values) {
     // 0xB1 = struct 1; 0x71 = record signature
     WriteRAW("\xB1\x71", 2);
     WriteList(values);
@@ -57,7 +57,7 @@ class Encoder : private BaseEncoder<Buffer> {
    * @param metadata the metadata map object that should be sent
    * @param flush should method flush the socket
    */
-  void MessageSuccess(const std::map<std::string, TypedValue> &metadata,
+  void MessageSuccess(const std::map<std::string, query::TypedValue> &metadata,
                       bool flush = true) {
     // 0xB1 = struct 1; 0x70 = success signature
     WriteRAW("\xB1\x70", 2);
@@ -74,7 +74,7 @@ class Encoder : private BaseEncoder<Buffer> {
    * This function sends a success message without additional metadata.
    */
   void MessageSuccess() {
-    std::map<std::string, TypedValue> metadata;
+    std::map<std::string, query::TypedValue> metadata;
     MessageSuccess(metadata);
   }
 
@@ -88,7 +88,7 @@ class Encoder : private BaseEncoder<Buffer> {
    *
    * @param metadata the metadata map object that should be sent
    */
-  void MessageFailure(const std::map<std::string, TypedValue> &metadata) {
+  void MessageFailure(const std::map<std::string, query::TypedValue> &metadata) {
     // 0xB1 = struct 1; 0x7F = failure signature
     WriteRAW("\xB1\x7F", 2);
     WriteMap(metadata);
@@ -105,7 +105,7 @@ class Encoder : private BaseEncoder<Buffer> {
    *
    * @param metadata the metadata map object that should be sent
    */
-  void MessageIgnored(const std::map<std::string, TypedValue> &metadata) {
+  void MessageIgnored(const std::map<std::string, query::TypedValue> &metadata) {
     // 0xB1 = struct 1; 0x7E = ignored signature
     WriteRAW("\xB1\x7E", 2);
     WriteMap(metadata);
diff --git a/src/communication/bolt/v1/encoder/result_stream.hpp b/src/communication/bolt/v1/encoder/result_stream.hpp
index 32b4d411d..d48e7c619 100644
--- a/src/communication/bolt/v1/encoder/result_stream.hpp
+++ b/src/communication/bolt/v1/encoder/result_stream.hpp
@@ -2,7 +2,7 @@
 
 #include "communication/bolt/v1/encoder/chunked_encoder_buffer.hpp"
 #include "communication/bolt/v1/encoder/encoder.hpp"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
 
 #include "logging/default.hpp"
 
@@ -27,10 +27,10 @@ class ResultStream {
    * @param fields the header fields that should be sent.
    */
   void Header(const std::vector<std::string> &fields) {
-    std::vector<TypedValue> vec;
-    std::map<std::string, TypedValue> data;
-    for (auto &i : fields) vec.push_back(TypedValue(i));
-    data.insert(std::make_pair(std::string("fields"), TypedValue(vec)));
+    std::vector<query::TypedValue> vec;
+    std::map<std::string, query::TypedValue> data;
+    for (auto &i : fields) vec.push_back(query::TypedValue(i));
+    data.insert(std::make_pair(std::string("fields"), query::TypedValue(vec)));
     // this call will automaticaly send the data to the client
     encoder_.MessageSuccess(data);
   }
@@ -47,7 +47,7 @@ class ResultStream {
    *
    * @param values the values that should be sent
    */
-  void Result(std::vector<TypedValue> &values) {
+  void Result(std::vector<query::TypedValue> &values) {
     encoder_.MessageRecord(values);
   }
 
@@ -63,7 +63,7 @@ class ResultStream {
    *
    * @param summary the summary map object that should be sent
    */
-  void Summary(const std::map<std::string, TypedValue> &summary) {
+  void Summary(const std::map<std::string, query::TypedValue> &summary) {
     // at this point message should not flush the socket so
     // here is false because chunk has to be called instead of flush
     encoder_.MessageSuccess(summary, false);
diff --git a/src/communication/bolt/v1/states/executor.hpp b/src/communication/bolt/v1/states/executor.hpp
index 29b917aa5..9be74160d 100644
--- a/src/communication/bolt/v1/states/executor.hpp
+++ b/src/communication/bolt/v1/states/executor.hpp
@@ -16,8 +16,9 @@ struct Query {
 };
 
 template <typename Session>
-void StateExecutorFailure(Session &session, Logger &logger,
-                          const std::map<std::string, TypedValue> &metadata) {
+void StateExecutorFailure(
+    Session &session, Logger &logger,
+    const std::map<std::string, query::TypedValue> &metadata) {
   try {
     session.encoder_.MessageFailure(metadata);
   } catch (const BoltException &e) {
diff --git a/src/communication/result_stream_faker.hpp b/src/communication/result_stream_faker.hpp
index 474f7b91b..691b80c8c 100644
--- a/src/communication/result_stream_faker.hpp
+++ b/src/communication/result_stream_faker.hpp
@@ -1,6 +1,8 @@
 #pragma once
 
-#include "query/backend/cpp/typed_value.hpp"
+#include <map>
+
+#include "query/typed_value.hpp"
 #include "utils/assert.hpp"
 
 /**
@@ -18,13 +20,13 @@ class ResultStreamFaker {
     current_state_ = State::WritingResults;
   }
 
-  void Result(const std::vector<TypedValue> &values) {
+  void Result(const std::vector<query::TypedValue> &values) {
     debug_assert(current_state_ == State::WritingResults,
                  "Can't accept results before header nor after summary");
     results_.push_back(values);
   }
 
-  void Summary(const std::map<std::string, TypedValue> &summary) {
+  void Summary(const std::map<std::string, query::TypedValue> &summary) {
     debug_assert(current_state_ != State::Done, "Can only send a summary once");
     summary_ = summary;
     current_state_ = State::Done;
@@ -54,6 +56,6 @@ class ResultStreamFaker {
 
   // the data that the record stream can accept
   std::vector<std::string> header_;
-  std::vector<std::vector<TypedValue>> results_;
-  std::map<std::string, TypedValue> summary_;
+  std::vector<std::vector<query::TypedValue>> results_;
+  std::map<std::string, query::TypedValue> summary_;
 };
diff --git a/src/query/console.cpp b/src/query/console.cpp
index cf74e3b78..64fc4a590 100644
--- a/src/query/console.cpp
+++ b/src/query/console.cpp
@@ -2,15 +2,17 @@
 // Copyright 2017 Memgraph
 // Created by Florijan Stamenkovic on 23.03.17.
 //
+#include "console.hpp"
 
 #include <algorithm>
 #include <iostream>
 #include <iterator>
 #include <sstream>
 
-#include "console.hpp"
 #include "query/exceptions.hpp"
 #include "query/interpreter.hpp"
+#include "query/typed_value.hpp"
+#include "utils/algorithm.hpp"
 
 #ifdef HAS_READLINE
 
@@ -47,59 +49,17 @@ std::string ReadLine(const char *prompt) {
 
 #endif  // HAS_READLINE
 
-/**
- * Helper function that outputs a collection of items to
- * the given stream, separating them with the given delimiter.
- */
-template <typename TStream, typename TIterable, typename TConverter>
-void PrintIterable(TStream &stream, const TIterable &iterable,
-                   const std::string &delim, TConverter converter = {}) {
-  bool first = true;
-  for (const auto &item : iterable) {
-    if (first)
-      first = false;
-    else
-      stream << delim;
-    stream << converter(item);
-  }
-}
-
 /**
  * Converts the given TypedValue into a string (single line).
  */
-std::string TypedValueToString(const TypedValue &value) {
+std::string TypedValueToString(const query::TypedValue &value) {
   std::stringstream ss;
   switch (value.type()) {
-    case TypedValue::Type::Vertex: {
-      auto va = value.Value<VertexAccessor>();
-      ss << "V(";
-      PrintIterable(ss, va.labels(), ":", [&](auto label) {
-        return va.db_accessor().label_name(label);
-      });
-      ss << " {";
-      PrintIterable(ss, va.Properties(), ", ", [&](const auto kv) {
-        return va.db_accessor().property_name(kv.first) + ": " +
-               TypedValueToString(kv.second);
-      });
-      ss << "})";
+    case query::TypedValue::Type::List:
       break;
-    }
-    case TypedValue::Type::Edge: {
-      auto ea = value.Value<EdgeAccessor>();
-      ss << "E[" << ea.db_accessor().edge_type_name(ea.edge_type());
-      ss << " {";
-      PrintIterable(ss, ea.Properties(), ", ", [&](const auto kv) {
-        return ea.db_accessor().property_name(kv.first) + ": " +
-               TypedValueToString(kv.second);
-      });
-      ss << "}]";
+    case query::TypedValue::Type::Map:
       break;
-    }
-    case TypedValue::Type::List:
-      break;
-    case TypedValue::Type::Map:
-      break;
-    case TypedValue::Type::Path:
+    case query::TypedValue::Type::Path:
       break;
     default:
       ss << value;
diff --git a/src/query/frontend/ast/ast.hpp b/src/query/frontend/ast/ast.hpp
index 4d6c79aeb..ce2a53f93 100644
--- a/src/query/frontend/ast/ast.hpp
+++ b/src/query/frontend/ast/ast.hpp
@@ -6,8 +6,8 @@
 
 #include "database/graph_db.hpp"
 #include "database/graph_db_datatypes.hpp"
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/frontend/ast/ast_visitor.hpp"
+#include "query/typed_value.hpp"
 #include "utils/visitor/visitable.hpp"
 
 namespace query {
diff --git a/src/query/frontend/interpret/interpret.hpp b/src/query/frontend/interpret/interpret.hpp
index d0b5bee1d..016dd85a5 100644
--- a/src/query/frontend/interpret/interpret.hpp
+++ b/src/query/frontend/interpret/interpret.hpp
@@ -3,9 +3,9 @@
 #include <map>
 #include <vector>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/frontend/ast/ast.hpp"
 #include "query/frontend/semantic/symbol_table.hpp"
+#include "query/typed_value.hpp"
 #include "utils/assert.hpp"
 #include "utils/exceptions/not_yet_implemented.hpp"
 
diff --git a/src/query/parameters.hpp b/src/query/parameters.hpp
index fb9be2905..0f8568319 100644
--- a/src/query/parameters.hpp
+++ b/src/query/parameters.hpp
@@ -6,7 +6,7 @@
 #ifndef MEMGRAPH_PARAMETERS_HPP
 #define MEMGRAPH_PARAMETERS_HPP
 
-#include <query/backend/cpp/typed_value.hpp>
+#include "query/typed_value.hpp"
 
 /**
  * Encapsulates user provided parameters (and stripped literals)
@@ -21,7 +21,7 @@ struct Parameters {
    * @param value
    * @return
    */
-  const std::string &Add(const TypedValue &value) {
+  const std::string &Add(const query::TypedValue &value) {
     return storage_.emplace(NextName(), value).first->first;
   }
 
@@ -33,7 +33,7 @@ struct Parameters {
    *  @param name Param name.
    *  @return Value for the given param.
    */
-  const TypedValue &At(const std::string &name) const {
+  const query::TypedValue &At(const std::string &name) const {
     auto found = storage_.find(name);
     permanent_assert(found != storage_.end(),
                      "Name must be present in stripped arg container");
@@ -51,7 +51,7 @@ struct Parameters {
    * @param position Which stripped param is sought.
    * @return Stripped param.
    */
-  const TypedValue &At(const size_t position) const {
+  const query::TypedValue &At(const size_t position) const {
     permanent_assert(position < storage_.size(), "Invalid position");
     return storage_.find(NameForPosition(position))->second;
   }
@@ -60,7 +60,7 @@ struct Parameters {
   const size_t Size() const { return storage_.size(); }
 
  private:
-  std::map<std::string, TypedValue> storage_;
+  std::map<std::string, query::TypedValue> storage_;
 
   /** Generates and returns a new name */
   std::string NextName() const { return NameForPosition(storage_.size()); }
diff --git a/src/query/stripped.hpp b/src/query/stripped.hpp
index c423f0d2d..a3e423605 100644
--- a/src/query/stripped.hpp
+++ b/src/query/stripped.hpp
@@ -2,10 +2,8 @@
 
 #include <map>
 
-#include "query/backend/cpp/typed_value.hpp"
-#include "storage/property_value_store.hpp"
-
 #include "parameters.hpp"
+#include "storage/property_value_store.hpp"
 #include "utils/assert.hpp"
 #include "utils/hashing/fnv.hpp"
 
diff --git a/src/query/backend/cpp/typed_value.cpp b/src/query/typed_value.cpp
similarity index 99%
rename from src/query/backend/cpp/typed_value.cpp
rename to src/query/typed_value.cpp
index 65ffe19ad..6d9a2f8e1 100644
--- a/src/query/backend/cpp/typed_value.cpp
+++ b/src/query/typed_value.cpp
@@ -1,4 +1,4 @@
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
 
 #include <fmt/format.h>
 #include <cmath>
@@ -7,6 +7,8 @@
 
 #include "utils/assert.hpp"
 
+namespace query {
+
 TypedValue::TypedValue(const PropertyValue &value) {
   switch (value.type()) {
     case PropertyValue::Type::Null:
@@ -728,3 +730,5 @@ TypedValue operator^(const TypedValue &a, const TypedValue &b) {
                               a.type(), b.type());
   }
 }
+
+}  // namespace query
diff --git a/src/query/backend/cpp/typed_value.hpp b/src/query/typed_value.hpp
similarity index 99%
rename from src/query/backend/cpp/typed_value.hpp
rename to src/query/typed_value.hpp
index 37baea8b2..cc79aee41 100644
--- a/src/query/backend/cpp/typed_value.hpp
+++ b/src/query/typed_value.hpp
@@ -15,6 +15,8 @@
 #include "utils/total_ordering.hpp"
 #include "utils/underlying_cast.hpp"
 
+namespace query {
+
 typedef traversal_template::Path<VertexAccessor, EdgeAccessor> Path;
 
 // TODO: Neo4j does overflow checking. Should we also implement it?
@@ -164,3 +166,5 @@ TypedValue operator^(const TypedValue &a, const TypedValue &b);
 
 // stream output
 std::ostream &operator<<(std::ostream &os, const TypedValue::Type type);
+
+}  // namespace query
diff --git a/src/storage/edge_accessor.cpp b/src/storage/edge_accessor.cpp
index a3f9a7004..1779b8c0e 100644
--- a/src/storage/edge_accessor.cpp
+++ b/src/storage/edge_accessor.cpp
@@ -1,6 +1,8 @@
 #include "storage/edge_accessor.hpp"
+
 #include "database/graph_db_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
+#include "utils/algorithm.hpp"
 
 GraphDbTypes::EdgeType EdgeAccessor::edge_type() const {
   return current().edge_type_;
@@ -13,3 +15,15 @@ VertexAccessor EdgeAccessor::from() const {
 VertexAccessor EdgeAccessor::to() const {
   return VertexAccessor(current().to_, db_accessor());
 }
+
+std::ostream &operator<<(std::ostream &os, const EdgeAccessor &ea) {
+  os << "E[" << ea.db_accessor().edge_type_name(ea.edge_type());
+  os << " {";
+  auto prop_to_string = [&](const auto kv) {
+    std::stringstream ss;
+    ss << ea.db_accessor().property_name(kv.first) << ": " << kv.second;
+    return ss.str();
+  };
+  PrintIterable(os, ea.Properties(), ", ", prop_to_string);
+  return os << "}]";
+}
diff --git a/src/storage/edge_accessor.hpp b/src/storage/edge_accessor.hpp
index 6be61d7c7..3261ed029 100644
--- a/src/storage/edge_accessor.hpp
+++ b/src/storage/edge_accessor.hpp
@@ -40,3 +40,5 @@ class EdgeAccessor : public RecordAccessor<Edge> {
 
   //  void remove();
 };
+
+std::ostream &operator<<(std::ostream &, const EdgeAccessor &);
diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp
index 7eeb01df7..849025cdd 100644
--- a/src/storage/vertex_accessor.cpp
+++ b/src/storage/vertex_accessor.cpp
@@ -1,9 +1,10 @@
+#include "storage/vertex_accessor.hpp"
+
 #include <algorithm>
 
 #include "database/graph_db_accessor.hpp"
-#include "storage/edge_accessor.hpp"
 #include "storage/util.hpp"
-#include "storage/vertex_accessor.hpp"
+#include "utils/algorithm.hpp"
 
 size_t VertexAccessor::out_degree() const { return current().out_.size(); }
 
@@ -38,3 +39,17 @@ bool VertexAccessor::has_label(GraphDbTypes::Label label) const {
 const std::vector<GraphDbTypes::Label> &VertexAccessor::labels() const {
   return this->current().labels_;
 }
+
+std::ostream &operator<<(std::ostream &os, const VertexAccessor &va) {
+  os << "V(";
+  PrintIterable(os, va.labels(), ":",
+                [&](auto label) { return va.db_accessor().label_name(label); });
+  os << " {";
+  auto prop_to_string = [&](const auto kv) {
+    std::stringstream ss;
+    ss << va.db_accessor().property_name(kv.first) << ": " << kv.second;
+    return ss.str();
+  };
+  PrintIterable(os, va.Properties(), ", ", prop_to_string);
+  return os << "})";
+}
diff --git a/src/storage/vertex_accessor.hpp b/src/storage/vertex_accessor.hpp
index d3988fc07..4c6405d55 100644
--- a/src/storage/vertex_accessor.hpp
+++ b/src/storage/vertex_accessor.hpp
@@ -73,3 +73,5 @@ class VertexAccessor : public RecordAccessor<Vertex> {
    */
   auto out() { return make_accessor_iterator<EdgeAccessor>(current().out_, db_accessor()); }
 };
+
+std::ostream &operator<<(std::ostream &, const VertexAccessor &);
diff --git a/src/utils/algorithm.hpp b/src/utils/algorithm.hpp
index b86b0e6d1..0df79af07 100644
--- a/src/utils/algorithm.hpp
+++ b/src/utils/algorithm.hpp
@@ -23,3 +23,27 @@ ForwardIt action_remove_if(ForwardIt first, ForwardIt last, UnaryPredicate p,
   std::for_each(it, last, a);
   return it;
 }
+
+/**
+ * Outputs a collection of items to the given stream, separating them with the
+ * given delimiter.
+ *
+ * @param stream Destination stream.
+ * @param iterable An iterable collection of items.
+ * @param delim Delimiter that is put between items.
+ * @param converter Function which converts an item to a type which supports
+ *        @c operator<<.
+ */
+template <typename TStream, typename TIterable, typename TConverter>
+void PrintIterable(TStream &stream, const TIterable &iterable,
+                   const std::string &delim = ", ", TConverter converter = {}) {
+  bool first = true;
+  for (const auto &item : iterable) {
+    if (first)
+      first = false;
+    else
+      stream << delim;
+    stream << converter(item);
+  }
+}
+
diff --git a/tests/integration/hardcoded_query/clique.hpp b/tests/integration/hardcoded_query/clique.hpp
index 09daef55c..f2b9c2402 100644
--- a/tests/integration/hardcoded_query/clique.hpp
+++ b/tests/integration/hardcoded_query/clique.hpp
@@ -4,9 +4,9 @@
 #include <string>
 
 #include "data_structures/bitset/static_bitset.hpp"
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
@@ -56,11 +56,11 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
         vertices[i].has_label(db_accessor.label("profile"))) {
       auto has_prop =
           vertices[i].PropsAt(db_accessor.property("profile_id")) == args.At(0);
-      if (has_prop.type() == TypedValue::Type::Null) continue;
+      if (has_prop.type() == query::TypedValue::Type::Null) continue;
       if (has_prop.Value<bool>() == false) continue;
       has_prop =
           vertices[i].PropsAt(db_accessor.property("partner_id")) == args.At(1);
-      if (has_prop.type() == TypedValue::Type::Null) continue;
+      if (has_prop.type() == query::TypedValue::Type::Null) continue;
       if (has_prop.Value<bool>() == false) continue;
       profile_index = i;
     }
@@ -121,7 +121,7 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
     const VertexAccessor v = *vertices_indexed[i];
     auto cmp_res = v.PropsAt(db_accessor.property("garment_id")) ==
                    args.At(query_type == CliqueQuery::SCORE_AND_LIMIT ? 8 : 0);
-    if (cmp_res.type() != TypedValue::Type::Bool) continue;
+    if (cmp_res.type() != query::TypedValue::Type::Bool) continue;
     if (cmp_res.Value<bool>() != true) continue;
     auto neigh = connected[i].Ones();
     for (int j : neigh) {
@@ -186,8 +186,8 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
     for (auto x : V) {
       auto edge = get_edge(vertices[profile_index], *vertices_indexed[x]);
       if (edge == nullptr) continue;
-      auto prop = TypedValue(edge->PropsAt(db_accessor.property("score")));
-      if (prop.type() == TypedValue::Type::Int) res += prop.Value<int64_t>();
+      auto prop = query::TypedValue(edge->PropsAt(db_accessor.property("score")));
+      if (prop.type() == query::TypedValue::Type::Int) res += prop.Value<int64_t>();
     }
     return res;
   };
@@ -203,7 +203,7 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
                         ? args.At((int)args.Size() - 1).Value<int64_t>()
                         : (int)results.size();
   for (int i = 0; i < std::min(limit, (int)results.size()); ++i) {
-    std::vector<TypedValue> result;
+    std::vector<query::TypedValue> result;
     for (auto x : results[i]) {
       result.push_back(vertices_indexed[x]
                            ->PropsAt(db_accessor.property("garment_id"))
@@ -213,8 +213,8 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
       result.push_back(calc_score(results[i]));
     stream.Result(result);
   }
-  std::map<std::string, TypedValue> meta{
-      std::make_pair(std::string("type"), TypedValue(std::string("r")))};
+  std::map<std::string, query::TypedValue> meta{
+      std::make_pair(std::string("type"), query::TypedValue(std::string("r")))};
   stream.Summary(meta);
   return true;
 }
diff --git a/tests/integration/hardcoded_query/create_full_profile_conceals_return.cpp b/tests/integration/hardcoded_query/create_full_profile_conceals_return.cpp
index 5af4e90fa..27468aaa5 100644
--- a/tests/integration/hardcoded_query/create_full_profile_conceals_return.cpp
+++ b/tests/integration/hardcoded_query/create_full_profile_conceals_return.cpp
@@ -3,12 +3,14 @@
 
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: CREATE (p:profile {profile_id: 112, partner_id: 55, conceals: 10})
 // RETURN p
diff --git a/tests/integration/hardcoded_query/create_full_profile_return.cpp b/tests/integration/hardcoded_query/create_full_profile_return.cpp
index 7be08f5d7..df5217e46 100644
--- a/tests/integration/hardcoded_query/create_full_profile_return.cpp
+++ b/tests/integration/hardcoded_query/create_full_profile_return.cpp
@@ -3,12 +3,14 @@
 
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: CREATE (p:profile {profile_id: 112, partner_id: 55}) RETURN p
 
diff --git a/tests/integration/hardcoded_query/create_full_profile_reveals_return.cpp b/tests/integration/hardcoded_query/create_full_profile_reveals_return.cpp
index be5056149..c68b5df11 100644
--- a/tests/integration/hardcoded_query/create_full_profile_reveals_return.cpp
+++ b/tests/integration/hardcoded_query/create_full_profile_reveals_return.cpp
@@ -3,12 +3,14 @@
 
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: CREATE (p:profile {profile_id: 112, partner_id: 55, reveals: 30})
 // RETURN p
diff --git a/tests/integration/hardcoded_query/create_garment.cpp b/tests/integration/hardcoded_query/create_garment.cpp
index bb3f676ca..0cf551cf4 100644
--- a/tests/integration/hardcoded_query/create_garment.cpp
+++ b/tests/integration/hardcoded_query/create_garment.cpp
@@ -3,12 +3,14 @@
 
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: CREATE (g:garment {garment_id: 1234, garment_category_id:1}) RETURN g
 
diff --git a/tests/integration/hardcoded_query/create_garment_conceals.cpp b/tests/integration/hardcoded_query/create_garment_conceals.cpp
index ce15dc798..736a1b104 100644
--- a/tests/integration/hardcoded_query/create_garment_conceals.cpp
+++ b/tests/integration/hardcoded_query/create_garment_conceals.cpp
@@ -3,12 +3,14 @@
 
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: CREATE (g:garment {garment_id: 1234, garment_category_id:
 // 1,conceals:30}) RETURN g
diff --git a/tests/integration/hardcoded_query/create_garment_reveals.cpp b/tests/integration/hardcoded_query/create_garment_reveals.cpp
index bda85f9d0..75bbac042 100644
--- a/tests/integration/hardcoded_query/create_garment_reveals.cpp
+++ b/tests/integration/hardcoded_query/create_garment_reveals.cpp
@@ -3,12 +3,14 @@
 
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: CREATE (g:garment {garment_id: 1234, garment_category_id:
 // 1,reveals:30}) RETURN g
diff --git a/tests/integration/hardcoded_query/delete_all.cpp b/tests/integration/hardcoded_query/delete_all.cpp
index 7350e9aa1..b188ed17b 100644
--- a/tests/integration/hardcoded_query/delete_all.cpp
+++ b/tests/integration/hardcoded_query/delete_all.cpp
@@ -1,14 +1,15 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
 #include "query/stripped.hpp"
+#include "query/typed_value.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (n) DETACH DELETE n
 
diff --git a/tests/integration/hardcoded_query/match_garment.cpp b/tests/integration/hardcoded_query/match_garment.cpp
index de7a022fc..5cf1bd061 100644
--- a/tests/integration/hardcoded_query/match_garment.cpp
+++ b/tests/integration/hardcoded_query/match_garment.cpp
@@ -1,15 +1,16 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (g:garment {garment_id: 1234}) RETURN g
 
diff --git a/tests/integration/hardcoded_query/match_garment_default_outfit.cpp b/tests/integration/hardcoded_query/match_garment_default_outfit.cpp
index 215c84e1e..78652f4a5 100644
--- a/tests/integration/hardcoded_query/match_garment_default_outfit.cpp
+++ b/tests/integration/hardcoded_query/match_garment_default_outfit.cpp
@@ -1,15 +1,16 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (g1:garment {garment_id: 1234}), (g2:garment {garment_id: 4567})
 // CREATE (g1)-[r:default_outfit]->(g2) RETURN r
diff --git a/tests/integration/hardcoded_query/match_garment_set_label_general_return.hpp b/tests/integration/hardcoded_query/match_garment_set_label_general_return.hpp
index f14c6e2a1..0d5720676 100644
--- a/tests/integration/hardcoded_query/match_garment_set_label_general_return.hpp
+++ b/tests/integration/hardcoded_query/match_garment_set_label_general_return.hpp
@@ -1,9 +1,9 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
@@ -20,18 +20,19 @@ bool run_general_query(GraphDbAccessor &db_accessor, const Parameters &args,
   stream.Header(headers);
   for (auto vertex : db_accessor.vertices()) {
     if (vertex.has_label(db_accessor.label("garment"))) {
-      TypedValue prop = vertex.PropsAt(db_accessor.property("garment_id"));
-      if (prop.type() == TypedValue::Type::Null) continue;
-      TypedValue cmp = prop == args.At(0);
-      if (cmp.type() != TypedValue::Type::Bool) continue;
+      query::TypedValue prop =
+          vertex.PropsAt(db_accessor.property("garment_id"));
+      if (prop.type() == query::TypedValue::Type::Null) continue;
+      query::TypedValue cmp = prop == args.At(0);
+      if (cmp.type() != query::TypedValue::Type::Bool) continue;
       if (cmp.Value<bool>() != true) continue;
       vertex.add_label(db_accessor.label(general_label));
-      std::vector<TypedValue> result{TypedValue(vertex)};
+      std::vector<query::TypedValue> result{query::TypedValue(vertex)};
       stream.Result(result);
     }
   }
-  std::map<std::string, TypedValue> meta{
-      std::make_pair(std::string("type"), TypedValue(std::string("rw")))};
+  std::map<std::string, query::TypedValue> meta{std::make_pair(
+      std::string("type"), query::TypedValue(std::string("rw")))};
   stream.Summary(meta);
   return true;
 }
diff --git a/tests/integration/hardcoded_query/match_profile.cpp b/tests/integration/hardcoded_query/match_profile.cpp
index 642624e5f..a295e62d6 100644
--- a/tests/integration/hardcoded_query/match_profile.cpp
+++ b/tests/integration/hardcoded_query/match_profile.cpp
@@ -1,15 +1,16 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (p:profile {profile_id: 112, partner_id: 77}) RETURN p
 
diff --git a/tests/integration/hardcoded_query/match_profile_garment_score.cpp b/tests/integration/hardcoded_query/match_profile_garment_score.cpp
index 92ca5816b..a31840598 100644
--- a/tests/integration/hardcoded_query/match_profile_garment_score.cpp
+++ b/tests/integration/hardcoded_query/match_profile_garment_score.cpp
@@ -1,16 +1,17 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
 #include "query/stripped.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (p:profile {profile_id: 111, partner_id:
 //  55})-[s:score]-(g:garment
diff --git a/tests/integration/hardcoded_query/match_profile_garment_set_score.cpp b/tests/integration/hardcoded_query/match_profile_garment_set_score.cpp
index fbfe27d56..252fb3911 100644
--- a/tests/integration/hardcoded_query/match_profile_garment_set_score.cpp
+++ b/tests/integration/hardcoded_query/match_profile_garment_set_score.cpp
@@ -1,15 +1,16 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (p:profile {profile_id: 111, partner_id: 55}), (g:garment
 // {garment_id: 1234}) CREATE (p)-[s:score]->(g) SET s.score=1500 RETURN s
diff --git a/tests/integration/hardcoded_query/match_profile_garment_update_score.cpp b/tests/integration/hardcoded_query/match_profile_garment_update_score.cpp
index dfc5ec81c..bd357a0a5 100644
--- a/tests/integration/hardcoded_query/match_profile_garment_update_score.cpp
+++ b/tests/integration/hardcoded_query/match_profile_garment_update_score.cpp
@@ -1,15 +1,16 @@
 #include <iostream>
 #include <string>
 
-#include "query/backend/cpp/typed_value.hpp"
 #include "query/parameters.hpp"
 #include "query/plan_interface.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "using.hpp"
 
 using std::cout;
 using std::endl;
+using query::TypedValue;
 
 // Query: MATCH (p:profile {profile_id: 111, partner_id:
 //  55})-[s:score]-(g:garment
diff --git a/tests/integration/stream/print_record_stream.hpp b/tests/integration/stream/print_record_stream.hpp
index 525eef3cd..c4b9daff6 100644
--- a/tests/integration/stream/print_record_stream.hpp
+++ b/tests/integration/stream/print_record_stream.hpp
@@ -5,38 +5,10 @@
 #include <string>
 #include <vector>
 
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
 #include "storage/edge_accessor.hpp"
 #include "storage/vertex_accessor.hpp"
 
-void write_properties(std::ostream &os, const GraphDbAccessor &access,
-                      const PropertyValueStore<GraphDbTypes::Property> &properties) {
-  if (properties.size() > 0) {
-    os << "{";
-    for (auto x : properties) {
-      os << access.property_name(x.first) << ": " << x.second << ",";
-    }
-    os << "}\n";
-  }
-}
-
-std::ostream &operator<<(std::ostream &os, const VertexAccessor &vertex) {
-  if (vertex.labels().size() > 0) {
-    for (GraphDbTypes::Label label : vertex.labels()) {
-      os << vertex.db_accessor().property_name(label) << ", ";
-    }
-    os << "\n";
-  }
-  write_properties(os, vertex.db_accessor(), vertex.Properties());
-  return os;
-}
-
-std::ostream &operator<<(std::ostream &os, const EdgeAccessor &edge) {
-  os << "Edge: " << edge.db_accessor().edge_type_name(edge.edge_type()) << "\n";
-  write_properties(os, edge.db_accessor(), edge.Properties());
-  return os;
-}
-
 class PrintRecordStream {
  private:
   std::ostream &stream;
@@ -49,11 +21,11 @@ class PrintRecordStream {
     stream << "Header\n";
   }
 
-  void Result(std::vector<TypedValue> &values) {
+  void Result(std::vector<query::TypedValue> &values) {
     stream << "Result\n";
   }
 
-  void Summary(const std::map<std::string, TypedValue> &summary) {
+  void Summary(const std::map<std::string, query::TypedValue> &summary) {
     stream << "Summary\n";
   }
 };
diff --git a/tests/unit/bolt_decoder.cpp b/tests/unit/bolt_decoder.cpp
index 711b3969d..0118830e8 100644
--- a/tests/unit/bolt_decoder.cpp
+++ b/tests/unit/bolt_decoder.cpp
@@ -2,7 +2,9 @@
 #include "bolt_testdata.hpp"
 
 #include "communication/bolt/v1/decoder/decoder.hpp"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
+
+using query::TypedValue;
 
 constexpr const int SIZE = 131072;
 uint8_t data[SIZE];
diff --git a/tests/unit/bolt_encoder.cpp b/tests/unit/bolt_encoder.cpp
index f53b9fca2..f1c311244 100644
--- a/tests/unit/bolt_encoder.cpp
+++ b/tests/unit/bolt_encoder.cpp
@@ -4,7 +4,9 @@
 #include "communication/bolt/v1/encoder/encoder.hpp"
 #include "database/graph_db.hpp"
 #include "database/graph_db_accessor.hpp"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
+
+using query::TypedValue;
 
 /**
  * TODO (mferencevic): document
diff --git a/tests/unit/bolt_result_stream.cpp b/tests/unit/bolt_result_stream.cpp
index 4947cc8b6..330207429 100644
--- a/tests/unit/bolt_result_stream.cpp
+++ b/tests/unit/bolt_result_stream.cpp
@@ -3,7 +3,9 @@
 #include "communication/bolt/v1/encoder/chunked_encoder_buffer.hpp"
 #include "communication/bolt/v1/encoder/encoder.hpp"
 #include "communication/bolt/v1/encoder/result_stream.hpp"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
+
+using query::TypedValue;
 
 using BufferT = communication::bolt::ChunkedEncoderBuffer<TestSocket>;
 using EncoderT = communication::bolt::Encoder<BufferT>;
diff --git a/tests/unit/cypher_main_visitor.cpp b/tests/unit/cypher_main_visitor.cpp
index b9632150d..687405093 100644
--- a/tests/unit/cypher_main_visitor.cpp
+++ b/tests/unit/cypher_main_visitor.cpp
@@ -12,11 +12,13 @@
 #include "query/frontend/ast/ast.hpp"
 #include "query/frontend/ast/cypher_main_visitor.hpp"
 #include "query/frontend/opencypher/parser.hpp"
+#include "query/typed_value.hpp"
 
 namespace {
 
 using namespace query;
 using namespace query::frontend;
+using query::TypedValue;
 using testing::UnorderedElementsAre;
 using testing::Pair;
 
diff --git a/tests/unit/query_stripper.cpp b/tests/unit/query_stripper.cpp
index 5ed062a74..8b42cc193 100644
--- a/tests/unit/query_stripper.cpp
+++ b/tests/unit/query_stripper.cpp
@@ -6,6 +6,9 @@
 #include "gtest/gtest.h"
 
 #include "query/stripper.hpp"
+#include "query/typed_value.hpp"
+
+using query::TypedValue;
 
 void EXPECT_PROP_TRUE(const TypedValue& a) {
   EXPECT_TRUE(a.type() == TypedValue::Type::Bool && a.Value<bool>());
diff --git a/tests/unit/typed_value.cpp b/tests/unit/typed_value.cpp
index bf8db5d37..faf9497d0 100644
--- a/tests/unit/typed_value.cpp
+++ b/tests/unit/typed_value.cpp
@@ -6,10 +6,13 @@
 #include <vector>
 
 #include "gtest/gtest.h"
-#include "query/backend/cpp/typed_value.hpp"
+#include "query/typed_value.hpp"
 
 namespace {
 
+using query::TypedValue;
+using query::TypedValueException;
+
 std::vector<TypedValue> MakePropsAllTypes() {
   return {
       true,