Index: src/lemon/graph_reader.h
===================================================================
--- src/lemon/graph_reader.h	(revision 1311)
+++ src/lemon/graph_reader.h	(revision 1333)
@@ -35,4 +35,6 @@
 namespace lemon {
 
+  /// \addtogroup io_group
+  /// @{
 
   /// \brief Standard ReaderTraits for the GraphReader class.
@@ -40,9 +42,11 @@
   /// Standard ReaderTraits for the GraphReader class.
   /// It defines standard reading method for all type of value. 
+  /// \author Balazs Dezso
   struct DefaultReaderTraits {
 
-   /// \brief Template class for reading an value.
+    /// \brief Template class for reading an value.
     ///
     /// Template class for reading an value.
+    /// \author Balazs Dezso
     template <typename _Value>
     struct Reader {
@@ -58,4 +62,11 @@
     };
 
+    /// \brief Returns wheter this name is an ID map name.
+    ///
+    /// Returns wheter this name is an ID map name.
+    static bool idMapName(const std::string& name) {
+      return name == "id";
+    }
+
     /// The reader class for the not needed maps.
     typedef Reader<std::string> DefaultReader;
@@ -67,4 +78,5 @@
   /// Reader class for quoted strings. It can process the escape
   /// sequences in the string.
+  /// \author Balazs Dezso
   class QuotedStringReader {
   public:
@@ -172,10 +184,67 @@
   /// \brief The graph reader class.
   ///
-  /// \ingroup io_group
-  /// The reader class for the graph input.
+  ///
+  /// The given file format may contain several maps and labeled nodes or 
+  /// edges.
+  ///
+  /// If you read a graph you need not read all the maps and items just those
+  /// that you need. The interface of the \c GraphReader is very similar to
+  /// the GraphWriter but the reading method does not depend on the order the
+  /// given commands.
+  ///
+  /// The reader object suppose that each not readed value does not contain 
+  /// whitespaces, therefore it has some extra possibilities to control how
+  /// it should skip the values when the string representation contains spaces.
+  ///
+  /// \code
+  /// GraphReader<ListGraph> reader(std::cin, graph);
+  /// \endcode
+  ///
+  /// The \c addNodeMap() function reads a map from the \c \@nodeset section.
+  /// If there is a map that you do not want to read from the file and there is
+  /// whitespace in the string represenation of the values then you should
+  /// call the \c skipNodeMap() template member function with proper 
+  /// parameters.
+  ///
+  /// \code
+  /// reader.addNodeMap("x-coord", xCoordMap);
+  /// reader.addNodeMap("y-coord", yCoordMap);
+  ///
+  /// reader.addNodeMap<QuotedStringReader>("label", labelMap);
+  /// reader.skipNodeMap<QuotedStringReader>("description");
+  ///
+  /// reader.addNodeMap("color", colorMap);
+  /// \endcode
+  ///
+  /// With the \c addEdgeMap() member function you can give an edge map
+  /// reading command similar to the NodeMaps. 
+  ///
+  /// \code
+  /// reader.addEdgeMap("weight", weightMap);
+  /// reader.addEdgeMap("label", labelMap);
+  /// \endcode
+  ///
+  /// With \c addNode() and \c addEdge() functions you can read labeled Nodes 
+  /// and Edges.
+  ///
+  /// \code
+  /// reader.addNode("source", sourceNode);
+  /// reader.addNode("target", targetNode);
+  ///
+  /// reader.addEdge("observed", edge);
+  /// \endcode
+  ///
+  /// After you give all read commands you must call the \c run() member
+  /// function, which execute all the commands.
+  ///
+  /// \code
+  /// reader.run();
+  /// \endcode
+  ///
   /// \see DefaultReaderTraits
   /// \see QuotedStringReader
   /// \see \ref GraphWriter
   /// \see \ref graph-io-page
+  /// \author Balazs Dezso
   template <typename _Graph, typename _ReaderTraits = DefaultReaderTraits> 
   class GraphReader {
@@ -201,5 +270,4 @@
     /// Destruct the graph reader.
     ~GraphReader() {
-
       for (typename NodeMapReaders::iterator it = node_map_readers.begin(); 
 	   it != node_map_readers.end(); ++it) {
@@ -365,5 +433,4 @@
 	std::istringstream ls(line);	
 	while (ls >> id) {
-	  if (id[0] == '#') break;
 	  typename NodeMapReaders::iterator it = node_map_readers.find(id);
 	  if (it != node_map_readers.end()) {
@@ -373,19 +440,22 @@
 	    index.push_back(&nodeSkipper);
 	  }
-	}
-      }
-
-      if (index.size() == 0) {
-	throw DataFormatError("Cannot find node id map");
-      }
-
-      nodeInverter = 
-	std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
+	  if (ReaderTraits::idMapName(id) && nodeInverter.get() == 0) {
+	    nodeInverter.reset(index.back()->getInverter());
+	    index.back() = nodeInverter.get();
+	  }
+	}
+      }
+
+//       if (index.size() == 0) {
+// 	throw DataFormatError("Cannot find node id map");
+//       }
+
+//       nodeInverter = 
+// 	std::auto_ptr<InverterBase<Node> >(index[0]->getInverter());
       std::string line;
       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
 	Node node = graph.addNode();
 	std::istringstream ls(line);
-	nodeInverter->read(ls, node);
-	for (int i = 1; i < (int)index.size(); ++i) {
+	for (int i = 0; i < (int)index.size(); ++i) {
 	  index[i]->read(ls, node);
 	}
@@ -403,5 +473,4 @@
 	std::istringstream ls(line);	
 	while (ls >> id) {
-	  if (id[0] == '#') break;
 	  typename EdgeMapReaders::iterator it = edge_map_readers.find(id);
 	  if (it != edge_map_readers.end()) {
@@ -411,13 +480,20 @@
 	    index.push_back(&edgeSkipper);
 	  }
-	}
-      }
-
-      if (index.size() == 0) {
-	throw DataFormatError("Cannot find edge id map");
-      }
-
-      edgeInverter = 
-	std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
+	  if (ReaderTraits::idMapName(id) && edgeInverter.get() == 0) {
+	    edgeInverter.reset(index.back()->getInverter());
+	    index.back() = edgeInverter.get();
+	  }
+	}
+      }
+      
+      if (nodeInverter.get() == 0) {
+ 	throw DataFormatError("Cannot find node id map");
+      }
+//       if (index.size() == 0) {
+// 	throw DataFormatError("Cannot find edge id map");
+//       }
+
+//       edgeInverter = 
+// 	std::auto_ptr<InverterBase<Edge> >(index[0]->getInverter());
       std::string line;
       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {	
@@ -426,6 +502,5 @@
 	Node target = nodeInverter->read(ls);
 	Edge edge = graph.addEdge(source, target);
-	edgeInverter->read(ls, edge);
-	for (int i = 1; i < (int)index.size(); ++i) {
+	for (int i = 0; i < (int)index.size(); ++i) {
 	  index[i]->read(ls, edge);
 	}
@@ -437,4 +512,7 @@
 			  std::auto_ptr<InverterBase<Node> >& nodeInverter) {
       std::string line;
+      if (nodeInverter.get() == 0) {
+ 	throw DataFormatError("Cannot find node id map");
+      }
       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
 	std::istringstream ls(line);
@@ -452,4 +530,7 @@
 			  std::auto_ptr<InverterBase<Edge> >& edgeInverter) {
       std::string line;
+      if (edgeInverter.get() == 0) {
+ 	throw DataFormatError("Cannot find edge id map");
+      }
       while (line = readNotEmptyLine(is, line_num), line[0] != '@') {
 	std::istringstream ls(line);
@@ -467,6 +548,11 @@
       std::string line;
       while (++line_num, getline(is, line)) {	
-	int vi = line.find_first_not_of(" \t");
-	if (vi != (int)std::string::npos && line[vi] != '#') {
+	int vi = line.find('#');
+	if (vi != (int)::std::string::npos) {
+	  line = line.substr(0, vi);
+	}
+	vi = line.find_first_not_of(" \t");
+	if (vi != (int)std::string::npos) { 
+	  std::cerr << "Line: " << line.substr(vi) << std::endl;
 	  return line.substr(vi);
 	}
@@ -474,14 +560,18 @@
       throw DataFormatError("End of stream error");
     }
-    
-    // Inverters store and give back the Item from the id,
-    // and may put the ids into a map.
     
     template <typename _Item>
-    class InverterBase {
+    class ReaderBase;
+    
+    template <typename _Item>
+    class InverterBase : public ReaderBase<_Item> {
     public:
       typedef _Item Item;
       virtual void read(std::istream&, const Item&) = 0;
       virtual Item read(std::istream&) = 0;
+
+      virtual InverterBase<_Item>* getInverter() {
+	return this;
+      }
     };
 
@@ -652,5 +742,13 @@
   };
 
-  /// Ready to use reader function.  
+  /// \brief Read a graph from the input.
+  ///
+  /// Read a graph from the input.
+  /// \param is The input stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
+  /// \param s The source node.
+  /// \param t The target node.
+  /// \param cost The cost map.
   template<typename Graph, typename CapacityMap, typename CostMap>
   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
@@ -665,4 +763,12 @@
   }
 
+  /// \brief Read a graph from the input.
+  ///
+  /// Read a graph from the input.
+  /// \param is The input stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
+  /// \param s The source node.
+  /// \param t The target node.
   template<typename Graph, typename CapacityMap>
   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
@@ -675,4 +781,11 @@
   }
 
+  /// \brief Read a graph from the input.
+  ///
+  /// Read a graph from the input.
+  /// \param is The input stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
+  /// \param s The source node.
   template<typename Graph, typename CapacityMap>
   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity, 
@@ -684,4 +797,10 @@
   }
 
+  /// \brief Read a graph from the input.
+  ///
+  /// Read a graph from the input.
+  /// \param is The input stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
   template<typename Graph, typename CapacityMap>
   void readGraph(std::istream& is, Graph &g, CapacityMap& capacity) {
@@ -691,4 +810,9 @@
   }
 
+  /// \brief Read a graph from the input.
+  ///
+  /// Read a graph from the input.
+  /// \param is The input stream.
+  /// \param g The graph.
   template<typename Graph>
   void readGraph(std::istream& is, Graph &g) {
@@ -697,4 +821,5 @@
   }
 
+  /// @}
 }
 
Index: src/lemon/graph_writer.h
===================================================================
--- src/lemon/graph_writer.h	(revision 1311)
+++ src/lemon/graph_writer.h	(revision 1333)
@@ -38,8 +38,12 @@
 namespace lemon {
 
+  /// \addtogroup io_group
+  /// @{
+
   /// \brief Standard WriterTraits for the GraphWriter class.
   ///
   /// Standard WriterTraits for the GraphWriter class.
   /// It defines standard writing method for all type of value. 
+  /// \author Balazs Dezso
   struct DefaultWriterTraits {
 
@@ -47,4 +51,5 @@
     ///
     /// Template class for writing an value.
+    /// \author Balazs Dezso
     template <typename _Value>
     struct Writer {
@@ -60,4 +65,11 @@
     };
 
+    /// \brief Returns wheter this name is an ID map name.
+    ///
+    /// Returns wheter this name is an ID map name.
+    static bool idMapName(const std::string& name) {
+      return name == "id";
+    }
+
   };
 
@@ -67,4 +79,5 @@
   /// Writer class for quoted strings. It can process the escape
   /// sequences in the string.
+  /// \author Balazs Dezso
   class QuotedStringWriter {
   public:
@@ -147,10 +160,64 @@
   /// \brief The graph writer class.
   ///
-  ///\ingroup io_group
-  /// The writer class for the graph output.
+  /// The \c GraphWriter class provides the graph output. To write a graph
+  /// you should first give writing commands for the writer. You can declare
+  /// write command as \c NodeMap or \c EdgeMap writing and labeled Node and
+  /// Edge writing.
+  ///
+  /// \code
+  /// GraphWriter<ListGraph> writer(std::cout, graph);
+  /// \endcode
+  ///
+  /// The \c addNodeMap() function declares a \c NodeMap writing command in the
+  /// \c GraphWriter. You should give as parameter the name of the map and the
+  /// map object. The NodeMap writing command with name "id" should write a 
+  /// unique map because it is regarded as ID map.
+  ///
+  /// \code
+  /// IdMap<ListGraph, Node> nodeIdMap;
+  /// writer.addNodeMap("id", nodeIdMap);
+  ///
+  /// writer.addNodeMap("x-coord", xCoordMap);
+  /// writer.addNodeMap("y-coord", yCoordMap);
+  /// writer.addNodeMap("color", colorMap);
+  /// \endcode
+  ///
+  /// With the \c addEdgeMap() member function you can give an edge map
+  /// writing command similar to the NodeMaps.
+  ///
+  /// \code
+  /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> > 
+  ///   edgeDescMap(graph);
+  /// writer.addEdgeMap("descriptor", edgeDescMap);
+  ///
+  /// writer.addEdgeMap("weight", weightMap);
+  /// writer.addEdgeMap("label", labelMap);
+  /// \endcode
+  ///
+  /// With \c addNode() and \c addEdge() functions you can point out Nodes and
+  /// Edges in the graph. By example, you can write out the source and target
+  /// of the graph.
+  ///
+  /// \code
+  /// writer.addNode("source", sourceNode);
+  /// writer.addNode("target", targetNode);
+  ///
+  /// writer.addEdge("observed", edge);
+  /// \endcode
+  ///
+  /// After you give all write commands you must call the \c run() member
+  /// function, which execute all the writer commands.
+  ///
+  /// \code
+  /// writer.run();
+  /// \endcode
+  ///
   /// \see DefaultWriterTraits
   /// \see QuotedStringWriter
+  /// \see IdMap
+  /// \see DescriptorMap
   /// \see \ref GraphReader
   /// \see \ref graph-io-page
+  /// \author Balazs Dezso
   template <typename _Graph, typename _WriterTraits = DefaultWriterTraits> 
   class GraphWriter {
@@ -255,79 +322,14 @@
     /// Executes the writer commands.
     void run() {   
-      writeNodeSet();
-      writeEdgeSet();
-      writeNodes();
-      writeEdges();
+      WriterBase<Node>* nodeWriter = 0;
+      WriterBase<Edge>* edgeWriter = 0;
+      writeNodeSet(nodeWriter);
+      writeEdgeSet(nodeWriter, edgeWriter);
+      writeNodes(nodeWriter);
+      writeEdges(edgeWriter);
       os << "@end" << std::endl;
     }
 
   private:
-
-    void writeNodeSet() {
-      if (node_map_writers.size() == 0) return;
-      os << "@nodeset" << std::endl;
-      for (int i = 0; i < (int)node_map_writers.size(); ++i) {
-	os << node_map_writers[i].first << '\t';
-      } 
-      os << std::endl;
-      for (NodeIt it(graph); it != INVALID; ++it) {
-	for (int i = 0; i < (int)node_map_writers.size(); ++i) {
-	  node_map_writers[i].second->write(os, it);
-	}
-	os << std::endl;
-      }
-
-    }
-
-    void writeEdgeSet() {
-      if (edge_map_writers.size() == 0) return;
-      if (node_map_writers.size() == 0) {
-	//	ErrorMessage message;
-	//	message << "Missing node id map";
-	//	throw IOLogicError(message);
-      }
-      os << "@edgeset" << std::endl;
-      os << "\t\t";
-      for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
-	os << edge_map_writers[i].first << '\t';
-      } 
-      os << std::endl;
-      for (EdgeIt it(graph); it != INVALID; ++it) {
-	node_map_writers[0].second->write(os, graph.source(it));
-	node_map_writers[0].second->write(os, graph.target(it));
-	for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
-	  edge_map_writers[i].second->write(os, it);
-	}
-	os << std::endl;
-      }
-    }
-
-    void writeNodes() {
-      if (node_writers.size() == 0) return;
-      if (node_map_writers.size() == 0) {
-	//	throw Exception() << "Missing node id map";
-      }
-      os << "@nodes" << std::endl;
-      for (int i = 0; i < (int)node_writers.size(); ++i) {
-	os << node_writers[i].first << '\t';
-	node_map_writers[0].second->write(os, node_writers[i].second);
-	os << std::endl;
-      } 
-    }
-
-    void writeEdges() {
-      if (edge_writers.size() == 0) return;
-      if (edge_map_writers.size() == 0) {
-	//	throw Exception() << "Missing edge id map";
-      }
-      os << "@edges" << std::endl;
-      for (int i = 0; i < (int)edge_writers.size(); ++i) {
-	os << edge_writers[i].first << '\t';
-	edge_map_writers[0].second->write(os, edge_writers[i].second);
-	os << std::endl;
-      } 
-    }
-    
-    // Writers
 
     template <class _Item>
@@ -359,4 +361,74 @@
     };
 
+    void writeNodeSet(WriterBase<Node>* & nodeWriter) {
+      if (node_map_writers.size() == 0) return;
+      os << "@nodeset" << std::endl;
+      for (int i = 0; i < (int)node_map_writers.size(); ++i) {
+	const std::string& id = node_map_writers[i].first;
+	os << id << '\t';
+	if (WriterTraits::idMapName(id) && nodeWriter == 0) {
+	  nodeWriter = node_map_writers[i].second;
+	}
+      } 
+      os << std::endl;
+      for (NodeIt it(graph); it != INVALID; ++it) {
+	for (int i = 0; i < (int)node_map_writers.size(); ++i) {
+	  node_map_writers[i].second->write(os, it);
+	}
+	os << std::endl;
+      }
+
+    }
+
+    void writeEdgeSet(WriterBase<Node>* nodeWriter, 
+		      WriterBase<Edge>* & edgeWriter) {
+      if (nodeWriter == 0) {
+	throw DataFormatError("Cannot find node id map");
+      }
+      os << "@edgeset" << std::endl;
+      os << "\t\t";
+      for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
+	const std::string& id = edge_map_writers[i].first;
+	os << id << '\t';
+	if (WriterTraits::idMapName(id) && edgeWriter == 0) {
+	  edgeWriter = edge_map_writers[i].second;
+	}
+      } 
+      os << std::endl;
+      for (EdgeIt it(graph); it != INVALID; ++it) {
+	nodeWriter->write(os, graph.source(it));
+	nodeWriter->write(os, graph.target(it));
+	for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
+	  edge_map_writers[i].second->write(os, it);
+	}
+	os << std::endl;
+      }
+    }
+
+    void writeNodes(WriterBase<Node>* nodeWriter) {
+      if (nodeWriter == 0) {
+	throw DataFormatError("Cannot find node id map");
+      }
+      os << "@nodes" << std::endl;
+      for (int i = 0; i < (int)node_writers.size(); ++i) {
+	os << node_writers[i].first << '\t';
+	nodeWriter->write(os, node_writers[i].second);
+	os << std::endl;
+      } 
+    }
+
+    void writeEdges(WriterBase<Edge>* edgeWriter) {
+      if (edgeWriter == 0) {
+	throw DataFormatError("Cannot find node id map");
+      }
+      os << "@edges" << std::endl;
+      for (int i = 0; i < (int)edge_writers.size(); ++i) {
+	os << edge_writers[i].first << '\t';
+        edgeWriter->write(os, edge_writers[i].second);
+	os << std::endl;
+      } 
+    }
+    
+
 
 
@@ -380,5 +452,13 @@
   };
 
