diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9efec42c3..a4cbc58b6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -213,10 +213,12 @@ FILE(COPY ${include_dir}/storage/model/properties/string.hpp DESTINATION ${build
 FILE(COPY ${include_dir}/storage/model/properties/floating.hpp DESTINATION ${build_include_dir}/storage/model/properties)
 FILE(COPY ${include_dir}/storage/model/properties/number.hpp DESTINATION ${build_include_dir}/storage/model/properties)
 FILE(COPY ${include_dir}/storage/model/properties/integral.hpp DESTINATION ${build_include_dir}/storage/model/properties)
+FILE(COPY ${include_dir}/storage/model/properties/property_family.hpp DESTINATION ${build_include_dir}/storage/model/properties)
 FILE(COPY ${include_dir}/storage/model/properties/utils/math_operations.hpp DESTINATION ${build_include_dir}/storage/model/properties/utils)
 FILE(COPY ${include_dir}/storage/model/properties/utils/unary_negation.hpp DESTINATION ${build_include_dir}/storage/model/properties/utils)
 FILE(COPY ${include_dir}/storage/model/properties/utils/modulo.hpp DESTINATION ${build_include_dir}/storage/model/properties/utils)
 
+
 FILE(COPY ${include_dir}/storage/model/edge_model.hpp DESTINATION ${build_include_dir}/storage/model)
 FILE(COPY ${include_dir}/storage/model/property_model.hpp DESTINATION ${build_include_dir}/storage/model)
 FILE(COPY ${include_dir}/storage/model/vertex_model.hpp DESTINATION ${build_include_dir}/storage/model)
@@ -401,6 +403,8 @@ set(memgraph_src_files
     ${src_dir}/storage/model/properties/bool.cpp
     ${src_dir}/storage/model/properties/string.cpp
     ${src_dir}/storage/model/properties/properties.cpp
+    ${src_dir}/storage/model/properties/property_family.cpp
+    ${src_dir}/storage/indexes/impl/nonunique_unordered_index.cpp
     ${src_dir}/storage/locking/record_lock.cpp
     ${src_dir}/storage/vertex_accessor.cpp
     ${src_dir}/transactions/transaction.cpp
@@ -416,6 +420,8 @@ set(memgraph_src_files
     ${src_dir}/database/db_accessor.cpp
     ${src_dir}/database/db_transaction.cpp
     ${src_dir}/storage/edge_accessor.cpp
+    ${src_dir}/storage/record_accessor.cpp
+
 )
 
 # STATIC library used by memgraph executables
diff --git a/include/data_structures/bitset/dynamic_bitset.hpp b/include/data_structures/bitset/dynamic_bitset.hpp
index c228e9571..43024fade 100644
--- a/include/data_structures/bitset/dynamic_bitset.hpp
+++ b/include/data_structures/bitset/dynamic_bitset.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
-#include <cassert>
 #include <atomic>
+#include <cassert>
 
 #include "threading/sync/lockable.hpp"
 #include "threading/sync/spinlock.hpp"
@@ -13,8 +13,8 @@ class DynamicBitset : Lockable<SpinLock>
     {
         Block() = default;
 
-        Block(Block&) = delete;
-        Block(Block&&) = delete;
+        Block(Block &) = delete;
+        Block(Block &&) = delete;
 
         static constexpr size_t size = sizeof(block_t) * 8;
 
@@ -41,7 +41,7 @@ class DynamicBitset : Lockable<SpinLock>
             block.fetch_and(~(bitmask(n) << k), order);
         }
 
-        std::atomic<block_t> block {0};
+        std::atomic<block_t> block{0};
     };
 
     struct Chunk
@@ -49,16 +49,13 @@ class DynamicBitset : Lockable<SpinLock>
         Chunk() : next(nullptr)
         {
             static_assert(chunk_size % sizeof(block_t) == 0,
-                "chunk size not divisible by block size");
+                          "chunk size not divisible by block size");
         }
 
-        Chunk(Chunk&) = delete;
-        Chunk(Chunk&&) = delete;
+        Chunk(Chunk &) = delete;
+        Chunk(Chunk &&) = delete;
 
-        ~Chunk()
-        {
-            delete next;
-        }
+        ~Chunk() { delete next; }
 
         static constexpr size_t size = chunk_size * Block::size;
         static constexpr size_t n_blocks = chunk_size / sizeof(block_t);
@@ -79,54 +76,62 @@ class DynamicBitset : Lockable<SpinLock>
         }
 
         Block blocks[n_blocks];
-        std::atomic<Chunk*> next;
+        std::atomic<Chunk *> next;
     };
 
 public:
     DynamicBitset() : head(new Chunk()) {}
 
-    DynamicBitset(DynamicBitset&) = delete;
-    DynamicBitset(DynamicBitset&&) = delete;
+    DynamicBitset(DynamicBitset &) = delete;
+    DynamicBitset(DynamicBitset &&) = delete;
+
+    ~DynamicBitset()
+    {
+        auto now = head.load();
+        while (now != nullptr) {
+            auto next = now->next.load();
+            delete now;
+            now = next;
+        }
+    }
 
     block_t at(size_t k, size_t n)
     {
-        auto& chunk = find_chunk(k);
+        auto &chunk = find_chunk(k);
         return chunk.at(k, n, std::memory_order_seq_cst);
     }
 
     bool at(size_t k)
     {
-        auto& chunk = find_chunk(k);
+        auto &chunk = find_chunk(k);
         return chunk.at(k, 1, std::memory_order_seq_cst);
     }
 
     void set(size_t k, size_t n = 1)
     {
-        auto& chunk = find_chunk(k);
+        auto &chunk = find_chunk(k);
         return chunk.set(k, n, std::memory_order_seq_cst);
     }
 
     void clear(size_t k, size_t n = 1)
     {
-        auto& chunk = find_chunk(k);
+        auto &chunk = find_chunk(k);
         return chunk.clear(k, n, std::memory_order_seq_cst);
     }
 
 private:
