Index: demo/Makefile.am
===================================================================
--- demo/Makefile.am	(revision 1678)
+++ demo/Makefile.am	(revision 1680)
@@ -15,5 +15,6 @@
 	sub_graph_adaptor_demo \
 	descriptor_map_demo \
-	coloring
+	coloring \
+	grid_graph_demo
 
 if HAVE_GLPK
@@ -38,4 +39,6 @@
 graph_to_eps_demo_SOURCES = graph_to_eps_demo.cc
 
+grid_graph_demo_SOURCES = grid_graph_demo.cc
+
 graph_orientation_SOURCES = graph_orientation.cc
 
Index: demo/grid_graph_demo.cc
===================================================================
--- demo/grid_graph_demo.cc	(revision 1680)
+++ demo/grid_graph_demo.cc	(revision 1680)
@@ -0,0 +1,29 @@
+#include <lemon/grid_graph.h>
+#include <lemon/graph_adaptor.h>
+#include <lemon/graph_to_eps.h>
+#include <lemon/xy.h>
+
+#include <iostream>
+#include <fstream>
+
+using namespace lemon;
+using namespace std;
+
+int main() {
+  GridGraph graph(5, 7);
+  GridGraph::NodeMap<xy<double> > coord(graph);
+  for (int i = 0; i < graph.width(); ++i) {
+    for (int j = 0; j < graph.height(); ++j) {
+      coord[graph(i, j)] = xy<double>(i * 10.0, j * 10.0);
+    }
+  }
+  graphToEps(graph, "grid_graph.eps").scaleToA4().
+    title("Grid graph").
+    copyright("(C) 2005 LEMON Project").
+    coords(coord).
+    enableParallel().
+    nodeScale(.45).
+    drawArrows().
+    run();
+  return 0;
+}
Index: lemon/grid_graph.h
===================================================================
--- lemon/grid_graph.h	(revision 1623)
+++ lemon/grid_graph.h	(revision 1680)
@@ -48,9 +48,58 @@
     ///
     /// Creates a grid graph with the given size.
-    void construct(int height, int width) {
+    void construct(int width, int height) {
       _height = height; _width = width;
       _nodeNum = height * width; _edgeNum = 2 * _nodeNum - width - height;
       _edgeLimit = _nodeNum - width;
     }
+
+    /// \brief Gives back the edge goes down from the node.
+    ///
+    /// Gives back the edge goes down from the node. If there is not
+    /// outgoing edge then it gives back INVALID.
+    Edge _down(Node n) const {
+      if (n.id < _nodeNum - _width) {
+	return Edge(n.id);
+      } else {
+	return INVALID;
+      }
+    }
+
+    /// \brief Gives back the edge comes from up into the node.
+    ///
+    /// Gives back the edge comes from up into the node. If there is not
+    /// incoming edge then it gives back INVALID.
+    Edge _up(Node n) const {
+      if (n.id >= _width) {
+	return Edge(n.id - _width);
+      } else {
+	return INVALID;
+      }
+    }
+
+    /// \brief Gives back the edge goes right from the node.
+    ///
+    /// Gives back the edge goes right from the node. If there is not
+    /// outgoing edge then it gives back INVALID.
+    Edge _right(Node n) const {
+      if (n.id % _width < _width - 1) {
+	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1);
+      } else {
+	return INVALID;
+      }
+    }
+
+    /// \brief Gives back the edge comes from left into the node.
+    ///
+    /// Gives back the edge comes left up into the node. If there is not
+    /// incoming edge then it gives back INVALID.
+    Edge _left(Node n) const {
+      if (n.id % _width > 0) {
+	return _edgeLimit + n.id % _width + (n.id / _width) * (_width - 1) - 1;
+      } else {
+	return INVALID;
+      }
+    }
+
 
   public:
@@ -60,5 +109,5 @@
     /// Gives back the node on the given position.
     Node operator()(int i, int j) const {
-      return Node(i * _width + j);
+      return Node(i + j * _width);
     }
 
@@ -73,5 +122,5 @@
     ///
     /// Gives back the coloumn index of the node.
