# HG changeset patch
# User Frantisek Csajka <csferi27@gmail.com>
# Date 1286198489 -7200
# Node ID 454f0c2a380c72615d988f0baa3655301cc7ed11
# Parent  a93f1a27d83125233114f2052c1e523c5e2f26e1
Blgf

diff -r a93f1a27d831 -r 454f0c2a380c doc/blgf.dox
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/blgf.dox	Mon Oct 04 15:21:29 2010 +0200
@@ -0,0 +1,89 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, 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.
+ *
+ */
+
+namespace lemon {
+/*!
+
+
+
+\page blgf-format Binary LEMON Graph Format (BLGF)
+
+The \e BLGF is a <em>binary</em>
+file format for storing graphs and associated data like
+node and edge maps.
+
+Each BLGF file starts with a signature, which are the "BLGF" letters followed by the two digit 
+version number.
+After that, the file consists of several blocks.
+Each block is preceded by its type, which is a 2 byte unsigned integer value (UINT16). 
+Currently, there are three types of blocks:
+
+- Nodes block
+- Arcs block
+- Attributes block
+
+Note: There may be several Nodes and Arcs blocks but only one Attributes block.
+
+\section Nodes Nodes block
+
+This type of block describes a set of nodes and associated maps. 
+It consists of two parts, the header and the data terminated by a null byte.
+The header contains the name of the block and 
+the number of nodes described (i.e. the item count in each map) stored as a 4 byte unsigned integer (UINT32).
+The data part contains the maps stored one after the other. The ﬁrst map in the Nodes
+block is a special one, called \c Label, which contains unique id (label) for each node.
+When describing end points of an arc, these ids are used to refer to the target and
+the source node. \c Label map has an empty name (i.e. only NULL byte) and it must
+not be absent! The order of nodes in each map must be the same (e.g. the i. item
+in each map describes the node labeled by the i. item in the \c Label map)!
+
+
+\section Arcs Arcs block
+
+This type of block is very similar to the Nodes block. It again starts with a
+header containing the name of the block and the number of items described (i.e. the
+number of arcs or edges). The diﬀerence between these two types of blocks is the following: the
+\c Label map is optional here and the ﬁrst map in this block must be the \c From-To map,
+which contains node pairs describing the source and the destination for each arc.
+The \c From-To map has also an empty name. If there is a \c Label map in Arcs block,
+it must be on the second place right after the \c From-To map.
+
+As in the Nodes block, the order of the arcs in the maps must be the same!
+
+\section Attributes Attributes  block
+
+As it was mentioned before, only one Attributes block can take place in the
+BLGF ﬁle. This block contains a null-terminated sequence of key-value pairs. The
+Attributes block contains no header, since the name is not necessary, and the type
+of the values is ﬁxed (STRING).
+
+
+\section Limitations Limitations
+
+Compared to LGF, the implementation of BLGF has some limitations:
+- Using real types with their default value converters, the BLGF becomes portable
+only on machines with the same memory endianness (i.e. big-endian or little-
+endian).
+- Long double type is not supported yet.
+- The values of the label maps must be fundamental types (integer, real or
+string).
+
+*/
+}
+
+//  LocalWords:  whitespace whitespaces
diff -r a93f1a27d831 -r 454f0c2a380c doc/groups.dox
--- a/doc/groups.dox	Mon Mar 08 08:33:41 2010 +0100
+++ b/doc/groups.dox	Mon Oct 04 15:21:29 2010 +0200
@@ -659,13 +659,14 @@
 postscript (EPS) format.
 */
 
+
 /**
-@defgroup lemon_io LEMON Graph Format
+@defgroup lemon_io LEMON Graph Formats
 @ingroup io_group
-\brief Reading and writing LEMON Graph Format.
+\brief Reading and writing LEMON Graph Format and its binary version.
 
 This group contains methods for reading and writing
-\ref lgf-format "LEMON Graph Format".
+\ref lgf-format "LEMON Graph Format" and \ref blgf-format "Binary LEMON Graph Format".
 */
 
 /**
diff -r a93f1a27d831 -r 454f0c2a380c doc/references.dox
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/references.dox	Mon Oct 04 15:21:29 2010 +0200
@@ -0,0 +1,254 @@
+/**
+\page references References
+
+\section amo93networkflows [AMO93]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Ravindra K. Ahuja, Thomas L. Magnanti, and James B. Orlin.
+<em>Network Flows: Theory, Algorithms, and Applications</em>.
+Prentice-Hall, Inc.,
+February 1993.
+</div>
+
+\section boost [Boost]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Boost C++ Libraries.
+<a href="http://www.boost.org/">http://www.boost.org/</a>.
+</div>
+
+\section bunnagel98efficient [BKV98]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Ursula B&uuml;nnagel, Bernhard Korte, and Jens Vygen.
+Efficient implementation of the Goldberg-Tarjan minimum-cost flow algorithm.
+<em>Optimization Methods and Software</em>,
+10:157-174,
+1998.
+</div>
+
+\section cmake [CMake]
+<div style="margin-top: -4ex; margin-left: 8em;">
+CMake -- Cross Platform Make.
+<a href="http://www.cmake.org/">http://www.cmake.org/</a>.
+</div>
+
+\section coinor [COIN-OR]
+<div style="margin-top: -4ex; margin-left: 8em;">
+COIN-OR -- Computational Infrastructure for Operations Research.
+<a href="http://www.coin-or.org/">http://www.coin-or.org/</a>.
+</div>
+
+\section cplex [CPLEX]
+<div style="margin-top: -4ex; margin-left: 8em;">
+ILOG CPLEX.
+<a href="http://www.ilog.com/">http://www.ilog.com/</a>.
+</div>
+
+\section cbc [Cbc]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Cbc -- Coin-Or Branch and Cut.
+<a href="http://projects.coin-or.org/Cbc/">http://projects.coin-or.org/Cbc/</a>.
+</div>
+
+\section clp [Clp]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Clp -- Coin-Or Linear Programming.
+<a href="http://projects.coin-or.org/Clp/">http://projects.coin-or.org/Clp/</a>.
+</div>
+
+\section clrs01algorithms [CLRS01]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein.
+<em>Introduction to Algorithms</em>.
+The MIT Press,
+2nd edition,
+2001.
+</div>
+
+\section dantzig63linearprog [Dan63]
+<div style="margin-top: -4ex; margin-left: 8em;">
+George B. Dantzig.
+<em>Linear Programming and Extensions</em>.
+Princeton University Press,
+1963.
+</div>
+
+\section dasdan98minmeancycle [DG98]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Ali Dasdan and Rajesh K. Gupta.
+Faster maximum and minimum mean cycle alogrithms for system performance analysis.
+<em>IEEE Transactions on Computer-Aided Design of Integrated Circuits and Systems</em>,
+17(10):889-899,
+1998.
+</div>
+
+\section dinic70algorithm [Din70]
+<div style="margin-top: -4ex; margin-left: 8em;">
+E. A. Dinic.
+Algorithm for solution of a problem of maximum flow in a network with power estimation.
+<em>Soviet Math. Doklady</em>,
+11:1277-1280,
+1970.
+</div>
+
+\section doxygen [Doxygen]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Doxygen -- Source code documentation generator tool.
+<a href="http://www.doxygen.org/">http://www.doxygen.org/</a>.
+</div>
+
+\section egres [EGRES]
+<div style="margin-top: -4ex; margin-left: 8em;">
+EGRES -- Egerv&aacute;ry Research Group on Combinatorial Optimization.
+<a href="http://www.cs.elte.hu/egres/">http://www.cs.elte.hu/egres/</a>.
+</div>
+
+\section edmondskarp72theoretical [EK72]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Jack Edmonds and Richard M. Karp.
+Theoretical improvements in algorithmic efficiency for network flow problems.
+<em>Journal of the ACM</em>,
+19(2):248-264,
+1972.
+</div>
+
+\section glpk [GLPK]
+<div style="margin-top: -4ex; margin-left: 8em;">
+GLPK -- GNU Linear Programming Kit.
+<a href="http://www.gnu.org/software/glpk/">http://www.gnu.org/software/glpk/</a>.
+</div>
+
+\section goldberg97efficient [Gol97]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Andrew V. Goldberg.
+An efficient implementation of a scaling minimum-cost flow algorithm.
+<em>Journal of Algorithms</em>,
+22(1):1-29,
+1997.
+</div>
+
+\section goldberg08partial [Gol08]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Andrew V. Goldberg.
+The partial augment-relabel algorithm for the maximum flow problem.
+<em>16th Annual European Symposium on Algorithms</em>,
+pages 466-477,
+2008.
+</div>
+
+\section goldberg88newapproach [GT88]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Andrew V. Goldberg and Robert E. Tarjan.
+A new approach to the maximum flow problem.
+<em>Journal of the ACM</em>,
+35(4):921-940,
+1988.
+</div>
+
+\section goldberg89cyclecanceling [GT89]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Andrew V. Goldberg and Robert E. Tarjan.
+Finding minimum-cost circulations by canceling negative cycles.
+<em>Journal of the ACM</em>,
+36(4):873-886,
+1989.
+</div>
+
+\section goldberg90approximation [GT90]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Andrew V. Goldberg and Robert E. Tarjan.
+Finding minimum-cost circulations by successive approximation.
+<em>Mathematics of Operations Research</em>,
+15(3):430-466,
+1990.
+</div>
+
+\section karp78characterization [Kar78]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Richard M. Karp.
+A characterization of the minimum cycle mean in a digraph.
+<em>Discrete Math.</em>,
+23:309-311,
+1978.
+</div>
+
+\section kellyoneill91netsimplex [KO91]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Damian J. Kelly and Garrett M. O'Neill.
+The minimum cost flow problem and the network simplex method.
+Master's thesis,
+University College,
+Dublin, Ireland,
+September 1991.
+</div>
+
+\section klein67primal [Kle67]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Morton Klein.
+A primal method for minimal cost flows with applications to the assignment and transportation problems.
+<em>Management Science</em>,
+14:205-220,
+1967.
+</div>
+
+\section leda [LEDA]
+<div style="margin-top: -4ex; margin-left: 8em;">
+LEDA -- Library of Efficient Data Types and Algorithms.
+<a href="http://www.algorithmic-solutions.com/">http://www.algorithmic-solutions.com/</a>.
+</div>
+
+\section lemon [LEMON]
+<div style="margin-top: -4ex; margin-left: 8em;">
+LEMON -- Library for Efficient Modeling and Optimization in Networks.
+<a href="http://lemon.cs.elte.hu/">http://lemon.cs.elte.hu/</a>,
+2009.
+</div>
+
+\section ledabook [MN99]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Kurt Mehlhorn and Stefan N&auml;her.
+<em>LEDA: A platform for combinatorial and geometric computing</em>.
+Cambridge University Press,
+New York, NY, USA,
+1999.
+</div>
+
+\section schrijver03combinatorial [Sch03]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Alexander Schrijver.
+<em>Combinatorial Optimization: Polyhedra and Efficiency</em>.
+Springer-Verlag,
+2003.
+</div>
+
+\section bglbook [SLL02]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Jeremy G. Siek, Lee-Quan Lee, and Andrew Lumsdaine.
+<em>The Boost Graph Library: User Guide and Reference Manual</em>.
+Addison-Wesley,
+2002.
+</div>
+
+\section sleator83dynamic [ST83]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Daniel D. Sleator and Robert E. Tarjan.
+A data structure for dynamic trees.
+<em>Journal of Computer and System Sciences</em>,
+26(3):362-391,
+1983.
+</div>
+
+\section soplex [SoPlex]
+<div style="margin-top: -4ex; margin-left: 8em;">
+SoPlex -- The Sequential Object-Oriented Simplex.
+<a href="http://soplex.zib.de/">http://soplex.zib.de/</a>.
+</div>
+
+\section stroustrup00cpp [Str00]
+<div style="margin-top: -4ex; margin-left: 8em;">
+Bjarne Stroustrup.
+<em>The C++ Programming Language</em>.
+Addison-Wesley Professional,
+3rd edition,
+February 2000.
+</div>
+
+*/
diff -r a93f1a27d831 -r 454f0c2a380c lemon/Makefile.am
--- a/lemon/Makefile.am	Mon Mar 08 08:33:41 2010 +0100
+++ b/lemon/Makefile.am	Mon Oct 04 15:21:29 2010 +0200
@@ -95,6 +95,7 @@
 	lemon/karp.h \
 	lemon/kruskal.h \
 	lemon/hao_orlin.h \
+	lemon/blgf.h \
 	lemon/lgf_reader.h \
 	lemon/lgf_writer.h \
 	lemon/list_graph.h \
