Index: lemon/lgf_reader.h
===================================================================
--- lemon/lgf_reader.h	(revision 1197)
+++ lemon/lgf_reader.h	(revision 1198)
@@ -155,14 +155,14 @@
     };
 
-    template <typename Value>
+    template <typename Value,
+              typename Map = std::map<std::string, Value> >
     struct MapLookUpConverter {
-      const std::map<std::string, Value>& _map;
-
-      MapLookUpConverter(const std::map<std::string, Value>& map)
+      const Map& _map;
+
+      MapLookUpConverter(const Map& map)
         : _map(map) {}
 
       Value operator()(const std::string& str) {
-        typename std::map<std::string, Value>::const_iterator it =
-          _map.find(str);
+        typename Map::const_iterator it = _map.find(str);
         if (it == _map.end()) {
           std::ostringstream msg;
@@ -171,4 +171,37 @@
         }
         return it->second;
+      }
+    };
+
+    template <typename Value,
+              typename Map1 = std::map<std::string, Value>,
+              typename Map2 = std::map<std::string, Value> >
+    struct DoubleMapLookUpConverter {
+      const Map1& _map1;
+      const Map2& _map2;
+
+      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
+        : _map1(map1), _map2(map2) {}
+
+      Value operator()(const std::string& str) {
+        typename Map1::const_iterator it1 = _map1.find(str);
+        typename Map2::const_iterator it2 = _map2.find(str);
+        if (it1 == _map1.end()) {
+          if (it2 == _map2.end()) {
+            std::ostringstream msg;
+            msg << "Item not found: " << str;
+            throw FormatError(msg.str());
+          } else {
+            return it2->second;
+          }
+        } else {
+          if (it2 == _map2.end()) {
+            return it1->second;
+          } else {
+            std::ostringstream msg;
+            msg << "Item is ambigous: " << str;
+            throw FormatError(msg.str());
+          }
+        }
       }
     };
@@ -2172,13 +2205,17 @@
     std::string _attributes_caption;
 
-    typedef std::map<std::string, Node> NodeIndex;
-    NodeIndex _node_index;
+    typedef std::map<std::string, RedNode> RedNodeIndex;
+    RedNodeIndex _red_node_index;
+    typedef std::map<std::string, BlueNode> BlueNodeIndex;
+    BlueNodeIndex _blue_node_index;
     typedef std::map<std::string, Edge> EdgeIndex;
     EdgeIndex _edge_index;
 
     typedef std::vector<std::pair<std::string,
-      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
-    NodeMaps _red_maps;
-    NodeMaps _blue_maps;
+      _reader_bits::MapStorageBase<RedNode>*> > RedNodeMaps;
+    RedNodeMaps _red_node_maps;
+    typedef std::vector<std::pair<std::string,
+      _reader_bits::MapStorageBase<BlueNode>*> > BlueNodeMaps;
+    BlueNodeMaps _blue_node_maps;
 
     typedef std::vector<std::pair<std::string,
@@ -2242,11 +2279,11 @@
     /// \brief Destructor
     ~BpGraphReader() {
-      for (typename NodeMaps::iterator it = _red_maps.begin();
-           it != _red_maps.end(); ++it) {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
         delete it->second;
       }
 
-      for (typename NodeMaps::iterator it = _blue_maps.begin();
-           it != _blue_maps.end(); ++it) {
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
         delete it->second;
       }
@@ -2285,9 +2322,10 @@
       other.local_is = false;
 
-      _node_index.swap(other._node_index);
+      _red_node_index.swap(other._red_node_index);
+      _blue_node_index.swap(other._blue_node_index);
       _edge_index.swap(other._edge_index);
 
-      _red_maps.swap(other._red_maps);
-      _blue_maps.swap(other._blue_maps);
+      _red_node_maps.swap(other._red_node_maps);
+      _blue_node_maps.swap(other._blue_node_maps);
       _edge_maps.swap(other._edge_maps);
       _attributes.swap(other._attributes);
@@ -2312,10 +2350,10 @@
     BpGraphReader& nodeMap(const std::string& caption, Map& map) {
       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
-      _reader_bits::MapStorageBase<Node>* red_storage =
-        new _reader_bits::MapStorage<Node, Map>(map);
-      _red_maps.push_back(std::make_pair(caption, red_storage));
-      _reader_bits::MapStorageBase<Node>* blue_storage =
-        new _reader_bits::MapStorage<Node, Map>(map);
-      _blue_maps.push_back(std::make_pair(caption, blue_storage));
+      _reader_bits::MapStorageBase<RedNode>* red_storage =
+        new _reader_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _reader_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
       return *this;
     }
@@ -2329,10 +2367,10 @@
                            const Converter& converter = Converter()) {
       checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
-      _reader_bits::MapStorageBase<Node>* red_storage =
-        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _red_maps.push_back(std::make_pair(caption, red_storage));
-      _reader_bits::MapStorageBase<Node>* blue_storage =
-        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _blue_maps.push_back(std::make_pair(caption, blue_storage));
+      _reader_bits::MapStorageBase<RedNode>* red_storage =
+        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _reader_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
       return *this;
     }