-  /// Ready to use writer function.  
+  /// \brief Write a graph to the output.
+  ///
+  /// Write a graph to the output.
+  /// \param os The output stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
+  /// \param s The source node.
+  /// \param t The target node.
+  /// \param cost The cost map.
   template<typename Graph, typename CapacityMap, typename CostMap>
   void writeGraph(std::ostream& os, const Graph &g, 
@@ -397,5 +477,12 @@
   }
 
-  /// Ready to use writer function.  
+  /// \brief Write a graph to the output.
+  ///
+  /// Write a graph to the output.
+  /// \param os The output stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
+  /// \param s The source node.
+  /// \param t The target node.
   template<typename Graph, typename CapacityMap>
   void writeGraph(std::ostream& os, const Graph &g, 
@@ -413,5 +500,11 @@
   }
 
-  /// Ready to use writer function.  
+  /// \brief Write a graph to the output.
+  ///
+  /// Write a graph to the output.
+  /// \param os The output stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
+  /// \param s The source node.
   template<typename Graph, typename CapacityMap>
   void writeGraph(std::ostream& os, const Graph &g, 
@@ -426,5 +519,11 @@
     reader.run();
   }
-  /// Ready to use writer function.  
+
+  /// \brief Write a graph to the output.
+  ///
+  /// Write a graph to the output.
+  /// \param os The output stream.
+  /// \param g The graph.
+  /// \param capacity The capacity map.
   template<typename Graph, typename CapacityMap>
   void writeGraph(std::ostream& os, const Graph &g, 
@@ -438,5 +537,10 @@
     reader.run();
   }
-  /// Ready to use writer function.  
+
+  /// \brief Write a graph to the output.
+  ///
+  /// Write a graph to the output.
+  /// \param os The output stream.
+  /// \param g The graph.
   template<typename Graph>
   void writeGraph(std::ostream& os, const Graph &g) {
@@ -449,4 +553,5 @@
   }
 
+  /// @}
 
 }