diff -r a93f1a27d831 -r 454f0c2a380c lemon/blgf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lemon/blgf.h	Mon Oct 04 15:21:29 2010 +0200
@@ -0,0 +1,881 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2009
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, 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 lemon_io
+/// \file
+/// \brief \ref blgf-format "Binary LEMON Graph Format"'s common
+/// interfaces and constats.
+
+#ifndef _BLGF_H
+#define	_BLGF_H
+
+#include <limits>
+#include <sstream>
+#include <cstring>
+#include <lemon/config.h>
+#include <lemon/error.h>
+
+
+namespace lemon {
+  namespace _blgf_bits {
+
+#if LEMON_HAVE_LONG_LONG
+    typedef unsigned long long ULInt;
+    typedef long long int LInt;
+#else
+    typedef unsigned long ULInt;
+    typedef long int LInt;
+#endif
+
+    const char BLGF_VERSION[] = "BLGF01";
+
+    //----------------------------------------------
+    const unsigned int TYPE_GROUP_MASK = 0x0F0;
+    const unsigned int TYPE_UNSIGNED_BASE = 0x00;
+    const unsigned int TYPE_SIGNED_BASE = 0x10;
+    const unsigned int TYPE_REAL_BASE = 0x20;
+    const unsigned int TYPE_OTHER_BASE = 0x40;
+
+
+    enum BlgfType {
+      UINT8 = TYPE_UNSIGNED_BASE + 1,
+      UINT16,
+      UINT32,
+      UINT64,
+
+      INT8 = TYPE_SIGNED_BASE + 1,
+      INT16,
+      INT32,
+      INT64,
+
+      FLOAT = TYPE_REAL_BASE + 1,
+      DOUBLE,
+      //LONG_DOUBLE,
+      STRING = TYPE_OTHER_BASE + 1,
+      DATA
+    };
+
+    enum BlgfBlockType {
+      ATTRIBUTES,
+      NODES,
+      ARCS
+    };
+
+    const unsigned int UINT8_SIZE = 1;
+    const unsigned int INT8_SIZE = 1;
+
+    const unsigned int UINT16_SIZE = 2;
+    const unsigned int INT16_SIZE = 2;
+
+    const unsigned int UINT32_SIZE = 4;
+    const unsigned int INT32_SIZE = 4;
+
+    const unsigned int UINT64_SIZE = 8;
+    const unsigned int INT64_SIZE = 8;
+
+    const unsigned int FLOAT_SIZE = 4;
+    const unsigned int DOUBLE_SIZE = 8;
+    const unsigned int LONG_DOUBLE_SIZE = 8;
+
+    const unsigned int TYPE_SPEC_SIZE = UINT16_SIZE;
+    const BlgfType TYPE_SPEC_TYPE = UINT16;
+
+    const unsigned int BLOCK_SPEC_SIZE = UINT16_SIZE;
+    const BlgfType BLOCK_SPEC_TYPE = UINT16;
+
+    const unsigned int SIZE_SPEC_SIZE = UINT32_SIZE;
+    const BlgfType SIZE_SPEC_TYPE = INT32;
+
+    inline bool is_signed(BlgfType type) {
+      return (((type) & TYPE_GROUP_MASK) == TYPE_SIGNED_BASE);
+    }
+
+    inline bool is_unsigned(BlgfType type) {
+      return (((type) & TYPE_GROUP_MASK) == TYPE_UNSIGNED_BASE);
+    }
+
+    inline bool is_integer(BlgfType type) {
+      return (is_signed(type) || is_unsigned(type));
+    }
+
+    inline bool is_real(BlgfType type) {
+      return (((type) & TYPE_GROUP_MASK) == TYPE_REAL_BASE);
+    }
+
+    inline int get_type_size(BlgfType type) {
+      switch (type) {
+        case INT8:
+        case UINT8:
+          return INT8_SIZE;
+
+        case INT16:
+        case UINT16:
+          return INT16_SIZE;
+
+        case INT32:
+        case UINT32:
+          return INT32_SIZE;
+
+        case INT64:
+        case UINT64:
+          return INT64_SIZE;
+
+        case FLOAT:
+          return FLOAT_SIZE;
+
+        case DOUBLE:
+          return DOUBLE_SIZE;
+
+        case DATA:
+        case STRING:
+          return -1;
+
+        default:
+          throw ("Unknown type");
+      }
+
+    }
+  };
+
+  namespace _reader_bits {
+
+    template <typename Value>
+    struct DefaultValueConverter {
+
+      Value operator()(const std::string & str) {
+        std::istringstream is(str);
+        Value value;
+        if (!(is >> value)) {
+          throw FormatError("Cannot read token");
+        }
+
+        char c;
+        if (is >> std::ws >> c) {
+          throw FormatError("Remaining characters in token");
+        }
+        return value;
+      }
+    };
+
+    template <>
+    struct DefaultValueConverter<std::string> {
+
+      std::string operator()(const std::string & str) {
+        return str;
+      }
+    };
+
+    class SuperType {
+    private:
+
+      union {
+        _blgf_bits::ULInt _uint;
+        _blgf_bits::LInt _sint;
+
+        double _double;
+        float _float;
+      } _value;
+
+      _blgf_bits::BlgfType _type;
+      std::string _strvalue;
+      char *_cdata;
+
+      template <typename CppType>
+      void fromBinary(const char* array, int n, bool is_signed,
+        CppType& value) {
+        value = 0;
+        if (n < static_cast <int>( sizeof(CppType)) && is_signed &&
+          (array[0] & static_cast<char>(0x80)) != 0) {
+          value = -1;
+        }
+        for (register int i = 0; i != n; i++) {
+          value = value << static_cast<CppType>(8);
+          value = value | static_cast<CppType>(static_cast<CppType>(array[i]) & static_cast<CppType>(0xff));
+        }
+      }
+
+
+    public:
+
+      SuperType() {
+      }
+
+      void read(const _blgf_bits::BlgfType type, const char* buffer) {
+        _type = type;
+  
+        if (_blgf_bits::is_signed(_type)) {
+          fromBinary(buffer, get_type_size(type), is_signed(type), _value._sint);
+        } else if (_blgf_bits::is_unsigned(_type)) {
+          //if ((_type & _blgf_bits::TYPE_GROUP_MASK) == _blgf_bits::TYPE_UNSIGNED_BASE) {
+          fromBinary(buffer, get_type_size(type), is_signed(type), _value._uint);
+        } else if (_type == static_cast<unsigned int>(_blgf_bits::DOUBLE)) {
+          _value._double = *(reinterpret_cast<double*>(const_cast<char*>(buffer)));
+        } else if (_type == static_cast<unsigned int>(_blgf_bits::FLOAT)) {
+          _value._float = *(reinterpret_cast<float*>(const_cast<char*>(buffer)));//*(float*) (const_cast<char*>(buffer));
+        } else if (_type == static_cast<unsigned int>(_blgf_bits::STRING)) {
+          _strvalue = std::string(buffer);
+        } else if (_type == static_cast<unsigned int>(_blgf_bits::DATA)) {
+
+        } else {
+          throw FormatError("Unknown data type");
+        }
+
+      }
+
+      template<typename T>
+      operator T() {
+        if (_blgf_bits::is_signed(_type)) {
+          _blgf_bits::LInt val = _value._sint;
+
+          //check unsigned long long becouse it's size can not be converted to LInt
+          if (!std::numeric_limits<T>::is_signed) {
+            if (val >= 0 && static_cast<_blgf_bits::ULInt>(val)
+              <= static_cast<_blgf_bits::ULInt>(std::numeric_limits<T>::max()))
+              return val;
+            else
+              throw FormatError("Value out of range");
+          } else {
+            if (val <= std::numeric_limits<T>::max() && val
+              >= std::numeric_limits<T>::min())
+              return val;
+            else
+              throw FormatError("Value out of range");
+          }
+
+        } else if (_blgf_bits::is_unsigned(_type)) {
+          if (_value._uint <= static_cast<_blgf_bits::ULInt>(std::numeric_limits<T>::max()))
+            return _value._uint;
+          else
+            throw FormatError("Value out of range");
+
+        } else if (_type == _blgf_bits::STRING)
+          return DefaultValueConverter<T > ()(_strvalue);
+
+        else {
+          throw FormatError("Can not convert this type of value");
+        }
+
+      }
+
+      operator float() {
+        if (_type == _blgf_bits::FLOAT)
+          return _value._float;
+        else if (_type == _blgf_bits::DOUBLE){
+          if (_value._double > static_cast<double>(std::numeric_limits<float>::max()) ||
+            _value._double < static_cast<double>(std::numeric_limits<float>::min()))
+            throw FormatError("Float value out of range");
+          return _value._double;
+        }else if (_blgf_bits::is_signed(_type))
+          return _value._sint;
+        else if (_blgf_bits::is_unsigned(_type))
+          return _value._uint;
+        else if (_type == _blgf_bits::STRING)
+          return DefaultValueConverter<float>()(_strvalue);
+        else
+          throw FormatError("Not a float value");
+      };
+
+      operator double() {
+
+        if (_type == _blgf_bits::DOUBLE)
+          return _value._double;
+        else if (_type == _blgf_bits::FLOAT)
+          return _value._float;
+        else if (_blgf_bits::is_signed(_type))
+          return _value._sint;
+        else if (_blgf_bits::is_unsigned(_type))
+          return _value._uint;
+        else if (_type == _blgf_bits::STRING)
+          return DefaultValueConverter<double>()(_strvalue);
+        else
+          throw FormatError("Not a double value");
+      }
+
+      operator std::string() {
+        std::ostringstream os;
+        if (_blgf_bits::is_signed(_type)) {
+          os << this->operator _blgf_bits::LInt();
+        } else if (_blgf_bits::is_unsigned(_type)) {
+          os << _value._uint;
+        } else if (_type == _blgf_bits::DOUBLE) {
+          os << _value._double;
+        } else if (_type == _blgf_bits::FLOAT) {
+          os << _value._float;
+        } else if (_type == _blgf_bits::STRING) {
+          os << _strvalue;
+        } else {
+          throw FormatError("Cannot convert this type of data to string");
+        }
+
+        return os.str();
+      }
+
+
+    };
+
+    template <typename Value>
+    struct DefaultBinaryConverter {
+
+      Value operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
+        SuperType t;
+        t.read(blgfType, data);
+        Value val = t.operator Value();
+        return val;
+      };
+    };
+
+    template <>
+    struct DefaultBinaryConverter<float> {
+
+      float operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
+        SuperType t;
+        t.read(blgfType, data);
+        return t.operator float();
+
+      };
+    };
+
+    template <>
+    struct DefaultBinaryConverter<double> {
+
+      double operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
+        SuperType t;
+        t.read(blgfType, data);
+        return t.operator double();
+
+      };
+    };
+
+    template <>
+    struct DefaultBinaryConverter<std::string> {
+
+      std::string operator()(const _blgf_bits::BlgfType blgfType, const char* data) {
+        SuperType t;
+        t.read(blgfType, data);
+        return t.operator std::string();
+
+      };
+    };
+
+    inline std::istream& readStrBinary(std::istream& is, std::string& str) {
+      std::ostringstream os;
+      char c;
+
+      is.get(c);
+
+      while (is && c != 0) {
+        os << c;
+        is.get(c);
+      }
+      str = os.str();
+      if (!is)
+        throw FormatError("String not properly ended");
+      return is;
+    }
+
+    class BinaryToken {
+    private:
+      char* _data;
+      int _size;
+
+      char* read(std::istream& _is, const _blgf_bits::BlgfType type) {
+        if (_data != 0)
+          delete _data;
+
+        if ((type & _blgf_bits::TYPE_GROUP_MASK) == _blgf_bits::TYPE_OTHER_BASE) {
+
+          if (type == _blgf_bits::STRING) {
+            std::string s;
+            _reader_bits::readStrBinary(_is, s);
+            _size = s.length() + 1;
+            _data = new char[_size];
+            s.copy(_data, s.length(), 0);
+
+          } else if (type == _blgf_bits::DATA) {
+            char valueBuffer[16];
+            _is.read(valueBuffer, _blgf_bits::SIZE_SPEC_SIZE);
+            _size = _reader_bits::DefaultBinaryConverter<int>()(_blgf_bits::SIZE_SPEC_TYPE, valueBuffer);
+            _data = new char[_size];
+            _is.read(_data, _size);
+          }
+        } else {
+
+          _size = _blgf_bits::get_type_size(type);
+          _data = new char[_size];
+          _is.read(_data, _size);
+
+        }
+
+        if (!_is)
+          throw FormatError("Unexpected end of file");
+
+        return _data;
+      }
+    public:
+
+      BinaryToken() : _data(0), _size(0) {
+      }
+
+      BinaryToken(const BinaryToken& other) : _data(0), _size(0) {
+        if (this != &other && other.getSize() > 0) {
+          _data = new char[_size = other.getSize()];
+
+          std::memcpy(_data, other.getData(), _size);
+        }
+      }
+
+      BinaryToken & operator=(const BinaryToken& other) {
+        if (this != &other) {
+          delete _data;
+          _data = 0;
+
+          if ((_size = other.getSize()) > 0) {
+            _data = new char[_size];
+            std::memcpy(_data, other.getData(), _size);
+          }
+        }
+
+        return *this;
+      }
+
+      ~BinaryToken() {
+        delete _data;
+      }
+
+      char const * getData() const {
+        return _data;
+      }
+
+      int getSize() const {
+        return _size;
+      }
+
+      friend inline std::istream& readTokenBinary(std::istream& is, BinaryToken& token, const _blgf_bits::BlgfType type);
+    };
+
+    inline std::istream& readTokenBinary(std::istream& is, BinaryToken& token, const _blgf_bits::BlgfType type) {
+      token.read(is, type);
+      return is;
+    }
+
+    template<typename Value>
+    inline std::istream& readValueBinary(std::istream& is, _blgf_bits::BlgfType type, Value& value) {
+      _reader_bits::BinaryToken token;
+      readTokenBinary(is, token, type);
+      value = _reader_bits::DefaultBinaryConverter<Value > ()(type, token.getData());
+      return is;
+    }
+  };
+
+  namespace _writer_bits {
+
+    template <typename CppType>
+    void toBinary(CppType value, char* array, int n) {
+      //TODO: assert ??
+      throw FormatError("Not an integer type ");
+    };
+
+
+#define MK_INTEGER_TO_BINARY(CppType)\
+    template <> inline void toBinary<CppType>(CppType value, char* array, int n) {\
+      for (register int i = n - 1; i >= 0; i--) {\
+        array[i] = static_cast<char> (value & static_cast<CppType> (0xff));\
+        value = value >> static_cast<CppType>(8);\
+      }\
+    };
+
+    /*MK_INTEGER_TO_BINARY:
+     * Avoiding compilation error when using only specialised text converter.
+     * In this case default binary converter is defined even if it is not used
+     * and it causes a compilation error becouse the & operator is not defined
+     * for most custom data types. So template toBinary() used for serializing 
+     * integer types is defined throught these macros only for integer types,
+     * for others it throws error.
+    */
+
+    MK_INTEGER_TO_BINARY(char)
+    MK_INTEGER_TO_BINARY(signed char)
+    MK_INTEGER_TO_BINARY(unsigned char)
+
+    MK_INTEGER_TO_BINARY(signed short)
+    MK_INTEGER_TO_BINARY(unsigned short)
+
+    MK_INTEGER_TO_BINARY(signed int)
+    MK_INTEGER_TO_BINARY(unsigned int)
+
+    MK_INTEGER_TO_BINARY(signed long)
+    MK_INTEGER_TO_BINARY(unsigned long)
+
+#if LEMON_HAVE_LONG_LONG
+    MK_INTEGER_TO_BINARY(signed long long)
+    MK_INTEGER_TO_BINARY(unsigned long long)
+#endif
+
+    /// \ingroup lemon_io
+    ///
+    /// \brief Common interface for manipulating with specialized value
+    /// converters used in \ref blgf-format "BLGF" writer.
+    ///
+    /// This class defines an interface for manipulating with binary
+    /// representation of the data.
+    class BinaryTokenBase {
+    public:
+      /// \brief Destructor
+      ///
+      virtual ~BinaryTokenBase(){}
+
+      ///  \brief Get the \ref blgf-format "BLGF" type of the data.
+      ///
+      /// Get the \ref blgf-format "BLGF" type of the data.
+      virtual _blgf_bits::BlgfType getType() const {
+        return _blgf_bits::DATA;
+      };
+
+      /// \brief Get the binary representation's size (in bytes).
+      ///
+      /// Get the binary representation's size (in bytes).
+      virtual int getSize() const = 0;
+
+      /// \brief Copy converted data to buffer.
+      ///
+      /// Copy converted data to a specified buffer with a given size.
+      virtual int write(char* buffer, int buffer_size) const = 0;
+    };
+
+    /// \ingroup lemon_io
+    ///
+    /// \brief Base class for specialized value converters used in
+    ///  \ref blgf-format "BLGF" writer.
+    ///
+    /// This class is a base class for all binary converters used in
+    /// \ref blgf-format "BLGF" writer.
+    /// It defines an interface for value conversions and for
+    /// manipulations with the data.
+    template <typename Value>
+    class DefaultBinaryConverterBase : public BinaryTokenBase {
+    public:
+      /// \brief Set a new value for the converter.
+      /// 
+      /// Set a new value for the converter. The \ref blgf-format "BLGF"
+      /// type will be determined automatically.
+      virtual void setValue(const Value& value) = 0;
+
+      /// \brief Set a new value for the converter
+      ///
+      /// Sets a new value for the binary converter and specifies \ref blgf-format "BLGF"
+      /// type in which the data will be converted to.
+      virtual void setValue(const Value& value, const _blgf_bits::BlgfType type){
+        if (type != _blgf_bits::DATA)
+          throw FormatError("Error custom converter data type");
+
+        setValue(value);
+      }
+    };
+
+    //Used for integer types
+    template <typename Value>
+    class DefaultBinaryConverter : public DefaultBinaryConverterBase<Value> {
+    protected:
+      Value _value;
+      _blgf_bits::BlgfType _type;
+    public:
+
+      DefaultBinaryConverter() {
+      }
+
+      DefaultBinaryConverter(const Value& value) {
+        setValue(value);
+      }
+
+      void setValue(const Value& value, const _blgf_bits::BlgfType type) {
+        if (std::numeric_limits<Value>::is_integer && _blgf_bits::is_integer(type)) {
+          _value = value;
+          _type = type;
+          //TODO range check ?
+
+        } else
+          throw FormatError("Not an integer type");
+
+      }
+
+      virtual void setValue(const Value& value) {
+        _value = value;
+        if (std::numeric_limits<Value>::is_integer) {
+          if (std::numeric_limits<Value>::is_signed) {
+            if (sizeof (Value) <= _blgf_bits::INT8_SIZE)
+              _type = _blgf_bits::INT8;
+            else if (sizeof (Value) <= _blgf_bits::INT16_SIZE)
+              _type = _blgf_bits::INT16;
+            else if (sizeof (Value) <= _blgf_bits::INT32_SIZE)
+              _type = _blgf_bits::INT32;
+            else if (sizeof (Value) <= _blgf_bits::INT64_SIZE)
+              _type = _blgf_bits::INT64;
+            else
+              throw FormatError("Integer format too big");
+
+          } else {
+            if (sizeof (Value) <= _blgf_bits::UINT8_SIZE)
+              _type = _blgf_bits::UINT8;
+            else if (sizeof (Value) <= _blgf_bits::UINT16_SIZE)
+              _type = _blgf_bits::UINT16;
+            else if (sizeof (Value) <= _blgf_bits::UINT32_SIZE)
+              _type = _blgf_bits::UINT32;
+            else if (sizeof (Value) <= _blgf_bits::UINT64_SIZE)
+              _type = _blgf_bits::UINT64;
+            else
+              throw FormatError("Integer format too big");
+          }
+        } else if (std::numeric_limits<Value>::is_iec559) {
+          if (sizeof (Value) == _blgf_bits::FLOAT_SIZE)
+            _type = _blgf_bits::FLOAT;
+          else if (sizeof (Value) == _blgf_bits::DOUBLE_SIZE)
+            _type = _blgf_bits::DOUBLE;
+          else
+            throw FormatError("Unknown real type");
+        } else {
+          throw FormatError("Unknown type");
+        }
+
+
+      }
+
+      virtual _blgf_bits::BlgfType getType() const {
+        return _type;
+      }
+
+      virtual int getSize()const {
+        return _blgf_bits::get_type_size(_type);
+      }
+
+      virtual int write(char* buffer, const int buffer_size) const {
+        int size = getSize();
+        if (buffer_size < size) {
+          throw FormatError("Buffer too small");
+        }
+
+        if ((_blgf_bits::is_signed(_type)) ||
+          (_blgf_bits::is_unsigned(_type))) {
+
+          toBinary(_value, buffer, size);
+
+        } else if (_blgf_bits::is_real(_type)) {
+          for (register unsigned int i = 0; i< sizeof (Value); i++)
+            buffer[i] = (reinterpret_cast<char*>(const_cast<Value*>(& _value)))[i];
+        } else {
+          throw FormatError("Error");
+        }
+
+        return size;
+      }
+
+
+    };
+
+    template<>
+    class DefaultBinaryConverter<float> : public DefaultBinaryConverterBase<float> {
+    private:
+      float _value;
+      double _dvalue;
+      _blgf_bits::BlgfType _type;
+
+    public:
+
+      DefaultBinaryConverter() {
+
+      }
+
+      DefaultBinaryConverter(const float& value) {
+        setValue(value);
+      }
+
+      virtual void setValue(const float& value, const _blgf_bits::BlgfType type){
+        _type = type;
+        if (type == _blgf_bits::FLOAT){
+          _value = value;
+        }else if (type == _blgf_bits::DOUBLE){
+          _dvalue = value;
+        }else
+          throw FormatError("Can not convert float to this type");
+      }
+      
+      virtual void setValue(const float& value) {
+        setValue(value,_blgf_bits::FLOAT);
+      }
+
+      virtual _blgf_bits::BlgfType getType() const {
+        return _type;
+      }
+
+      virtual int getSize()const {
+        return _blgf_bits::get_type_size(_type);
+      }
+
+      virtual int write(char* buffer, const int buffer_size) const {
+        char* data = 0;
+        int size = getSize();
+
+        if (getType() == _blgf_bits::FLOAT)
+          data = reinterpret_cast<char*>(const_cast<float *>(&_value));
+        else if (getType() == _blgf_bits::DOUBLE)
+          data = reinterpret_cast<char*>(const_cast<double*>(&_dvalue));
+        else
+          throw FormatError("Can not convert float to this type of data");
+
+        if (buffer_size < size) {
+          throw FormatError("Buffer too small");
+        }
+        if (_blgf_bits::is_real(_type)) {
+          for (register int i = 0; i< size; i++)
+            buffer[i] = (data)[i];
+        } else {
+          throw FormatError("Error float converter");
+        }
+        return size;
+
+      }
+    };
+
+    template<>
+    class DefaultBinaryConverter<double> : public DefaultBinaryConverterBase<double> {
+    private:
+      double _value;
+      float _fvalue;
+      _blgf_bits::BlgfType _type;
+
+    public:
+
+      DefaultBinaryConverter() {
+
+      }
+
+      DefaultBinaryConverter(const double& value) {
+        setValue(value);
+      }
+
+      virtual void setValue(const double& value, const _blgf_bits::BlgfType type){
+         _type = type;
+        if (type == _blgf_bits::FLOAT){
+          if (value > static_cast<double>(std::numeric_limits<float>::max()) ||
+            value < static_cast<double>(std::numeric_limits<float>::min()))
+            throw FormatError("Float value out of range");
+          _fvalue = value;
+        }else if (type == _blgf_bits::DOUBLE){
+          _value = value;
+        }else
+          throw FormatError("Can not convert double to this type");
+      }
+
+      virtual void setValue(const double& value) {
+        setValue(value,_blgf_bits::DOUBLE);
+      }
+
+   
+      virtual _blgf_bits::BlgfType getType() const {
+        return _type;
+      }
+
+      virtual int getSize()const {
+        return _blgf_bits::get_type_size(_type);
+      }
+
+      virtual int write(char* buffer, const int buffer_size) const {
+        char * data = 0;
+        int size = getSize();
+        if (buffer_size < size) {
+          throw FormatError("Buffer too small");
+        }
+
+        if (getType() == _blgf_bits::FLOAT)
+          data = reinterpret_cast<char*>(const_cast<float*>(&_fvalue));
+        else if (getType() == _blgf_bits::DOUBLE)
+          data = reinterpret_cast<char*>(const_cast<double*>(&_value));
+        else
+          throw FormatError("Can not convert double to this type of data");
+
+        if (_blgf_bits::is_real(_type)) {
+          for (register int i = 0; i< size; i++)
+            buffer[i] = (data)[i];
+        } else {
+          throw FormatError("Error double converter");
+        }
+ 
+        return size;
+
+      }
+    };
+
+    template<>
+    class DefaultBinaryConverter<std::string> : public DefaultBinaryConverterBase<std::string> {
+    private:
+      std::string _value;
+      _blgf_bits::BlgfType _type;
+    public:
+
+      DefaultBinaryConverter() {
+
+      }
+
+      DefaultBinaryConverter(const std::string& value) {
+        setValue(value);
+      }
+
+
+      virtual void setValue(const std::string& value, const _blgf_bits::BlgfType type){
+        if (type != _blgf_bits::STRING)
+          throw FormatError("Cannot convert string to other type than STRING");
+        setValue(value);
+      }
+
+      void setValue(const std::string& value) {
+        _value = value;
+        _type = _blgf_bits::STRING;
+      }
+
+      virtual int write(char* buffer, const int buffer_size) const {
+        int size = getSize();
+        if (buffer_size < size) {
+          throw FormatError("Buffer too small");
+        }
+        for (register int i = 0; i < size; i++)
+          buffer[i] = _value.c_str()[i];
+        return size;
+      }
+
+      virtual int getSize()const {
+        return _value.length() + 1;
+      }
+
+      virtual _blgf_bits::BlgfType getType() const {
+        return _blgf_bits::STRING;
+      }
+    };
+
+    inline void writeDataBinary(std::ostream& os, const BinaryTokenBase& conv) {
+      int size = conv.getSize();
+      char *buff = new char[size];
+      conv.write(buff, conv.getSize());
+      os.write(buff, conv.getSize());
+      delete buff;
+    }
+
+  };
+
+};
+
+#endif	/* _BLGF_H */
+
diff -r a93f1a27d831 -r 454f0c2a380c lemon/lgf_reader.h
--- a/lemon/lgf_reader.h	Mon Mar 08 08:33:41 2010 +0100
+++ b/lemon/lgf_reader.h	Mon Oct 04 15:21:29 2010 +0200
@@ -18,12 +18,15 @@
 
 ///\ingroup lemon_io
 ///\file
