Changes in preparation of making SemistaticGraph non-copyable.
diff --git a/include/fruit/impl/data_structures/semistatic_graph.defn.h b/include/fruit/impl/data_structures/semistatic_graph.defn.h
index 3f83c23..6dade64 100644
--- a/include/fruit/impl/data_structures/semistatic_graph.defn.h
+++ b/include/fruit/impl/data_structures/semistatic_graph.defn.h
@@ -53,6 +53,36 @@
 }
 
 template <typename NodeId, typename Node>
+inline SemistaticGraph<NodeId, Node>::const_node_iterator::const_node_iterator(
+  typename std::vector<NodeData>::const_iterator itr) 
+  : itr(itr) {
+}
+
+template <typename NodeId, typename Node>
+inline const Node& SemistaticGraph<NodeId, Node>::const_node_iterator::getNode() {
+  assert(itr->edgesBeginOffset != invalidEdgesBeginOffset);
+  return itr->node;
+}
+
+template <typename NodeId, typename Node>
+inline bool SemistaticGraph<NodeId, Node>::const_node_iterator::isTerminal() {
+  assert(itr->edgesBeginOffset != invalidEdgesBeginOffset);
+  return itr->edgesBeginOffset == 0;
+}
+
+template <typename NodeId, typename Node>
+inline void SemistaticGraph<NodeId, Node>::const_node_iterator::setTerminal() {
+  assert(itr->edgesBeginOffset != invalidEdgesBeginOffset);
+  itr->edgesBeginOffset = 0;
+}
+
+template <typename NodeId, typename Node>
+inline bool SemistaticGraph<NodeId, Node>::const_node_iterator::operator==(const const_node_iterator& other) const {
+  return itr == other.itr;
+}
+
+
+template <typename NodeId, typename Node>
 inline typename SemistaticGraph<NodeId, Node>::edge_iterator SemistaticGraph<NodeId, Node>::node_iterator::neighborsBegin(
     SemistaticGraph<NodeId, Node>& graph) {
   return edge_iterator{graph.edgesStorage.begin() + itr->edgesBeginOffset};
@@ -87,11 +117,30 @@
 }
 
 template <typename NodeId, typename Node>
+inline typename SemistaticGraph<NodeId, Node>::const_node_iterator SemistaticGraph<NodeId, Node>::end() const {
+  return const_node_iterator{nodes.end()};
+}
+
+template <typename NodeId, typename Node>
 inline typename SemistaticGraph<NodeId, Node>::node_iterator SemistaticGraph<NodeId, Node>::at(NodeId nodeId) {
   return node_iterator{nodes.begin() + nodeIndexMap.at(nodeId)};
 }
 
 template <typename NodeId, typename Node>
