Index: lemon/graph_reader.h
===================================================================
--- lemon/graph_reader.h	(revision 1435)
+++ lemon/graph_reader.h	(revision 1476)
@@ -262,4 +262,5 @@
     GraphReader& readEdge(std::string name, Edge& edge) {
       edge_reader.readEdge(name, edge);
+      return *this;
     }
 
Index: lemon/lemon_reader.h
===================================================================
--- lemon/lemon_reader.h	(revision 1435)
+++ lemon/lemon_reader.h	(revision 1476)
@@ -37,8 +37,31 @@
 #include <lemon/bits/item_reader.h>
 
+#include <lemon/concept_check.h>
+#include <lemon/concept/maps.h>
 
 namespace lemon {
 
   namespace _reader_bits {
+
+    template <typename Item>
+    class ItemIdReader {
+    public:
+
+      bool isIdReader() { return true; }
+
+      Item readId(std::istream&, Item) { return Item();}
+      
+      template <class _ItemIdReader>
+      struct Constraints {
+	void constraints() {
+	  bool b = reader.isIdReader();
+	  ignore_unused_variable_warning(b);
+	  Item item = reader.readId(is, Item());
+	}
+	_ItemIdReader& reader;
+	std::istream& is;
+      };
+
+    };
   
     template <typename T>
@@ -532,4 +555,5 @@
       typedef _Item Item;
       virtual Item read(std::istream& is) const = 0;
+      virtual bool isIdReader() const = 0;
     };
 
@@ -547,4 +571,8 @@
       virtual Item read(std::istream& is) const {
 	return boxedIdReader.readId(is, Item());
+      }
+
+      virtual bool isIdReader() const {
+	return boxedIdReader.isIdReader();
       }
     };
@@ -818,7 +846,8 @@
 		  const std::string& _id = std::string(),
 		  const DefaultSkipper& _skipper = DefaultSkipper()) 
-      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
-	nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {} 
-
+      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
+      checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
+      nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
+    }
     /// \brief Destructor.
     ///
@@ -922,4 +951,7 @@
     /// It reads the content of the section.
     virtual void read(std::istream& is) {
+      if (!nodeIdReader->isIdReader()) {
+	throw DataFormatError("Cannot find nodeset or ID map");
+      }
       std::vector<ReaderBase<Edge>* > index;
       std::string line;
@@ -1034,7 +1066,8 @@
 		       const std::string& _id = std::string(),
 		       const DefaultSkipper& _skipper = DefaultSkipper()) 
-      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper),
-	nodeIdReader(new IdReader<Node, NodeIdReader>(_nodeIdReader)) {} 
-
+      : Parent(_reader), graph(_graph), id(_id), skipper(_skipper) {
+      checkConcept<_reader_bits::ItemIdReader<Node>, NodeIdReader>();
+      nodeIdReader.reset(new IdReader<Node, NodeIdReader>(_nodeIdReader));
+    }
     /// \brief Destructor.
     ///