-///\brief \ref lgf-format "LEMON Graph Format" reader.
+///\brief \ref lgf-format "LEMON Graph Format" and
+///\ref blgf-format "Binary LEMON Graph Format" reader.
 
 
 #ifndef LEMON_LGF_READER_H
 #define LEMON_LGF_READER_H
 
+#include  <string>
+
 #include <iostream>
 #include <fstream>
 #include <sstream>
@@ -33,13 +36,17 @@
 
 #include <lemon/core.h>
 
+#include <lemon/blgf.h>
 #include <lemon/lgf_writer.h>
 
 #include <lemon/concept_check.h>
 #include <lemon/concepts/maps.h>
 
+
+//#include <limits>
+
 namespace lemon {
-
+  
   namespace _reader_bits {
 
     template <typename Value>
@@ -76,37 +83,48 @@
       virtual ~MapStorageBase() {}
 
       virtual void set(const Item& item, const std::string& value) = 0;
+      virtual void setBinary(const Item& item ,const  char* data, const _blgf_bits::BlgfType blgfType) = 0;
 
     };
 
     template <typename _Item, typename _Map,
-              typename _Converter = DefaultConverter<typename _Map::Value> >
+              typename _Converter = DefaultConverter<typename _Map::Value>,
+              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
     class MapStorage : public MapStorageBase<_Item> {
     public:
       typedef _Map Map;
       typedef _Converter Converter;
+      typedef _BinaryConverter BinaryConverter;
       typedef _Item Item;
 
     private:
       Map& _map;
       Converter _converter;
+      BinaryConverter _binaryConverter;
 
     public:
-      MapStorage(Map& map, const Converter& converter = Converter())
-        : _map(map), _converter(converter) {}
+      MapStorage(Map& map, const Converter& converter = Converter(),
+              const BinaryConverter& binaryConverter = BinaryConverter())
+        : _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
       virtual ~MapStorage() {}
 
       virtual void set(const Item& item ,const std::string& value) {
         _map.set(item, _converter(value));
       }
+
+      virtual void setBinary(const Item& item ,const  char* data, const _blgf_bits::BlgfType blgfType) {
+        _map.set(item, _binaryConverter(blgfType,data));
+      }
     };
 
     template <typename _GR, bool _dir, typename _Map,
-              typename _Converter = DefaultConverter<typename _Map::Value> >
+              typename _Converter = DefaultConverter<typename _Map::Value>,
+              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
     class GraphArcMapStorage : public MapStorageBase<typename _GR::Edge> {
     public:
       typedef _Map Map;
       typedef _Converter Converter;
+      typedef _BinaryConverter BinaryConverter;
       typedef _GR GR;
       typedef typename GR::Edge Item;
       static const bool dir = _dir;
@@ -115,16 +133,22 @@
       const GR& _graph;
       Map& _map;
       Converter _converter;
+      BinaryConverter _binaryConverter;
 
     public:
       GraphArcMapStorage(const GR& graph, Map& map,
-                         const Converter& converter = Converter())
-        : _graph(graph), _map(map), _converter(converter) {}
+                         const Converter& converter = Converter(),
+                         const BinaryConverter& binaryConverter = BinaryConverter())
+        : _graph(graph), _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
       virtual ~GraphArcMapStorage() {}
 
       virtual void set(const Item& item ,const std::string& value) {
         _map.set(_graph.direct(item, dir), _converter(value));
       }
+
+      virtual void setBinary(const Item& item ,const char* data, const _blgf_bits::BlgfType blgfType) {
+        _map.set(_graph.direct(item, dir), _binaryConverter(blgfType,data));
+      }
     };
 
     class ValueStorageBase {
@@ -147,7 +171,8 @@
 
     public:
       ValueStorage(Value& value, const Converter& converter = Converter())
-        : _value(value), _converter(converter) {}
+        : _value(value), _converter(converter)
+        {}
 
       virtual void set(const std::string& value) {
         _value = _converter(value);
@@ -285,6 +310,9 @@
       }
     }
 