+inline typename SemistaticGraph<NodeId, Node>::const_node_iterator SemistaticGraph<NodeId, Node>::find(NodeId nodeId) const {
+  const std::size_t* nodeIndexPtr = nodeIndexMap.find(nodeId);
+  if (nodeIndexPtr == nullptr) {
+    return const_node_iterator{nodes.end()};
+  } else {
+    auto itr = nodes.begin() + *nodeIndexPtr;
+    if (itr->edgesBeginOffset == invalidEdgesBeginOffset) {
+      return const_node_iterator{nodes.end()};
+    }
+    return const_node_iterator{itr};
+  }
+}
+
+template <typename NodeId, typename Node>
 inline typename SemistaticGraph<NodeId, Node>::node_iterator SemistaticGraph<NodeId, Node>::find(NodeId nodeId) {
   std::size_t* nodeIndexPtr = nodeIndexMap.find(nodeId);
   if (nodeIndexPtr == nullptr) {
diff --git a/include/fruit/impl/data_structures/semistatic_graph.h b/include/fruit/impl/data_structures/semistatic_graph.h
index d8fa367..b27316e 100644
--- a/include/fruit/impl/data_structures/semistatic_graph.h
+++ b/include/fruit/impl/data_structures/semistatic_graph.h
@@ -93,6 +93,29 @@
     bool operator==(const node_iterator&) const;
   };
   
+  class const_node_iterator {
+  private:
+    typename std::vector<NodeData>::const_iterator itr;
+    
+    friend class SemistaticGraph<NodeId, Node>;
+    
+    const_node_iterator(typename std::vector<NodeData>::const_iterator itr);
+    
+  public:
+    const Node& getNode();
+    
+    bool isTerminal();
+    
+    // Turns the node into a terminal node, also removing all the deps.
+    void setTerminal();
+  
+    // Assumes !isTerminal().
+    // neighborsEnd() is NOT provided/stored for efficiency, the client code is expected to know the number of neighbors.
+    edge_iterator neighborsBegin(SemistaticGraph<NodeId, Node>& graph);
+    
+    bool operator==(const const_node_iterator&) const;
+  };
+  
   class edge_iterator {
   private:
     // Iterator on edgesStorage.
@@ -126,13 +149,14 @@
   template <typename NodeIter>
   SemistaticGraph(NodeIter first, NodeIter last);
   
-  SemistaticGraph(const SemistaticGraph&) = default;
   SemistaticGraph(SemistaticGraph&&) = default;
+  SemistaticGraph(const SemistaticGraph&) = default;
   
   SemistaticGraph& operator=(const SemistaticGraph&) = default;
   SemistaticGraph& operator=(SemistaticGraph&&) = default;
   
   node_iterator end();
+  const_node_iterator end() const;
   
   // Precondition: `nodeId' must exist in the graph.
   // Unlike std::map::at(), this yields undefined behavior if the precondition isn't satisfied (instead of throwing).
@@ -141,6 +165,7 @@
   // Prefer using at() when possible, this is slightly slower.
   // Returns end() if the node ID was not found.
   node_iterator find(NodeId nodeId);
+  const_node_iterator find(NodeId nodeId) const;
     
   // Sets nodeId as a non-terminal node with outgoing edges [edgesBegin, edgesEnd).
   // If the node already exists, combine(oldNode, newNode) is called and the result (also of type Node) is used as the node value.
diff --git a/include/fruit/impl/data_structures/semistatic_map.h b/include/fruit/impl/data_structures/semistatic_map.h
index a04cf7d..05c1e12 100644
--- a/include/fruit/impl/data_structures/semistatic_map.h
+++ b/include/fruit/impl/data_structures/semistatic_map.h
@@ -92,6 +92,7 @@
   
   // Prefer using at() when possible, this is slightly slower.
   // Returns nullptr if the key was not found.
+  const Value* find(Key key) const;
   Value* find(Key key);
   
   // Inserts (key, value). If `key' already exists, inserts (key, combine(oldValue, (*this)[key])) instead.
diff --git a/include/fruit/impl/data_structures/semistatic_map.templates.h b/include/fruit/impl/data_structures/semistatic_map.templates.h
index 9b1f33c..22ef897 100644
--- a/include/fruit/impl/data_structures/semistatic_map.templates.h
+++ b/include/fruit/impl/data_structures/semistatic_map.templates.h
@@ -136,6 +136,12 @@
 
 template <typename Key, typename Value>
 Value* SemistaticMap<Key, Value>::find(Key key) {
+  const SemistaticMap<Key, Value>* cthis = this;
+  return const_cast<Value*>(cthis->find(key));
+}
+
+template <typename Key, typename Value>
+const Value* SemistaticMap<Key, Value>::find(Key key) const {
   Unsigned h = hash(key);
   Unsigned first_candidate_index = lookup_table[h];
   Unsigned last_candidate_index = values.size();
diff --git a/src/injector_storage.cpp b/src/injector_storage.cpp
index df2801f..c967c9e 100644
--- a/src/injector_storage.cpp
+++ b/src/injector_storage.cpp
@@ -117,8 +117,7 @@
 
 InjectorStorage::InjectorStorage(const NormalizedComponentStorage& normalizedComponent,
                                  ComponentStorage&& component)
-  : typeRegistry(normalizedComponent.typeRegistry),
-    typeRegistryForMultibindings(normalizedComponent.typeRegistryForMultibindings) {
+  : typeRegistryForMultibindings(normalizedComponent.typeRegistryForMultibindings) {
 
   std::size_t total_size = normalizedComponent.total_size;
   
@@ -130,9 +129,9 @@
   // Step 2: Filter out already-present bindings, and check for inconsistent bindings between `normalizedComponent' and
   // `component'.
   auto itr = std::remove_if(component.typeRegistry.begin(), component.typeRegistry.end(),
-                            [this](const std::pair<TypeId, BindingData>& p) {
-                              auto node_itr = typeRegistry.find(p.first);
-                              if (node_itr == typeRegistry.end()) {
+                            [&normalizedComponent](const std::pair<TypeId, BindingData>& p) {
+                              auto node_itr = normalizedComponent.typeRegistry.find(p.first);
+                              if (node_itr == normalizedComponent.typeRegistry.end()) {
                                 // Not bound yet, keep the new binding.
                                 return false;
                               }
@@ -145,6 +144,8 @@
                             });
   component.typeRegistry.erase(itr, component.typeRegistry.end());
   
+  typeRegistry = Graph(normalizedComponent.typeRegistry);
+  
   // Step 3: Add the new bindings.
   for (auto& p : component.typeRegistry) {
     TypeId typeId = p.first;
@@ -162,10 +163,14 @@
       typeRegistry.setNode(typeId, NormalizedBindingData{b.getCreate()},
                            bindingDeps->deps, bindingDeps->deps + bindingDeps->num_deps, combine);
     }
-    total_size += maximumRequiredSpace(typeId);
+  }
+    
+  // Step 4: Update total_size taking into account the new bindings.
+  for (auto& p : component.typeRegistry) {
+    total_size += maximumRequiredSpace(p.first);
   }
   
-  // Step 4: Add multibindings.
+  // Step 5: Add multibindings.
   addMultibindings(typeRegistryForMultibindings, total_size, std::move(component.typeRegistryForMultibindings));
   
   // The +1 is because we waste the first byte (singletonStorageLastUsed points to the beginning of storage).