-    Chunk& find_chunk(size_t& k)
+    Chunk &find_chunk(size_t &k)
     {
-        Chunk* chunk = head.load(), *next = nullptr;
+        Chunk *chunk = head.load(), *next = nullptr;
 
         // while i'm not in the right chunk
         // (my index is bigger than the size of this chunk)
-        while(k >= Chunk::size)
-        {
+        while (k >= Chunk::size) {
             next = chunk->next.load();
 
             // if a next chunk exists, switch to it and decrement my
             // pointer by the size of the current chunk
-            if(next != nullptr)
-            {
+            if (next != nullptr) {
                 chunk = next;
                 k -= Chunk::size;
                 continue;
@@ -139,8 +144,7 @@ private:
 
             // double-check locking. if the chunk exists now, some other thread
             // has just created it, continue searching for my chunk
-            if(chunk->next.load() != nullptr)
-                continue;
+            if (chunk->next.load() != nullptr) continue;
 
             chunk->next.store(new Chunk());
         }
@@ -149,5 +153,5 @@ private:
         return *chunk;
     }
 
-    std::atomic<Chunk*> head;
+    std::atomic<Chunk *> head;
 };
diff --git a/include/data_structures/concurrent/concurrent_list.hpp b/include/data_structures/concurrent/concurrent_list.hpp
new file mode 100644
index 000000000..0e364a325
--- /dev/null
+++ b/include/data_structures/concurrent/concurrent_list.hpp
@@ -0,0 +1,284 @@
+#pragma once
+
+#include <atomic>
+#include <cassert>
+#include "utils/crtp.hpp"
+
+template <class T>
+class List
+{
+
+    template <class V>
+    static V load(std::atomic<V> &atomic)
+    {
+        return atomic.load(std::memory_order_acquire);
+    }
+
+    template <class V>
+    static void store(std::atomic<V> &atomic, V desired)
+    { // Maybe could be relaxed
+        atomic.store(desired, std::memory_order_release);
+    }
+
+    template <class V>
+    static bool cas(std::atomic<V> &atomic, V expected, V desired)
+    { // Could be relaxed must be atleast Release.
+        return atomic.compare_exchange_strong(expected, desired,
+                                              std::memory_order_seq_cst);
+    }
+
+    template <class V>
+    static V *swap(std::atomic<V *> &atomic, V *desired)
+    { // Could be relaxed
+        return atomic.exchange(desired, std::memory_order_seq_cst);
+    }
+
+private:
+    class Node
+    {
+    public:
+        Node(const T &data) : data(data) {}
+        Node(T &&data) : data(std::move(data)) {}
+
+        T data;
+        std::atomic<Node *> next{nullptr};
+        std::atomic<Node *> next_rem{nullptr};
+        std::atomic<bool> removed{false};
+    };
+
+    template <class It>
+    class IteratorBase : public Crtp<It>
+    {
+        friend class List;
+
+    protected:
+        IteratorBase() : list(nullptr), curr(nullptr) {}
+
+        IteratorBase(List *list) : list(list)
+        {
+            assert(list != nullptr);
+            list->count++;
+            reset();
+        }
+
+    public:
+        IteratorBase(const IteratorBase &) = delete;
+
+        IteratorBase(IteratorBase &&other)
+            : list(other.list), curr(other.curr), prev(other.prev)
+        {
+            other.list = nullptr;
+            other.curr = nullptr;
+        }
+
+        ~IteratorBase()
+        {
+            if (list == nullptr) {
+                return;
+            }
+
+            auto head_rem = load(list->removed);
+            // Fetch could be relaxed
+            // There exist possibility that no one will delete garbage at this
+            // time.
+            if (list->count.fetch_sub(1) == 1 && head_rem != nullptr &&
+                cas<Node *>(
+                    list->removed, head_rem,
+                    nullptr)) { // I am the last one and there is garbage to be
+                                // removed.
+                auto now = head_rem;
+                do {
+                    auto next = load(now->next_rem);
+                    delete now;
+                    now = next;
+                } while (now != nullptr);
+            }
+        }
+
+        T &operator*() const
+        {
+            assert(valid());
+            return curr->data;
+        }
+        T *operator->() const
+        {
+            assert(valid());
+            return &(curr->data);
+        }
+
+        bool valid() const { return curr != nullptr; }
+
+        // Iterating is wait free.
+        It &operator++()
+        {
+            assert(valid());
+            do {
+                prev = curr;
+                curr = load(curr->next);
+            } while (valid() && is_removed());
+            return this->derived();
+        }
+        It &operator++(int) { return operator++(); }
+
+        bool is_removed()
+        {
+            assert(valid());
+            return load(curr->removed);
+        }
+
+        // Returns IteratorBase to begining
+        void reset()
+        {
+            prev = nullptr;
+            curr = load(list->head);
+            while (valid() && is_removed()) {
+                operator++();
+            }
+        }
+
+        // Adds to the begining of list
+        // It is lock free but it isn't wait free.
+        void push(T &&data)
+        {
+            auto node = new Node(data);
+            Node *next = nullptr;
+            do {
+                next = load(list->head);
+                store(node->next, next);
+            } while (!cas(list->head, next, node));
+        }
+
+        // True only if this call removed the element. Only reason for fail is
+        // if
+        // the element is already removed.
+        // Remove has deadlock if another thread dies between marking node for
+        // removal
+        // and the disconnection.
+        // This can be improved with combinig the removed flag with prev.next or
+        // curr.next
+        bool remove()
+        {
+            assert(valid());
+            if (cas(curr->removed, false, true)) {
+                if (!disconnect()) {
+                    find_and_disconnect();
+                }
+                store(curr->next_rem, swap(list->removed, curr));
+                return true;
+            }
+            return false;
+        }
+
+        friend bool operator==(const It &a, const It &b)
+        {
+            return a.curr == b.curr;
+        }
+
+        friend bool operator!=(const It &a, const It &b) { return !(a == b); }
+
+    private:
+        void find_and_disconnect()
+        {
+            auto it = It(list);
+            auto next = load(curr->next);
+            while (it.valid()) {
+                if (it.curr == curr) {
+                    if (it.disconnect()) {
+                        return;
+                    }
+                    it.reset();
+                } else if (it.curr == next) { // Comparison with next is
+                                              // optimization for early return.
+                    return;
+                } else {
+                    it++;
+                }
+            }
+        }
+
+        bool disconnect()
+        {
+            auto next = load(curr->next);
+            if (prev != nullptr) {
+                store(prev->next, next);
+                if (load(prev->removed)) {
+                    return false;
+                }
+            } else if (!cas(list->head, curr, next)) {
+                return false;
+            }
+            return true;
+        }
+
+        List *list;
+        Node *prev{nullptr};
+        Node *curr;
+    };
+
+public:
+    class ConstIterator : public IteratorBase<ConstIterator>
+    {
+        friend class List;
+
+    public:
+        using IteratorBase<ConstIterator>::IteratorBase;
+
+        const T &operator*() const
+        {
+            return IteratorBase<ConstIterator>::operator*();
+        }
+
+        const T *operator->() const
+        {
+            return IteratorBase<ConstIterator>::operator->();
+        }
+
+        operator const T &() const
+        {
+            return IteratorBase<ConstIterator>::operator T &();
+        }
+    };
+
+    class Iterator : public IteratorBase<Iterator>
+    {
+        friend class List;
+
+    public:
+        using IteratorBase<Iterator>::IteratorBase;
+    };
+
+public:
+    List() = default;
+
+    List(List &) = delete;
+    List(List &&) = delete;
+
+    ~List()
+    {
+        auto now = head.load();
+        while (now != nullptr) {
+            auto next = now->next.load();
+            delete now;
+            now = next;
+        }
+    }
+
+    void operator=(List &) = delete;
+
+    Iterator begin() { return Iterator(this); }
+
+    // ConstIterator begin() { return ConstIterator(this); }
+
+    ConstIterator cbegin() { return ConstIterator(this); }
+
+    Iterator end() { return Iterator(); }
+
+    // ConstIterator end() { return ConstIterator(); }
+
+    ConstIterator cend() { return ConstIterator(); }
+
+private:
+    std::atomic<std::size_t> count{0};
+    std::atomic<Node *> head{nullptr};
+    std::atomic<Node *> removed{nullptr};
+};
diff --git a/include/data_structures/concurrent/concurrent_set.hpp b/include/data_structures/concurrent/concurrent_set.hpp
index c550c081b..036463ad2 100644
--- a/include/data_structures/concurrent/concurrent_set.hpp
+++ b/include/data_structures/concurrent/concurrent_set.hpp
@@ -30,7 +30,7 @@ public:
 
         std::pair<list_it, bool> insert(T &&item)
         {
-            return accessor.insert(std::forward<T>(item));
+            return accessor.insert(std::move(item));
         }
 
         list_it_con find(const T &item) const { return accessor.find(item); }
diff --git a/include/data_structures/concurrent/skiplist.hpp b/include/data_structures/concurrent/skiplist.hpp
index a0367a57c..2722cc343 100644
--- a/include/data_structures/concurrent/skiplist.hpp
+++ b/include/data_structures/concurrent/skiplist.hpp
@@ -157,7 +157,7 @@ public:
 
             // we have raw memory and we need to construct an object
             // of type Node on it
-            return new (node) Node(std::forward<T>(item), height);
+            return new (node) Node(std::move(item), height);
         }
 
         static void destroy(Node *node)
@@ -182,7 +182,7 @@ public:
 
         Node(T &&data, uint8_t height) : Node(height)
         {
-            this->data.set(std::forward<T>(data));
+            this->data.set(std::move(data));
         }
 
         ~Node()
@@ -522,7 +522,7 @@ public:
 
         std::pair<Iterator, bool> insert(T &&item)
         {
-            return skiplist->insert(std::forward<T>(item), preds, succs);
+            return skiplist->insert(std::move(item), preds, succs);
         }
 
         Iterator insert_non_unique(const T &item)
@@ -683,7 +683,7 @@ private:
     static bool lock_nodes(uint8_t height, guard_t guards[], Node *preds[],
                            Node *succs[])
     {
-        Node *prepred, *pred, *succ = nullptr;
+        Node *prepred = nullptr, *pred = nullptr, *succ = nullptr;
         bool valid = true;
 
         for (int level = 0; valid && level < height; ++level) {
@@ -790,8 +790,7 @@ private:
             // has the locks
             if (!lock_nodes<true>(height, guards, preds, succs)) continue;
 
-            return {insert_here(std::forward<T>(data), preds, succs, height,
-                                guards),
+            return {insert_here(std::move(data), preds, succs, height, guards),
                     true};
         }
     }
@@ -801,7 +800,7 @@ private:
                          guard_t guards[])
     {
         // you have the locks, create a new node
-        auto new_node = Node::create(std::forward<T>(data), height);
+        auto new_node = Node::create(std::move(data), height);
 
         // link the predecessors and successors, e.g.
         //
diff --git a/include/database/db_accessor.hpp b/include/database/db_accessor.hpp
index e4cbd86a6..be19ba520 100644
--- a/include/database/db_accessor.hpp
+++ b/include/database/db_accessor.hpp
@@ -1,15 +1,20 @@
 #pragma once
 
-#include "database/db.hpp"
-#include "database/db_accessor.hpp"
-#include "storage/record_accessor.hpp"
-#include "storage/vertex.hpp"
+#include "database/db_transaction.hpp"
+// #include "storage/record_accessor.hpp"
+// #include "storage/vertex.hpp"
 #include "storage/vertex_accessor.hpp"
-#include "storage/vertices.hpp"
-#include "transactions/transaction.hpp"
-#include "utils/iterator/iterator.hpp"
+// #include "storage/vertices.hpp"
+// #include "transactions/transaction.hpp"
+// #include "utils/iterator/iterator.hpp"
+#include "utils/border.hpp"
 #include "utils/option.hpp"
 
+namespace tx
+{
+class Transaction;
+}
+
 /*
 * DbAccessor
 * -Guarantees that access to Vertex and Edge is possible only through
@@ -65,21 +70,31 @@ public:
 
     bool label_contains(const std::string &name);
 
-    VertexIndexRecordCollection &label_find_index(const Label &label);
-
     //********************TYPE METHODS
 
     const EdgeType &type_find_or_create(const std::string &name);
 
     bool type_contains(const std::string &name);
 
+    //********************PROPERTY METHODS
+    // Vertices::prop_familys_t::Accessor vertex_property_family_access();
+    //
+    // auto edge_property_family_access();
+
+    PropertyFamily &vertex_property_family_get(const std::string &name);
+
+    PropertyFamily &edge_property_family_get(const std::string &name);
+
     //********************TRANSACTION METHODS
 
     void commit();
     void abort();
 
 private:
-    DbTransaction db;
+    template <class T, class K>
+    friend class NonUniqueUnorderedIndex;
+
+    DbTransaction db_transaction;
 };
 
 //**********************CONVENIENT FUNCTIONS
diff --git a/include/database/db_transaction.hpp b/include/database/db_transaction.hpp
index a7b862c82..a36dd1d18 100644
--- a/include/database/db_transaction.hpp
+++ b/include/database/db_transaction.hpp
@@ -1,7 +1,5 @@
 #pragma once
 
-#include "storage/indexes/index_record.hpp"
-#include "storage/label/label.hpp"
 #include "transactions/transaction.hpp"
 
 class Db;
@@ -9,6 +7,8 @@ class DbAccessor;
 
 // Inner structures local to transaction can hold ref to this structure and use
 // its methods.
+// Also serves as a barrier for calling methods defined public but meant for
+// internal use. That kind of method should request DbTransaction&.
 class DbTransaction
 {
     friend DbAccessor;
@@ -16,8 +16,10 @@ class DbTransaction
 public:
     DbTransaction(Db &db, tx::Transaction &trans) : db(db), trans(trans) {}
 
-    void update_label_index(const Label &label,
-                            VertexIndexRecord &&index_record);
+    // Global transactional algorithms,operations and general methods meant for
+    // internal use should be here or should be routed through this object.
+    // This should provide cleaner hierarchy of operations on database.
+    // For example cleaner.
 
     tx::Transaction &trans;
 
diff --git a/include/query_engine/hardcode/queries.hpp b/include/query_engine/hardcode/queries.hpp
index 5ef8dbfe5..f413ae9bd 100644
--- a/include/query_engine/hardcode/queries.hpp
+++ b/include/query_engine/hardcode/queries.hpp
@@ -5,8 +5,11 @@
 #include "database/db_accessor.hpp"
 #include "query_engine/query_stripper.hpp"
 #include "query_engine/util.hpp"
+#include "storage/indexes/impl/nonunique_unordered_index.cpp"
 #include "storage/model/properties/property.hpp"
+#include "storage/model/properties/property_family.hpp"
 #include "utils/command_line/arguments.hpp"
+#include "utils/iterator/iterator.hpp"
 
 auto load_queries(Db &db)
 {
@@ -15,8 +18,12 @@ auto load_queries(Db &db)
     // CREATE (n {prop: 0}) RETURN n)
     auto create_node = [&db](const properties_t &args) {
         DbAccessor t(db);
+        auto prop_key = t.vertex_property_family_get("prop")
+                            .get(args[0]->flags)
+                            .family_key();
+
         auto vertex_accessor = t.vertex_insert();
-        vertex_accessor.property("prop", args[0]);
+        vertex_accessor.set(prop_key, args[0]);
         t.commit();
         return true;
     };
@@ -24,8 +31,12 @@ auto load_queries(Db &db)
 
     auto create_labeled_and_named_node = [&db](const properties_t &args) {
         DbAccessor t(db);
+        auto prop_key = t.vertex_property_family_get("name")
+                            .get(args[0]->flags)
+                            .family_key();
+
         auto vertex_accessor = t.vertex_insert();
-        vertex_accessor.property("name", args[0]);
+        vertex_accessor.set(prop_key, args[0]);
         auto &label = t.label_find_or_create("LABEL");
         vertex_accessor.add_label(label);
         cout_properties(vertex_accessor.properties());
@@ -35,11 +46,23 @@ auto load_queries(Db &db)
 
     auto create_account = [&db](const properties_t &args) {
         DbAccessor t(db);
+        auto prop_id =
+            t.vertex_property_family_get("id").get(args[0]->flags).family_key();
+        auto prop_name = t.vertex_property_family_get("name")
+                             .get(args[1]->flags)
+                             .family_key();
+        auto prop_country = t.vertex_property_family_get("country")
+                                .get(args[2]->flags)
+                                .family_key();
+        auto prop_created = t.vertex_property_family_get("created_at")
+                                .get(args[3]->flags)
+                                .family_key();
+
         auto vertex_accessor = t.vertex_insert();
-        vertex_accessor.property("id", args[0]);
-        vertex_accessor.property("name", args[1]);
-        vertex_accessor.property("country", args[2]);
-        vertex_accessor.property("created_at", args[3]);
+        vertex_accessor.set(prop_id, args[0]);
+        vertex_accessor.set(prop_name, args[1]);
+        vertex_accessor.set(prop_country, args[2]);
+        vertex_accessor.set(prop_created, args[3]);
         auto &label = t.label_find_or_create("ACCOUNT");
         vertex_accessor.add_label(label);
         cout_properties(vertex_accessor.properties());
@@ -49,8 +72,7 @@ auto load_queries(Db &db)
 
     auto find_node_by_internal_id = [&db](const properties_t &args) {
         DbAccessor t(db);
-        auto id = static_cast<Int32 &>(*args[0]);
-        auto maybe_va = t.vertex_find(Id(id.value));
+        auto maybe_va = t.vertex_find(Id(args[0]->as<Int32>().value));
         if (!option_fill(maybe_va)) {
             cout << "vertex doesn't exist" << endl;
             t.commit();
@@ -117,12 +139,15 @@ auto load_queries(Db &db)
 
     auto update_node = [&db](const properties_t &args) {
         DbAccessor t(db);
+        auto prop_name = t.vertex_property_family_get("name")
+                             .get(args[1]->flags)
+                             .family_key();
 
         auto maybe_v = t.vertex_find(args[0]->as<Int32>().value);
         if (!option_fill(maybe_v)) return t.commit(), false;
         auto v = maybe_v.get();
 
-        v.property("name", args[1]);
+        v.set(prop_name, args[1]);
         cout_properties(v.properties());
 
         t.commit();
@@ -134,13 +159,19 @@ auto load_queries(Db &db)
     // weight: 70}]-(n2) RETURN r
     auto create_edge_v2 = [&db](const properties_t &args) {
         DbAccessor t(db);
+        auto prop_age =
+            t.edge_property_family_get("age").get(args[2]->flags).family_key();
+        auto prop_weight = t.edge_property_family_get("weight")
+                               .get(args[3]->flags)
+                               .family_key();
+
         auto n1 = t.vertex_find(args[0]->as<Int64>().value);
         if (!option_fill(n1)) return t.commit(), false;
         auto n2 = t.vertex_find(args[1]->as<Int64>().value);
         if (!option_fill(n2)) return t.commit(), false;
         auto r = t.edge_insert(n2.get(), n1.get());
-        r.property("age", args[2]);
-        r.property("weight", args[3]);
+        r.set(prop_age, args[2]);
+        r.set(prop_weight, args[3]);
         auto &IS = t.type_find_or_create("IS");
         r.edge_type(IS);
 
@@ -173,13 +204,12 @@ auto load_queries(Db &db)
         DbAccessor t(db);
 
         auto &label = t.label_find_or_create("LABEL");
+        auto prop_key =
+            t.vertex_property_family_get("name").get(Type::String).family_key();
 
-        auto &index_record_collection = t.label_find_index(label);
-        auto accessor = index_record_collection.access();
         cout << "VERTICES" << endl;
-        for (auto &v : accessor) {
-            cout << v.record->data.props.at("name").as<String>().value << endl;
-        }
+        iter::for_all(label.index->for_range_exact(t),
+                      [&](auto a) { cout << a.at(prop_key) << endl; });
 
         // TODO
         // db.graph.vertices.fileter("LABEL").all(t, handler);
diff --git a/include/query_engine/util.hpp b/include/query_engine/util.hpp
index 76bf1e5a6..40b5b5a57 100644
--- a/include/query_engine/util.hpp
+++ b/include/query_engine/util.hpp
@@ -40,5 +40,4 @@ std::string code_line(const std::string &format_str, const Args &... args)
 {
     return "\t" + format(format_str, args...) + "\n";
 }
-
 }
diff --git a/include/storage/edges.hpp b/include/storage/edges.hpp
index 660962be8..e980675b6 100644
--- a/include/storage/edges.hpp
+++ b/include/storage/edges.hpp
@@ -1,13 +1,17 @@
 #pragma once
 
+#include <string>
 #include "data_structures/concurrent/concurrent_map.hpp"
 #include "mvcc/version_list.hpp"
 #include "storage/common.hpp"
 #include "storage/edge_accessor.hpp"
+#include "storage/model/properties/property_family.hpp"
 #include "utils/option.hpp"
 
 class Edges
 {
+    using prop_familys_t = ConcurrentMap<std::string, PropertyFamily *>;
+
 public:
     Option<const Edge::Accessor> find(DbTransaction &t, const Id &id);
 
@@ -15,7 +19,15 @@ public:
     Edge::Accessor insert(DbTransaction &t, VertexRecord *from,
                           VertexRecord *to);
 
+    // auto property_family_access();
+
+    PropertyFamily &property_family_find_or_create(const std::string &name);
+
 private:
     ConcurrentMap<uint64_t, EdgeRecord> edges;
+    // TODO: Because familys wont be removed this could be done with more
+    // efficent
+    // data structure.
+    prop_familys_t prop_familys;
     AtomicCounter<uint64_t> counter;
 };
diff --git a/include/storage/indexes/impl/nonunique_unordered_index.hpp b/include/storage/indexes/impl/nonunique_unordered_index.hpp
new file mode 100644
index 000000000..01bebb1c5
--- /dev/null
+++ b/include/storage/indexes/impl/nonunique_unordered_index.hpp
@@ -0,0 +1,38 @@
+#pragma once
+
+#include "storage/indexes/index_base.hpp"
+#include "storage/indexes/index_record.hpp"
+
+#include "data_structures/concurrent/concurrent_list.hpp"
+
+template <class T, class K>
+class NonUniqueUnorderedIndex : public IndexBase<T, K>
+{
+public:
+    typedef T value_type;
+    typedef K key_type;
+
+    NonUniqueUnorderedIndex();
+
+    // Insert's value.
+    // nonunique => always succeds.
+    bool insert(IndexRecord<T, K> &&value) final;
+
+    // Returns iterator which returns valid records in range.
+    // ordered==None => doesn't guarantee any order of submitting records.
+    std::unique_ptr<IteratorBase<const typename T::Accessor>>
+    for_range(DbAccessor &t, Border<K> from = Border<K>(),
+              Border<K> to = Border<K>()) final;
+
+    // Same as for_range just whit known returned iterator.
+    auto for_range_exact(DbAccessor &t, Border<K> from = Border<K>(),
+                         Border<K> to = Border<K>());
+
+    // Removes for all transactions obsolete Records.
+    // Cleaner has to call this method when he decideds that it is time for
+    // cleaning.
+    void clean(DbTransaction &) final;
+
+private:
+    List<IndexRecord<T, K>> list;
+};
diff --git a/include/storage/indexes/index.hpp b/include/storage/indexes/index.hpp
index 4b24e65a3..87007f0a7 100644
--- a/include/storage/indexes/index.hpp
+++ b/include/storage/indexes/index.hpp
@@ -1,44 +1,44 @@
-#pragma once
-
-#include <memory>
-
-#include "data_structures/concurrent/concurrent_map.hpp"
-#include "storage/indexes/index_record.hpp"
-#include "storage/indexes/index_record_collection.hpp"
-#include "storage/label/label.hpp"
-
-template <class Key, class Item>
-class Index
-{
-  public:
-  using container_t = ConcurrentMap<Key, Item>;
-
-  Index() : index(std::make_unique<container_t>()) {}
-
-  auto update(const Label &label, VertexIndexRecord &&index_record)
-  {
-    auto accessor = index->access();
-    auto label_ref = label_ref_t(label);
-
-    // create Index Record Collection if it doesn't exist
-    if (!accessor.contains(label_ref)) {
-      accessor.insert(label_ref, std::move(VertexIndexRecordCollection()));
-    }
-
-    // add Vertex Index Record to the Record Collection
-    auto &record_collection = (*accessor.find(label_ref)).second;
-    record_collection.add(std::forward<VertexIndexRecord>(index_record));
-  }
-
-  VertexIndexRecordCollection &find(const Label &label)
-  {
-    // TODO: accessor should be outside?
-    // bacause otherwise GC could delete record that has just be returned
-    auto label_ref = label_ref_t(label);
-    auto accessor = index->access();
-    return (*accessor.find(label_ref)).second;
-  }
-
-  private:
-  std::unique_ptr<container_t> index;
-};
+// #pragma once
+//
+// #include <memory>
+//
+// #include "data_structures/concurrent/concurrent_map.hpp"
+// #include "storage/indexes/index_record.hpp"
+// #include "storage/indexes/index_record_collection.hpp"
+// #include "storage/label/label.hpp"
+//
+// template <class Key, class Item>
+// class Index
+// {
+//   public:
+//   using container_t = ConcurrentMap<Key, Item>;
+//
+//   Index() : index(std::make_unique<container_t>()) {}
+//
+//   auto update(const Label &label, VertexIndexRecord &&index_record)
+//   {
+//     auto accessor = index->access();
+//     auto label_ref = label_ref_t(label);
+//
+//     // create Index Record Collection if it doesn't exist
+//     if (!accessor.contains(label_ref)) {
+//       accessor.insert(label_ref, std::move(VertexIndexRecordCollection()));
+//     }
+//
+//     // add Vertex Index Record to the Record Collection
+//     auto &record_collection = (*accessor.find(label_ref)).second;
+//     record_collection.add(std::forward<VertexIndexRecord>(index_record));
+//   }
+//
+//   VertexIndexRecordCollection &find(const Label &label)
+//   {
+//     // TODO: accessor should be outside?
+//     // bacause otherwise GC could delete record that has just be returned
+//     auto label_ref = label_ref_t(label);
+//     auto accessor = index->access();
+//     return (*accessor.find(label_ref)).second;
+//   }
+//
+//   private:
+//   std::unique_ptr<container_t> index;
+// };
diff --git a/include/storage/indexes/index_base.hpp b/include/storage/indexes/index_base.hpp
new file mode 100644
index 000000000..aa7603848
--- /dev/null
+++ b/include/storage/indexes/index_base.hpp
@@ -0,0 +1,60 @@
+#pragma once
+
+// #include "storage/indexes/index_record.hpp"
+#include <functional>
+#include <memory>
+#include "utils/border.hpp"
+#include "utils/iterator/iterator_base.hpp"
+
+class DbTransaction;
+class DbAccessor;
+
+template <class T, class K>
+class IndexRecord;
+
+// Defines ordering of data
+enum Order
+{
+    None = 0,
+    Ascending = 1,
+    Descending = 2,
+};
+
+// Interface for all indexes.
+// T type of record.
+// K type of key on which records are ordered
+template <class T, class K>
+class IndexBase
+{
+public:
+    typedef T value_type;
+    typedef K key_type;
+
+    IndexBase(bool unique, Order order) : unique(unique), order(order) {}
+
+    // Insert's value.
+    // unique => returns false if there is already valid equal value.
+    // nonunique => always succeds.
+    virtual bool insert(IndexRecord<T, K> &&value) = 0;
+
+    // Returns iterator which returns valid records in range.
+    // order==noe => doesn't guarantee any order of returned records.
+    // order==Ascending => guarantees order of returnd records will be from
+    // smallest to largest.
+    // order==Descending => guarantees order of returned records will be from
+    // largest to smallest.
+    // Range must be from<=to
+    virtual std::unique_ptr<IteratorBase<const typename T::Accessor>>
+    for_range(DbAccessor &, Border<K> from = Border<K>(),
+              Border<K> to = Border<K>()) = 0;
+
+    // Removes for all transactions obsolete Records.
+    // Cleaner has to call this method when he decideds that it is time for
+    // cleaning.
+    virtual void clean(DbTransaction &) = 0;
+
+    // Are the records unique
+    const bool unique;
+    // Ordering of the records.
+    const Order order;
+};
diff --git a/include/storage/indexes/index_record.hpp b/include/storage/indexes/index_record.hpp
index b7e63efaa..70f05af71 100644
--- a/include/storage/indexes/index_record.hpp
+++ b/include/storage/indexes/index_record.hpp
@@ -1,46 +1,67 @@
 #pragma once
 
+#include "database/db_transaction.hpp"
 #include "mvcc/version_list.hpp"
 #include "utils/total_ordering.hpp"
 
-template <class T>
-class IndexRecord : TotalOrdering<IndexRecord<T>>
+// class DbTransaction;
+// namespace tx
+// {
+// class Transaction;
+// }
+
+// T type of record.
+// K key on which record is ordered.
+template <class T, class K>
+class IndexRecord : public TotalOrdering<IndexRecord<T, K>>
 {
 public:
     using vlist_t = mvcc::VersionList<T>;
 
     IndexRecord() = default;
 
-    IndexRecord(T *record, vlist_t *vlist) : record(record), vlist(vlist)
+    IndexRecord(K key, T *record, vlist_t *vlist)
+        : key(std::move(key)), record(record), vlist(vlist)
     {
         assert(record != nullptr);
         assert(vlist != nullptr);
     }
 
-    friend bool operator<(const IndexRecord& lhs, const IndexRecord& rhs)
+    friend bool operator<(const IndexRecord &lhs, const IndexRecord &rhs)
     {
-        return lhs.record < rhs.record;
+        return lhs.key < rhs.key ||
+               (lhs.key == rhs.key && lhs.vlist == rhs.vlist &&
+                lhs.record < rhs.record);
     }
 
-    friend bool operator==(const IndexRecord& lhs, const IndexRecord& rhs)
+    friend bool operator==(const IndexRecord &lhs, const IndexRecord &rhs)
     {
-        return lhs.record == rhs.record;
+        return lhs.key == rhs.key &&
+               (lhs.vlist != rhs.vlist || lhs.record == rhs.record);
     }
 
     bool empty() const { return record == nullptr; }
 
-    // const typename T::Accessor get()
-    // {
-    //     // TODO: if somebody wants to read T content
-    //     // const T::Accessor has to be returned from here
-    //     // the problem is that here we don't have pointer to store
-    //     // TODO: figure it out
-    // }
+    bool is_valid(tx::Transaction &t) const
+    {
+        assert(!empty());
+        return record == vlist->find(t);
+    }
 
-// private:
+    const auto access(DbTransaction &db) const
+    {
+        return T::Accessor::create(record, vlist, db);
+    }
+
+    const K key;
+
+private:
     T *const record{nullptr};
     vlist_t *const vlist{nullptr};
 };
 
-using VertexIndexRecord = IndexRecord<Vertex>;
-using EdgeIndexRecord = IndexRecord<Edge>;
+template <class K>
+using VertexIndexRecord = IndexRecord<Vertex, K>;
+
+template <class K>
+using EdgeIndexRecord = IndexRecord<Edge, K>;
diff --git a/include/storage/indexes/index_record_collection.hpp b/include/storage/indexes/index_record_collection.hpp
index 0d06e2a91..53d4a1ba3 100644
--- a/include/storage/indexes/index_record_collection.hpp
+++ b/include/storage/indexes/index_record_collection.hpp
@@ -1,38 +1,38 @@
-#pragma once
-
-#include <memory>
-
-#include "data_structures/concurrent/concurrent_set.hpp"
-#include "storage/indexes/index_record.hpp"
-
-template <class T>
-class IndexRecordCollection
-{
-public:
-    using index_record_t = IndexRecord<T>;
-    using index_record_collection_t = ConcurrentSet<index_record_t>;
-
-    IndexRecordCollection()
-        : records(std::make_unique<index_record_collection_t>())
-    {
-    }
-
-    void add(index_record_t &&record)
-    {
-        auto accessor = records->access();
-        accessor.insert(std::forward<index_record_t>(record));
-    }
-
-    auto access()
-    {
-        return records->access();
-    } 
-
-    // TODO: iterator and proxy
-
-private:
-    std::unique_ptr<index_record_collection_t> records;
-};
-
-using VertexIndexRecordCollection = IndexRecordCollection<Vertex>;
-using EdgeIndexRecordCollection = IndexRecordCollection<Edge>;
+// #pragma once
+//
+// #include <memory>
+//
+// #include "data_structures/concurrent/concurrent_set.hpp"
+// #include "storage/indexes/index_record.hpp"
+//
+// template <class T>
+// class IndexRecordCollection
+// {
+// public:
+//     using index_record_t = IndexRecord<T>;
+//     using index_record_collection_t = ConcurrentSet<index_record_t>;
+//
+//     IndexRecordCollection()
+//         : records(std::make_unique<index_record_collection_t>())
+//     {
+//     }
+//
+//     void add(index_record_t &&record)
+//     {
+//         auto accessor = records->access();
+//         accessor.insert(std::forward<index_record_t>(record));
+//     }
+//
+//     auto access()
+//     {
+//         return records->access();
+//     }
+//
+//     // TODO: iterator and proxy
+//
+// private:
+//     std::unique_ptr<index_record_collection_t> records;
+// };
+//
+// using VertexIndexRecordCollection = IndexRecordCollection<Vertex>;
+// using EdgeIndexRecordCollection = IndexRecordCollection<Edge>;
diff --git a/include/storage/indexes/sort_order.hpp b/include/storage/indexes/sort_order.hpp
index 82a60f61d..5d9348601 100644
--- a/include/storage/indexes/sort_order.hpp
+++ b/include/storage/indexes/sort_order.hpp
@@ -3,7 +3,7 @@
 template <class T>
 struct Ascending
 {
-    constexpr bool operator()(const T& lhs, const T& rhs) const
+    constexpr bool operator()(const T &lhs, const T &rhs) const
     {
         return lhs < rhs;
     }
@@ -12,7 +12,7 @@ struct Ascending
 template <class T>
 struct Descending
 {
-    constexpr bool operator()(const T& lhs, const T& rhs) const
+    constexpr bool operator()(const T &lhs, const T &rhs) const
     {
         return lhs > rhs;
     }
diff --git a/include/storage/label/label.hpp b/include/storage/label/label.hpp
index 97430fe5a..bcb478921 100644
--- a/include/storage/label/label.hpp
+++ b/include/storage/label/label.hpp
@@ -1,27 +1,39 @@
 #pragma once
 
-#include <stdint.h>
 #include <ostream>
+#include <stdint.h>
 
-#include "utils/total_ordering.hpp"
+#include "storage/indexes/impl/nonunique_unordered_index.hpp"
+#include "storage/vertex.hpp"
+#include "storage/vertex_accessor.hpp"
 #include "utils/reference_wrapper.hpp"
+#include "utils/total_ordering.hpp"
+#include "utils/void.hpp"
+
+using LabelIndexRecord = VertexIndexRecord<std::nullptr_t>;
 
 class Label : public TotalOrdering<Label>
 {
 public:
-    Label(const std::string& name);
-    Label(std::string&& name);
+    using label_index_t = NonUniqueUnorderedIndex<Vertex, std::nullptr_t>;
 
-    Label(const Label&) = default;
-    Label(Label&&) = default;
+    Label() = delete;
 
-    friend bool operator<(const Label& lhs, const Label& rhs);
+    Label(const std::string &name);
+    Label(std::string &&name);
 
-    friend bool operator==(const Label& lhs, const Label& rhs);
+    Label(const Label &) = delete;
+    Label(Label &&other) = default;
 
-    friend std::ostream& operator<<(std::ostream& stream, const Label& label);
+    friend bool operator<(const Label &lhs, const Label &rhs);
 
-    operator const std::string&() const;
+    friend bool operator==(const Label &lhs, const Label &rhs);
+
+    friend std::ostream &operator<<(std::ostream &stream, const Label &label);
+
+    operator const std::string &() const;
+
+    std::unique_ptr<label_index_t> index;
 
 private:
     std::string name;
diff --git a/include/storage/label/label_collection.hpp b/include/storage/label/label_collection.hpp
index e52f5d7cb..c8ab924d9 100644
--- a/include/storage/label/label_collection.hpp
+++ b/include/storage/label/label_collection.hpp
@@ -2,7 +2,11 @@
 
 #include <set>
 
-#include "storage/label/label.hpp"
+// #include "storage/label/label.hpp"
+#include "utils/reference_wrapper.hpp"
+
+class Label;
+using label_ref_t = ReferenceWrapper<const Label>;
 
 class LabelCollection
 {
@@ -15,12 +19,12 @@ public:
     auto end() const;
     auto cend() const;
 
-    bool add(const Label& label);
-    bool has(const Label& label) const;
+    bool add(const Label &label);
+    bool has(const Label &label) const;
     size_t count() const;
-    bool remove(const Label& label);
+    bool remove(const Label &label);
     void clear();
-    const std::set<label_ref_t>& operator()() const;
+    const std::set<label_ref_t> &operator()() const;
 
 private:
     std::set<label_ref_t> _labels;
diff --git a/include/storage/model/properties/all.hpp b/include/storage/model/properties/all.hpp
index 2bb5bb493..3d09e84d8 100644
--- a/include/storage/model/properties/all.hpp
+++ b/include/storage/model/properties/all.hpp
@@ -6,4 +6,3 @@
 #include "storage/model/properties/int32.hpp"
 #include "storage/model/properties/int64.hpp"
 #include "storage/model/properties/string.hpp"
-
diff --git a/include/storage/model/properties/flags.hpp b/include/storage/model/properties/flags.hpp
new file mode 100644
index 000000000..0997b0685
--- /dev/null
+++ b/include/storage/model/properties/flags.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+enum class Flags : unsigned
+{
+    // Type       | Mask
+    // -----------+----------------------------------------
+    // Null       | 0000 0000 0000 0000 0000 0000 0000 0000
+    // -----------+----------------------------------------
+    // Bool       | 0000 0000 0000 0000 0000 0000 0000 0001
+    // + True     | 0000 0000 0000 0000 0000 0000 0000 0011
+    // + False    | 0000 0000 0000 0000 0000 0000 0000 0101
+    // -----------+----------------------------------------
+    // String     | 0000 0000 0000 0000 0000 0000 0000 1000
+    // -----------+----------------------------------------
+    // Number     | 0000 0000 0000 0000 0000 0000 0001 0000
+    // + Integral | 0000 0000 0000 0000 0000 0000 0011 0000
+    //  + Int32   | 0000 0000 0000 0000 0000 0000 0111 0000
+    //  + Int64   | 0000 0000 0000 0000 0000 0000 1011 0000
+    // + Floating | 0000 0000 0000 0000 0000 0001 0001 0000
+    //  + Float   | 0000 0000 0000 0000 0000 0011 0001 0000
+    //  + Double  | 0000 0000 0000 0000 0000 0101 0001 0000
+    // -----------+----------------------------------------
+    // Array      | 0000 0000 0000 0000 0001 0000 0000 0000
+    // -----------+----------------------------------------
+
+    Null = 0x0,
+    Bool = 0x1,
+    True = 0x2 | Bool,
+    False = 0x4 | Bool,
+
+    String = 0x8,
+
+    Number = 0x10,
+    Integral = 0x20 | Number,
+    Int32 = 0x40 | Integral,
+    Int64 = 0x80 | Integral,
+
+    Floating = 0x100 | Number,
+    Float = 0x200 | Floating,
+    Double = 0x400 | Floating,
+
+    Array = 0x1000,
+
+    type_mask = 0xFFF
+};
diff --git a/include/storage/model/properties/handler.hpp b/include/storage/model/properties/handler.hpp
index 2fab3abae..0a7bf790e 100644
--- a/include/storage/model/properties/handler.hpp
+++ b/include/storage/model/properties/handler.hpp
@@ -1,35 +1,35 @@
 #pragma once
 
-#include "storage/model/properties/property.hpp"
 #include "storage/model/properties/all.hpp"
+#include "storage/model/properties/property.hpp"
 
 template <class Handler>
 void accept(const Property &property, Handler &h)
 {
     switch (property.flags) {
 
-        case Property::Flags::True:
-            return h.handle(static_cast<const Bool &>(property));
+    case Flags::True:
+        return h.handle(static_cast<const Bool &>(property));
 
-        case Property::Flags::False:
-            return h.handle(static_cast<const Bool &>(property));
+    case Flags::False:
+        return h.handle(static_cast<const Bool &>(property));
 
-        case Property::Flags::String:
-            return h.handle(static_cast<const String &>(property));
+    case Flags::String:
+        return h.handle(static_cast<const String &>(property));
 
-        case Property::Flags::Int32:
-            return h.handle(static_cast<const Int32 &>(property));
+    case Flags::Int32:
+        return h.handle(static_cast<const Int32 &>(property));
 
-        case Property::Flags::Int64:
-            return h.handle(static_cast<const Int64 &>(property));
+    case Flags::Int64:
+        return h.handle(static_cast<const Int64 &>(property));
 
-        case Property::Flags::Float:
-            return h.handle(static_cast<const Float &>(property));
+    case Flags::Float:
+        return h.handle(static_cast<const Float &>(property));
 
-        case Property::Flags::Double:
-            return h.handle(static_cast<const Double &>(property));
+    case Flags::Double:
+        return h.handle(static_cast<const Double &>(property));
 
-        default:
-            return;
+    default:
+        return;
     }
 }
diff --git a/include/storage/model/properties/properties.hpp b/include/storage/model/properties/properties.hpp
index b2c023af2..3165169bc 100644
--- a/include/storage/model/properties/properties.hpp
+++ b/include/storage/model/properties/properties.hpp
@@ -3,42 +3,49 @@
 #include <map>
 
 #include "storage/model/properties/property.hpp"
+#include "storage/model/properties/property_family.hpp"
+#include "utils/option.hpp"
+
+using prop_key_t = PropertyFamily::PropertyType::PropertyFamilyKey;
+
+template <class T>
+using type_key_t = PropertyFamily::PropertyType::PropertyTypeKey<T>;
 
 class Properties
 {
 public:
     using sptr = std::shared_ptr<Properties>;
 
-    auto begin()  const { return props.begin(); }
+    auto begin() const { return props.begin(); }
     auto cbegin() const { return props.cbegin(); }
 
-    auto end()  const { return props.end(); }
+    auto end() const { return props.end(); }
     auto cend() const { return props.cend(); }
 
-    size_t size() const
-    {
-        return props.size();
-    }
+    size_t size() const { return props.size(); }
 
-    const Property& at(const std::string& key) const;
+    const Property &at(prop_key_t &key) const;
+
+    template <class T>
+    auto at(type_key_t<T> &key) const;
 
     template <class T, class... Args>
-    void set(const std::string& key, Args&&... args);
+    void set(type_key_t<T> &key, Args &&... args);
 
-    void set(const std::string& key, Property::sptr value);
+    void set(prop_key_t &key, Property::sptr value);
 
-    void clear(const std::string& key);
+    void clear(prop_key_t &key);
 
     template <class Handler>
-    void accept(Handler& handler) const
+    void accept(Handler &handler) const
     {
-        for(auto& kv : props)
+        for (auto &kv : props)
             handler.handle(kv.first, *kv.second);
 
         handler.finish();
     }
 
 private:
-    using props_t = std::map<std::string, Property::sptr>;
+    using props_t = std::map<prop_key_t, Property::sptr>;
     props_t props;
 };
diff --git a/include/storage/model/properties/property.hpp b/include/storage/model/properties/property.hpp
index 43c818239..2299be164 100644
--- a/include/storage/model/properties/property.hpp
+++ b/include/storage/model/properties/property.hpp
@@ -1,11 +1,12 @@
 #pragma once
 
-#include <memory>
-#include <string>
 #include <cassert>
+#include <memory>
 #include <ostream>
+#include <string>
 #include <vector>
 
+#include "storage/model/properties/flags.hpp"
 #include "utils/underlying_cast.hpp"
 
 class Null;
@@ -15,57 +16,13 @@ class Property
 public:
     using sptr = std::shared_ptr<Property>;
 
-    enum class Flags : unsigned
-    {
-        // Type       | Mask
-        // -----------+----------------------------------------
-        // Null       | 0000 0000 0000 0000 0000 0000 0000 0000
-        // -----------+----------------------------------------
-        // Bool       | 0000 0000 0000 0000 0000 0000 0000 0001
-        // + True     | 0000 0000 0000 0000 0000 0000 0000 0011
-        // + False    | 0000 0000 0000 0000 0000 0000 0000 0101
-        // -----------+----------------------------------------
-        // String     | 0000 0000 0000 0000 0000 0000 0000 1000
-        // -----------+----------------------------------------
-        // Number     | 0000 0000 0000 0000 0000 0000 0001 0000
-        // + Integral | 0000 0000 0000 0000 0000 0000 0011 0000
-        //  + Int32   | 0000 0000 0000 0000 0000 0000 0111 0000
-        //  + Int64   | 0000 0000 0000 0000 0000 0000 1011 0000
-        // + Floating | 0000 0000 0000 0000 0000 0001 0001 0000
-        //  + Float   | 0000 0000 0000 0000 0000 0011 0001 0000
-        //  + Double  | 0000 0000 0000 0000 0000 0101 0001 0000
-        // -----------+----------------------------------------
-        // Array      | 0000 0000 0000 0000 0001 0000 0000 0000
-        // -----------+----------------------------------------
-
-        Null     = 0x0,
-        Bool     = 0x1,
-        True     = 0x2 | Bool,
-        False    = 0x4 | Bool,
-
-        String   = 0x8,
-
-        Number   = 0x10,
-        Integral = 0x20 | Number,
-        Int32    = 0x40 | Integral,
-        Int64    = 0x80 | Integral,
-
-        Floating = 0x100 | Number,
-        Float    = 0x200 | Floating,
-        Double   = 0x400 | Floating,
-
-        Array    = 0x1000,
-
-        type_mask = 0xFFF
-    };
-
     static const Null Null;
 
     Property(Flags flags);
 
-    virtual bool operator==(const Property& other) const = 0;
+    virtual bool operator==(const Property &other) const = 0;
 
-    bool operator!=(const Property& other) const;
+    bool operator!=(const Property &other) const;
 
     template <class T>
     bool is() const
@@ -74,22 +31,22 @@ public:
     }
 
     template <class T>
-    T& as()
+    T &as()
     {
         assert(this->is<T>());
-        return *static_cast<T*>(this);
+        return *static_cast<T *>(this);
     }
 
     template <class T>
-    const T& as() const
+    const T &as() const
     {
         assert(this->is<T>());
-        return *static_cast<const T*>(this);
+        return *static_cast<const T *>(this);
     }
 
-    virtual std::ostream& print(std::ostream& stream) const = 0;
+    virtual std::ostream &print(std::ostream &stream) const = 0;
 
-    friend std::ostream& operator<<(std::ostream& stream, const Property& prop);
+    friend std::ostream &operator<<(std::ostream &stream, const Property &prop);
 
     const Flags flags;
 };
diff --git a/include/storage/model/properties/property_family.hpp b/include/storage/model/properties/property_family.hpp
new file mode 100644
index 000000000..cdb979ee9
--- /dev/null
+++ b/include/storage/model/properties/property_family.hpp
@@ -0,0 +1,181 @@
+#pragma once
+
+#include <memory>
+#include "data_structures/concurrent/concurrent_map.hpp"
+#include "storage/model/properties/flags.hpp"
+#include "utils/option.hpp"
+#include "utils/total_ordering.hpp"
+#include "utils/underlying_cast.hpp"
+
+typedef Flags Type;
+
+// Family of properties with the same name but different types.
+// Ordered on name.
+class PropertyFamily : public TotalOrdering<PropertyFamily>
+{
+    friend class PropertyType;
+    friend class PropertyFamilyKey;
+    friend class PropertyTypeKey;
+
+public:
+    // Type of property defined with his family and his type.
+    // Ordered on PropertyFamily and Type.
+    class PropertyType : public TotalOrdering<PropertyType>
+    {
+        friend class PropertyFamilyKey;
+        friend class PropertyTypeKey;
+        friend class PropertyFamily;
+
+    public:
+        // Ordered on POINTERS to PropertyFamily
+        class PropertyFamilyKey : public TotalOrdering<PropertyFamilyKey>
+        {
+            friend class PropertyType;
+            friend class PropertyTypeKey;
+
+            PropertyFamilyKey(const PropertyType &type) : type(&type) {}
+
+        public:
+            friend bool operator==(const PropertyFamilyKey &lhs,
+                                   const PropertyFamilyKey &rhs)
+            {
+                return &(lhs.type->family) == &(rhs.type->family);
+            }
+
+            friend bool operator<(const PropertyFamilyKey &lhs,
+                                  const PropertyFamilyKey &rhs)
+            {
+                return &(lhs.type->family) < &(rhs.type->family);
+            }
+
+            Type prop_type() const { return type->type; }
+
+            std::string const &family_name() const
+            {
+                return type->family.name();
+            }
+
+        private:
+            const PropertyType *type;
+        };
+
+        // Ordered on POINTERS to PropertyType.
+        // When compared with PropertyFamilyKey behaves as PropertyFamilyKey.
+        template <class T>
+        class PropertyTypeKey
+            : public TotalOrdering<PropertyTypeKey<T>>,
+              public TotalOrdering<PropertyFamilyKey, PropertyTypeKey<T>>,
+              public TotalOrdering<PropertyTypeKey<T>, PropertyFamilyKey>
+        {
+            friend class PropertyType;
+
+            PropertyTypeKey(const PropertyType &type) : type(type) {}
+        public:
+            PropertyFamilyKey family_key() { return PropertyFamilyKey(type); }
+
+            Type prop_type() const { return type.type; }
+
+            friend bool operator==(const PropertyTypeKey &lhs,
+                                   const PropertyTypeKey &rhs)
+            {
+                return &(lhs.type) == &(rhs.type);
+            }
+
+            friend bool operator<(const PropertyTypeKey &lhs,
+                                  const PropertyTypeKey &rhs)
+            {
+                return &(lhs.type) < &(rhs.type);
+            }
+
+            friend bool operator==(const PropertyFamilyKey &lhs,
+                                   const PropertyTypeKey &rhs)
+            {
+                return &(lhs.type->family) == &(rhs.type.family);
+            }
+
+            friend bool operator<(const PropertyFamilyKey &lhs,
+                                  const PropertyTypeKey &rhs)
+            {
+                return &(lhs.type->family) < &(rhs.type.family);
+            }
+
+            friend bool operator==(const PropertyTypeKey &lhs,
+                                   const PropertyFamilyKey &rhs)
+            {
+                return &(lhs.type.family) == &(rhs.type->family);
+            }
+
+            friend bool operator<(const PropertyTypeKey &lhs,
+                                  const PropertyFamilyKey &rhs)
+            {
+                return &(lhs.type.family) < &(rhs.type->family);
+            }
+
+        private:
+            const PropertyType &type;
+        };
+
+    private:
+        PropertyType(PropertyFamily &family, Type type);
+        PropertyType(PropertyFamily &other) = delete;
+        PropertyType(PropertyFamily &&other) = delete;
+
+    public:
+        template <class T>
+        bool is() const
+        {
+            return underlying_cast(type) & underlying_cast(T::type);
+        }
+
+        bool is(Type &t) const;
+
+        // Returns key ordered on POINTERS to PropertyType.
+        // When compared with PropertyFamilyKey behaves as PropertyFamilyKey.
+        template <class T>
+        PropertyTypeKey<T> type_key()
+        {
+            assert(this->is<T>());
+            return PropertyTypeKey<T>(*this);
+        }
+
+        // Returns key ordered on POINTERS to PropertyFamily
+        PropertyFamilyKey family_key();
+
+        friend bool operator<(const PropertyType &lhs, const PropertyType &rhs)
+        {
+            return lhs.family < rhs.family ||
+                   (lhs.family == rhs.family && lhs.type < rhs.type);
+        }
+
+        friend bool operator==(const PropertyType &lhs, const PropertyType &rhs)
+        {
+            return lhs.family == rhs.family && lhs.type == rhs.type;
+        }
+
+    private:
+        const PropertyFamily &family;
+        const Type type;
+    };
+
+    PropertyFamily(std::string const &name_v);
+    PropertyFamily(std::string &&name_v);
+    PropertyFamily(PropertyFamily &other) = delete;
+    PropertyFamily(PropertyFamily &&other) = delete;
+
+    std::string const &name() const;
+
+    // Returns type if it exists otherwise creates it.
+    PropertyType &get(Type type);
+
+    friend bool operator<(const PropertyFamily &lhs, const PropertyFamily &rhs);
+
+    friend bool operator==(const PropertyFamily &lhs,
+                           const PropertyFamily &rhs);
+
+private:
+    const std::string name_v;
+
+    // TODO: Because types wont be removed this could be done with more efficent
+    // data structure.
+    ConcurrentMap<Type, std::unique_ptr<PropertyType>> types;
+};
diff --git a/include/storage/model/properties/traversers/consolewriter.hpp b/include/storage/model/properties/traversers/consolewriter.hpp
index 8562fb2bb..dedc5eb4d 100644
--- a/include/storage/model/properties/traversers/consolewriter.hpp
+++ b/include/storage/model/properties/traversers/consolewriter.hpp
@@ -2,8 +2,8 @@
 
 #include <iostream>
 
-#include "storage/model/properties/properties.hpp"
 #include "storage/model/properties/handler.hpp"
+#include "storage/model/properties/properties.hpp"
 
 using std::cout;
 using std::endl;
@@ -13,12 +13,12 @@ class ConsoleWriter
 public:
     ConsoleWriter() {}
 
-    void handle(const std::string &key, const Property &value)
+    void handle(const prop_key_t &key, const Property &value)
     {
-        cout << "KEY: " << key << "; VALUE: ";
+        cout << "KEY: " << key.family_name() << "; VALUE: ";
 
         accept(value, *this);
-    
+
         // value.accept(*this);
 
         cout << endl;
diff --git a/include/storage/model/properties/traversers/jsonwriter.hpp b/include/storage/model/properties/traversers/jsonwriter.hpp
index 28d411ea3..3daabcbef 100644
--- a/include/storage/model/properties/traversers/jsonwriter.hpp
+++ b/include/storage/model/properties/traversers/jsonwriter.hpp
@@ -1,7 +1,7 @@
 #pragma once
 
-#include "storage/model/properties/properties.hpp"
 #include "storage/model/properties/handler.hpp"
+#include "storage/model/properties/properties.hpp"
 
 template <class Buffer>
 struct JsonWriter
@@ -9,13 +9,13 @@ struct JsonWriter
 public:
     JsonWriter(Buffer &buffer) : buffer(buffer) { buffer << '{'; };
 
-    void handle(const std::string &key, const Property &value)
+    void handle(const prop_key_t &key, const Property &value)
     {
         if (!first) buffer << ',';
 
         if (first) first = false;
 
-        buffer << '"' << key << "\":";
+        buffer << '"' << key.family_name() << "\":";
         // value.accept(*this);
         accept(value, *this);
     }
diff --git a/include/storage/record_accessor.hpp b/include/storage/record_accessor.hpp
index cb7350c1a..8928b90ad 100644
--- a/include/storage/record_accessor.hpp
+++ b/include/storage/record_accessor.hpp
@@ -2,8 +2,10 @@
 
 #include "database/db_transaction.hpp"
 #include "mvcc/version_list.hpp"
+#include "storage/indexes/index_record.hpp"
 #include "storage/model/properties/properties.hpp"
 #include "storage/model/properties/property.hpp"
+#include "storage/model/properties/property_family.hpp"
 #include "transactions/transaction.hpp"
 
 template <class T, class Derived, class vlist_t = mvcc::VersionList<T>>
@@ -57,30 +59,32 @@ public:
         return vlist->remove(record, db.trans);
     }
 
-    const Property &property(const std::string &key) const
-    {
-        return record->data.props.at(key);
-    }
+    const Property &at(prop_key_t &key) const { return properties().at(key); }
+
+    template <class V>
+    auto at(type_key_t<V> &key) const;
 
     template <class V, class... Args>
-    void property(const std::string &key, Args &&... args)
+    void set(type_key_t<V> &key, Args &&... args)
     {
-        record->data.props.template set<V>(key, std::forward<Args>(args)...);
+        properties().template set<V>(key, std::forward<Args>(args)...);
     }
 
-    void property(const std::string &key, Property::sptr value)
+    void set(prop_key_t &key, Property::sptr value)
     {
-        record->data.props.set(key, std::move(value));
+        properties().set(key, std::move(value));
+    }
+
+    void clear(prop_key_t &key) { properties().clear(key); }
+
+    template <class Handler>
+    void accept(Handler &handler) const
+    {
+        properties().template accept<Handler>(handler);
     }
 
     Properties &properties() const { return record->data.props; }
 
-    template <class V>
-    auto at(const std::string &key) const
-    {
-        return properties().at(key).template as<V>().value_ref();
-    }
-
     explicit operator bool() const { return record != nullptr; }
 
     T const *operator->() const { return record; }
@@ -99,6 +103,12 @@ public:
     }
 
 protected:
+    template <class K>
+    IndexRecord<T, K> create_ir(K &&key)
+    {
+        return IndexRecord<T, K>(std::move(key), record, vlist);
+    }
+
     T *record{nullptr};
     vlist_t *const vlist;
     DbTransaction &db;
diff --git a/include/storage/vertex_accessor.hpp b/include/storage/vertex_accessor.hpp
index 0222413ed..71b65d0c1 100644
--- a/include/storage/vertex_accessor.hpp
+++ b/include/storage/vertex_accessor.hpp
@@ -10,13 +10,23 @@ class Vertex::Accessor : public RecordAccessor<Vertex, Vertex::Accessor>
 public:
     using RecordAccessor::RecordAccessor;
 
+    static Vertex::Accessor create(Vertex *t, mvcc::VersionList<Vertex> *vlist,
+                                   DbTransaction &db)
+    {
+        return Vertex::Accessor(t, vlist, db);
+    }
+
     size_t out_degree() const;
 
     size_t in_degree() const;
 
     size_t degree() const;
 
-    void add_label(const Label &label);
+    // False if it's label with it already.
+    bool add_label(const Label &label);
+
+    // False if it doesn't have label.
+    bool remove_label(const Label &label);
 
     bool has_label(const Label &label) const;
 
diff --git a/include/storage/vertices.hpp b/include/storage/vertices.hpp
index 8f5b78299..616f63ed9 100644
--- a/include/storage/vertices.hpp
+++ b/include/storage/vertices.hpp
@@ -1,17 +1,24 @@
 #pragma once
 
+#include <memory>
+#include <string>
 #include "data_structures/concurrent/concurrent_map.hpp"
-#include "database/db_transaction.hpp"
+// #include "database/db_transaction.hpp"
 #include "storage/common.hpp"
-#include "storage/indexes/index.hpp"
-#include "storage/indexes/index_record_collection.hpp"
+// #include "storage/indexes/index.hpp"
+// #include "storage/indexes/index_record_collection.hpp"
+#include "storage/model/properties/property_family.hpp"
 #include "storage/vertex_accessor.hpp"
 #include "utils/option.hpp"
 
+class DbTransaction;
+
 class Vertices
 {
 public:
     using vertices_t = ConcurrentMap<uint64_t, VertexRecord>;
+    using prop_familys_t =
+        ConcurrentMap<std::string, std::unique_ptr<PropertyFamily>>;
 
     vertices_t::Accessor access();
 
@@ -20,13 +27,15 @@ public:
     // Creates new Vertex and returns filled Vertex::Accessor.
     Vertex::Accessor insert(DbTransaction &t);
 
-    void update_label_index(const Label &label,
-                            VertexIndexRecord &&index_record);
+    PropertyFamily &property_family_find_or_create(const std::string &name);
 
-    VertexIndexRecordCollection &find_label_index(const Label &label);
+    // prop_familys_t::Accessor property_family_access();
 
 private:
     vertices_t vertices;
-    Index<label_ref_t, VertexIndexRecordCollection> label_index;
+    // TODO: Because familys wont be removed this could be done with more
+    // efficent
+    // data structure.
+    prop_familys_t prop_familys;
     AtomicCounter<uint64_t> counter;
 };
diff --git a/include/utils/border.hpp b/include/utils/border.hpp
new file mode 100644
index 000000000..94e56a712
--- /dev/null
+++ b/include/utils/border.hpp
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "utils/option.hpp"
+
+// Defines Including as [ and Excluding < for ranges.
+enum BorderType
+{
+    Including = 0,
+    Excluding = 1,
+};
+
+template <class T>
+class Border
+{
+
+public:
+    Border() : key(Option<T>()), type(Including) {}
+    Border(T Tey, BorderType type) : key(Option<T>(std::move(key))), type(type)
+    {
+    }
+
+    // Border(Border &other) = default;
+    Border(Border &other) = default;
+    Border(Border &&other) = default;
+
+    Border &operator=(Border &&other) = default;
+    Border &operator=(Border &other) = default;
+
+    // true if no border or this>key or this>=key depends on border type.
+    bool operator>(const T &other) const
+    {
+        return !key.is_present() || key.get() > other ||
+               (type == Including && key.get() == other);
+    }
+
+    // true if no border or this<key or this<=key depends on border type.
+    bool operator<(const T &other) const
+    {
+        return !key.is_present() || key.get() < other ||
+               (type == Including && key.get() == other);
+    }
+
+    Option<T> key;
+    const BorderType type;
+};
+
+template <class T>
+auto make_inf_border()
+{
+    return Border<T>();
+}
diff --git a/include/utils/iterator/accessor.hpp b/include/utils/iterator/accessor.hpp
index 88d5f32b6..55dbddcc9 100644
--- a/include/utils/iterator/accessor.hpp
+++ b/include/utils/iterator/accessor.hpp
@@ -1,28 +1,35 @@
 #pragma once
 
-#include "utils/iterator/wrap.hpp"
+#include "utils/iterator/range_iterator.hpp"
 #include "utils/option.hpp"
 
 namespace iter
 {
+// Class which turns ranged iterator with next() into accessor.
+// T - type of return value
+// I - iterator type
 template <class T, class I>
 class OneTimeAccessor
 {
 public:
-    OneTimeAccessor() : it(Option<Wrap<T, I>>()) {}
-    OneTimeAccessor(I &&it) : it(Wrap<T, I>(std::move(it))) {}
+    OneTimeAccessor() : it(Option<RangeIterator<T, I>>()) {}
+    OneTimeAccessor(I &&it) : it(RangeIterator<T, I>(std::move(it))) {}
 
-    Wrap<T, I> begin() { return it.take(); }
+    RangeIterator<T, I> begin() { return it.take(); }
 
-    Wrap<T, I> end() { return Wrap<T, I>(); }
+    RangeIterator<T, I> end() { return RangeIterator<T, I>(); }
 
 private:
-    Option<Wrap<T, I>> it;
+    Option<RangeIterator<T, I>> it;
 };
 
 template <class I>
 auto make_one_time_accessor(I &&iter)
 {
+    // Because function isn't receving or in any way using type T from
+    // OneTimeAccessor compiler can't deduce it thats way there is decltype in
+    // construction of OneTimeAccessor. Resoulting type of iter.next().take() is
+    // T.
     return OneTimeAccessor<decltype(iter.next().take()), I>(std::move(iter));
 }
 }
diff --git a/include/utils/iterator/for_all.hpp b/include/utils/iterator/for_all.hpp
index ba5b8f2dc..b001cab7c 100644
--- a/include/utils/iterator/for_all.hpp
+++ b/include/utils/iterator/for_all.hpp
@@ -14,4 +14,14 @@ void for_all(I &&iter, C &&consumer)
         e = iter.next();
     }
 }
+
+template <class I, class C>
+void for_all(std::unique_ptr<I> &&iter, C &&consumer)
+{
+    auto e = iter->next();
+    while (e.is_present()) {
+        consumer(e.take());
+        e = iter->next();
+    }
+}
 }
diff --git a/include/utils/iterator/func_iterator.hpp b/include/utils/iterator/func_iterator.hpp
new file mode 100644
index 000000000..c420d9d8d
--- /dev/null
+++ b/include/utils/iterator/func_iterator.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include "utils/iterator/iterator_base.hpp"
+
+namespace iter
+{
+// Wraps function into interator with next().
+// T - type of return value
+// F - type of wraped function
+template <class T, class F>
+class FunctionIterator : public IteratorBase<T>
+{
+public:
+    FunctionIterator(F &&f) : func(std::move(f)) {}
+
+    Option<T> next() final { return func(); }
+
+private:
+    F func;
+};
+
+// Wraps function which returns options as an iterator.
+template <class F>
+auto make_iterator(F &&f)
+{
+    // Because function isn't receving or in any way using type T from
+    // FunctionIterator compiler can't deduce it thats way there is decltype in
+    // construction of FunctionIterator. Resoulting type of iter.next().take()
+    // is T.
+    return FunctionIterator<decltype(f().take()), F>(std::move(f));
+}
+}
diff --git a/include/utils/iterator/iter.hpp b/include/utils/iterator/iter.hpp
deleted file mode 100644
index cfb3c974a..000000000
--- a/include/utils/iterator/iter.hpp
+++ /dev/null
@@ -1,48 +0,0 @@
-#pragma once
-
-#include "utils/option.hpp"
-
-namespace iter
-{
-template <class T, class I, class A>
-class Iter
-{
-public:
-    Iter() = delete;
-
-    Iter(A &&acc) : begin(std::move(acc.begin())), acc(std::forward<A>(acc)) {}
-    // Iter(const Iter &other) = delete;
-    // Iter(Iter &&other) :
-    // begin(std::move(other.begin)),end(std::move(other.end)) {};
-
-    auto next()
-    {
-        if (begin != acc.end()) {
-            auto ret = Option<T>(&(*(begin.operator->())));
-            begin++;
-            return ret;
-        } else {
-            return Option<T>();
-        }
-    }
-
-private:
-    I begin;
-    A acc;
-};
-
-// TODO: Join to make functions into one
-template <class A>
-auto make_iter(A &&acc)
-{
-    return Iter<decltype(&(*(acc.begin().operator->()))), decltype(acc.begin()),
-                A>(std::move(acc));
-}
-
-template <class A>
-auto make_iter_ref(A &acc)
-{
-    return Iter<decltype(&(*(acc.begin().operator->()))), decltype(acc.begin()),
-                A &>(acc);
-}
-}
diff --git a/include/utils/iterator/iterator.hpp b/include/utils/iterator/iterator.hpp
index e3e8c1cd1..f91d4e9e2 100644
--- a/include/utils/iterator/iterator.hpp
+++ b/include/utils/iterator/iterator.hpp
@@ -2,6 +2,8 @@
 
 #include "utils/iterator/accessor.hpp"
 #include "utils/iterator/for_all.hpp"
-#include "utils/iterator/iter.hpp"
+#include "utils/iterator/func_iterator.hpp"
+#include "utils/iterator/iterator_accessor.hpp"
+#include "utils/iterator/iterator_base.hpp"
 #include "utils/iterator/map.hpp"
-#include "utils/iterator/wrap.hpp"
+#include "utils/iterator/range_iterator.hpp"
diff --git a/include/utils/iterator/iterator_accessor.hpp b/include/utils/iterator/iterator_accessor.hpp
new file mode 100644
index 000000000..794a9cf4a
--- /dev/null
+++ b/include/utils/iterator/iterator_accessor.hpp
@@ -0,0 +1,59 @@
+#pragma once
+
+#include "utils/iterator/iterator_base.hpp"
+#include "utils/option.hpp"
+
+namespace iter
+{
+
+// Class which turns accessor int next() based iterator.
+// T - type of return value
+// I - iterator type gotten from accessor
+// A - accessor type
+template <class T, class I, class A>
+class IteratorAccessor : public IteratorBase<T>
+{
+public:
+    IteratorAccessor() = delete;
+
+    IteratorAccessor(A &&acc)
+        : begin(std::move(acc.begin())), acc(std::forward<A>(acc))
+    {
+    }
+    // Iter(const Iter &other) = delete;
+    // Iter(Iter &&other) :
+    // begin(std::move(other.begin)),end(std::move(other.end)) {};
+
+    Option<T> next() final
+    {
+        if (begin != acc.end()) {
+            auto ret = Option<T>(&(*(begin.operator->())));
+            begin++;
+            return ret;
+        } else {
+            return Option<T>();
+        }
+    }
+
+private:
+    I begin;
+    A acc;
+};
+
+// TODO: Join to make functions into one
+template <class A>
+auto make_iter(A &&acc)
+{
+    // Compiler cant deduce types T and I. decltype are here to help with it.
+    return IteratorAccessor<decltype(&(*(acc.begin().operator->()))),
+                            decltype(acc.begin()), A>(std::move(acc));
+}
+
+template <class A>
+auto make_iter_ref(A &acc)
+{
+    // Compiler cant deduce types T and I. decltype are here to help with it.
+    return IteratorAccessor<decltype(&(*(acc.begin().operator->()))),
+                            decltype(acc.begin()), A &>(acc);
+}
+}
diff --git a/include/utils/iterator/iterator_base.hpp b/include/utils/iterator/iterator_base.hpp
new file mode 100644
index 000000000..0d805edfa
--- /dev/null
+++ b/include/utils/iterator/iterator_base.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "utils/option.hpp"
+
+// Base iterator for next() kind iterator.
+// T - type of return value
+template <class T>
+class IteratorBase
+{
+public:
+    virtual Option<T> next() = 0;
+};
diff --git a/include/utils/iterator/map.hpp b/include/utils/iterator/map.hpp
index 7bc8ba474..2f4543bcb 100644
--- a/include/utils/iterator/map.hpp
+++ b/include/utils/iterator/map.hpp
@@ -1,38 +1,47 @@
 #pragma once
 
+#include "utils/iterator/iterator_base.hpp"
 #include "utils/option.hpp"
 
 namespace iter
 {
-template <class U, class I, class MapOperator>
-class Map
+
+// Class which maps values returned by I iterator into value of type T with OP
+// function.
+// T - type of return value
+// I - iterator type
+// OP - type of mapper function
+template <class T, class I, class OP>
+class Map : public IteratorBase<T>
 {
 
 public:
     Map() = delete;
-    template <class IT, class OP>
-    Map(IT &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op))
-    {
-    }
 
-    auto next()
+    // Map operation is designed to be used in chained calls which operate on a
+    // iterator. Map will in that usecase receive other iterator by value and
+    // std::move is a optimization for it.
+    Map(I &&iter, OP &&op) : iter(std::move(iter)), op(std::move(op)) {}
+
+    Option<T> next() final
     {
         auto item = iter.next();
         if (item.is_present()) {
-            return Option<U>(op(item.take()));
+            return Option<T>(op(item.take()));
         } else {
-            return Option<U>();
+            return Option<T>();
         }
     }
 
 private:
     I iter;
-    MapOperator op;
+    OP op;
 };
 
 template <class I, class OP>
 auto make_map(I &&iter, OP &&op)
 {
+    // Compiler cant deduce type T. decltype is here to help with it.
     return Map<decltype(op(iter.next().take())), I, OP>(std::move(iter),
                                                         std::move(op));
 }
diff --git a/include/utils/iterator/range_iterator.hpp b/include/utils/iterator/range_iterator.hpp
new file mode 100644
index 000000000..923e9525c
--- /dev/null
+++ b/include/utils/iterator/range_iterator.hpp
@@ -0,0 +1,74 @@
+#pragma once
+
+#include "utils/option.hpp"
+
+namespace iter
+{
+
+// Class which wraps iterator with next() into c++ iterator.
+// T - type of return value
+// I - iterator type
+template <class T, class I>
+class RangeIterator
+{
+
+public:
+    RangeIterator() : iter(Option<I>()), value(Option<T>()){};
+
+    RangeIterator(I &&iter)
+        : value(iter.next()), iter(Option<I>(std::move(iter)))
+    {
+    }
+
+    T &operator*()
+    {
+        assert(value.is_present());
+        return value.get();
+    }
+
+    T *operator->()
+    {
+        assert(value.is_present());
+        return &value.get();
+    }
+
+    operator T &()
+    {
+        assert(value.is_present());
+        return value.get();
+    }
+
+    RangeIterator &operator++()
+    {
+        assert(iter.is_present());
+        value = iter.get().next();
+        return (*this);
+    }
+
+    RangeIterator &operator++(int) { return operator++(); }
+
+    friend bool operator==(const RangeIterator &a, const RangeIterator &b)
+    {
+        return a.value.is_present() == b.value.is_present();
+    }
+
+    friend bool operator!=(const RangeIterator &a, const RangeIterator &b)
+    {
+        return !(a == b);
+    }
+
+private:
+    Option<I> iter;
+    Option<T> value;
+};
+
+template <class I>
+auto make_range_iterator(I &&iter)
+{
+    // Because function isn't receving or in any way using type T from
+    // RangeIterator compiler can't deduce it thats way there is decltype in
+    // construction of RangeIterator. Resoulting type of iter.next().take() is
+    // T.
+    return RangeIterator<decltype(iter.next().take()), I>(std::move(iter));
+}
+}
diff --git a/include/utils/iterator/wrap.hpp b/include/utils/iterator/wrap.hpp
deleted file mode 100644
index a39fe6d2c..000000000
--- a/include/utils/iterator/wrap.hpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#pragma once
-
-#include "utils/option.hpp"
-
-namespace iter
-{
-template <class T, class I>
-class Wrap
-{
-
-public:
-    Wrap() : iter(Option<I>()), value(Option<T>()){};
-
-    Wrap(I &&iter) : value(iter.next()), iter(Option<I>(std::move(iter))) {}
-
-    T &operator*()
-    {
-        assert(value.is_present());
-        return value.get();
-    }
-
-    T *operator->()
-    {
-        assert(value.is_present());
-        return &value.get();
-    }
-
-    operator T &()
-    {
-        assert(value.is_present());
-        return value.get();
-    }
-
-    Wrap &operator++()
-    {
-        assert(iter.is_present());
-        value = iter.get().next();
-        return (*this);
-    }
-
-    Wrap &operator++(int) { return operator++(); }
-
-    friend bool operator==(const Wrap &a, const Wrap &b)
-    {
-        return a.value.is_present() == b.value.is_present();
-    }
-
-    friend bool operator!=(const Wrap &a, const Wrap &b) { return !(a == b); }
-
-private:
-    Option<I> iter;
-    Option<T> value;
-};
-
-template <class I>
-auto make_wrap(I &&iter)
-{
-    return Wrap<decltype(iter.next().take()), I>(std::move(iter));
-}
-}
diff --git a/include/utils/option.hpp b/include/utils/option.hpp
index 8e1b66d44..a3aae3c5f 100644
--- a/include/utils/option.hpp
+++ b/include/utils/option.hpp
@@ -1,5 +1,6 @@
 #pragma once
 
+#include <cassert>
 #include <ext/aligned_buffer.h>
 #include <utility>
 
@@ -8,6 +9,12 @@ class Option
 {
 public:
     Option() {}
+    //
+    // Option(T item)
+    // {
+    //     new (data._M_addr()) T(std::forward(item));
+    //     initialized = true;
+    // }
 
     Option(T const &item)
     {
@@ -22,6 +29,9 @@ public:
     }
 
     Option(Option &other) = default;
+    // Containers from std which have strong exception guarantees wont use move
+    // constructors and operators wihtout noexcept. "Optimized C++,2016 , Kurt
+    // Guntheroth, page: 142, title: Moving instances into std::vector"
     Option(Option &&other) noexcept
     {
         if (other.initialized) {
@@ -36,7 +46,8 @@ public:
         if (initialized) get().~T();
     }
 
-    Option<T> &operator=(Option<T> &&other)
+    Option &operator=(Option &other) = default;
+    Option &operator=(Option &&other)
     {
         if (initialized) {
             get().~T();
@@ -60,7 +71,11 @@ public:
         return *data._M_ptr();
     }
 
-    const T &get() const noexcept { assert(initialized); }
+    const T &get() const noexcept
+    {
+        assert(initialized);
+        return *data._M_ptr();
+    }
 
     T take()
     {
@@ -72,6 +87,9 @@ public:
     explicit operator bool() const { return initialized; }
 
 private:
+    // Aligned buffer is here to ensure aligment for data of type T. It isn't
+    // applicable to just put T field because the field has to be able to be
+    // uninitialized to fulfill the semantics of Option class.
     __gnu_cxx::__aligned_buffer<T> data;
     bool initialized = false;
 };
diff --git a/include/utils/void.hpp b/include/utils/void.hpp
new file mode 100644
index 000000000..ff36ff3b1
--- /dev/null
+++ b/include/utils/void.hpp
@@ -0,0 +1,10 @@
+#pragma once
+
+#include "utils/total_ordering.hpp"
+
+class Void : public TotalOrdering<Void>
+{
+    friend bool operator<(const Void &lhs, const Void &rhs) { return false; }
+
+    friend bool operator==(const Void &lhs, const Void &rhs) { return true; }
+};
diff --git a/poc/astar.cpp b/poc/astar.cpp
index 7e9be0e03..1490efb31 100644
--- a/poc/astar.cpp
+++ b/poc/astar.cpp
@@ -11,8 +11,15 @@
 #include "data_structures/map/rh_hashmap.hpp"
 #include "database/db.hpp"
 #include "database/db_accessor.hpp"
+#include "storage/edges.cpp"
+#include "storage/edges.hpp"
+#include "storage/indexes/impl/nonunique_unordered_index.cpp"
+#include "storage/model/properties/properties.cpp"
+#include "storage/record_accessor.cpp"
 #include "storage/vertex_accessor.cpp"
 #include "storage/vertex_accessor.hpp"
+#include "storage/vertices.cpp"
+#include "storage/vertices.hpp"
 
 using namespace std;
 typedef Vertex::Accessor VertexAccessor;
@@ -23,13 +30,19 @@ class Node
 {
 public:
     Node *parent = {nullptr};
+    type_key_t<Double> tkey;
     double cost;
     int depth = {0};
     VertexAccessor vacc;
 
-    Node(VertexAccessor vacc, double cost) : cost(cost), vacc(vacc) {}
-    Node(VertexAccessor vacc, double cost, Node *parent)
-        : cost(cost), vacc(vacc), parent(parent), depth(parent->depth + 1)
+    Node(VertexAccessor vacc, double cost, type_key_t<Double> tkey)
+        : cost(cost), vacc(vacc), tkey(tkey)
+    {
+    }
+    Node(VertexAccessor vacc, double cost, Node *parent,
+         type_key_t<Double> tkey)
+        : cost(cost), vacc(vacc), parent(parent), depth(parent->depth + 1),
+          tkey(tkey)
     {
     }
 
@@ -38,7 +51,7 @@ public:
         auto now = this;
         double sum = 0;
         do {
-            sum += now->vacc.at<Double>("score");
+            sum += *(now->vacc.at(tkey).get());
             now = now->parent;
         } while (now != nullptr);
         return sum;
@@ -105,10 +118,11 @@ void found_result(Node *res)
     }
 }
 
-double calc_heuristic_cost_dummy(Edge::Accessor &edge, Vertex::Accessor &vertex)
+double calc_heuristic_cost_dummy(type_key_t<Double> tkey, Edge::Accessor &edge,
+                                 Vertex::Accessor &vertex)
 {
     assert(!vertex.empty());
-    return 1 - vertex.at<Double>("score");
+    return 1 - *vertex.at(tkey).get();
 }
 
 typedef bool (*EdgeFilter)(DbAccessor &t, Edge::Accessor &, Node *before);
@@ -168,11 +182,16 @@ bool vertex_filter_contained(DbAccessor &t, Vertex::Accessor &v, Node *before)
 // Filtri vracaju true ako element zadovoljava uvjete.
 auto a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
             VertexFilter v_filter[],
-            double (*calc_heuristic_cost)(Edge::Accessor &edge,
+            double (*calc_heuristic_cost)(type_key_t<Double> tkey,
+                                          Edge::Accessor &edge,
                                           Vertex::Accessor &vertex),
             int limit)
 {
     DbAccessor t(db);
+    type_key_t<Double> tkey = t.vertex_property_family_get("score")
+                                  .get(Type::Double)
+                                  .type_key<Double>();
+
     auto best_found = new std::map<Id, Score>[max_depth];
 
     std::vector<Node *> best;
@@ -182,7 +201,7 @@ auto a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
     auto start_vr = t.vertex_find(sys_id_start);
     assert(start_vr);
     start_vr.get().fill();
-    Node *start = new Node(start_vr.take(), 0);
+    Node *start = new Node(start_vr.take(), 0, tkey);
     queue.push(start);
     int count = 0;
     do {
@@ -213,8 +232,8 @@ auto a_star(Db &db, int64_t sys_id_start, uint max_depth, EdgeFilter e_filter[],
             if (e_filter[now->depth](t, edge, now)) {
                 VertexAccessor va = edge.to();
                 if (v_filter[now->depth](t, va, now)) {
-                    auto cost = calc_heuristic_cost(edge, va);
-                    Node *n = new Node(va, now->cost + cost, now);
+                    auto cost = calc_heuristic_cost(tkey, edge, va);
+                    Node *n = new Node(va, now->cost + cost, now, tkey);
                     queue.push(n);
                 }
             }
@@ -346,6 +365,18 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
     std::string line;
 
     DbAccessor t(db);
+    auto key_id =
+        t.vertex_property_family_get("id").get(Type::Int32).family_key();
+    auto key_garment_id = t.vertex_property_family_get("garment_id")
+                              .get(Type::Int32)
+                              .family_key();
+    auto key_garment_category_id =
+        t.vertex_property_family_get("garment_category_id")
+            .get(Type::Int32)
+            .family_key();
+    auto key_score =
+        t.vertex_property_family_get("score").get(Type::Double).family_key();
+
     int max_score = 1000000;
 
     // VERTEX import
@@ -356,14 +387,15 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
         }
 
         auto vertex_accessor = t.vertex_insert();
-        vertex_accessor.property("id", std::make_shared<Int32>(id));
-        vertex_accessor.property("garment_id", std::make_shared<Int32>(gar_id));
-        vertex_accessor.property("garment_category_id",
-                                 std::make_shared<Int32>(cat_id));
+        vertex_accessor.set(key_id, std::make_shared<Int32>(id));
+        vertex_accessor.set(key_garment_id, std::make_shared<Int32>(gar_id));
+        vertex_accessor.set(key_garment_category_id,
+                            std::make_shared<Int32>(cat_id));
         std::srand(id ^ 0x7482616);
-        vertex_accessor.property(
-            "score", std::make_shared<Double>((std::rand() % max_score) /
-                                              (max_score + 0.0)));
+        vertex_accessor.set(key_score,
+                            std::make_shared<Double>((std::rand() % max_score) /
+                                                     (max_score + 0.0)));
+
         for (auto l_name : labels) {
             auto &label = t.label_find_or_create(l_name);
             vertex_accessor.add_label(label);
@@ -372,6 +404,7 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
         return vertex_accessor;
     };
 
+    // Skip header
     std::getline(file, line);
 
     vector<Vertex::Accessor> va;
@@ -423,39 +456,39 @@ int load_csv(Db &db, char *file_path, char *edge_file_path)
 void load_graph_dummy(Db &db)
 {
     DbAccessor t(db);
-    auto v = [&](auto id, auto score) {
-        auto vertex_accessor = t.vertex_insert();
-        vertex_accessor.property("id", std::make_shared<Int32>(id));
-        vertex_accessor.property("score", std::make_shared<Double>(score));
-        return vertex_accessor.id();
-    };
-
-    Id va[] = {
-        v(0, 0.5), v(1, 1), v(2, 0.3), v(3, 0.15), v(4, 0.8), v(5, 0.8),
-    };
-
-    auto e = [&](auto from, auto type, auto to) {
-        auto v1 = t.vertex_find(va[from]);
-
-        auto v2 = t.vertex_find(va[to]);
-
-        auto edge_accessor = t.edge_insert(v1.get(), v2.get());
-
-        auto &edge_type = t.type_find_or_create(type);
-        edge_accessor.edge_type(edge_type);
-    };
-
-    e(0, "ok", 3);
-    e(0, "ok", 2);
-    e(0, "ok", 4);
-    e(1, "ok", 3);
-    e(2, "ok", 1);
-    e(2, "ok", 4);
-    e(3, "ok", 4);
-    e(3, "ok", 5);
-    e(4, "ok", 0);
-    e(4, "ok", 1);
-    e(5, "ok", 2);
+    // auto v = [&](auto id, auto score) {
+    //     auto vertex_accessor = t.vertex_insert();
+    //     vertex_accessor.property("id", std::make_shared<Int32>(id));
+    //     vertex_accessor.property("score", std::make_shared<Double>(score));
+    //     return vertex_accessor.id();
+    // };
+    //
+    // Id va[] = {
+    //     v(0, 0.5), v(1, 1), v(2, 0.3), v(3, 0.15), v(4, 0.8), v(5, 0.8),
+    // };
+    //
+    // auto e = [&](auto from, auto type, auto to) {
+    //     auto v1 = t.vertex_find(va[from]);
+    //
+    //     auto v2 = t.vertex_find(va[to]);
+    //
+    //     auto edge_accessor = t.edge_insert(v1.get(), v2.get());
+    //
+    //     auto &edge_type = t.type_find_or_create(type);
+    //     edge_accessor.edge_type(edge_type);
+    // };
+    //
+    // e(0, "ok", 3);
+    // e(0, "ok", 2);
+    // e(0, "ok", 4);
+    // e(1, "ok", 3);
+    // e(2, "ok", 1);
+    // e(2, "ok", 4);
+    // e(3, "ok", 4);
+    // e(3, "ok", 5);
+    // e(4, "ok", 0);
+    // e(4, "ok", 1);
+    // e(5, "ok", 2);
 
     t.commit();
 }
diff --git a/src/data_structures/map/rh_common.hpp b/src/data_structures/map/rh_common.hpp
index 69593bdb0..9fa396e30 100644
--- a/src/data_structures/map/rh_common.hpp
+++ b/src/data_structures/map/rh_common.hpp
@@ -187,22 +187,26 @@ public:
 
     RhBase() {}
 
-    RhBase(const RhBase &other)
-    {
-        capacity = other.capacity;
-        count = other.count;
-        if (capacity > 0) {
-            size_t bytes = sizeof(Combined) * capacity;
-            array = (Combined *)malloc(bytes);
-            memcpy(array, other.array, bytes);
+    RhBase(const RhBase &other) { copy_from(other); }
 
-        } else {
-            array = nullptr;
-        }
-    }
+    RhBase(RhBase &&other) { take_from(std::move(other)); }
 
     ~RhBase() { this->clear(); }
 
+    RhBase &operator=(const RhBase &other)
+    {
+        clear();
+        copy_from(other);
+        return *this;
+    }
+
+    RhBase &operator=(RhBase &&other)
+    {
+        clear();
+        take_from(std::move(other));
+        return *this;
+    }
+
     Iterator begin() { return Iterator(this); }
 
     ConstIterator begin() const { return ConstIterator(this); }
@@ -216,6 +220,30 @@ public:
     ConstIterator cend() const { return ConstIterator(); }
 
 protected:
+    void copy_from(const RhBase &other)
+    {
+        capacity = other.capacity;
+        count = other.count;
+        if (capacity > 0) {
+            size_t bytes = sizeof(Combined) * capacity;
+            array = (Combined *)malloc(bytes);
+            memcpy(array, other.array, bytes);
+
+        } else {
+            array = nullptr;
+        }
+    }
+
+    void take_from(RhBase &&other)
+    {
+        capacity = other.capacity;
+        count = other.count;
+        array = other.array;
+        other.array = nullptr;
+        other.count = 0;
+        other.capacity = 0;
+    }
+
     void init_array(size_t size)
     {
         size_t bytes = sizeof(Combined) * size;
diff --git a/src/database/db.cpp b/src/database/db.cpp
index 9ceb50a77..df9abaa74 100644
--- a/src/database/db.cpp
+++ b/src/database/db.cpp
@@ -1,4 +1,5 @@
 #include "database/db.hpp"
+#include "storage/model/properties/property_family.hpp"
 
 Db::Db() = default;
 Db::Db(const std::string &name) : name_(name) {}
diff --git a/src/database/db_accessor.cpp b/src/database/db_accessor.cpp
index b3972e29a..ca07dc89a 100644
--- a/src/database/db_accessor.cpp
+++ b/src/database/db_accessor.cpp
@@ -1,36 +1,46 @@
 #include "database/db_accessor.hpp"
 
-DbAccessor::DbAccessor(Db &db) : db(DbTransaction(db, db.tx_engine.begin())) {}
+#include "database/db.hpp"
+
+#include "utils/iterator/iterator.hpp"
+
+DbAccessor::DbAccessor(Db &db)
+    : db_transaction(DbTransaction(db, db.tx_engine.begin()))
+{
+}
 
 // VERTEX METHODS
 auto DbAccessor::vertex_access()
 {
     return iter::make_map(
-        iter::make_iter(this->db.db.graph.vertices.access()),
-        [&](auto e) -> auto { return Vertex::Accessor(&(e->second), db); });
+        iter::make_iter(this->db_transaction.db.graph.vertices.access()),
+        [&](auto e) -> auto {
+            return Vertex::Accessor(&(e->second), db_transaction);
+        });
 }
 
 Option<const Vertex::Accessor> DbAccessor::vertex_find(const Id &id)
 {
-    return this->db.db.graph.vertices.find(db, id);
+    return this->db_transaction.db.graph.vertices.find(db_transaction, id);
 }
 
 Vertex::Accessor DbAccessor::vertex_insert()
 {
-    return this->db.db.graph.vertices.insert(db);
+    return this->db_transaction.db.graph.vertices.insert(db_transaction);
 }
 
 // EDGE METHODS
 
 Option<const Edge::Accessor> DbAccessor::edge_find(const Id &id)
 {
-    return db.db.graph.edges.find(db, id);
+    return db_transaction.db.graph.edges.find(db_transaction, id);
 }
 
 Edge::Accessor DbAccessor::edge_insert(Vertex::Accessor const &from,
                                        Vertex::Accessor const &to)
 {
-    auto edge_accessor = db.db.graph.edges.insert(db, from.vlist, to.vlist);
+    auto edge_accessor = db_transaction.db.graph.edges.insert(
+        db_transaction, from.vlist, to.vlist);
     from.update()->data.out.add(edge_accessor.vlist);
     to.update()->data.in.add(edge_accessor.vlist);
     return edge_accessor;
@@ -39,37 +49,57 @@ Edge::Accessor DbAccessor::edge_insert(Vertex::Accessor const &from,
 // LABEL METHODS
 const Label &DbAccessor::label_find_or_create(const std::string &name)
 {
-    return db.db.graph.label_store.find_or_create(
+    return db_transaction.db.graph.label_store.find_or_create(
         std::forward<const std::string &>(name));
 }
 
 bool DbAccessor::label_contains(const std::string &name)
 {
-    return db.db.graph.label_store.contains(
+    return db_transaction.db.graph.label_store.contains(
         std::forward<const std::string &>(name));
 }
 
-VertexIndexRecordCollection &DbAccessor::label_find_index(const Label &label)
-{
-    return db.db.graph.vertices.find_label_index(label);
-}
-
 // TYPE METHODS
 const EdgeType &DbAccessor::type_find_or_create(const std::string &name)
 {
-    return db.db.graph.edge_type_store.find_or_create(
+    return db_transaction.db.graph.edge_type_store.find_or_create(
         std::forward<const std::string &>(name));
 }
 
 bool DbAccessor::type_contains(const std::string &name)
 {
-    return db.db.graph.edge_type_store.contains(
+    return db_transaction.db.graph.edge_type_store.contains(
         std::forward<const std::string &>(name));
 }
 
+//********************PROPERTY METHODS
+// Vertices::prop_familys_t::Accessor
+// DbAccessor::vertex_property_family_access()
+// {
+//     return db.db.graph.vertices.property_family_access();
+// }
+//
+// auto DbAccessor::edge_property_family_access()
+// {
+//     return db.db.graph.edges.property_family_access();
+// }
+
+auto edge_property_family_access();
+
+PropertyFamily &DbAccessor::vertex_property_family_get(const std::string &name)
+{
+    return db_transaction.db.graph.vertices.property_family_find_or_create(
+        name);
+}
+
+PropertyFamily &DbAccessor::edge_property_family_get(const std::string &name)
+{
+    return db_transaction.db.graph.edges.property_family_find_or_create(name);
+}
+
 // TRANSACTION METHODS
-void DbAccessor::commit() { db.trans.commit(); }
-void DbAccessor::abort() { db.trans.abort(); }
+void DbAccessor::commit() { db_transaction.trans.commit(); }
+void DbAccessor::abort() { db_transaction.trans.abort(); }
 
 // // EASE OF USE METHODS
 // tx::Transaction &DbAccessor::operator*() { return db.trans; }
diff --git a/src/database/db_transaction.cpp b/src/database/db_transaction.cpp
index 3760ce479..c16be5e5f 100644
--- a/src/database/db_transaction.cpp
+++ b/src/database/db_transaction.cpp
@@ -1,8 +1,2 @@
-#include "database/db.hpp"
-#include "database/db_transaction.hpp"
-
-void DbTransaction::update_label_index(const Label &label,
-                                       VertexIndexRecord &&index_record)
-{
-    db.graph.vertices.update_label_index(label, std::move(index_record));
-}
+// #include "database/db.hpp"
+// #include "database/db_transaction.hpp"
diff --git a/src/query_engine/util.cpp b/src/query_engine/util.cpp
index 9a980826e..2efcaf5f3 100644
--- a/src/query_engine/util.cpp
+++ b/src/query_engine/util.cpp
@@ -15,7 +15,7 @@ void cout_properties(const Properties &properties)
     cout << "----" << endl;
 }
 
-void cout_property(const std::string &key, const Property &property)
+void cout_property(const prop_key_t &key, const Property &property)
 {
     ConsoleWriter writer;
     writer.handle(key, property);
diff --git a/src/storage/edges.cpp b/src/storage/edges.cpp
index 5c142e9a8..3c5a3bfe1 100644
--- a/src/storage/edges.cpp
+++ b/src/storage/edges.cpp
@@ -1,4 +1,6 @@
 #include "storage/edges.hpp"
+#include "storage/model/properties/property_family.hpp"
+#include "utils/iterator/iterator.hpp"
 
 Option<const Edge::Accessor> Edges::find(DbTransaction &t, const Id &id)
 {
@@ -30,3 +32,25 @@ Edge::Accessor Edges::insert(DbTransaction &t, VertexRecord *from,
 
     return Edge::Accessor(edge, &inserted_edge_record->second, t);
 }
+
+// auto Edges::property_family_access()
+// { // Returnig access directly would allow extern code to remove elements.
+// Which
+//     // would be BAD, VERY BAD.
+//     return iter::make_iter(prop_familys.access());
+// }
+
+PropertyFamily &Edges::property_family_find_or_create(const std::string &name)
+{
+    auto acc = prop_familys.access();
+    auto it = acc.find(name);
+    if (it == acc.end()) {
+        PropertyFamily *family = new PropertyFamily(name);
+        auto res = acc.insert(name, family);
+        if (!res.second) {
+            delete family;
+        }
+        it = res.first;
+    }
+    return *(it->second);
+}
diff --git a/src/storage/indexes/impl/nonunique_unordered_index.cpp b/src/storage/indexes/impl/nonunique_unordered_index.cpp
new file mode 100644
index 000000000..7278d3dc4
--- /dev/null
+++ b/src/storage/indexes/impl/nonunique_unordered_index.cpp
@@ -0,0 +1,61 @@
+#include "storage/indexes/impl/nonunique_unordered_index.hpp"
+
+#include "database/db_accessor.hpp"
+#include "database/db_transaction.hpp"
+#include "utils/iterator/iterator.hpp"
+
+template <class T, class K>
+NonUniqueUnorderedIndex<T, K>::NonUniqueUnorderedIndex()
+    : IndexBase<T, K>(false, None)
+{
+}
+
+template <class T, class K>
+bool NonUniqueUnorderedIndex<T, K>::insert(IndexRecord<T, K> &&value)
+{
+    list.begin().push(std::move(value));
+    return true;
+}
+
+template <class T, class K>
+std::unique_ptr<IteratorBase<const typename T::Accessor>>
+NonUniqueUnorderedIndex<T, K>::for_range(DbAccessor &t, Border<K> from,
+                                         Border<K> to)
+{
+    return std::make_unique<decltype(
+        for_range_exact(t, std::move(from), std::move(to)))>(
+        for_range_exact(t, std::move(from), std::move(to)));
+}
+
+template <class T, class K>
+auto NonUniqueUnorderedIndex<T, K>::for_range_exact(DbAccessor &t_v,
+                                                    Border<K> from_v,
+                                                    Border<K> to_v)
+{
+    return iter::make_iterator([
+        it = list.cbegin(), end = list.cend(), from = from_v, to = to_v, t = t_v
+    ]() mutable->auto {
+        while (it != end) {
+            const IndexRecord<T, K> &r = *it;
+            if (from < r.key && to > r.key &&
+                r.is_valid(t.db_transaction.trans)) {
+                const typename T::Accessor acc = r.access(t.db_transaction);
+                it++;
+                return make_option(std::move(acc));
+            }
+            it++;
+        }
+
+        return Option<const typename T::Accessor>();
+    });
+}
+
+template <class T, class K>
+void NonUniqueUnorderedIndex<T, K>::clean(DbTransaction &)
+{
+    // TODO: Actual cleaning
+}
+
+#include "storage/vertex.hpp"
+// #include "utils/singleton.hpp"
+template class NonUniqueUnorderedIndex<Vertex, std::nullptr_t>;
diff --git a/src/storage/label/label.cpp b/src/storage/label/label.cpp
index 9e0b8228f..b669fcc56 100644
--- a/src/storage/label/label.cpp
+++ b/src/storage/label/label.cpp
@@ -1,24 +1,29 @@
+// #include "storage/indexes/impl/nonunique_unordered_index.hpp"
 #include "storage/label/label.hpp"
 
-Label::Label(const std::string& name) : name(name) {}
-Label::Label(std::string&& name) : name(std::move(name)) {}
+Label::Label(const std::string &name)
+    : name(name), index(std::unique_ptr<label_index_t>(new label_index_t()))
+{
+}
+Label::Label(std::string &&name)
+    : name(std::move(name)),
+      index(std::unique_ptr<label_index_t>(new label_index_t()))
+{
+}
 
-bool operator<(const Label& lhs, const Label& rhs)
+bool operator<(const Label &lhs, const Label &rhs)
 {
     return lhs.name < rhs.name;
 }
 
-bool operator==(const Label& lhs, const Label& rhs)
+bool operator==(const Label &lhs, const Label &rhs)
 {
     return lhs.name == rhs.name;
 }
 
-std::ostream& operator<<(std::ostream& stream, const Label& label)
+std::ostream &operator<<(std::ostream &stream, const Label &label)
 {
     return stream << label.name;
 }
 
-Label::operator const std::string&() const
-{
-    return name;
-}
+Label::operator const std::string &() const { return name; }
diff --git a/src/storage/label/label_collection.cpp b/src/storage/label/label_collection.cpp
index 3131ce5b2..22a77380a 100644
--- a/src/storage/label/label_collection.cpp
+++ b/src/storage/label/label_collection.cpp
@@ -1,5 +1,7 @@
 #include "storage/label/label_collection.hpp"
 
+#include "storage/label/label.hpp"
+
 auto LabelCollection::begin() { return _labels.begin(); }
 auto LabelCollection::begin() const { return _labels.begin(); }
 auto LabelCollection::cbegin() const { return _labels.begin(); }
@@ -8,36 +10,30 @@ auto LabelCollection::end() { return _labels.end(); }
 auto LabelCollection::end() const { return _labels.end(); }
 auto LabelCollection::cend() const { return _labels.end(); }
 
-bool LabelCollection::add(const Label& label)
+bool LabelCollection::add(const Label &label)
 {
     return _labels.insert(label_ref_t(label)).second;
 }
 
-bool LabelCollection::has(const Label& label) const
+bool LabelCollection::has(const Label &label) const
 {
     return _labels.count(label);
 }
 
-size_t LabelCollection::count() const {
-    return _labels.size();
-}
+size_t LabelCollection::count() const { return _labels.size(); }
 
-bool LabelCollection::remove(const Label& label)
+bool LabelCollection::remove(const Label &label)
 {
     auto it = _labels.find(label);
 
-    if(it == _labels.end())
-        return false;
+    if (it == _labels.end()) return false;
 
     return _labels.erase(it), true;
 }
 
-void LabelCollection::clear()
-{
-    _labels.clear();
-}
+void LabelCollection::clear() { _labels.clear(); }
 
-const std::set<label_ref_t>& LabelCollection::operator()() const
+const std::set<label_ref_t> &LabelCollection::operator()() const
 {
     return _labels;
 }
diff --git a/src/storage/model/properties/properties.cpp b/src/storage/model/properties/properties.cpp
index c4dec594d..0f3110427 100644
--- a/src/storage/model/properties/properties.cpp
+++ b/src/storage/model/properties/properties.cpp
@@ -1,54 +1,76 @@
 #include "storage/model/properties/properties.hpp"
 
 #include "storage/model/properties/null.hpp"
+#include "storage/model/properties/property_family.hpp"
+#include "utils/option.hpp"
 
-const Property& Properties::at(const std::string& key) const
+const Property &Properties::at(prop_key_t &key) const
 {
     auto it = props.find(key);
 
-    if(it == props.end())
-        return Property::Null;
+    if (it == props.end()) return Property::Null;
 
     return *it->second.get();
 }
 
+template <class T>
+auto Properties::at(type_key_t<T> &key) const
+{
+    auto f_key = key.family_key();
+    auto it = props.find(f_key);
+
+    if (it == props.end() || it->first.prop_type() != key.prop_type())
+        return Option<decltype(
+            &(it->second.get()->template as<T>().value_ref()))>();
+
+    return make_option(&(it->second.get()->template as<T>().value_ref()));
+}
+
 template <class T, class... Args>
-void Properties::set(const std::string& key, Args&&... args)
+void Properties::set(type_key_t<T> &key, Args &&... args)
 {
     auto value = std::make_shared<T>(std::forward<Args>(args)...);
 
     // try to emplace the item
+    // TODO: There is uneccesary copying of value here.
     auto result = props.emplace(std::make_pair(key, value));
 
-    // return if we succedded
-    if(result.second)
-        return;
-
-    // the key already exists, replace the value it holds
-    result.first->second = std::move(value);
+    if (!result.second) {
+        // It is necessary to change key because the types from before and now
+        // could be different.
+        prop_key_t &key_ref = const_cast<prop_key_t &>(result.first->first);
+        key_ref = key;
+        result.first->second = std::move(value);
+    }
 }
 
-void Properties::set(const std::string& key, Property::sptr value)
+void Properties::set(prop_key_t &key, Property::sptr value)
 {
-    props[key] = std::move(value);
+    // TODO: There is uneccesary copying of value here.
+    auto result = props.insert(make_pair(key, value));
+    if (!result.second) {
+        // It is necessary to change key because the types from before and now
+        // could be different.
+        prop_key_t &key_ref = const_cast<prop_key_t &>(result.first->first);
+        key_ref = key;
+        result.first->second = std::move(value);
+    }
 }
 
-void Properties::clear(const std::string& key)
-{
-    props.erase(key);
-}
+void Properties::clear(prop_key_t &key) { props.erase(key); }
 
 // template <class Handler>
 // void Properties::accept(Handler& handler) const
 // {
 //     for(auto& kv : props)
 //         handler.handle(kv.first, *kv.second);
-// 
+//
 //     handler.finish();
 // }
 
-template<>
-inline void Properties::set<Null>(const std::string& key)
+template <>
+inline void Properties::set<Null>(type_key_t<Null> &key)
 {
-    clear(key);
+    auto fk = key.family_key();
+    clear(fk);
 }
diff --git a/src/storage/model/properties/property_family.cpp b/src/storage/model/properties/property_family.cpp
new file mode 100644
index 000000000..c6bc34dea
--- /dev/null
+++ b/src/storage/model/properties/property_family.cpp
@@ -0,0 +1,39 @@
+#include "storage/model/properties/property_family.hpp"
+
+PropertyFamily::PropertyFamily(std::string const &name_v)
+    : name_v(std::forward<const std::string>(name_v))
+{
+}
+PropertyFamily::PropertyFamily(std::string &&name_v) : name_v(std::move(name_v))
+{
+}
+
+std::string const &PropertyFamily::name() const { return name_v; }
+
+// Returns type if it exists otherwise creates it.
+PropertyFamily::PropertyType &PropertyFamily::get(Type type)
+{
+    auto acc = types.access();
+    auto it = acc.find(type);
+    if (it == acc.end()) {
+        auto value =
+            std::unique_ptr<PropertyType>(new PropertyType(*this, type));
+        auto res = acc.insert(type, std::move(value));
+        it = res.first;
+    }
+    return *(it->second);
+}
+
+PropertyFamily::PropertyType::PropertyType(PropertyFamily &family, Type type)
+    : family(family), type(std::move(type))
+{
+}
+
+bool PropertyFamily::PropertyType::is(Type &t) const { return type == t; }
+
+// Returns key ordered on POINTERS to PropertyFamily
+PropertyFamily::PropertyType::PropertyFamilyKey
+PropertyFamily::PropertyType::family_key()
+{
+    return PropertyFamilyKey(*this);
+}
diff --git a/src/storage/record_accessor.cpp b/src/storage/record_accessor.cpp
new file mode 100644
index 000000000..21198de4c
--- /dev/null
+++ b/src/storage/record_accessor.cpp
@@ -0,0 +1,8 @@
+#include "storage/record_accessor.hpp"
+
+template <class T, class Derived, class vlist_t>
+template <class V>
+auto RecordAccessor<T, Derived, vlist_t>::at(type_key_t<V> &key) const
+{
+    return properties().template at<V>(key);
+}
diff --git a/src/storage/vertex_accessor.cpp b/src/storage/vertex_accessor.cpp
index 250910689..ab27a5b3a 100644
--- a/src/storage/vertex_accessor.cpp
+++ b/src/storage/vertex_accessor.cpp
@@ -15,14 +15,20 @@ size_t Vertex::Accessor::in_degree() const
 
 size_t Vertex::Accessor::degree() const { return in_degree() + out_degree(); }
 
-void Vertex::Accessor::add_label(const Label &label)
+bool Vertex::Accessor::add_label(const Label &label)
 {
     // update vertex
-    this->record->data.labels.add(label);
+    if (this->record->data.labels.add(label)) {
+        label.index->insert(create_ir(std::nullptr_t()));
+        return true;
+    }
+    return false;
+}
 
-    // update index
-    this->db.update_label_index(label,
-                                VertexIndexRecord(this->record, this->vlist));
+bool Vertex::Accessor::remove_label(const Label &label)
+{
+    // update vertex
+    return this->record->data.labels.remove(label);
 }
 
 bool Vertex::Accessor::has_label(const Label &label) const
diff --git a/src/storage/vertices.cpp b/src/storage/vertices.cpp
index a6cf69c9a..84aaee3e2 100644
--- a/src/storage/vertices.cpp
+++ b/src/storage/vertices.cpp
@@ -1,4 +1,5 @@
 #include "storage/vertices.hpp"
+#include "utils/iterator/iterator.hpp"
 
 Vertices::vertices_t::Accessor Vertices::access() { return vertices.access(); }
 
@@ -33,13 +34,21 @@ Vertex::Accessor Vertices::insert(DbTransaction &t)
     return Vertex::Accessor(vertex, &inserted_vertex_record->second, t);
 }
 
-void Vertices::update_label_index(const Label &label,
-                                  VertexIndexRecord &&index_record)
-{
-    label_index.update(label, std::forward<VertexIndexRecord>(index_record));
-}
+//
+// Vertices::prop_familys_t::Accessor Vertices::property_family_access()
+// {
+//     return prop_familys.access();
+// }
 
-VertexIndexRecordCollection &Vertices::find_label_index(const Label &label)
+PropertyFamily &
+Vertices::property_family_find_or_create(const std::string &name)
 {
-    return label_index.find(label);
+    auto acc = prop_familys.access();
+    auto it = acc.find(name);
+    if (it == acc.end()) {
+        auto family = std::unique_ptr<PropertyFamily>(new PropertyFamily(name));
+        auto res = acc.insert(name, std::move(family));
+        it = res.first;
+    }
+    return *(it->second);
 }
diff --git a/tests/integration/queries.cpp b/tests/integration/queries.cpp
index 81acd19b8..ed940dee1 100644
--- a/tests/integration/queries.cpp
+++ b/tests/integration/queries.cpp
@@ -1,4 +1,8 @@
 #include "query_engine/hardcode/queries.hpp"
+#include "storage/edges.cpp"
+#include "storage/edges.hpp"
+#include "storage/vertices.cpp"
+#include "storage/vertices.hpp"
 #include "utils/assert.hpp"
 
 int main(void)
@@ -14,11 +18,10 @@ int main(void)
         "CREATE (n:LABEL {name: \"TEST1\"}) RETURN n",
         "CREATE (n:LABEL {name: \"TEST2\"}) RETURN n",
         "CREATE (n:LABEL {name: \"TEST3\"}) RETURN n",
-        "CREATE (n:ACCOUNT {id: 2322, name: \"TEST\", country: \"Croatia\", created_at: 2352352}) RETURN n" ,
-        "MATCH (n {id: 0}) RETURN n",
-        "MATCH (n {id: 1}) RETURN n",
-        "MATCH (n {id: 2}) RETURN n",
-        "MATCH (n {id: 3}) RETURN n",
+        "CREATE (n:ACCOUNT {id: 2322, name: \"TEST\", country: \"Croatia\", "
+        "created_at: 2352352}) RETURN n",
+        "MATCH (n {id: 0}) RETURN n", "MATCH (n {id: 1}) RETURN n",
+        "MATCH (n {id: 2}) RETURN n", "MATCH (n {id: 3}) RETURN n",
         "MATCH (a {id:0}), (p {id: 1}) CREATE (a)-[r:IS]->(p) RETURN r",
         "MATCH (a {id:1}), (p {id: 2}) CREATE (a)-[r:IS]->(p) RETURN r",
         "MATCH ()-[r]-() WHERE ID(r)=0 RETURN r",
@@ -26,8 +29,7 @@ int main(void)
         "MATCH (n: {id: 0}) SET n.name = \"TEST100\" RETURN n",
         "MATCH (n: {id: 1}) SET n.name = \"TEST101\" RETURN n",
         "MATCH (n: {id: 0}) SET n.name = \"TEST102\" RETURN n",
-        "MATCH (n:LABEL) RETURN n"
-    };
+        "MATCH (n:LABEL) RETURN n"};
 
     for (auto &query : queries) {
         auto stripped = stripper.strip(query);
diff --git a/tests/manual/queries.cpp b/tests/manual/queries.cpp
index fbc0d2336..a65a9e231 100644
--- a/tests/manual/queries.cpp
+++ b/tests/manual/queries.cpp
@@ -1,6 +1,10 @@
 #include <iostream>
 
 #include "query_engine/hardcode/queries.hpp"
+#include "storage/edges.cpp"
+#include "storage/edges.hpp"
+#include "storage/vertices.cpp"
+#include "storage/vertices.hpp"
 
 using namespace std;
 
diff --git a/tests/unit/concurrent_list.cpp b/tests/unit/concurrent_list.cpp
new file mode 100644
index 000000000..54d42a9c8
--- /dev/null
+++ b/tests/unit/concurrent_list.cpp
@@ -0,0 +1,75 @@
+#define CATCH_CONFIG_MAIN
+#include "catch.hpp"
+
+#include "data_structures/concurrent/concurrent_list.hpp"
+
+TEST_CASE("Conncurent List insert")
+{
+    List<int> list;
+    auto it = list.begin();
+    it.push(32);
+    it.reset();
+    REQUIRE(*it == 32);
+}
+
+TEST_CASE("Conncurent List iterate")
+{
+    List<int> list;
+    auto it = list.begin();
+    it.push(32);
+    it.push(7);
+    it.push(9);
+    it.push(0);
+    it.reset();
+
+    REQUIRE(*it == 0);
+    it++;
+    REQUIRE(*it == 9);
+    it++;
+    REQUIRE(*it == 7);
+    it++;
+    REQUIRE(*it == 32);
+    it++;
+    REQUIRE(it == list.end());
+}
+
+TEST_CASE("Conncurent List head remove")
+{
+    List<int> list;
+    auto it = list.begin();
+    it.push(32);
+    it.reset();
+
+    REQUIRE(it.remove());
+    REQUIRE(it.is_removed());
+    REQUIRE(!it.remove());
+
+    it.reset();
+    REQUIRE(it == list.end());
+}
+
+TEST_CASE("Conncurent List remove")
+{
+    List<int> list;
+    auto it = list.begin();
+    it.push(32);
+    it.push(7);
+    it.push(9);
+    it.push(0);
+    it.reset();
+
+    it++;
+    it++;
+    REQUIRE(it.remove());
+    REQUIRE(it.is_removed());
+    REQUIRE(!it.remove());
+
+    it.reset();
+    REQUIRE(*it == 0);
+    it++;
+    REQUIRE(*it == 9);
+    it++;
+    REQUIRE(*it == 32);
+    it++;
+    REQUIRE(it == list.end());
+}