+    
+
+    
     inline std::istream& readToken(std::istream& is, std::string& str) {
       std::ostringstream os;
 
@@ -399,23 +427,26 @@
 
   /// \ingroup lemon_io
   ///
-  /// \brief \ref lgf-format "LGF" reader for directed graphs
+  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF"
+  /// reader for directed graphs.
   ///
-  /// This utility reads an \ref lgf-format "LGF" file.
+  /// This utility reads an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
+  /// It automatically recognizes whether it is an \ref lgf-format "LGF" or
+  /// a \ref blgf-format "BLGF" format.
   ///
   /// The reading method does a batch processing. The user creates a
   /// reader object, then various reading rules can be added to the
   /// reader, and eventually the reading is executed with the \c run()
   /// member function. A map reading rule can be added to the reader
   /// with the \c nodeMap() or \c arcMap() members. An optional
-  /// converter parameter can also be added as a standard functor
-  /// converting from \c std::string to the value type of the map. If it
-  /// is set, it will determine how the tokens in the file should be
-  /// converted to the value type of the map. If the functor is not set,
-  /// then a default conversion will be used. One map can be read into
-  /// multiple map objects at the same time. The \c attribute(), \c
-  /// node() and \c arc() functions are used to add attribute reading
-  /// rules.
+  /// converter parameters can also be added as a standard
+  /// functors converting from \c std::string or binary data
+  /// to the value type of the map. If it is set, it will determine how
+  /// the tokens in the file should be converted to the value type of
+  /// the map. If the functor is not set, then a default conversion will
+  /// be used. One map can be read into multiple map objects at the same time.
+  /// The \c attribute(), \c node() and \c arc() functions are used to add
+  /// attribute reading rules.
   ///
   ///\code
   /// DigraphReader<DGR>(digraph, std::cin).
@@ -427,8 +458,8 @@
   ///   run();
   ///\endcode
   ///
-  /// By default, the reader uses the first section in the file of the
-  /// proper type. If a section has an optional name, then it can be
+  /// By default, the reader uses the first section/block in the file of the
+  /// proper type. If a section/block has an optional name, then it can be
   /// selected for reading by giving an optional name parameter to the
   /// \c nodes(), \c arcs() or \c attributes() functions.
   ///
@@ -437,7 +468,7 @@
   /// graph) during the reading, but instead the label map of the items
   /// are given as a parameter of these functions. An
   /// application of these functions is multipass reading, which is
-  /// important if two \c \@arcs sections must be read from the
+  /// important if two \c \@arcs sections/blocks must be read from the
   /// file. In this case the first phase would read the node set and one
   /// of the arc sets, while the second phase would read the second arc
   /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
@@ -609,7 +640,7 @@
 
     /// \brief Node map reading rule
     ///
-    /// Add a node map reading rule with specialized converter to the
+    /// Add a node map reading rule with specialized text converter to the
     /// reader.
     template <typename Map, typename Converter>
     DigraphReader& nodeMap(const std::string& caption, Map& map,
@@ -621,6 +652,23 @@
       return *this;
     }
 
+
+     /// \brief Node map reading rule
+    ///
+    /// Add a node map reading rule with specialized text and  binary converters
+    /// to the reader.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    DigraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter(),
+                            const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+
     /// \brief Arc map reading rule
     ///
     /// Add an arc map reading rule to the reader.
@@ -635,7 +683,22 @@
 
     /// \brief Arc map reading rule
     ///
-    /// Add an arc map reading rule with specialized converter to the
+    /// Add an arc map reading rule with specialized text and binary converters
+    /// to the reader.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    DigraphReader& arcMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter(),
+                            const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Arc>* storage =
+        new _reader_bits::MapStorage<Arc, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _arc_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
+    /// Add an arc map reading rule with specialized text converter to the
     /// reader.
     template <typename Map, typename Converter>
     DigraphReader& arcMap(const std::string& caption, Map& map,
@@ -851,6 +914,148 @@
       }
     }
 
+    void skipMap(int itemCount, bool readCaption = true) {
+      std::string caption;
+      std::string str;
+
+      if (readCaption) {
+        _reader_bits::readStrBinary(*_is, caption);
+      }
+      
+      int type;
+      _reader_bits::readValueBinary(*_is,_blgf_bits::TYPE_SPEC_TYPE, type);
+
+      if (type == _blgf_bits::STRING) {
+        for (int i = 0; i < itemCount && readSuccess(); i++) {
+          _reader_bits::readStrBinary(*_is, str);
+        }
+      } else if (type == _blgf_bits::DATA) {
+        for (int i = 0; i < itemCount && readSuccess(); i++) {
+          int size;
+          _reader_bits::readValueBinary(*_is,_blgf_bits::SIZE_SPEC_TYPE, size);
+          _is->seekg(size, std::ios_base::cur);
+        }
+      } else {
+        _is->seekg(itemCount * _blgf_bits::get_type_size((_blgf_bits::BlgfType)type), std::ios_base::cur);
+      }
+
+     
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+
+    }
+
+    void skipBlock(_blgf_bits::BlgfBlockType type) {
+      int count;
+      char c;
+      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, count);
+
+
+      /* As the Label and From-To maps are obligatory and have empty names(only 0 byte)
+       * they have to be read before the loop.
+       */
+      if (type == _blgf_bits::ARCS)
+        skipMap(count * 2); //skip From-To map
+      if (type == _blgf_bits::NODES)
+        skipMap(count);  //skip Label map
+
+      _is->get(c);
+      while (readSuccess() && c != 0) {
+        _is->putback(c);
+        skipMap(count);
+        _is->get(c);
+      }
+     
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+      if (c != 0)
+        throw FormatError("Map is not properly closed");
+
+    }
+
+    void readNodesBinary() {
+      char c;
+      int size;
+      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
+      std::vector<Node> nodes(size);
+      std::set<std::string> maps;
+      std::string map_name;
+      int map_type;
+      bool label_map = true;
+
+      _is->get(c);
+      while (readSuccess() && (c!=0 || label_map) ) {
+        _is->putback(c);
+        //
+        _reader_bits::readStrBinary(*_is, map_name);
+        if (label_map) {
+          if (!map_name.empty())
+            throw FormatError("Label map not found");
+          map_name = "label";
+        }
+        //
+        std::set<std::string>::iterator mit = maps.find(map_name);
+
+        if (mit != maps.end()) {
+          std::ostringstream ss;
+          ss << "Multiple occurence of map: " << map_name;
+          throw FormatError(ss.str());
+        } else
+          maps.insert(map_name);
+        //
+        int map_index = 0;
+        for (map_index = 0; map_index < _node_maps.size() && _node_maps[map_index].first != map_name; map_index++);
+        //
+        if (!label_map && map_index == _node_maps.size()) {
+          skipMap(size, false);
+        } else {
+          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
+          for (int i = 0; i < size; i++) {
+            _reader_bits::BinaryToken token;
+            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
+
+            Node n;
+            if (label_map) {
+              if (!_use_nodes) {
+                n = _digraph.addNode();
+
+                _node_index.insert(
+                  std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
+                  , n));
+              } else {
+                typename std::map<std::string, Node>::iterator it =
+                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData()));
+                n = it->second;
+              }
+              nodes[i] = n;
+
+              //save to label map if exists
+              if (map_index < _node_maps.size())
+                _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
+
+            } else {
+              n = nodes[i];
+              _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
+            }
+
+          }
+        }
+        //
+        label_map = false;
+        _is->get(c);
+      }
+
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+      
+      if (c != 0)
+        throw FormatError("Nodes block is not properly closed.");
+
+      if (maps.size()< _node_maps.size())
+        throw FormatError("Not all maps have been read.");
+    }
+
+  
     void readNodes() {
 
       std::vector<int> map_index(_node_maps.size());
@@ -944,6 +1149,126 @@
       }
     }
 
+    void readArcsBinary(){
+      char c;
+      int size;
+      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
+      std::vector<Arc> arcs(size);
+      std::vector<std::string> labels(size);
+      std::set<std::string> maps;
+      std::string map_name;
+      int map_type;
+      bool from_to_map = true;
+
+      if(_use_arcs){
+        skipMap(2 * size);
+        from_to_map = false;
+      }
+
+      //
+      _is->get(c);
+      while (readSuccess() && (c != 0 || from_to_map)) {
+        _is->putback(c);
+        //
+        _reader_bits::readStrBinary(*_is, map_name);
+        if (from_to_map) {
+          if (!map_name.empty())
+            throw FormatError("From-to map not found");
+        }
+        //
+        std::set<std::string>::iterator mit = maps.find(map_name);
+
+        if (mit != maps.end()) {
+          std::ostringstream ss;
+          ss << "Multiple occurence of map: " << map_name;
+          throw FormatError(ss.str());
+        } else{
+          if (!map_name.empty())
+            maps.insert(map_name);
+        }
+        //
+        int map_index = 0;
+        for (map_index = 0; map_index < _arc_maps.size() && _arc_maps[map_index].first != map_name; map_index++);
+        //
+
+        if (!from_to_map && map_index == _arc_maps.size() && map_name !="label") {
+          skipMap(size, false);
+        } else {
+          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
+
+          for (int i = 0; i < size; i++) {
+            _reader_bits::BinaryToken token;
+            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
+
+            Arc a;
+            if (from_to_map) {
+              
+                typename std::map<std::string, Node>::iterator it =
+                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token.getData()));
+    
+                if (it == _node_index.end())
+                  throw FormatError("Source node not found");
+                Node source = it->second;
+
+                _reader_bits::BinaryToken token2;
+                _reader_bits::readTokenBinary(*_is,token2,(_blgf_bits::BlgfType)map_type);
+
+                it = _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token2.getData()));
+                if (it == _node_index.end())
+                  throw FormatError("Node u not found");
+                Node target = it->second;
+            
+                a = _digraph.addArc(source, target);
+
+                arcs[i] = a;
+            } else {
+
+              if (!_use_arcs){
+                a = arcs[i];
+                if (map_name =="label"){
+                  
+                  _arc_index.insert(
+                    std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
+                    , a));
+                }
+              }else{
+                if (map_name =="label"){
+                  labels[i] = _reader_bits::DefaultBinaryConverter<std::string>()((_blgf_bits::BlgfType)map_type,token.getData());
+                }
+
+                typename std::map<std::string, Arc>::iterator it =
+                  _arc_index.find(labels[i]);
+                if (it == _arc_index.end()) {
+                  std::ostringstream msg;
+                  msg << "Arc with label not found: " << labels[i];
+                  throw FormatError(msg.str());
+
+                }
+                a = it->second;
+              }
+              
+              //becouse of the label map
+              if (map_index < _arc_maps.size())
+                _arc_maps[map_index].second->setBinary(a, token.getData(), (_blgf_bits::BlgfType)map_type);
+            }
+          }
+        }
+        from_to_map = false;
+        //
+        _is->get(c);
+      }
+
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+      if (c != 0)
+        throw FormatError("Arcs block is not properly closed");
+
+      if (maps.size()< _arc_maps.size())
+        throw FormatError("Not all maps have been read.");
+
+    }
+  
+    
     void readArcs() {
 
       std::vector<int> map_index(_arc_maps.size());
@@ -1065,6 +1390,47 @@
       }
     }
 