-    int col(Node node) const {
+    int col(Node n) const {
       return n.id % _width;    
     }
@@ -278,12 +327,8 @@
 
 
-  typedef UndirGraphExtender<GridGraphBase>
-  UndirGridGraphBase;
-  typedef AlterableUndirGraphExtender<UndirGridGraphBase> 
-  AlterableGridGraphBase;
-  typedef IterableUndirGraphExtender<AlterableGridGraphBase> 
-  IterableGridGraphBase;
-  typedef MappableUndirGraphExtender<IterableGridGraphBase> 
-  MappableGridGraphBase;
+  typedef MappableUndirGraphExtender<
+    IterableUndirGraphExtender<
+    AlterableUndirGraphExtender<
+    UndirGraphExtender<GridGraphBase> > > > ExtendedGridGraphBase;
 
   /// \ingroup graphs
@@ -312,8 +357,45 @@
   ///
   /// \author Balazs Dezso
-  class GridGraph : public MappableGridGraphBase {
+  class GridGraph : public ExtendedGridGraphBase {
   public:
     
-    GridGraph(int m, int n) { construct(m, n); }
+    GridGraph(int n, int m) { construct(n, m); }
+    
+    /// \brief Gives back the edge goes down from the node.
+    ///
+    /// Gives back the edge goes down from the node. If there is not
+    /// outgoing edge then it gives back INVALID.
+    Edge down(Node n) const {
+      UndirEdge ue = _down(n);
+      return ue != INVALID ? direct(ue, true) : INVALID;
+    }
+    
+    /// \brief Gives back the edge goes up from the node.
+    ///
+    /// Gives back the edge goes up from the node. If there is not
+    /// outgoing edge then it gives back INVALID.
+    Edge up(Node n) const {
+      UndirEdge ue = _up(n);
+      return ue != INVALID ? direct(ue, false) : INVALID;
+    }
+
+    /// \brief Gives back the edge goes right from the node.
+    ///
+    /// Gives back the edge goes right from the node. If there is not
+    /// outgoing edge then it gives back INVALID.
+    Edge right(Node n) const {
+      UndirEdge ue = _right(n);
+      return ue != INVALID ? direct(ue, true) : INVALID;
+    }
+
+    /// \brief Gives back the edge goes left from the node.
+    ///
+    /// Gives back the edge goes left from the node. If there is not
+    /// outgoing edge then it gives back INVALID.
+    Edge left(Node n) const {
+      UndirEdge ue = _left(n);
+      return ue != INVALID ? direct(ue, false) : INVALID;
+    }
+    
   };
 }
Index: test/undir_graph_test.cc
===================================================================
--- test/undir_graph_test.cc	(revision 1568)
+++ test/undir_graph_test.cc	(revision 1680)
@@ -6,4 +6,5 @@
 #include <lemon/smart_graph.h>
 #include <lemon/full_graph.h>
+#include <lemon/grid_graph.h>
 
 #include <lemon/graph_utils.h>
@@ -44,10 +45,33 @@
 
   checkConcept<UndirGraph, UndirGraph>();
+
+  checkConcept<UndirGraph, GridGraph>();
 }
 
 template <typename Graph>
 void check_item_counts(Graph &g, int n, int e) {
-  check(countNodes(g)==n, "Wrong node number.");
-  check(countEdges(g)==2*e, "Wrong edge number.");
+  int nn = 0;
+  for (typename Graph::NodeIt it(g); it != INVALID; ++it) {
+    ++nn;
+  }
+
+  check(nn == n, "Wrong node number.");
+  check(countNodes(g) == n, "Wrong node number.");
+
+  int ee = 0;
+  for (typename Graph::EdgeIt it(g); it != INVALID; ++it) {
+    ++ee;
+  }
+
+  check(ee == 2*e, "Wrong edge number.");
+  check(countEdges(g) == 2*e, "Wrong edge number.");
+
+  int uee = 0;
+  for (typename Graph::UndirEdgeIt it(g); it != INVALID; ++it) {
+    ++uee;
+  }
+
+  check(uee == e, "Wrong undir edge number.");
+  check(countUndirEdges(g) == e, "Wrong undir edge number.");
 }
 
@@ -109,6 +133,48 @@
 
   check_item_counts(g,3,2);
-
-
+}
+
+void checkGridGraph(const GridGraph& g, int w, int h) {
+  check(g.width() == w, "Wrong width");
+  check(g.height() == h, "Wrong height");
+
+  for (int i = 0; i < w; ++i) {
+    for (int j = 0; j < h; ++j) {
+      check(g.col(g(i, j)) == i, "Wrong col");
+      check(g.row(g(i, j)) == j, "Wrong row");
+    }
+  }
+  
+  for (int i = 0; i < w; ++i) {
+    for (int j = 0; j < h - 1; ++j) {
+      check(g.source(g.down(g(i, j))) == g(i, j), "Wrong down");
+      check(g.target(g.down(g(i, j))) == g(i, j + 1), "Wrong down");
+    }
+    check(g.down(g(i, h - 1)) == INVALID, "Wrong down");
+  }
+
+  for (int i = 0; i < w; ++i) {
+    for (int j = 1; j < h; ++j) {
+      check(g.source(g.up(g(i, j))) == g(i, j), "Wrong up");
+      check(g.target(g.up(g(i, j))) == g(i, j - 1), "Wrong up");
+    }
+    check(g.up(g(i, 0)) == INVALID, "Wrong up");
+  }
+
+  for (int j = 0; j < h; ++j) {
+    for (int i = 0; i < w - 1; ++i) {
+      check(g.source(g.right(g(i, j))) == g(i, j), "Wrong right");
+      check(g.target(g.right(g(i, j))) == g(i + 1, j), "Wrong right");      
+    }
+    check(g.right(g(w - 1, j)) == INVALID, "Wrong right");    
+  }
+
+  for (int j = 0; j < h; ++j) {
+    for (int i = 1; i < w; ++i) {
+      check(g.source(g.left(g(i, j))) == g(i, j), "Wrong left");
+      check(g.target(g.left(g(i, j))) == g(i - 1, j), "Wrong left");      
+    }
+    check(g.left(g(0, j)) == INVALID, "Wrong left");    
+  }
 }
 
@@ -124,4 +190,12 @@
   }
 
+  {
+    GridGraph g(5, 6);
+    check_item_counts(g, 30, 49);
+    checkGridGraph(g, 5, 6);
+  }
+
+  std::cout << __FILE__ ": All tests passed.\n";
+
   return 0;
 }