@@ -2341,8 +2379,8 @@
     template <typename Map>
     BpGraphReader& redNodeMap(const std::string& caption, Map& map) {
-      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
-      _reader_bits::MapStorageBase<Node>* storage =
-        new _reader_bits::MapStorage<Node, Map>(map);
-      _red_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* storage =
+        new _reader_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -2355,8 +2393,8 @@
     BpGraphReader& redNodeMap(const std::string& caption, Map& map,
                               const Converter& converter = Converter()) {
-      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
-      _reader_bits::MapStorageBase<Node>* storage =
-        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _red_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::WriteMap<RedNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<RedNode>* storage =
+        new _reader_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -2365,8 +2403,8 @@
     template <typename Map>
     BpGraphReader& blueNodeMap(const std::string& caption, Map& map) {
-      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
-      _reader_bits::MapStorageBase<Node>* storage =
-        new _reader_bits::MapStorage<Node, Map>(map);
-      _blue_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<BlueNode>* storage =
+        new _reader_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -2379,8 +2417,8 @@
     BpGraphReader& blueNodeMap(const std::string& caption, Map& map,
                                const Converter& converter = Converter()) {
-      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
-      _reader_bits::MapStorageBase<Node>* storage =
-        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _blue_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::WriteMap<BlueNode, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<BlueNode>* storage =
+        new _reader_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -2474,8 +2512,33 @@
     /// Add a node reading rule to reader.
     BpGraphReader& node(const std::string& caption, Node& node) {
-      typedef _reader_bits::MapLookUpConverter<Node> Converter;
-      Converter converter(_node_index);
+      typedef _reader_bits::DoubleMapLookUpConverter<
+        Node, RedNodeIndex, BlueNodeIndex> Converter;
+      Converter converter(_red_node_index, _blue_node_index);
       _reader_bits::ValueStorageBase* storage =
         new _reader_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node reading rule
+    ///
+    /// Add a red node reading rule to reader.
+    BpGraphReader& redNode(const std::string& caption, RedNode& node) {
+      typedef _reader_bits::MapLookUpConverter<RedNode> Converter;
+      Converter converter(_red_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<RedNode, Converter>(node, converter);
+      _attributes.insert(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node reading rule
+    ///
+    /// Add a blue node reading rule to reader.
+    BpGraphReader& blueNode(const std::string& caption, BlueNode& node) {
+      typedef _reader_bits::MapLookUpConverter<BlueNode> Converter;
+      Converter converter(_blue_node_index);
+      _reader_bits::ValueStorageBase* storage =
+        new _reader_bits::ValueStorage<BlueNode, Converter>(node, converter);
       _attributes.insert(std::make_pair(caption, storage));
       return *this;
@@ -2550,6 +2613,9 @@
       _use_nodes = true;
       _writer_bits::DefaultConverter<typename Map::Value> converter;
-      for (NodeIt n(_graph); n != INVALID; ++n) {
-        _node_index.insert(std::make_pair(converter(map[n]), n));
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        _red_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {
+        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
       }
       return *this;
@@ -2567,6 +2633,9 @@
       LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
       _use_nodes = true;
-      for (NodeIt n(_graph); n != INVALID; ++n) {
-        _node_index.insert(std::make_pair(converter(map[n]), n));
+      for (RedNodeIt n(_graph); n != INVALID; ++n) {
+        _red_node_index.insert(std::make_pair(converter(map[n]), n));
+      }
+      for (BlueNodeIt n(_graph); n != INVALID; ++n) {      
+        _blue_node_index.insert(std::make_pair(converter(map[n]), n));
       }
       return *this;
@@ -2665,5 +2734,5 @@
     void readRedNodes() {
 
-      std::vector<int> map_index(_red_maps.size());
+      std::vector<int> map_index(_red_node_maps.size());
       int map_num, label_index;
 
@@ -2671,5 +2740,5 @@
       if (!readLine() || !(line >> c) || c == '@') {
         if (readSuccess() && line) line.putback(c);
-        if (!_red_maps.empty())
+        if (!_red_node_maps.empty())
           throw FormatError("Cannot find map names");
         return;
@@ -2692,10 +2761,10 @@
         }
 
-        for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) {
+        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
           std::map<std::string, int>::iterator jt =
-            maps.find(_red_maps[i].first);
+            maps.find(_red_node_maps[i].first);
           if (jt == maps.end()) {
             std::ostringstream msg;
-            msg << "Map not found: " << _red_maps[i].first;
+            msg << "Map not found: " << _red_node_maps[i].first;
             throw FormatError(msg.str());
           }
@@ -2728,15 +2797,15 @@
           throw FormatError("Extra character at the end of line");
 
-        Node n;
+        RedNode n;
         if (!_use_nodes) {
           n = _graph.addRedNode();
           if (label_index != -1)
-            _node_index.insert(std::make_pair(tokens[label_index], n));
+            _red_node_index.insert(std::make_pair(tokens[label_index], n));
         } else {
           if (label_index == -1)
             throw FormatError("Label map not found");
-          typename std::map<std::string, Node>::iterator it =
-            _node_index.find(tokens[label_index]);
-          if (it == _node_index.end()) {
+          typename std::map<std::string, RedNode>::iterator it =
+            _red_node_index.find(tokens[label_index]);
+          if (it == _red_node_index.end()) {
             std::ostringstream msg;
             msg << "Node with label not found: " << tokens[label_index];
@@ -2746,6 +2815,6 @@
         }
 
-        for (int i = 0; i < static_cast<int>(_red_maps.size()); ++i) {
-          _red_maps[i].second->set(n, tokens[map_index[i]]);
+        for (int i = 0; i < static_cast<int>(_red_node_maps.size()); ++i) {
+          _red_node_maps[i].second->set(n, tokens[map_index[i]]);
         }
 
@@ -2758,5 +2827,5 @@
     void readBlueNodes() {
 
-      std::vector<int> map_index(_blue_maps.size());
+      std::vector<int> map_index(_blue_node_maps.size());
       int map_num, label_index;
 
@@ -2764,5 +2833,5 @@
       if (!readLine() || !(line >> c) || c == '@') {
         if (readSuccess() && line) line.putback(c);
-        if (!_blue_maps.empty())
+        if (!_blue_node_maps.empty())
           throw FormatError("Cannot find map names");
         return;
@@ -2785,10 +2854,10 @@
         }
 
-        for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) {
+        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
           std::map<std::string, int>::iterator jt =
-            maps.find(_blue_maps[i].first);
+            maps.find(_blue_node_maps[i].first);
           if (jt == maps.end()) {
             std::ostringstream msg;
-            msg << "Map not found: " << _blue_maps[i].first;
+            msg << "Map not found: " << _blue_node_maps[i].first;
             throw FormatError(msg.str());
           }
@@ -2821,15 +2890,15 @@
           throw FormatError("Extra character at the end of line");
 
-        Node n;
+        BlueNode n;
         if (!_use_nodes) {
           n = _graph.addBlueNode();
           if (label_index != -1)
-            _node_index.insert(std::make_pair(tokens[label_index], n));
+            _blue_node_index.insert(std::make_pair(tokens[label_index], n));
         } else {
           if (label_index == -1)
             throw FormatError("Label map not found");
-          typename std::map<std::string, Node>::iterator it =
-            _node_index.find(tokens[label_index]);
-          if (it == _node_index.end()) {
+          typename std::map<std::string, BlueNode>::iterator it =
+            _blue_node_index.find(tokens[label_index]);
+          if (it == _blue_node_index.end()) {
             std::ostringstream msg;
             msg << "Node with label not found: " << tokens[label_index];
@@ -2839,6 +2908,6 @@
         }
 
-        for (int i = 0; i < static_cast<int>(_blue_maps.size()); ++i) {
-          _blue_maps[i].second->set(n, tokens[map_index[i]]);
+        for (int i = 0; i < static_cast<int>(_blue_node_maps.size()); ++i) {
+          _blue_node_maps[i].second->set(n, tokens[map_index[i]]);
         }
 
@@ -2925,37 +2994,24 @@
         Edge e;
         if (!_use_edges) {
-
-          typename NodeIndex::iterator it;
-
-          it = _node_index.find(source_token);
-          if (it == _node_index.end()) {
+          typename RedNodeIndex::iterator rit =
+            _red_node_index.find(source_token);
+          if (rit == _red_node_index.end()) {
             std::ostringstream msg;
             msg << "Item not found: " << source_token;
             throw FormatError(msg.str());
           }
-          Node source = it->second;
-          if (!_graph.red(source)) {
-            std::ostringstream msg;
-            msg << "Item is not red node: " << source_token;
-            throw FormatError(msg.str());
-          }
-
-          it = _node_index.find(target_token);
-          if (it == _node_index.end()) {
+          RedNode source = rit->second;
+          typename BlueNodeIndex::iterator it =
+            _blue_node_index.find(target_token);
+          if (it == _blue_node_index.end()) {
             std::ostringstream msg;
             msg << "Item not found: " << target_token;
             throw FormatError(msg.str());
           }
-          Node target = it->second;
-          if (!_graph.blue(target)) {
-            std::ostringstream msg;
-            msg << "Item is not red node: " << source_token;
-            throw FormatError(msg.str());
-          }
+          BlueNode target = it->second;
 
           // It is checked that source is red and
           // target is blue, so this should be safe:
-          e = _graph.addEdge(_graph.asRedNodeUnsafe(source),
-                             _graph.asBlueNodeUnsafe(target));
+          e = _graph.addEdge(source, target);
           if (label_index != -1)
             _edge_index.insert(std::make_pair(tokens[label_index], e));
Index: lemon/lgf_writer.h
===================================================================
--- lemon/lgf_writer.h	(revision 1194)
+++ lemon/lgf_writer.h	(revision 1198)
@@ -186,5 +186,5 @@
       ValueStorage(const Value& value, const Converter& converter = Converter())
         : _value(value), _converter(converter) {}
-
+      
       virtual std::string get() {
         return _converter(_value);
@@ -192,18 +192,47 @@
     };
 
-    template <typename Value>
+    template <typename Value,
+              typename Map = std::map<Value, std::string> >
     struct MapLookUpConverter {
-      const std::map<Value, std::string>& _map;
-
-      MapLookUpConverter(const std::map<Value, std::string>& map)
+      const Map& _map;
+
+      MapLookUpConverter(const Map& map)
         : _map(map) {}
 
-      std::string operator()(const Value& str) {
-        typename std::map<Value, std::string>::const_iterator it =
-          _map.find(str);
+      std::string operator()(const Value& value) {
+        typename Map::const_iterator it = _map.find(value);
         if (it == _map.end()) {
           throw FormatError("Item not found");
         }
         return it->second;
+      }
+    };
+
+    template <typename Value,
+              typename Map1 = std::map<Value, std::string>,
+              typename Map2 = std::map<Value, std::string> >
+    struct DoubleMapLookUpConverter {
+      const Map1& _map1;
+      const Map2& _map2;
+
+      DoubleMapLookUpConverter(const Map1& map1, const Map2& map2)
+        : _map1(map1), _map2(map2) {}
+
+      std::string operator()(const Value& value) {
+        typename Map1::const_iterator it1 = _map1.find(value);
+        typename Map1::const_iterator it2 = _map2.find(value);
+        if (it1 == _map1.end()) {
+          if (it2 == _map2.end()) {
+            throw FormatError("Item not found");
+          } else {
+            return it2->second;
+          }
+        } else {
+          if (it2 == _map2.end()) {
+            return it1->second;
+          } else {
+            throw FormatError("Item is ambigous");
+          }
+        }
       }
     };
@@ -1652,13 +1681,17 @@
     std::string _attributes_caption;
 
-    typedef std::map<Node, std::string> NodeIndex;
-    NodeIndex _node_index;
+    typedef std::map<Node, std::string> RedNodeIndex;
+    RedNodeIndex _red_node_index;
+    typedef std::map<Node, std::string> BlueNodeIndex;
+    BlueNodeIndex _blue_node_index;
     typedef std::map<Edge, std::string> EdgeIndex;
     EdgeIndex _edge_index;
 
     typedef std::vector<std::pair<std::string,
-      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
-    NodeMaps _red_maps;
-    NodeMaps _blue_maps;
+      _writer_bits::MapStorageBase<RedNode>* > > RedNodeMaps;
+    RedNodeMaps _red_node_maps;
+    typedef std::vector<std::pair<std::string,
+      _writer_bits::MapStorageBase<BlueNode>* > > BlueNodeMaps;
+    BlueNodeMaps _blue_node_maps;
 
     typedef std::vector<std::pair<std::string,
@@ -1711,11 +1744,11 @@
     /// \brief Destructor
     ~BpGraphWriter() {
-      for (typename NodeMaps::iterator it = _red_maps.begin();
-           it != _red_maps.end(); ++it) {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
         delete it->second;
       }
 
-      for (typename NodeMaps::iterator it = _blue_maps.begin();
-           it != _blue_maps.end(); ++it) {
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
         delete it->second;
       }
@@ -1754,9 +1787,10 @@
       other.local_os = false;
 
-      _node_index.swap(other._node_index);
+      _red_node_index.swap(other._red_node_index);
+      _blue_node_index.swap(other._blue_node_index);
       _edge_index.swap(other._edge_index);
 
-      _red_maps.swap(other._red_maps);
-      _blue_maps.swap(other._blue_maps);
+      _red_node_maps.swap(other._red_node_maps);
+      _blue_node_maps.swap(other._blue_node_maps);
       _edge_maps.swap(other._edge_maps);
       _attributes.swap(other._attributes);
@@ -1780,10 +1814,10 @@
     BpGraphWriter& nodeMap(const std::string& caption, const Map& map) {
       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
-      _writer_bits::MapStorageBase<Node>* red_storage =
-        new _writer_bits::MapStorage<Node, Map>(map);
-      _red_maps.push_back(std::make_pair(caption, red_storage));
-      _writer_bits::MapStorageBase<Node>* blue_storage =
-        new _writer_bits::MapStorage<Node, Map>(map);
-      _blue_maps.push_back(std::make_pair(caption, blue_storage));
+      _writer_bits::MapStorageBase<RedNode>* red_storage =
+        new _writer_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _writer_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
       return *this;
     }
@@ -1797,10 +1831,10 @@
                            const Converter& converter = Converter()) {
       checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
-      _writer_bits::MapStorageBase<Node>* red_storage =
-        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _red_maps.push_back(std::make_pair(caption, red_storage));
-      _writer_bits::MapStorageBase<Node>* blue_storage =
-        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _blue_maps.push_back(std::make_pair(caption, blue_storage));
+      _writer_bits::MapStorageBase<RedNode>* red_storage =
+        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, red_storage));
+      _writer_bits::MapStorageBase<BlueNode>* blue_storage =
+        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, blue_storage));
       return *this;
     }
@@ -1811,8 +1845,8 @@
     template <typename Map>
     BpGraphWriter& redNodeMap(const std::string& caption, const Map& map) {
-      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
-      _writer_bits::MapStorageBase<Node>* storage =
-        new _writer_bits::MapStorage<Node, Map>(map);
-      _red_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* storage =
+        new _writer_bits::MapStorage<RedNode, Map>(map);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -1825,8 +1859,8 @@
     BpGraphWriter& redNodeMap(const std::string& caption, const Map& map,
                               const Converter& converter = Converter()) {
-      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
-      _writer_bits::MapStorageBase<Node>* storage =
-        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _red_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::ReadMap<RedNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<RedNode>* storage =
+        new _writer_bits::MapStorage<RedNode, Map, Converter>(map, converter);
+      _red_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -1837,8 +1871,8 @@
     template <typename Map>
     BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map) {
-      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
-      _writer_bits::MapStorageBase<Node>* storage =
-        new _writer_bits::MapStorage<Node, Map>(map);
-      _blue_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<BlueNode>* storage =
+        new _writer_bits::MapStorage<BlueNode, Map>(map);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -1851,8 +1885,8 @@
     BpGraphWriter& blueNodeMap(const std::string& caption, const Map& map,
                                const Converter& converter = Converter()) {
-      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
-      _writer_bits::MapStorageBase<Node>* storage =
-        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
-      _blue_maps.push_back(std::make_pair(caption, storage));
+      checkConcept<concepts::ReadMap<BlueNode, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<BlueNode>* storage =
+        new _writer_bits::MapStorage<BlueNode, Map, Converter>(map, converter);
+      _blue_node_maps.push_back(std::make_pair(caption, storage));
       return *this;
     }
@@ -1946,6 +1980,31 @@
     /// Add a node writing rule to the writer.
     BpGraphWriter& node(const std::string& caption, const Node& node) {
+      typedef _writer_bits::DoubleMapLookUpConverter<
+        Node, RedNodeIndex, BlueNodeIndex> Converter;
+      Converter converter(_red_node_index, _blue_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Red node writing rule
+    ///
+    /// Add a red node writing rule to the writer.
+    BpGraphWriter& redNode(const std::string& caption, const RedNode& node) {
       typedef _writer_bits::MapLookUpConverter<Node> Converter;
-      Converter converter(_node_index);
+      Converter converter(_red_node_index);
+      _writer_bits::ValueStorageBase* storage =
+        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
+      _attributes.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Blue node writing rule
+    ///
+    /// Add a blue node writing rule to the writer.
+    BpGraphWriter& blueNode(const std::string& caption, const BlueNode& node) {
+      typedef _writer_bits::MapLookUpConverter<Node> Converter;
+      Converter converter(_blue_node_index);
       _writer_bits::ValueStorageBase* storage =
         new _writer_bits::ValueStorage<Node, Converter>(node, converter);
@@ -2034,7 +2093,7 @@
 
     void writeRedNodes() {
-      _writer_bits::MapStorageBase<Node>* label = 0;
-      for (typename NodeMaps::iterator it = _red_maps.begin();
-           it != _red_maps.end(); ++it) {
+      _writer_bits::MapStorageBase<RedNode>* label = 0;
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
         if (it->first == "label") {
           label = it->second;
@@ -2052,11 +2111,11 @@
         *_os << "label" << '\t';
       }
-      for (typename NodeMaps::iterator it = _red_maps.begin();
-           it != _red_maps.end(); ++it) {
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
         _writer_bits::writeToken(*_os, it->first) << '\t';
       }
       *_os << std::endl;
 
-      std::vector<Node> nodes;
+      std::vector<RedNode> nodes;
       for (RedNodeIt n(_graph); n != INVALID; ++n) {
         nodes.push_back(n);
@@ -2072,18 +2131,18 @@
 
       for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
-        Node n = nodes[i];
+        RedNode n = nodes[i];
         if (label == 0) {
           std::ostringstream os;
-          os << _graph.id(n);
+          os << _graph.id(static_cast<Node>(n));
           _writer_bits::writeToken(*_os, os.str());
           *_os << '\t';
-          _node_index.insert(std::make_pair(n, os.str()));
-        }
-        for (typename NodeMaps::iterator it = _red_maps.begin();
-             it != _red_maps.end(); ++it) {
+          _red_node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+             it != _red_node_maps.end(); ++it) {
           std::string value = it->second->get(n);
           _writer_bits::writeToken(*_os, value);
           if (it->first == "label") {
-            _node_index.insert(std::make_pair(n, value));
+            _red_node_index.insert(std::make_pair(n, value));
           }
           *_os << '\t';
@@ -2094,7 +2153,7 @@
 
     void writeBlueNodes() {
-      _writer_bits::MapStorageBase<Node>* label = 0;
-      for (typename NodeMaps::iterator it = _blue_maps.begin();
-           it != _blue_maps.end(); ++it) {
+      _writer_bits::MapStorageBase<BlueNode>* label = 0;
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
         if (it->first == "label") {
           label = it->second;
@@ -2112,11 +2171,11 @@
         *_os << "label" << '\t';
       }
-      for (typename NodeMaps::iterator it = _blue_maps.begin();
-           it != _blue_maps.end(); ++it) {
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
         _writer_bits::writeToken(*_os, it->first) << '\t';
       }
       *_os << std::endl;
 
-      std::vector<Node> nodes;
+      std::vector<BlueNode> nodes;
       for (BlueNodeIt n(_graph); n != INVALID; ++n) {
         nodes.push_back(n);
@@ -2132,18 +2191,18 @@
 
       for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
-        Node n = nodes[i];
+        BlueNode n = nodes[i];
         if (label == 0) {
           std::ostringstream os;
-          os << _graph.id(n);
+          os << _graph.id(static_cast<Node>(n));
           _writer_bits::writeToken(*_os, os.str());
           *_os << '\t';
-          _node_index.insert(std::make_pair(n, os.str()));
-        }
-        for (typename NodeMaps::iterator it = _blue_maps.begin();
-             it != _blue_maps.end(); ++it) {
+          _blue_node_index.insert(std::make_pair(n, os.str()));
+        }
+        for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+             it != _blue_node_maps.end(); ++it) {
           std::string value = it->second->get(n);
           _writer_bits::writeToken(*_os, value);
           if (it->first == "label") {
-            _node_index.insert(std::make_pair(n, value));
+            _blue_node_index.insert(std::make_pair(n, value));
           }
           *_os << '\t';
@@ -2154,7 +2213,7 @@
 
     void createRedNodeIndex() {
-      _writer_bits::MapStorageBase<Node>* label = 0;
-      for (typename NodeMaps::iterator it = _red_maps.begin();
-           it != _red_maps.end(); ++it) {
+      _writer_bits::MapStorageBase<RedNode>* label = 0;
+      for (typename RedNodeMaps::iterator it = _red_node_maps.begin();
+           it != _red_node_maps.end(); ++it) {
         if (it->first == "label") {
           label = it->second;
@@ -2164,13 +2223,13 @@
 
       if (label == 0) {
-        for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (RedNodeIt n(_graph); n != INVALID; ++n) {
           std::ostringstream os;
           os << _graph.id(n);
-          _node_index.insert(std::make_pair(n, os.str()));
+          _red_node_index.insert(std::make_pair(n, os.str()));
         }
       } else {
-        for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (RedNodeIt n(_graph); n != INVALID; ++n) {
           std::string value = label->get(n);
-          _node_index.insert(std::make_pair(n, value));
+          _red_node_index.insert(std::make_pair(n, value));
         }
       }
@@ -2178,7 +2237,7 @@
 
     void createBlueNodeIndex() {
-      _writer_bits::MapStorageBase<Node>* label = 0;
-      for (typename NodeMaps::iterator it = _blue_maps.begin();
-           it != _blue_maps.end(); ++it) {
+      _writer_bits::MapStorageBase<BlueNode>* label = 0;
+      for (typename BlueNodeMaps::iterator it = _blue_node_maps.begin();
+           it != _blue_node_maps.end(); ++it) {
         if (it->first == "label") {
           label = it->second;
@@ -2188,13 +2247,13 @@
 
       if (label == 0) {
-        for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
           std::ostringstream os;
           os << _graph.id(n);
-          _node_index.insert(std::make_pair(n, os.str()));
+          _blue_node_index.insert(std::make_pair(n, os.str()));
         }
       } else {
-        for (NodeIt n(_graph); n != INVALID; ++n) {
+        for (BlueNodeIt n(_graph); n != INVALID; ++n) {
           std::string value = label->get(n);
-          _node_index.insert(std::make_pair(n, value));
+          _blue_node_index.insert(std::make_pair(n, value));
         }
       }
@@ -2242,8 +2301,8 @@
       for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
         Edge e = edges[i];
-        _writer_bits::writeToken(*_os, _node_index.
+        _writer_bits::writeToken(*_os, _red_node_index.
                                  find(_graph.redNode(e))->second);
         *_os << '\t';
-        _writer_bits::writeToken(*_os, _node_index.
+        _writer_bits::writeToken(*_os, _blue_node_index.
                                  find(_graph.blueNode(e))->second);
         *_os << '\t';