+    void readAttributesBinary() {
+        std::set<std::string> read_attr;
+        char c;
+        std::string attr_name;
+        std::string attr_value;
+        
+        _is->get(c);
+        while (readSuccess() && c != 0) {
+        _is->putback(c);
+        
+        _reader_bits::readStrBinary(*_is, attr_name);
+        if (!readSuccess())
+          throw FormatError("Attribute name not found");
+        _reader_bits::readStrBinary(*_is, attr_value);
+        if (!readSuccess())
+          throw FormatError("Attribute value not found");
+        {
+          std::set<std::string>::iterator it = read_attr.find(attr_name);
+          if (it != read_attr.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of attribute: " << attr_name;
+            throw FormatError(msg.str());
+          }
+          read_attr.insert(attr_name);
+        }
+
+        {
+          typename Attributes::iterator it = _attributes.lower_bound(attr_name);
+          while (it != _attributes.end() && it->first == attr_name) {
+            it->second->set(attr_value);
+            ++it;
+          }
+        }
+
+        _is->get(c);
+      }
+
+      if (c != 0)
+        throw FormatError("Attribute block is not properly closed");
+    }
+
     void readAttributes() {
 
       std::set<std::string> read_attr;
@@ -1113,16 +1479,81 @@
       }
     }
 
-  public:
-
-    /// \name Execution of the Reader
-    /// @{
-
-    /// \brief Start the batch processing
-    ///
-    /// This function starts the batch processing
-    void run() {
-      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+    void runBinary() {
+      bool nodes_done = _skip_nodes;
+      bool arcs_done = _skip_arcs;
+      bool attributes_done = false;
+      char version[7];
+      std::string caption;
+
+      _is->read(version, 6);
+      version[7] = 0;
+      std::string s(version);
+
+      if (s.compare(0, 4, _blgf_bits::BLGF_VERSION, 0, 4) != 0)
+        throw FormatError("Unknown file format");
+
+      char c;
+      _is->get(c);
+      
+      while (readSuccess()){
+
+        _is->putback(c);
+
+        try {
+          int blockType = 0;
+         
+          if (!_reader_bits::readValueBinary(*_is,_blgf_bits::BLOCK_SPEC_TYPE,blockType))
+            throw FormatError("Unexpectedend of file");
+
+          if (blockType == _blgf_bits::NODES) {
+            _reader_bits::readStrBinary(*_is, caption);
+            
+            if ((!nodes_done) && (_nodes_caption.empty() || _nodes_caption == caption)) {
+              readNodesBinary();
+              nodes_done = true;
+            } else
+              skipBlock((_blgf_bits::BlgfBlockType) blockType);
+
+          } else if (blockType == _blgf_bits::ARCS) {
+            _reader_bits::readStrBinary(*_is, caption);
+            if ((!arcs_done) && (_arcs_caption.empty() || _arcs_caption == caption)) {
+              readArcsBinary();
+              arcs_done = true;
+            } else
+              skipBlock((_blgf_bits::BlgfBlockType)blockType);
+
+          } else if (blockType == _blgf_bits::ATTRIBUTES) {
+            readAttributesBinary();
+            attributes_done = true;
+          } else {
+            throw FormatError("Unrecognized type of block");
+          }
+
+        } catch (FormatError& error) {
+          error.file(_filename);
+          throw error;
+        }
+        _is->get(c);
+
+       
+      }
+
+      
+      if (!nodes_done) {
+        throw FormatError("Nodes block not found");
+      }
+
+      if (!arcs_done) {
+        throw FormatError("Arcs block not found");
+      }
+
+      if (!attributes_done && !_attributes.empty()) {
+        throw FormatError("Attributes block not found");
+      }
+    }
+
+    void runText() {
 
       bool nodes_done = _skip_nodes;
       bool arcs_done = _skip_arcs;
@@ -1174,7 +1605,7 @@
         throw FormatError("Section @nodes not found");
       }
 
-      if (!arcs_done) {
+      if (!arcs_done) { 
         throw FormatError("Section @arcs not found");
       }
 
@@ -1183,6 +1614,31 @@
       }
 
     }
+  public:
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing
+    void run() {
+
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      char c;
+     _is->get(c);
+      _is->putback(c);
+
+      if (c == _blgf_bits::BLGF_VERSION[0]){
+          runBinary();
+      }else{
+          runText();
+      }
+
+
+
+    }
 
     /// @}
 
@@ -1195,8 +1651,9 @@
   /// This function just returns a \ref DigraphReader class.
   ///
   /// With this function a digraph can be read from an 
-  /// \ref lgf-format "LGF" file or input stream with several maps and
-  /// attributes. For example, there is network flow problem on a
+  /// \ref lgf-format "LGF" or an \ref blgf-format "BLGF" file or input stream
+  /// with several maps and attributes.
+  /// For example, there is network flow problem on a
   /// digraph, i.e. a digraph with a \e capacity map on the arcs and
   /// \e source and \e target nodes. This digraph can be read with the
   /// following code:
@@ -1247,7 +1704,7 @@
     return tmp;
   }
 
-  template <typename GR>
+  template <typename GR> 
   class GraphReader;
  
   template <typename TGR>
@@ -1259,9 +1716,12 @@
 
   /// \ingroup lemon_io
   ///
-  /// \brief \ref lgf-format "LGF" reader for undirected graphs
+  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" reader for
+  /// undirected graphs
   ///
-  /// This utility reads an \ref lgf-format "LGF" file.
+  /// This utility reads an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
+  /// It automatically recognizes whether it is an \ref lgf-format "LGF" or
+  /// a \ref blgf-format "BLGF" format.
   ///
   /// It can be used almost the same way as \c DigraphReader.
   /// The only difference is that this class can handle edges and
@@ -1432,6 +1892,21 @@
 
     /// \brief Node map reading rule
     ///
+    /// Add a node map reading rule with specialized converters to the
+    /// reader.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    GraphReader& nodeMap(const std::string& caption, Map& map,
+                           const Converter& converter = Converter(),
+                            const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Node>* storage =
+        new _reader_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Node map reading rule
+    ///
     /// Add a node map reading rule with specialized converter to the
     /// reader.
     template <typename Map, typename Converter>
@@ -1456,6 +1931,20 @@
       return *this;
     }
 
+     /// \brief Edge map reading rule
+    ///
+    /// Add an edge map reading rule with specialized converters to the
+    /// reader.
+    template <typename Map, typename Converter,typename BinaryConverter>
+    GraphReader& edgeMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter(),
+                            const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* storage =
+        new _reader_bits::MapStorage<Edge, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
     /// \brief Edge map reading rule
     ///
     /// Add an edge map reading rule with specialized converter to the
@@ -1487,6 +1976,26 @@
 
     /// \brief Arc map reading rule
     ///
+    /// Add an arc map reading rule with specialized converters to the
+    /// reader.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    GraphReader& arcMap(const std::string& caption, Map& map,
+                          const Converter& converter = Converter(),
+                            const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
+      _reader_bits::MapStorageBase<Edge>* forward_storage =
+        new _reader_bits::GraphArcMapStorage<GR, true, Map, Converter, BinaryConverter>
+        (_graph, map, converter, binaryConverter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _reader_bits::MapStorageBase<Edge>* backward_storage =
+        new _reader_bits::GraphArcMapStorage<GR, false, Map, Converter,BinaryConverter>
+        (_graph, map, converter,binaryConverter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+      return *this;
+    }
+
+    /// \brief Arc map reading rule
+    ///
     /// Add an arc map reading rule with specialized converter to the
     /// reader.
     template <typename Map, typename Converter>
@@ -1515,6 +2024,7 @@
       return *this;
     }
 
+
     /// \brief Attribute reading rule
     ///
     /// Add an attribute reading rule with specialized converter to the
@@ -1721,6 +2231,149 @@
       }
     }
 
+    void skipMap(int itemCount, bool readCaption = true) {
+      std::string caption;
+      std::string str;
+
+      if (readCaption) {
+        _reader_bits::readStrBinary(*_is, caption);
+      }
+
+      int type;
+      _reader_bits::readValueBinary(*_is,_blgf_bits::TYPE_SPEC_TYPE, type);
+
+      if (type == _blgf_bits::STRING) {
+        for (int i = 0; i < itemCount && readSuccess(); i++) {
+          _reader_bits::readStrBinary(*_is, str);
+        }
+      } else if (type == _blgf_bits::DATA) {
+        for (int i = 0; i < itemCount && readSuccess(); i++) {
+          int size;
+          _reader_bits::readValueBinary(*_is,_blgf_bits::SIZE_SPEC_TYPE, size);
+          _is->seekg(size, std::ios_base::cur);
+        }
+      } else {
+        _is->seekg(itemCount * _blgf_bits::get_type_size((_blgf_bits::BlgfType)type), std::ios_base::cur);
+      }
+
+
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+
+    }
+
+    void skipBlock(_blgf_bits::BlgfBlockType type) {
+      int count;
+      char c;
+      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, count);
+
+      /* As the Label and From-To maps are obligatory and have empty names(only 0 byte)
+       * they have to be read before the loop.
+       */
+      if (type == _blgf_bits::ARCS)
+        skipMap(count * 2); //skip From-To map
+      if (type == _blgf_bits::NODES)
+        skipMap(count);  //skip Label map
+
+      _is->get(c);
+      while (readSuccess() && c != 0) {
+        _is->putback(c);
+        skipMap(count);
+        _is->get(c);
+      }
+
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+      if (c != 0)
+        throw FormatError("Map is not properly closed");
+
+    }
+
+    void readNodesBinary() {
+      char c;
+      int size;
+      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
+      std::vector<Node> nodes(size);
+      std::set<std::string> maps;
+      std::string map_name;
+      int map_type;
+      bool label_map = true;
+
+      _is->get(c);
+      while (readSuccess() && (c!=0 || label_map) ) {
+        _is->putback(c);
+        //
+        _reader_bits::readStrBinary(*_is, map_name);
+        if (label_map) {
+          if (!map_name.empty())
+            throw FormatError("Label map not found");
+          map_name = "label";
+        }
+        //
+        std::set<std::string>::iterator mit = maps.find(map_name);
+
+        if (mit != maps.end()) {
+          std::ostringstream ss;
+          ss << "Multiple occurence of map: " << map_name;
+          throw FormatError(ss.str());
+        } else
+          maps.insert(map_name);
+        //
+        int map_index = 0;
+        for (map_index = 0; map_index < _node_maps.size() && _node_maps[map_index].first != map_name; map_index++);
+        //
+        if (!label_map && map_index == _node_maps.size()) {
+          skipMap(size, false);
+        } else {
+
+          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
+          for (int i = 0; i < size; i++) {
+            _reader_bits::BinaryToken token;
+            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
+
+            Node n;
+            if (label_map) {
+              if (!_use_nodes) {
+                n = _graph.addNode();
+
+                _node_index.insert(
+                  std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
+                  , n));
+              } else {
+                typename std::map<std::string, Node>::iterator it =
+                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData()));
+                n = it->second;
+              }
+              nodes[i] = n;
+
+              //save to label map if exists
+              if (map_index < _node_maps.size())
+                _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
+
+            } else {
+              n = nodes[i];
+              _node_maps[map_index].second->setBinary(n, token.getData(), (_blgf_bits::BlgfType)map_type);
+            }
+
+          }
+        }
+        //
+        label_map = false;
+        _is->get(c);
+      }
+
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+
+      if (c != 0)
+        throw FormatError("Nodes block is not properly closed.");
+
+      if (maps.size()< _node_maps.size())
+        throw FormatError("Not all maps have been read.");
+    }
+
+  
+
     void readNodes() {
 
       std::vector<int> map_index(_node_maps.size());
@@ -1814,6 +2467,127 @@
       }
     }
 