@@ -1198,4 +1231,7 @@
     /// It reads the content of the section.
     virtual void read(std::istream& is) {
+      if (!nodeIdReader->isIdReader()) {
+	throw DataFormatError("Cannot find nodeset or ID map");
+      }
       std::vector<ReaderBase<UndirEdge>* > index;
       std::string line;
@@ -1303,6 +1339,8 @@
     NodeReader(LemonReader& _reader, const _IdReader& _idReader, 
 	       const std::string& _id = std::string()) 
-      : Parent(_reader), id(_id), 
-	idReader(new IdReader<typename Graph::Node, _IdReader>(_idReader)) {} 
+      : Parent(_reader), id(_id) {
+      checkConcept<_reader_bits::ItemIdReader<Node>, _IdReader>();
+      idReader.reset(new IdReader<Node, _IdReader>(_idReader));
+    }
 
     /// \brief Destructor.
@@ -1348,4 +1386,7 @@
     /// It reads the content of the section.
     virtual void read(std::istream& is) {
+      if (!idReader->isIdReader()) {
+	throw DataFormatError("Cannot find nodeset or ID map");
+      }
       std::string line;
       while (getline(is, line)) {
@@ -1395,6 +1436,8 @@
     EdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
 	       const std::string& _id = std::string()) 
-      : Parent(_reader), id(_id), 
-	idReader(new IdReader<typename Graph::Edge, _IdReader>(_idReader)) {} 
+      : Parent(_reader), id(_id) {
+      checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
+      idReader.reset(new IdReader<Edge, _IdReader>(_idReader));
+    }
 
     /// \brief Destructor.
@@ -1439,4 +1482,7 @@
     /// It reads the content of the section.
     virtual void read(std::istream& is) {
+      if (!idReader->isIdReader()) {
+	throw DataFormatError("Cannot find edgeset or ID map");
+      }
       std::string line;
       while (getline(is, line)) {
@@ -1488,8 +1534,10 @@
     UndirEdgeReader(LemonReader& _reader, const _IdReader& _idReader, 
 	       const std::string& _id = std::string()) 
-      : Parent(_reader), id(_id), 
-	undirEdgeIdReader(new IdReader<UndirEdge, _IdReader>(_idReader)),
-	edgeIdReader(new IdReader<Edge, _IdReader>(_idReader))
-    {} 
+      : Parent(_reader), id(_id) {
+      checkConcept<_reader_bits::ItemIdReader<UndirEdge>, _IdReader>();
+      checkConcept<_reader_bits::ItemIdReader<Edge>, _IdReader>();
+      undirEdgeIdReader.reset(new IdReader<UndirEdge, _IdReader>(_idReader));
+      egdeIdReader.reset(new IdReader<Edge, _IdReader>(_idReader));
+    }
 
     /// \brief Destructor.
@@ -1546,4 +1594,10 @@
     /// It reads the content of the section.
     virtual void read(std::istream& is) {
+      if (!edgeIdReader->isIdReader()) {
+	throw DataFormatError("Cannot find undirected edgeset or ID map");
+      }
+      if (!undirEdgeIdReader->isIdReader()) {
+	throw DataFormatError("Cannot find undirected edgeset or ID map");
+      }
       std::string line;
       while (getline(is, line)) {
Index: lemon/lemon_writer.h
===================================================================
--- lemon/lemon_writer.h	(revision 1435)
+++ lemon/lemon_writer.h	(revision 1476)
@@ -37,6 +37,35 @@
 #include <lemon/maps.h>
 
+#include <lemon/concept_check.h>
+#include <lemon/concept/maps.h>
+
 
 namespace lemon {
+
+  namespace _writer_bits {
+    
+    template <typename Item>
+    class ItemIdWriter {
+    public:
+
+      bool isIdWriter() { return true; }
+
+      void writeId(std::ostream&, const Item&) {}
+      
+      template <class _ItemIdWriter>
+      struct Constraints {
+	void constraints() {
+	  const Item item;
+	  bool b = writer.isIdWriter();
+	  ignore_unused_variable_warning(b);
+	  writer.writeId(os, item);
+	}
+	_ItemIdWriter& writer;
+	std::ostream& os;
+      };
+
+    };
+
+  }
 
   /// \ingroup io_group
@@ -230,4 +259,5 @@
       typedef _Item Item;
       virtual void write(std::ostream&, const Item&) const = 0;
+      virtual bool isIdWriter() const = 0;
     };
 
@@ -245,4 +275,8 @@
       virtual void write(std::ostream& os, const Item& item) const {
 	idWriter.writeId(os, item);
+      }
+
+      virtual bool isIdWriter() const {
+	return idWriter.isIdWriter();
       }
     };
@@ -319,4 +353,5 @@
     NodeSetWriter& writeNodeMap(std::string name, const Map& map, 
 			    const Writer& writer = Writer()) {
+      checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>();
       writers.push_back(
 	make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
@@ -447,6 +482,8 @@
 		  bool _forceIdMap = true)
       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
-	graph(_graph), id(_id),
-	nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {} 
+	graph(_graph), id(_id) {
+      checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
+      nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
+    } 
 
     /// \brief Destructor.
@@ -481,4 +518,5 @@
     EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
 			    const Writer& writer = Writer()) {
+      checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
       writers.push_back(
 	make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer)));
@@ -499,4 +537,7 @@
     /// Write the content of the section.
     virtual void write(std::ostream& os) {
+      if (!nodeIdWriter->isIdWriter()) {
+	throw DataFormatError("Cannot find nodeset or ID map");
+      }
       for (int i = 0; i < (int)writers.size(); ++i) {
 	if (writers[i].first == "id") {
@@ -622,6 +663,8 @@
 		       bool _forceIdMap = true)
       : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
-	graph(_graph), id(_id),
-	nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {} 
+	graph(_graph), id(_id) {
+      checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>();
+      nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter));
+    } 
 
     /// \brief Destructor.
@@ -656,4 +699,5 @@
     UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, 
 					  const Writer& writer = Writer()) {
+      checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>();
       writers.push_back(
 	make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
@@ -666,4 +710,5 @@
     template <typename Map>
     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
+      checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
       writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
       writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
@@ -677,6 +722,7 @@
     UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, 
 				     const Writer& writer = Writer()) {
+      checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>();
       writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
-      writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
+      writeUndirEdge("-" + name, composeMap(backwardMap(graph), map), writer);
       return *this;
     }
@@ -695,4 +741,7 @@
     /// Write the content of the section.
     virtual void write(std::ostream& os) {
+      if (!nodeIdWriter->isIdWriter()) {
+	throw DataFormatError("Cannot find nodeset or ID map");
+      }
       for (int i = 0; i < (int)writers.size(); ++i) {
 	if (writers[i].first == "id") {
@@ -812,6 +861,9 @@
     NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
 	       const std::string& _id = std::string()) 
-      : Parent(_writer), id(_id), 
-	idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {} 
+      : Parent(_writer), id(_id) {
+      checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>();
+      idWriter.reset(new IdWriter<Node, _IdWriter>(_idWriter));
+    }
+
 
     /// \brief Destructor.
@@ -847,4 +899,7 @@
     /// Write the content of the section.
     virtual void write(std::ostream& os) {
+      if (!idWriter->isIdWriter()) {
+	throw DataFormatError("Cannot find nodeset or ID map");
+      }
       for (int i = 0; i < (int)writers.size(); ++i) {
 	os << writers[i].first << ' ';
@@ -888,6 +943,8 @@
     EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
 	       const std::string& _id = std::string()) 
-      : Parent(_writer), id(_id), 
-	idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {} 
+      : Parent(_writer), id(_id) {
+      checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
+      idWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
+    }
 
     /// \brief Destructor.
@@ -922,4 +979,7 @@
     /// Write the content of the section.
     virtual void write(std::ostream& os) {
+      if (!idWriter->isIdWriter()) {
+	throw DataFormatError("Cannot find edgeset or ID map");
+      }
       for (int i = 0; i < (int)writers.size(); ++i) {
 	os << writers[i].first << ' ';
@@ -967,7 +1027,10 @@
     UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, 
 	       const std::string& _id = std::string()) 
-      : Parent(_writer), id(_id), 
-	undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
-	edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
+      : Parent(_writer), id(_id) {
+      checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>();
+      checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>();
+      undirEdgeIdWriter.reset(new IdWriter<UndirEdge, _IdWriter>(_idWriter));
+      edgeIdWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter));
+    }
 
     /// \brief Destructor.
@@ -1009,4 +1072,10 @@
     /// Write the content of the section.
     virtual void write(std::ostream& os) {
+      if (!edgeIdWriter->isIdWriter()) {
+	throw DataFormatError("Cannot find undirected edgeset or ID map");
+      }
+      if (!undirEdgeIdWriter->isIdWriter()) {
+	throw DataFormatError("Cannot find undirected edgeset or ID map");
+      }
       for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
 	os << undirEdgeWriters[i].first << ' ';
