Index: src/work/deba/graph_io_test.cc
===================================================================
--- src/work/deba/graph_io_test.cc	(revision 1032)
+++ src/work/deba/graph_io_test.cc	(revision 1032)
@@ -0,0 +1,23 @@
+#include <lemon/smart_graph.h>
+#include <lemon/graph_reader.h>
+
+#include <iostream>
+#include <fstream>
+
+using namespace std;
+using namespace lemon;
+
+int main() {
+  ifstream input("test.lgf");
+  SmartGraph graph;
+  GraphReader<SmartGraph> reader(input, graph);
+  SmartGraph::NodeMap<int> cost(graph);
+  reader.readNodeMap("cost", cost);
+  SmartGraph::NodeMap<string> color(graph);
+  reader.readNodeMap("color", color);
+  reader.read();
+  for (SmartGraph::NodeIt it(graph); it != INVALID; ++it) {
+    cout << cost[it] << color[it] << endl;
+  }
+  return 0;
+}
Index: src/work/deba/graph_reader.h
===================================================================
--- src/work/deba/graph_reader.h	(revision 1032)
+++ src/work/deba/graph_reader.h	(revision 1032)
@@ -0,0 +1,212 @@
+/* -*- C++ -*-
+ * src/lemon/graph_reader.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Combinatorial Optimization Research Group, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup gio
+///\file
+///\brief Map utilities.
+
+#include <iostream>
+#include <sstream>
+
+#include <map>
+#include <vector>
+
+#include <lemon/error.h>
+
+/// \todo fix exceptions
+
+
+namespace lemon {
+  
+  struct DefaultReaderTraits {
+
+    template <typename _Value>
+    struct Reader {
+      typedef _Value Value;
+      void read(std::istream& is, Value& value) {
+	is >> value;
+      }
+    };
+
+    template <typename _Value>
+    struct Skipper {
+      typedef _Value Value;
+      void read(std::istream& is) {
+	Value tmp;
+	is >> tmp;
+      }      
+    };
+
+    struct DefaultSkipper {
+      void read(std::istream& is) {
+	std::string tmp;
+	is >> tmp;
+      }
+    };
+  };
+
+  class IOException {
+    virtual string message() = 0;
+  };
+
+  class FileReaderException {
+    virtual int getLine() = 0;    
+  };
+
+  
+  
+  template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
+  class GraphReader {
+
+  public:
+    
+    typedef _Graph Graph;
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Edge Edge;
+
+    typedef _ReaderTraits ReaderTraits;
+    
+
+    GraphReader(std::istream& _is, Graph& _graph) : is(_is), graph(_graph) {}
+
+    template <typename Map>
+    GraphReader& readNodeMap(std::string name, Map& map, 
+			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
+			     typename ReaderTraits::template Reader<typename Map::Value>()) {
+      return readNodeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
+    }
+
+    template <typename Map, typename Reader>
+    GraphReader& readNodeMap(std::string name, Map& map, const Reader& reader = Reader()) {
+      node_readers.insert(make_pair(name, new MapReader<Node, Map, Reader>(map, reader)));
+      return *this;
+    }
+
+    template <typename Map>
+    GraphReader& readEdgeMap(std::string name, Map& map, 
+			     const typename ReaderTraits::template Reader<typename Map::Value>& reader =
+			     typename ReaderTraits::template Reader<typename Map::Value>()) {
+      return readEdgeMap<Map, typename ReaderTraits::template Reader<typename Map::Value> >(name, map, reader);
+    }
+
+    template <typename Map, typename Reader>
+    GraphReader& readEdgeMap(std::string name, Map& map, const Reader& reader = Reader()) {
+      edge_readers.insert(make_pair(name, new MapReader<Edge, Map, Reader>(map, reader)));
+      return *this;
+    }
+
+    void read() {
+      int line_num = 0;
+      readNodeSet(line_num);
+      readEdgeSet(line_num);
+      {
+	std::string line = readNotEmptyLine(is, line_num);
+      }
+    }
+
+  private:
+
+    void readNodeSet(int& line_num) {
+      int n = 0;
+      {
+	std::string line = readNotEmptyLine(is, line_num);	
+      }
+      std::vector<MapReaderBase<Node>*> index;
+      {
+	std::string line = readNotEmptyLine(is, line_num);    
+	std::string id;
+	std::istringstream ls(line);	
+	while (ls >> id) {
+	  typename map<std::string, MapReaderBase<Node>* >::iterator it = node_readers.find(id);
+	  if (it != node_readers.end()) {
+	    index.push_back(it->second);
+	  } else {
+	    index.push_back(0);
+	  }
+	  ++n;
+	}
+      }
+      std::string line;
+      while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
+	Node node = graph.addNode();
+	std::istringstream ls(line);
+	for (int i = 0; i < n; ++i) {
+	  if (index[i] != 0) {	    
+	    index[i]->read(ls, node);
+	  } else {
+	    default_skipper.read(ls);
+	  }
+	}
+      }
+    }
+
+    void readEdgeSet(int& line_num) {
+      
+    }
+
+    std::string readNotEmptyLine(std::istream& is, int& line_num) {
+      std::string line;
+      while (++line_num, getline(is, line)) {	
+	int vi = line.find_first_not_of(" \t");
+	if (vi != string::npos && line[vi] != '#') {
+	  return line.substr(vi);
+	}
+      }
+      throw Exception();
+    }
+    
+    istream& is;
+    Graph& graph;
+
+    typename ReaderTraits::DefaultSkipper default_skipper;
+
+    template <typename _Item>    
+    class MapReaderBase {
+    public:
+      typedef _Item Item;
+      virtual void read(istream& is, const Item& item) = 0;
+    };
+    
+    template <typename _Item, typename _Map, typename _Reader>
+    class MapReader : public MapReaderBase<_Item> {
+    public:
+      typedef _Map Map;
+      typedef _Reader Reader;
+      typedef _Item Item;
+      
+      Map& map;
+      Reader reader;
+
+      MapReader(Map& _map, const Reader& _reader) 
+	: map(_map), reader(_reader) {}
+
+
+      virtual void read(istream& is, const Item& item) {
+	typename Reader::Value value;
+	reader.read(is, value);
+	map.set(item, value);
+      }
+    };
+
+    typedef std::map<std::string, MapReaderBase<Node>* > NodeReaders;
+    NodeReaders node_readers;
+
+    typedef std::map<std::string, MapReaderBase<Edge>* > EdgeReaders;
+    EdgeReaders edge_readers;
+
+  };
+
+}
Index: src/work/deba/map_utils.h
===================================================================
--- src/work/deba/map_utils.h	(revision 1032)
+++ src/work/deba/map_utils.h	(revision 1032)
@@ -0,0 +1,98 @@
+/* -*- C++ -*-
+ * src/lemon/map_utils.h - Part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Combinatorial Optimization Research Group, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+///\ingroup gutils
+///\file
+///\brief Map utilities.
+
+#include <map>
+
+
+namespace lemon {
+
+  /// \addtogroup gutils
+  /// @{
+
+
+  /// \brief General inversable map type.
+
+  /// This type provides simple inversable map functions. 
+  /// The InversableMap wraps an arbitrary ReadWriteMap 
+  /// and if a key is setted to a new value then store it
+  /// in the inverse map.
+  template <
+    typename _Graph, 
+    typename _Map, 
+    template <typename, typename> class _InvMap = std::Map
+  >
+  class InversableMap : protected _Map {
+
+  public:
+
+    typename _Map Map;
+    typename _InvMap<Map::Value, Map::Key> InverseMap;
+    
+    typename _Map::Key Key;
+    typename _Map::Value Value;
+    typename _Map::ConstReference ConstReference;
+
+    /// Constructor.
+
+    /// Construct a new InversableMap for the graph.
+    ///
+    InversableMap(const Graph& graph) : Map(graph) {} 
+    
+    /// The setter function of the map.
+
+    /// It sets the map and the inverse map 
+    void set(const Key& key, const Value& val) {
+      Value oldval = Map::operator[](key);
+      InverseMap::iterator it = invMap.find(oldval);
+      if (it != invMap.end() && it->second == key) {
+	invMap.erase(it);
+      }      
+      invMap.insert(make_pair(val, key));
+      Map::set(key, val);
+    }
+
+    ConstReference operator[](const Key&) const {
+      return Map::operator[](key);
+    }
+
+    virtual void add(const Key&) {
+      Map::add(key);
+    }
+
+    virtual void erase(const Key&) {
+      Value val = Map::operator[](key);
+      InverseMap::iterator it = invMap.find(val);
+      if (it != invMap.end() && it->second == key) {
+	invMap.erase(it);
+      }
+      Map::erase(key);
+    }
+
+    const InverseMap& inverse() const {
+      return invMap;
+    } 
+
+
+  private:
+    InverseMap invMap;    
+  };
+
+}
+
Index: src/work/deba/test.lgf
===================================================================
--- src/work/deba/test.lgf	(revision 1032)
+++ src/work/deba/test.lgf	(revision 1032)
@@ -0,0 +1,30 @@
+
+@nodes
+
+id cost color
+
+1 1 green
+2 2 blue
+# hatalom dicsoseg
+3 1 red
+4 2 red
+5 1 green
+10 1 green # ez nem egy igazan jo sor
+    # hello - bello csucsok
+6 2 blue
+7 1 blue
+8 2 red
+9 1 green
+@edges
+source target weight
+1 4 10
+3 5 29
+3 4 92
+2 3 92
+9 5 49
+10 4 40
+1 3 84
+6 7 83
+8 9 37
+7 8 89
+@end