+    void readEdgesBinary() {
+      char c;
+      int size;
+      _reader_bits::readValueBinary(*_is, _blgf_bits::SIZE_SPEC_TYPE, size);
+      std::vector<Edge> edges(size);
+      std::vector<std::string> labels(size);
+      std::set<std::string> maps;
+      std::string map_name;
+      int map_type;
+      bool from_to_map = true;
+
+      if(_use_edges){
+        skipMap(2 * size);
+        from_to_map = false;
+      }
+
+      //
+      _is->get(c);
+      while (readSuccess() && (c != 0 || from_to_map)) {
+        _is->putback(c);
+        //
+        _reader_bits::readStrBinary(*_is, map_name);
+        if (from_to_map) {
+          if (!map_name.empty())
+            throw FormatError("From-to map not found");
+        }
+        //
+        std::set<std::string>::iterator mit = maps.find(map_name);
+
+        if (mit != maps.end()) {
+          std::ostringstream ss;
+          ss << "Multiple occurence of map: " << map_name;
+          throw FormatError(ss.str());
+        } else{
+          if (!map_name.empty())
+            maps.insert(map_name);
+        }
+        //
+        int map_index = 0;
+        for (map_index = 0; map_index < _edge_maps.size() && _edge_maps[map_index].first != map_name; map_index++);
+        //
+
+        if (!from_to_map && map_index == _edge_maps.size() && map_name !="label") {
+          skipMap(size, false);
+        } else {
+          _reader_bits::readValueBinary(*_is, _blgf_bits::TYPE_SPEC_TYPE, map_type);
+
+          for (int i = 0; i < size; i++) {
+            _reader_bits::BinaryToken token;
+            _reader_bits::readTokenBinary(*_is,token,(_blgf_bits::BlgfType)map_type);
+
+            Edge e;
+            if (from_to_map) {
+
+                typename std::map<std::string, Node>::iterator it =
+                  _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token.getData()));
+
+                if (it == _node_index.end())
+                  throw FormatError("Source node not found");
+                Node u = it->second;
+
+                _reader_bits::BinaryToken token2;
+                _reader_bits::readTokenBinary(*_is,token2,(_blgf_bits::BlgfType)map_type);
+                
+                it = _node_index.find(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type,token2.getData()));
+                if (it == _node_index.end())
+                  throw FormatError("Node u not found");
+                Node v = it->second;
+
+                e = _graph.addEdge(u, v);
+
+                edges[i] = e;
+            } else {
+
+              if (!_use_edges){
+                e = edges[i];
+                if (map_name =="label"){
+
+                  _edge_index.insert(
+                    std::make_pair(_reader_bits::DefaultBinaryConverter<std::string > ()((_blgf_bits::BlgfType)map_type, token.getData())
+                    , e));
+                }
+              }else{
+                if (map_name =="label"){
+                  labels[i] = _reader_bits::DefaultBinaryConverter<std::string>()((_blgf_bits::BlgfType)map_type,token.getData());
+                }
+
+                typename std::map<std::string, Edge>::iterator it =
+                  _edge_index.find(labels[i]);
+                if (it == _edge_index.end()) {
+                  std::ostringstream msg;
+                  msg << "Edge with label not found: " << labels[i];
+                  throw FormatError(msg.str());
+
+                }
+                e = it->second;
+              }
+
+              //becouse of the label map
+              if (map_index < _edge_maps.size())
+                _edge_maps[map_index].second->setBinary(e, token.getData(), (_blgf_bits::BlgfType)map_type);
+            }
+          }
+        }
+        from_to_map = false;
+        //
+        _is->get(c);
+      }
+
+      if (!readSuccess())
+        throw FormatError("Unexpected end of file.");
+      if (c != 0)
+        throw FormatError("Edge block is not properly closed");
+
+      if (maps.size()< _edge_maps.size())
+        throw FormatError("Not all maps have been read.");
+
+    }
+
+
+
     void readEdges() {
 
       std::vector<int> map_index(_edge_maps.size());
@@ -1935,6 +2709,47 @@
       }
     }
 
+    void readAttributesBinary() {
+        std::set<std::string> read_attr;
+        char c;
+        std::string attr_name;
+        std::string attr_value;
+
+        _is->get(c);
+        while (readSuccess() && c != 0) {
+        _is->putback(c);
+
+        _reader_bits::readStrBinary(*_is, attr_name);
+        if (!readSuccess())
+          throw FormatError("Attribute name not found");
+        _reader_bits::readStrBinary(*_is, attr_value);
+        if (!readSuccess())
+          throw FormatError("Attribute value not found");
+        {
+          std::set<std::string>::iterator it = read_attr.find(attr_name);
+          if (it != read_attr.end()) {
+            std::ostringstream msg;
+            msg << "Multiple occurence of attribute: " << attr_name;
+            throw FormatError(msg.str());
+          }
+          read_attr.insert(attr_name);
+        }
+
+        {
+          typename Attributes::iterator it = _attributes.lower_bound(attr_name);
+          while (it != _attributes.end() && it->first == attr_name) {
+            it->second->set(attr_value);
+            ++it;
+          }
+        }
+
+        _is->get(c);
+      }
+
+      if (c != 0)
+        throw FormatError("Attribute block is not properly closed");
+    }
+
     void readAttributes() {
 
       std::set<std::string> read_attr;
@@ -1983,22 +2798,86 @@
       }
     }
 
-  public:
-
-    /// \name Execution of the Reader
-    /// @{
-
-    /// \brief Start the batch processing
-    ///
-    /// This function starts the batch processing
-    void run() {
-
-      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
-
+    void run_binary() {
       bool nodes_done = _skip_nodes;
       bool edges_done = _skip_edges;
       bool attributes_done = false;
-
+      char version[7];
+      std::string caption;
+
+      _is->read(version, 6);
+      version[7] = 0;
+      std::string s(version);
+
+      //TODO testing of the version number ??
+      if (s.compare(0, 4, _blgf_bits::BLGF_VERSION, 0, 4) != 0)
+        throw FormatError("Unknown file format");
+
+      char c;
+      _is->get(c);
+      
+      while (readSuccess()){
+        _is->putback(c);
+
+        try {
+          int blockType = 0;
+
+          if (!_reader_bits::readValueBinary(*_is,_blgf_bits::BLOCK_SPEC_TYPE,blockType))
+            throw FormatError("Unexpectedend of file");
+
+          if (blockType == _blgf_bits::NODES) {
+            _reader_bits::readStrBinary(*_is, caption);
+
+            if ((!nodes_done) && (_nodes_caption.empty() || _nodes_caption == caption)) {
+              readNodesBinary();
+              nodes_done = true;
+            } else
+              skipBlock((_blgf_bits::BlgfBlockType) blockType);
+
+          } else if (blockType == _blgf_bits::ARCS) {
+            _reader_bits::readStrBinary(*_is, caption);
+            if ((!edges_done) && (_edges_caption.empty() || _edges_caption == caption)) {
+              readEdgesBinary();
+              edges_done = true;
+            } else
+              skipBlock((_blgf_bits::BlgfBlockType)blockType);
+
+          } else if (blockType == _blgf_bits::ATTRIBUTES) {
+            readAttributesBinary();
+            attributes_done = true;
+          } else {
+            throw FormatError("Unrecognized type of block");
+          }
+
+        } catch (FormatError& error) {
+          error.file(_filename);
+          throw error;
+        }
+        _is->get(c);
+
+      }
+
+
+      if (!nodes_done) {
+        throw FormatError("Nodes block not found");
+      }
+
+      if (!edges_done) {
+        throw FormatError("Arcs block not found");
+      }
+
+      if (!attributes_done && !_attributes.empty()) {
+        throw FormatError("Attributes block not found");
+      }
+    }
+
+
+    void run_text() {
+
+      bool nodes_done = _skip_nodes;
+      bool edges_done = _skip_edges;
+      bool attributes_done = false;
+      
       line_num = 0;
       readLine();
       skipSection();
@@ -2052,6 +2931,35 @@
       if (!attributes_done && !_attributes.empty()) {
         throw FormatError("Section @attributes not found");
       }
+      
+    }
+
+
+  public:
+
+
+
+    /// \name Execution of the Reader
+    /// @{
+
+    /// \brief Start the batch processing
+    ///
+    /// This function starts the batch processing
+    void run() {
+
+      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
+
+      char c;
+     _is->get(c);
+      _is->putback(c);
+
+      if (c == _blgf_bits::BLGF_VERSION[0]){
+          run_binary();
+      }else{
+          run_text();
+      }
+
+     
 
     }
 
@@ -2066,7 +2974,7 @@
   /// This function just returns a \ref GraphReader class. 
   ///
   /// With this function a graph can be read from an 
-  /// \ref lgf-format "LGF" file or input stream with several maps and
+  /// \ref lgf-format "LGF" or an \ref blgf-format "BLGF" file or input stream with several maps and
   /// attributes. For example, there is weighted matching problem on a
   /// graph, i.e. a graph with a \e weight map on the edges. This
   /// graph can be read with the following code:
diff -r a93f1a27d831 -r 454f0c2a380c lemon/lgf_writer.h
--- a/lemon/lgf_writer.h	Mon Mar 08 08:33:41 2010 +0100
+++ b/lemon/lgf_writer.h	Mon Oct 04 15:21:29 2010 +0200
@@ -39,9 +39,11 @@
 #include <lemon/concept_check.h>
 #include <lemon/concepts/maps.h>
 
+#include <lemon/blgf.h>
+
 namespace lemon {
 
-  namespace _writer_bits {
+  namespace _writer_bits { 
 
     template <typename Value>
     struct DefaultConverter {
@@ -105,41 +107,59 @@
       virtual ~MapStorageBase() {}
 
       virtual std::string get(const Item& item) = 0;
+      
+      virtual BinaryTokenBase const* getBinary(const Item& item) = 0;
+
       virtual void sort(std::vector<Item>&) = 0;
     };
 
+
     template <typename _Item, typename _Map,
-              typename _Converter = DefaultConverter<typename _Map::Value> >
+              typename _Converter = DefaultConverter<typename _Map::Value>,
+              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
     class MapStorage : public MapStorageBase<_Item> {
     public:
       typedef _Map Map;
       typedef _Converter Converter;
+      typedef _BinaryConverter BinaryConverter;
       typedef _Item Item;
 
     private:
       const Map& _map;
       Converter _converter;
+      BinaryConverter _binaryConverter;
 
     public:
-      MapStorage(const Map& map, const Converter& converter = Converter())
-        : _map(map), _converter(converter) {}
+      MapStorage(const Map& map, const Converter& converter = Converter(),
+        const BinaryConverter& binaryConverter = BinaryConverter())
+        : _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
       virtual ~MapStorage() {}
 
       virtual std::string get(const Item& item) {
         return _converter(_map[item]);
       }
+
+      virtual BinaryTokenBase* getBinary(const Item& item) {
+        _binaryConverter.setValue(_map[item]);
+        return &_binaryConverter;
+        //return _converter(_map[item]);
+      }
+
       virtual void sort(std::vector<Item>& items) {
         MapLess<Map> less(_map);
         std::sort(items.begin(), items.end(), less);
       }
     };
 
+
     template <typename _Graph, bool _dir, typename _Map,
-              typename _Converter = DefaultConverter<typename _Map::Value> >
+              typename _Converter = DefaultConverter<typename _Map::Value>,
+              typename _BinaryConverter = DefaultBinaryConverter<typename _Map::Value> >
     class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
     public:
       typedef _Map Map;
       typedef _Converter Converter;
+      typedef _BinaryConverter BinaryConverter;
       typedef _Graph Graph;
       typedef typename Graph::Edge Item;
       static const bool dir = _dir;
@@ -148,16 +168,25 @@
       const Graph& _graph;
       const Map& _map;
       Converter _converter;
+      BinaryConverter _binaryConverter;
 
     public:
       GraphArcMapStorage(const Graph& graph, const Map& map,
-                         const Converter& converter = Converter())
-        : _graph(graph), _map(map), _converter(converter) {}
+                         const Converter& converter = Converter(),
+                         const BinaryConverter& binaryConverter = BinaryConverter())
+        : _graph(graph), _map(map), _converter(converter),_binaryConverter(binaryConverter) {}
       virtual ~GraphArcMapStorage() {}
 
       virtual std::string get(const Item& item) {
         return _converter(_map[_graph.direct(item, dir)]);
       }
+
+      virtual BinaryTokenBase* getBinary(const Item& item) {
+       ///_binaryConverter.setValue(_map[item]);
+        _binaryConverter.setValue(_map[_graph.direct(item, dir)]);
+        return &_binaryConverter;
+      }
+
       virtual void sort(std::vector<Item>& items) {
         GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
         std::sort(items.begin(), items.end(), less);
@@ -172,6 +201,7 @@
       virtual std::string get() = 0;
     };
 
+
     template <typename _Value, typename _Converter = DefaultConverter<_Value> >
     class ValueStorage : public ValueStorageBase {
     public:
@@ -184,11 +214,13 @@
 
     public:
       ValueStorage(const Value& value, const Converter& converter = Converter())
-        : _value(value), _converter(converter) {}
+        : _value(value), _converter(converter)
+        {}
 
       virtual std::string get() {
         return _converter(_value);
       }
+
     };
 
     template <typename Value>
@@ -206,6 +238,8 @@
         }
         return it->second;
       }
+
+
     };
 
     template <typename Graph>
@@ -362,14 +396,17 @@
 
   /// \ingroup lemon_io
   ///
-  /// \brief \ref lgf-format "LGF" writer for directed graphs
+  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" writer for directed graphs
   ///
-  /// This utility writes an \ref lgf-format "LGF" file.
+  /// This utility writes an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
   ///
   /// The writing method does a batch processing. The user creates a
   /// writer object, then various writing rules can be added to the
-  /// writer, and eventually the writing is executed with the \c run()
-  /// member function. A map writing rule can be added to the writer
+  /// writer, and eventually the writing is executed with the 
+  /// \c run(bool binary = false, bool append = false))
+  /// member function, where the \c binary parameter determines the file format and
+  /// the \c append tells the writer whether the file should be appended or not.
+  /// A map writing rule can be added to the writer
   /// with the \c nodeMap() or \c arcMap() members. An optional
   /// converter parameter can also be added as a standard functor
   /// converting from the value type of the map to \c std::string. If it
@@ -392,18 +429,19 @@
   ///
   ///
   /// By default, the writer does not write additional captions to the
-  /// sections, but they can be give as an optional parameter of
+  /// sections/blocks, but they can be given as an optional parameters of
   /// the \c nodes(), \c arcs() or \c
   /// attributes() functions.
   ///
   /// The \c skipNodes() and \c skipArcs() functions forbid the
-  /// writing of the sections. If two arc sections should be written
+  /// writing of the sections/blocks. If two arc sections/blocks should be written
   /// to the output, it can be done in two passes, the first pass
-  /// writes the node section and the first arc section, then the
-  /// second pass skips the node section and writes just the arc
-  /// section to the stream. The output stream can be retrieved with
+  /// writes the node section/block and the first arc section/block, then the
+  /// second pass skips the node section/block and writes just the arc
+  /// section/block to the stream. The output stream can be retrieved with
   /// the \c ostream() function, hence the second pass can append its
-  /// output to the output of the first pass.
+  /// output to the output of the first pass. In this case, if writing data binary,
+  /// \c run() method has to be called with both parameters set to true.
   template <typename DGR>
   class DigraphWriter {
   public:
@@ -565,6 +603,21 @@
       return *this;
     }
 
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule with specialized converters to the
+    /// writer.
+    template <typename Map, typename Converter,typename BinaryConverter>
+    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
+                           const Converter& converter = Converter(),
+                           const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Node>* storage =
+        new _writer_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
     /// \brief Arc map writing rule
     ///
     /// Add an arc map writing rule to the writer.
@@ -591,6 +644,21 @@
       return *this;
     }
 
+    /// \brief Arc map writing rule
+    ///
+    /// Add an arc map writing rule with specialized converters to the
+    /// writer.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    DigraphWriter& arcMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter(),
+                          const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Arc>* storage =
+        new _writer_bits::MapStorage<Arc, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _arc_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
     /// \brief Attribute writing rule
     ///
     /// Add an attribute writing rule to the writer.
@@ -615,12 +683,15 @@
       return *this;
     }
 
+
     /// \brief Node writing rule
     ///
     /// Add a node writing rule to the writer.
     DigraphWriter& node(const std::string& caption, const Node& node) {
       typedef _writer_bits::MapLookUpConverter<Node> Converter;
+
       Converter converter(_node_index);
+
       _writer_bits::ValueStorageBase* storage =
         new _writer_bits::ValueStorage<Node, Converter>(node, converter);
       _attributes.push_back(std::make_pair(caption, storage));
@@ -691,6 +762,133 @@
 
   private:
 
+    void writeNodesBinary() {
+      _writer_bits::MapStorageBase<Node>* label = 0;
+
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+        it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      std::vector<Node> nodes;
+      for (NodeIt n(_digraph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (nodes.size() == 0)
+        return;
+
+      if (label == 0) {
+        IdMap<DGR, Node> id_map(_digraph);
+        _writer_bits::MapLess<IdMap<DGR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      //BLOCK
+      //Type
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(_blgf_bits::NODES,_blgf_bits::BLOCK_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Caption
+      {
+
+        _writer_bits::DefaultBinaryConverter<std::string> conv(_nodes_caption);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Size
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        //int size  = static_cast<int>(nodes.size());
+        conv.setValue(static_cast<int>(nodes.size()),_blgf_bits::SIZE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //LABEL
+      //name
+      _os->put(0);
+      //type
+      {
+        _blgf_bits::BlgfType type;
+        if (label == 0 || static_cast<int>(nodes.size()) == 0)
+          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
+        else{
+          _writer_bits::BinaryTokenBase const*conv = label->getBinary(nodes[0]);
+          type = conv->getType();
+        }
+        //TODO: Documentatnion
+        if (type == _blgf_bits::DATA)
+          throw  FormatError("Labels must be a fundemental type");
+
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //data
+      for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
+        Node n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          int id = _digraph.id(n);
+          os << id;
+          
+          _writer_bits::DefaultBinaryConverter<int> conv(id);
+          _writer_bits::writeDataBinary(*_os,conv);
+
+          _node_index.insert(std::make_pair(n, os.str()));
+        } else {
+          //TODO: Documentation - get es nem getBinary
+          std::string value = label->get(n);
+
+          _writer_bits::BinaryTokenBase const* c = label->getBinary(n);
+          _writer_bits::writeDataBinary(*_os,*c);
+
+          _node_index.insert(std::make_pair(n, value));
+        }
+      }
+
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+        it != _node_maps.end(); ++it) {
+        if (it->first == "label")
+          continue;
+        
+        //Name
+        {
+          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+        //type
+        {
+          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
+          if (nodes.size()>0)
+            type = it->second->getBinary(nodes[0])->getType();
+
+          _writer_bits::DefaultBinaryConverter<int> conv;
+          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
+          _writer_bits::writeDataBinary(*_os, conv);
+        }
+        //Data
+        for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
+          Node n = nodes[i];
+          //
+          _writer_bits::BinaryTokenBase const * c = it->second->getBinary(n);
+          if (c->getType() == _blgf_bits::DATA){
+            _writer_bits::DefaultBinaryConverter<int> conv;
+            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
+            _writer_bits::writeDataBinary(*_os,conv);
+          }
+          _writer_bits::writeDataBinary(*_os,*c);
+        }
+      }
+
+      _os->put(0);
+    }
+
     void writeNodes() {
       _writer_bits::MapStorageBase<Node>* label = 0;
       for (typename NodeMaps::iterator it = _node_maps.begin();
@@ -775,6 +973,188 @@
       }
     }
 
+    void writeArcsBinary() {
+      _writer_bits::MapStorageBase<Arc>* label = 0;
+      _writer_bits::MapStorageBase<Node>* node_labels = 0;
+
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+        it != _arc_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+        it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          node_labels = it->second;
+          break;
+        }
+      }
+
+      std::vector<Arc> arcs;
+      for (ArcIt a(_digraph); a != INVALID; ++a) {
+        arcs.push_back(a);
+      }
+
+      if (arcs.size() == 0)
+        return;
+
+      if (label == 0) {
+        IdMap<DGR, Arc> id_map(_digraph);
+        _writer_bits::MapLess<IdMap<DGR, Arc> > id_less(id_map);
+        std::sort(arcs.begin(), arcs.end(), id_less);
+      } else {
+        label->sort(arcs);
+      }
+
+      //BLOCK
+      //Type
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(_blgf_bits::ARCS,_blgf_bits::BLOCK_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Caption
+      {
+
+        _writer_bits::DefaultBinaryConverter<std::string> conv(_arcs_caption);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Size
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(static_cast<int>(arcs.size()),_blgf_bits::SIZE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+
+      //FROM_TO
+      //name
+      _os->put(0);
+      //type
+      {
+        _blgf_bits::BlgfType type;
+        if (node_labels == 0 || static_cast<int> (arcs.size()) == 0)
+          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
+        else{
+
+          _writer_bits::BinaryTokenBase const* conv = node_labels->getBinary(_digraph.source(arcs[0]));
+          type = conv->getType();
+        }
+
+        if (type == _blgf_bits::DATA)
+          throw FormatError("Labels must be a fundemental type");
+        
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //data
+      for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
+        Arc a = arcs[i];
+
+        if (node_labels != 0) {
+          _writer_bits::BinaryTokenBase const * source = node_labels->getBinary(_digraph.source(a));
+          _writer_bits::writeDataBinary(*_os,*source);
+          _writer_bits::BinaryTokenBase const * target = node_labels->getBinary(_digraph.target(a));
+          _writer_bits::writeDataBinary(*_os,*target);
+
+        } else {
+          int source = _digraph.id(_digraph.source(a));
+          int target = _digraph.id(_digraph.target(a));
+          _writer_bits::DefaultBinaryConverter<int> conv;
+
+          conv.setValue(source);
+          _writer_bits::writeDataBinary(*_os,conv);
+
+          conv.setValue(target);
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+      }
+
+      if (label != 0) {
+        //Label
+        //name
+        {
+          _writer_bits::DefaultBinaryConverter<std::string> conv("label");
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+        //type
+        {
+          _blgf_bits::BlgfType type;
+          if (static_cast<int> (arcs.size()) == 0)
+            type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
+          else {
+            _writer_bits::BinaryTokenBase const * conv = label->getBinary(arcs[0]);
+            type = conv->getType();
+          }
+
+          if (type == _blgf_bits::DATA)
+            throw FormatError("Labels must be a fundemental type");
+          
+          _writer_bits::DefaultBinaryConverter<int> conv;
+          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
+          _writer_bits::writeDataBinary(*_os, conv);
+        }
+        //data
+        for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
+          Arc a = arcs[i];
+            _writer_bits::BinaryTokenBase const *conv = label->getBinary(a) ;
+            _writer_bits::writeDataBinary(*_os, *conv);
+
+             std::string value = label->get(a);
+            _arc_index.insert(std::make_pair(a, value));
+          }
+      }else{
+        for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
+          Arc a = arcs[i];
+          std::ostringstream os;
+          int id = _digraph.id(a);
+          os << id;
+
+          _arc_index.insert(std::make_pair(a, os.str()));
+        }
+      }
+
+
+      for (typename ArcMaps::iterator it = _arc_maps.begin();
+        it != _arc_maps.end(); ++it) {
+        if (it->first == "label")
+          continue;
+
+        //Name
+        {
+          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+        //type
+        {
+          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
+          if (arcs.size()>0)
+            type = it->second->getBinary(arcs[0])->getType();
+
+          _writer_bits::DefaultBinaryConverter<int> conv;
+          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
+          _writer_bits::writeDataBinary(*_os, conv);
+        }
+        //Data
+        for (int i = 0; i < static_cast<int> (arcs.size()); ++i) {
+          Arc n = arcs[i];
+          //
+          _writer_bits::BinaryTokenBase const *c = it->second->getBinary(n);
+          if (c->getType() == _blgf_bits::DATA){
+            _writer_bits::DefaultBinaryConverter<int> conv;
+            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
+            _writer_bits::writeDataBinary(*_os,conv);
+          }
+          _writer_bits::writeDataBinary(*_os,*c);
+        }
+      }
+      
+      _os->put(0);
+    }
+
     void writeArcs() {
       _writer_bits::MapStorageBase<Arc>* label = 0;
       for (typename ArcMaps::iterator it = _arc_maps.begin();
@@ -866,6 +1246,32 @@
       }
     }
 
+
+    void writeAttributesBinary() {
+      if (_attributes.size() == 0)
+        return;
+      //BLOCK
+      //Type
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(_blgf_bits::ATTRIBUTES,_blgf_bits::BLOCK_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+
+        _writer_bits::DefaultBinaryConverter<std::string> cstr(it->first);
+        _writer_bits::writeDataBinary(*_os,cstr);
+        
+        cstr.setValue(it->second->get());
+        _writer_bits::writeDataBinary(*_os,cstr);
+       
+      }
+
+      _os->put(0);
+    }
+
     void writeAttributes() {
       if (_attributes.empty()) return;
       *_os << "@attributes";
@@ -889,18 +1295,36 @@
     /// \brief Start the batch processing
     ///
     /// This function starts the batch processing.
-    void run() {
+    void run(bool binary = false, bool append = false) {
+
+      if (binary && !append){
+        _os->write(_blgf_bits::BLGF_VERSION,6);
+      }
+
+
       if (!_skip_nodes) {
-        writeNodes();
+        if (!binary)
+          writeNodes();
+        else
+          writeNodesBinary();
       } else {
         createNodeIndex();
       }
       if (!_skip_arcs) {
-        writeArcs();
+        if (!binary)
+          writeArcs();
+        else
+          writeArcsBinary();
       } else {
         createArcIndex();
       }
-      writeAttributes();
+      if (!binary)
+        writeAttributes();
+      else
+        writeAttributesBinary();
+
+      //if (binary)
+      //  _os->put(0);
     }
 
     /// \brief Give back the stream of the writer
@@ -920,7 +1344,7 @@
   /// This function just returns a \ref DigraphWriter class. 
   ///
   /// With this function a digraph can be write to a file or output
-  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// stream in \ref lgf-format "LGF" or \ref blgf-format "BLGF" format with several maps and
   /// attributes. For example, with the following code a network flow
   /// problem can be written to the standard output, i.e. a digraph
   /// with a \e capacity map on the arcs and \e source and \e target
@@ -986,9 +1410,9 @@
 
   /// \ingroup lemon_io
   ///
-  /// \brief \ref lgf-format "LGF" writer for directed graphs
+  /// \brief \ref lgf-format "LGF" and \ref blgf-format "BLGF" writer for undirected graphs
   ///
-  /// This utility writes an \ref lgf-format "LGF" file.
+  /// This utility writes an \ref lgf-format "LGF" or a \ref blgf-format "BLGF" file.
   ///
   /// It can be used almost the same way as \c DigraphWriter.
   /// The only difference is that this class can handle edges and
@@ -997,7 +1421,7 @@
   /// The arc maps are written into the file as two columns, the
   /// caption of the columns are the name of the map prefixed with \c
   /// '+' and \c '-'. The arcs are written into the \c \@attributes
-  /// section as a \c '+' or a \c '-' prefix (depends on the direction
+  /// section/block as a \c '+' or a \c '-' prefix (depends on the direction
   /// of the arc) and the label of corresponding edge.
   template <typename GR>
   class GraphWriter {
@@ -1144,6 +1568,22 @@
       return *this;
     }
 
+
+    /// \brief Node map writing rule
+    ///
+    /// Add a node map writing rule with specialized converters to the
+    /// writer.
+    template <typename Map, typename Converter,typename BinaryConverter>
+    GraphWriter& nodeMap(const std::string& caption, const Map& map,
+                           const Converter& converter = Converter(),
+                           const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Node>* storage =
+        new _writer_bits::MapStorage<Node, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _node_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
     /// \brief Node map writing rule
     ///
     /// Add a node map writing rule with specialized converter to the
@@ -1172,6 +1612,21 @@
 
     /// \brief Edge map writing rule
     ///
+    /// Add an edge map writing rule with specialized converters to the
+    /// writer.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    GraphWriter& edgeMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter(),
+                          const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
+      _writer_bits::MapStorageBase<Edge>* storage =
+        new _writer_bits::MapStorage<Edge, Map, Converter,BinaryConverter>(map, converter,binaryConverter);
+      _edge_maps.push_back(std::make_pair(caption, storage));
+      return *this;
+    }
+
+    /// \brief Edge map writing rule
+    ///
     /// Add an edge map writing rule with specialized converter to the
     /// writer.
     template <typename Map, typename Converter>
@@ -1201,6 +1656,29 @@
 
     /// \brief Arc map writing rule
     ///
+    /// Add an arc map writing rule with specialized converters to the
+    /// writer.
+    template <typename Map, typename Converter, typename BinaryConverter>
+    GraphWriter& arcMap(const std::string& caption, const Map& map,
+                          const Converter& converter = Converter(),
+                          const BinaryConverter& binaryConverter = BinaryConverter()) {
+      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
+
+      _writer_bits::MapStorageBase<Edge>* forward_storage =
+        new _writer_bits::GraphArcMapStorage<GR, true, Map, Converter,BinaryConverter>
+        (_graph, map, converter,binaryConverter);
+      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
+      _writer_bits::MapStorageBase<Edge>* backward_storage =
+        new _writer_bits::GraphArcMapStorage<GR, false, Map, Converter,BinaryConverter>
+        (_graph, map, converter,binaryConverter);
+      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
+
+
+      return *this;
+    }
+
+    /// \brief Arc map writing rule
+    ///
     /// Add an arc map writing rule with specialized converter to the
     /// writer.
     template <typename Map, typename Converter>
@@ -1218,6 +1696,9 @@
       return *this;
     }
 
+
+
+
     /// \brief Attribute writing rule
     ///
     /// Add an attribute writing rule to the writer.
@@ -1330,6 +1811,132 @@
 
   private:
 
+    void writeNodesBinary() {
+      _writer_bits::MapStorageBase<Node>* label = 0;
+
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+        it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      std::vector<Node> nodes;
+      for (NodeIt n(_graph); n != INVALID; ++n) {
+        nodes.push_back(n);
+      }
+
+      if (nodes.size() == 0)
+        return;
+
+      if (label == 0) {
+        IdMap<GR, Node> id_map(_graph);
+        _writer_bits::MapLess<IdMap<GR, Node> > id_less(id_map);
+        std::sort(nodes.begin(), nodes.end(), id_less);
+      } else {
+        label->sort(nodes);
+      }
+
+      //BLOCK
+      //Type
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(_blgf_bits::NODES,_blgf_bits::BLOCK_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Caption
+      {
+
+        _writer_bits::DefaultBinaryConverter<std::string> conv(_nodes_caption);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Size
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(static_cast<int>(nodes.size()),_blgf_bits::SIZE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //LABEL
+      //name
+      _os->put(0);
+      //type
+      {
+        _blgf_bits::BlgfType type;
+        if (label == 0 || static_cast<int>(nodes.size()) == 0)
+          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
+        else{
+          _writer_bits::BinaryTokenBase const*conv = label->getBinary(nodes[0]);
+          type = conv->getType();
+        }
+
+        if (type == _blgf_bits::DATA)
+          throw  FormatError("Labels must be a fundemental type");
+
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //data
+      for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
+        Node n = nodes[i];
+        if (label == 0) {
+          std::ostringstream os;
+          int id = _graph.id(n);
+          os << id;
+
+          _writer_bits::DefaultBinaryConverter<int> conv(id);
+          _writer_bits::writeDataBinary(*_os,conv);
+
+          _node_index.insert(std::make_pair(n, os.str()));
+        } else {
+
+          std::string value = label->get(n);
+
+          _writer_bits::BinaryTokenBase const* c = label->getBinary(n);
+          _writer_bits::writeDataBinary(*_os,*c);
+
+          _node_index.insert(std::make_pair(n, value));
+        }
+      }
+
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+        it != _node_maps.end(); ++it) {
+        if (it->first == "label")
+          continue;
+
+        //Name
+        {
+          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+        //type
+        {
+          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
+          if (nodes.size()>0)
+            type = it->second->getBinary(nodes[0])->getType();
+
+          _writer_bits::DefaultBinaryConverter<int> conv;
+          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
+          _writer_bits::writeDataBinary(*_os, conv);
+        }
+        //Data
+        for (int i = 0; i < static_cast<int> (nodes.size()); ++i) {
+          Node n = nodes[i];
+          //
+          _writer_bits::BinaryTokenBase const * c = it->second->getBinary(n);
+          if (c->getType() == _blgf_bits::DATA){
+            _writer_bits::DefaultBinaryConverter<int> conv;
+            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
+            _writer_bits::writeDataBinary(*_os,conv);
+          }
+          _writer_bits::writeDataBinary(*_os,*c);
+        }
+      }
+
+      _os->put(0);
+    }
+
     void writeNodes() {
       _writer_bits::MapStorageBase<Node>* label = 0;
       for (typename NodeMaps::iterator it = _node_maps.begin();
@@ -1414,6 +2021,187 @@
       }
     }
 
+     void writeEdgesBinary() {
+      _writer_bits::MapStorageBase<Edge>* label = 0;
+      _writer_bits::MapStorageBase<Node>* node_labels = 0;
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+        it != _edge_maps.end(); ++it) {
+        if (it->first == "label") {
+          label = it->second;
+          break;
+        }
+      }
+
+      for (typename NodeMaps::iterator it = _node_maps.begin();
+        it != _node_maps.end(); ++it) {
+        if (it->first == "label") {
+          node_labels = it->second;
+          break;
+        }
+      }
+
+      std::vector<Edge> edges;
+      for (EdgeIt e(_graph); e != INVALID; ++e) {
+        edges.push_back(e);
+      }
+
+      if (edges.size() == 0)
+        return;
+
+      if (label == 0) {
+        IdMap<GR, Edge> id_map(_graph);
+        _writer_bits::MapLess<IdMap<GR, Edge> > id_less(id_map);
+        std::sort(edges.begin(), edges.end(), id_less);
+      } else {
+        label->sort(edges);
+      }
+
+      //BLOCK
+      //Type
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(_blgf_bits::ARCS,_blgf_bits::BLOCK_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Caption
+      {
+        _writer_bits::DefaultBinaryConverter<std::string> conv(_edges_caption);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //Size
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(static_cast<int>(edges.size()),_blgf_bits::SIZE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+
+      //FROM_TO
+      //name
+      _os->put(0);
+      //type
+      {
+        _blgf_bits::BlgfType type;
+        if (node_labels == 0 || static_cast<int> (edges.size()) == 0)
+          type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
+        else{
+
+          _writer_bits::BinaryTokenBase const* conv = node_labels->getBinary(_graph.u(edges[0]));
+          type = conv->getType();
+        }
+        
+        if (type == _blgf_bits::DATA)
+          throw FormatError("Labels must be a fundemental type");
+
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(type,_blgf_bits::TYPE_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+      //data
+      for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
+        Edge e = edges[i];
+
+        if (node_labels != 0) {
+          _writer_bits::BinaryTokenBase const * u = node_labels->getBinary(_graph.u(e));
+          _writer_bits::writeDataBinary(*_os,*u);
+          _writer_bits::BinaryTokenBase const * v = node_labels->getBinary(_graph.v(e));
+          _writer_bits::writeDataBinary(*_os,*v);
+
+        } else {
+          int u = _graph.id(_graph.u(e));
+          int v = _graph.id(_graph.v(e));
+          _writer_bits::DefaultBinaryConverter<int> conv;
+
+          conv.setValue(u);
+          _writer_bits::writeDataBinary(*_os,conv);
+
+          conv.setValue(v);
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+      }
+
+      if (label != 0) {
+        //Label
+        //name
+        {
+          _writer_bits::DefaultBinaryConverter<std::string> conv("label");
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+        //type
+        {
+          _blgf_bits::BlgfType type;
+          if (static_cast<int> (edges.size()) == 0)
+            type = _writer_bits::DefaultBinaryConverter<int>(0).getType();
+          else {
+            _writer_bits::BinaryTokenBase const * conv = label->getBinary(edges[0]);
+            type = conv->getType();
+          }
+
+          if (type == _blgf_bits::DATA)
+            throw FormatError("Labels must be a fundemental type");
+
+          _writer_bits::DefaultBinaryConverter<int> conv;
+          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
+          _writer_bits::writeDataBinary(*_os, conv);
+        }
+        //data
+        for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
+          Edge e = edges[i];
+            _writer_bits::BinaryTokenBase const *conv = label->getBinary(e) ;
+            _writer_bits::writeDataBinary(*_os, *conv);
+
+             std::string value = label->get(e);
+            _edge_index.insert(std::make_pair(e, value));
+          }
+      }else{
+        for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
+          Edge e = edges[i];
+          std::ostringstream os;
+          int id = _graph.id(e);
+          os << id;
+
+          _edge_index.insert(std::make_pair(e, os.str()));
+        }
+      }
+
+
+      for (typename EdgeMaps::iterator it = _edge_maps.begin();
+        it != _edge_maps.end(); ++it) {
+        if (it->first == "label")
+          continue;
+
+        //Name
+        {
+          _writer_bits::DefaultBinaryConverter<std::string> conv(it->first);
+          _writer_bits::writeDataBinary(*_os,conv);
+        }
+        //type
+        {
+          _blgf_bits::BlgfType type = _blgf_bits::UINT8;
+          if (edges.size()>0)
+            type = it->second->getBinary(edges[0])->getType();
+
+          _writer_bits::DefaultBinaryConverter<int> conv;
+          conv.setValue(type, _blgf_bits::TYPE_SPEC_TYPE);
+          _writer_bits::writeDataBinary(*_os, conv);
+        }
+        //Data
+        for (int i = 0; i < static_cast<int> (edges.size()); ++i) {
+          Edge n = edges[i];
+          //
+          _writer_bits::BinaryTokenBase const *c = it->second->getBinary(n);
+          if (c->getType() == _blgf_bits::DATA){
+            _writer_bits::DefaultBinaryConverter<int> conv;
+            conv.setValue(c->getSize(),_blgf_bits::SIZE_SPEC_TYPE);
+            _writer_bits::writeDataBinary(*_os,conv);
+          }
+          _writer_bits::writeDataBinary(*_os,*c);
+        }
+      }
+
+      _os->put(0);
+    }
+
     void writeEdges() {
       _writer_bits::MapStorageBase<Edge>* label = 0;
       for (typename EdgeMaps::iterator it = _edge_maps.begin();
@@ -1505,6 +2293,30 @@
       }
     }
 
+    void writeAttributesBinary() {
+      if (_attributes.size() == 0)
+        return;
+      //BLOCK
+      //Type
+      {
+        _writer_bits::DefaultBinaryConverter<int> conv;
+        conv.setValue(_blgf_bits::ATTRIBUTES,_blgf_bits::BLOCK_SPEC_TYPE);
+        _writer_bits::writeDataBinary(*_os,conv);
+      }
+
+      for (typename Attributes::iterator it = _attributes.begin();
+           it != _attributes.end(); ++it) {
+
+        _writer_bits::DefaultBinaryConverter<std::string> cstr(it->first);
+        _writer_bits::writeDataBinary(*_os,cstr);
+
+        cstr.setValue(it->second->get());
+        _writer_bits::writeDataBinary(*_os,cstr);
+      }
+
+      _os->put(0);
+    }
+
     void writeAttributes() {
       if (_attributes.empty()) return;
       *_os << "@attributes";
@@ -1528,18 +2340,34 @@
     /// \brief Start the batch processing
     ///
     /// This function starts the batch processing.
-    void run() {
+    void run(bool binary = false, bool append = false) {
+
+      if (binary && !append){
+        _os->write(_blgf_bits::BLGF_VERSION,6);
+      }
+
+
       if (!_skip_nodes) {
-        writeNodes();
+        if (!binary)
+          writeNodes();
+        else
+          writeNodesBinary();
       } else {
         createNodeIndex();
       }
       if (!_skip_edges) {
-        writeEdges();
+        if (!binary)
+          writeEdges();
+        else
+          writeEdgesBinary();
       } else {
         createEdgeIndex();
       }
-      writeAttributes();
+      if (!binary)
+        writeAttributes();
+      else
+        writeAttributesBinary();
+
     }
 
     /// \brief Give back the stream of the writer
@@ -1559,7 +2387,7 @@
   /// This function just returns a \ref GraphWriter class. 
   ///
   /// With this function a graph can be write to a file or output
-  /// stream in \ref lgf-format "LGF" format with several maps and
+  /// stream in \ref lgf-format "LGF" or \ref blgf-format "BLGF" format with several maps and
   /// attributes. For example, with the following code a weighted
   /// matching problem can be written to the standard output, i.e. a
   /// graph with a \e weight map on the edges:
@@ -1833,3 +2661,4 @@
 }
 
 #endif
+
