This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository abyss.

commit fe441e45d54dba1acfdaf67dbaa227f7e2d42e5b
Author: Andreas Tille <[email protected]>
Date:   Tue Nov 1 12:04:19 2016 +0100

    Imported Upstream version 2.0.2
---
 BloomDBG/bloom-dbg.cc                  |   5 +-
 ChangeLog                              |   5 +
 Common/Dictionary.h                    |   8 +
 Graph/DotIO.h                          |  59 +-
 Graph/GraphIO.h                        |   3 +-
 Graph/Makefile.am                      |   3 +-
 Graph/SAMIO.h                          |   1 +
 Graph/UndirectedGraph.h                | 948 +++++++++++++++++++++++++++++++++
 Konnector/DBGBloom.h                   |   9 +
 README.md                              |  26 +-
 Unittest/DBG/LoadAlgorithmTest.cpp     |   1 +
 Unittest/Graph/DotIOTest.cpp           | 115 ++++
 Unittest/Graph/UndirectedGraphTest.cpp |  54 ++
 Unittest/Makefile.am                   |  15 +
 configure.ac                           |  13 +-
 doc/ABYSS.1                            |   2 +-
 doc/abyss-pe.1                         |   2 +-
 doc/abyss-tofastq.1                    |   2 +-
 doc/flowchart.graffle                  |   2 +-
 19 files changed, 1250 insertions(+), 23 deletions(-)

diff --git a/BloomDBG/bloom-dbg.cc b/BloomDBG/bloom-dbg.cc
index 2c6a05b..9ace1d5 100644
--- a/BloomDBG/bloom-dbg.cc
+++ b/BloomDBG/bloom-dbg.cc
@@ -41,8 +41,9 @@ static const char USAGE_MESSAGE[] =
 "\n"
 "Basic Options:\n"
 "\n"
-"  -b  --bloom-size=N         Bloom filter memory size with unit suffix\n"
-"                             'k', 'M', or 'G' [required]\n"
+"  -b  --bloom-size=N         overall memory budget for the assembly in 
bytes.\n"
+"                             Unit suffixes 'k' (kilobytes), 'M' 
(megabytes),\n"
+"                             or 'G' (gigabytes) may be used. [required]\n"
 "      --chastity             discard unchaste reads [default]\n"
 "      --no-chastity          do not discard unchaste reads\n"
 "  -g  --graph=FILE           write de Bruijn graph to FILE (GraphViz)\n"
diff --git a/ChangeLog b/ChangeLog
index 368e132..f07eade 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2016-10-21  Ben Vandervalk <[email protected]>
+
+       * Release version 2.0.2
+       * Fix compile errors with gcc 6 and boost 1.62
+
 2016-09-14  Ben Vandervalk <[email protected]>
 
        * Release version 2.0.1
diff --git a/Common/Dictionary.h b/Common/Dictionary.h
index 88f227a..f917fc4 100644
--- a/Common/Dictionary.h
+++ b/Common/Dictionary.h
@@ -100,6 +100,14 @@ class Dictionary
                        return m_vec.back();
                }
 
+               /** Clear dictionary contents and reset to default state. */
+               void clear()
+               {
+                       m_map.clear();
+                       m_vec.clear();
+                       m_locked = false;
+               }
+
        private:
                Map m_map;
                Vector m_vec;
diff --git a/Graph/DotIO.h b/Graph/DotIO.h
index 1c8449e..af76ed4 100644
--- a/Graph/DotIO.h
+++ b/Graph/DotIO.h
@@ -133,15 +133,61 @@ DotWriter<Graph> dot_writer(const Graph& g)
        return DotWriter<Graph>(g);
 }
 
+/** legal characters for an unquoted node ID */
+static const uint8_t GRAPHVIZ_ID_CHARS[256] = {
+       0, 0, 0, 0, 0, 0, 0, 0, // 000-007:
+       0, 0, 0, 0, 0, 0, 0, 0, // 008-015:
+       0, 0, 0, 0, 0, 0, 0, 0, // 016-023:
+       0, 0, 0, 0, 0, 0, 0, 0, // 024-031:
+       0, 0, 0, 0, 0, 0, 0, 0, // 032-039:    !, ", #, $, %, &, ',
+       0, 0, 0, 1, 0, 1, 1, 0, // 040-047: (, ), *, +, ,, -, ., /,
+       1, 1, 1, 1, 1, 1, 1, 1, // 048-055: 0, 1, 2, 3, 4, 5, 6, 7,
+       1, 1, 0, 0, 0, 0, 0, 0, // 056-063: 8, 9, :, ;, <, =, >, ?,
+       0, 1, 1, 1, 1, 1, 1, 1, // 064-071: @, A, B, C, D, E, F, G,
+       1, 1, 1, 1, 1, 1, 1, 1, // 072-079: H, I, J, K, L, M, N, O,
+       1, 1, 1, 1, 1, 1, 1, 1, // 080-087: P, Q, R, S, T, U, V, W,
+       1, 1, 1, 0, 0, 0, 0, 1, // 088-095: X, Y, Z, [, \, ], ^, _,
+       0, 1, 1, 1, 1, 1, 1, 1, // 096-103: `, a, b, c, d, e, f, g,
+       1, 1, 1, 1, 1, 1, 1, 1, // 104-111: h, i, j, k, l, m, n, o,
+       1, 1, 1, 1, 1, 1, 1, 1, // 112-119: p, q, r, s, t, u, v, w,
+       1, 1, 1, 0, 0, 0, 0, 0, // 120-127: x, y, z, {, |, }, ~,
+       0, 0, 0, 0, 0, 0, 0, 0, // 128-135:
+       0, 0, 0, 0, 0, 0, 0, 0, // 136-143:
+       0, 0, 0, 0, 0, 0, 0, 0, // 144-151:
+       0, 0, 0, 0, 0, 0, 0, 0, // 152-159:
+       0, 0, 0, 0, 0, 0, 0, 0, // 160-167:
+       0, 0, 0, 0, 0, 0, 0, 0, // 168-175:
+       0, 0, 0, 0, 0, 0, 0, 0, // 176-183:
+       0, 0, 0, 0, 0, 0, 0, 0, // 184-191:
+       0, 0, 0, 0, 0, 0, 0, 0, // 192-199:
+       0, 0, 0, 0, 0, 0, 0, 0, // 200-207:
+       0, 0, 0, 0, 0, 0, 0, 0, // 208-215:
+       0, 0, 0, 0, 0, 0, 0, 0, // 216-223:
+       0, 0, 0, 0, 0, 0, 0, 0, // 224-231:
+       0, 0, 0, 0, 0, 0, 0, 0, // 232-239:
+       0, 0, 0, 0, 0, 0, 0, 0, // 240-247:
+       0, 0, 0, 0, 0, 0, 0, 0  // 248-255:
+};
+
 /** Read a string delimited by double quotes. */
 static inline
 std::istream& read_dot_name(std::istream& in, std::string& s)
 {
-       if (in >> std::ws && in.peek() == '"') {
+       in >> std::ws;
+       if (in.peek() == '"') {
+               // quoted node ID
                in.get();
                getline(in, s, '"');
-       } else
+       } else if (GRAPHVIZ_ID_CHARS[in.peek()]) {
+               // unquoted node ID
+               std::ostringstream ss;
+               while (GRAPHVIZ_ID_CHARS[in.peek()])
+                       ss << (char)in.get();
+               assert(ss.good());
+               s = ss.str();
+       } else {
                in.clear(std::ios::failbit);
+       }
        return in;
 }
 
@@ -170,12 +216,17 @@ std::istream& read_dot(std::istream& in, Graph& g, 
BetterEP betterEP)
        typedef typename graph_traits<Graph>::edge_descriptor
                edge_descriptor;
        typedef typename edge_property<Graph>::type edge_property_type;
+       typedef typename graph_traits<Graph>::directed_category
+               directed_category;
+
+       bool isDirectedGraph = boost::detail::is_directed(directed_category());
 
        // Add vertices if this graph is empty.
        bool addVertices = num_vertices(g) == 0;
 
        // Graph properties
-       in >> expect("digraph") >> Ignore('{');
+       in >> expect(isDirectedGraph ? "digraph" : "graph");
+       in >> Ignore('{');
        assert(in);
 
        edge_property_type defaultEdgeProp;
@@ -243,7 +294,7 @@ std::istream& read_dot(std::istream& in, Graph& g, BetterEP 
betterEP)
                        }
                } else if (c == '-') {
                        // Edge
-                       in >> expect(">");
+                       in >> expect(isDirectedGraph ? ">" : "-");
                        assert(in);
                        g_contigNames.lock();
 
diff --git a/Graph/GraphIO.h b/Graph/GraphIO.h
index 78370e3..c8da010 100644
--- a/Graph/GraphIO.h
+++ b/Graph/GraphIO.h
@@ -53,7 +53,8 @@ std::istream& read_graph(std::istream& in, 
ContigGraph<Graph>& g,
        switch (in.peek()) {
          case '@': // @SQ: SAM format
                return read_sam_header(in, g);
-         case 'd': // digraph: GraphViz dot format
+         case 'd': // digraph: GraphViz dot format (directed graph)
+         case 'g': // graph:   GraphViz dot format (undirected graph)
                return read_dot<Graph>(in, g, betterEP);
          case 'H': {
                in.get();
diff --git a/Graph/Makefile.am b/Graph/Makefile.am
index cce5dd0..5a25efd 100644
--- a/Graph/Makefile.am
+++ b/Graph/Makefile.am
@@ -35,7 +35,8 @@ EXTRA_DIST = \
        Path.h \
        PopBubbles.h \
        Properties.h \
-       SAMIO.h
+       SAMIO.h \
+       UndirectedGraph.h
 
 abyss_gc_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/Common
 abyss_gc_LDADD = $(top_builddir)/Common/libcommon.a
diff --git a/Graph/SAMIO.h b/Graph/SAMIO.h
index 5a20270..2d99b31 100644
--- a/Graph/SAMIO.h
+++ b/Graph/SAMIO.h
@@ -1,6 +1,7 @@
 #ifndef SAMIO_H
 #define SAMIO_H 1
 
+#include "Common/ContigNode.h"
 #include "Graph/Properties.h"
 #include <istream>
 #include <sstream>
diff --git a/Graph/UndirectedGraph.h b/Graph/UndirectedGraph.h
new file mode 100644
index 0000000..1be38eb
--- /dev/null
+++ b/Graph/UndirectedGraph.h
@@ -0,0 +1,948 @@
+#ifndef UNDIRECTEDGRAPH_H
+#define UNDIRECTEDGRAPH_H 1
+
+#include "Common/ContigNode.h"
+#include "Common/Hash.h"
+#include "Graph/Properties.h"
+#include <algorithm>
+#include <cassert>
+#include <utility>
+#include <vector>
+#include <iostream>
+
+/**
+ * An edge for an undirected graph, having the key property that
+ * (u, v) == (v, u). The unsigned values here are the vertex_descriptor's.
+ */
+class UndirectedEdge : public std::pair<unsigned, unsigned>
+{
+
+public:
+
+       UndirectedEdge() : std::pair<unsigned, unsigned>() {}
+
+       UndirectedEdge(unsigned u, unsigned v)
+               : std::pair<unsigned, unsigned>(u, v) {}
+
+       bool operator ==(const UndirectedEdge& e) const
+       {
+               return (first == e.first && second == e.second) ||
+                       (first == e.second && second == e.first);
+       }
+
+       bool operator !=(const UndirectedEdge& e) const
+       {
+               return !(*this == e);
+       }
+
+       size_t hashCode() const
+       {
+               return first ^ second;
+       }
+};
+
+/**
+ * The hash function for an undirected edge, having the key property that
+ * hash(u, v) == hash(v, u).
+ */
+NAMESPACE_STD_HASH_BEGIN
+template <> struct hash<UndirectedEdge> {
+       /**
+        * Hash function for graph vertex type (vertex_descriptor)
+        */
+       size_t operator()(const UndirectedEdge& e) const
+       {
+               return e.hashCode();
+       }
+};
+NAMESPACE_STD_HASH_END
+
+/** A undirected graph. */
+template <typename VertexProp = no_property,
+                typename EdgeProp = no_property>
+class UndirectedGraph
+{
+       class Vertex;
+       typedef typename std::vector<Vertex> Vertices;
+       class Edge;
+       typedef typename std::vector<Edge> Edges;
+
+  public:
+       // Graph
+       /* typedef ContigNode vertex_descriptor; */
+       typedef unsigned vertex_descriptor;
+
+       // IncidenceGraph
+       typedef UndirectedEdge edge_descriptor;
+
+       typedef unsigned degree_size_type;
+
+       // BidirectionalGraph
+       typedef void in_edge_iterator;
+
+       // VertexListGraph
+       typedef unsigned vertices_size_type;
+
+       // EdgeListGraph
+       typedef unsigned edges_size_type;
+
+       // PropertyGraph
+       typedef VertexProp vertex_bundled;
+       typedef VertexProp vertex_property_type;
+       typedef EdgeProp edge_bundled;
+       typedef EdgeProp edge_property_type;
+
+       typedef boost::undirected_tag directed_category;
+       typedef boost::allow_parallel_edge_tag edge_parallel_category;
+       struct traversal_category
+               : boost::incidence_graph_tag,
+               boost::adjacency_graph_tag,
+               boost::vertex_list_graph_tag,
+               boost::edge_list_graph_tag { };
+
+/** Iterate through the vertices of this graph. */
+class vertex_iterator
+       : public std::iterator<std::input_iterator_tag,
+               const vertex_descriptor>
+{
+  public:
+       vertex_iterator() { }
+       explicit vertex_iterator(vertices_size_type v) : m_v(v) { }
+       const vertex_descriptor& operator *() const { return m_v; }
+
+       bool operator ==(const vertex_iterator& it) const
+       {
+               return m_v == it.m_v;
+       }
+
+       bool operator !=(const vertex_iterator& it) const
+       {
+               return m_v != it.m_v;
+       }
+
+       vertex_iterator& operator ++() { ++m_v; return *this; }
+       vertex_iterator operator ++(int)
+       {
+               vertex_iterator it = *this;
+               ++*this;
+               return it;
+       }
+
+  private:
+       vertex_descriptor m_v;
+};
+
+/** Iterate through the out-edges. */
+class out_edge_iterator
+       : public std::iterator<std::input_iterator_tag, edge_descriptor>
+{
+       typedef typename Edges::const_iterator const_iterator;
+
+  public:
+       out_edge_iterator() { }
+       out_edge_iterator(const const_iterator& it,
+                       vertex_descriptor src) : m_it(it), m_src(src) { }
+
+       edge_descriptor operator *() const
+       {
+               return edge_descriptor(m_src, m_it->target());
+       }
+
+       bool operator ==(const out_edge_iterator& it) const
+       {
+               return m_it == it.m_it;
+       }
+
+       bool operator !=(const out_edge_iterator& it) const
+       {
+               return m_it != it.m_it;
+       }
+
+       out_edge_iterator& operator ++() { ++m_it; return *this; }
+       out_edge_iterator operator ++(int)
+       {
+               out_edge_iterator it = *this;
+               ++*this;
+               return it;
+       }
+
+       const edge_property_type& get_property() const
+       {
+               return m_it->get_property();
+       }
+
+  private:
+       const_iterator m_it;
+       vertex_descriptor m_src;
+};
+
+/** Iterate through adjacent vertices. */
+class adjacency_iterator : public Edges::const_iterator
+{
+       typedef typename Edges::const_iterator It;
+  public:
+       adjacency_iterator() { }
+       adjacency_iterator(const It& it) : It(it) { }
+       vertex_descriptor operator*() const
+       {
+               return It::operator*().target();
+       }
+};
+
+/** Iterate through edges. */
+class edge_iterator
+       : public std::iterator<std::input_iterator_tag, edge_descriptor>
+{
+       void nextVertex()
+       {
+               vertex_iterator vlast = m_g->vertices().second;
+               for (; m_vit != vlast; ++m_vit) {
+                       std::pair<adjacency_iterator, adjacency_iterator>
+                               adj = m_g->adjacent_vertices(*m_vit);
+                       /*
+                        * Since each edge exists as both (u, v) and
+                        * (v, u), require `adj.first >= *m_vit` to visit only
+                        * one of the two possible forms.
+                        */
+                       if (adj.first != adj.second && *adj.first >= *m_vit) {
+                               m_eit = adj.first;
+                               return;
+                       }
+               }
+               // Set m_eit to a known value.
+               static const adjacency_iterator s_eitNULL;
+               m_eit = s_eitNULL;
+       }
+
+  public:
+       edge_iterator() { }
+       edge_iterator(const UndirectedGraph* g, const vertex_iterator& vit)
+               : m_g(g), m_vit(vit)
+       {
+               nextVertex();
+       }
+
+       edge_descriptor operator*() const
+       {
+               return edge_descriptor(*m_vit, *m_eit);
+       }
+
+       bool operator==(const edge_iterator& it) const
+       {
+               return m_vit == it.m_vit && m_eit == it.m_eit;
+       }
+
+       bool operator!=(const edge_iterator& it) const
+       {
+               return !(*this == it);
+       }
+
+       edge_iterator& operator++()
+       {
+               if (++m_eit == m_g->adjacent_vertices(*m_vit).second) {
+                       ++m_vit;
+                       nextVertex();
+               }
+               return *this;
+       }
+
+       edge_iterator operator++(int)
+       {
+               edge_iterator it = *this;
+               ++*this;
+               return it;
+       }
+
+  private:
+       const UndirectedGraph* m_g;
+       vertex_iterator m_vit;
+       adjacency_iterator m_eit;
+};
+
+  private:
+/** A vertex and its properties. */
+class Vertex
+{
+  public:
+       Vertex() { }
+       Vertex(const vertex_property_type& p) : m_prop(p) { }
+
+       /** Return the properties of this vertex. */
+       const vertex_property_type& get_property() const
+       {
+               return m_prop;
+       }
+
+       /** Returns an iterator-range to the out edges of vertex u. */
+       std::pair<out_edge_iterator, out_edge_iterator>
+       out_edges(vertex_descriptor u) const
+       {
+               return make_pair(out_edge_iterator(m_edges.begin(), u),
+                               out_edge_iterator(m_edges.end(), u));
+       }
+
+       /** Returns an iterator-range to the adjacent vertices. */
+       std::pair<adjacency_iterator, adjacency_iterator>
+       adjacent_vertices() const
+       {
+               return make_pair(m_edges.begin(), m_edges.end());
+       }
+
+       /** Return the number of outgoing edges. */
+       degree_size_type out_degree() const
+       {
+               return m_edges.size();
+       }
+
+       /** Add an edge to this vertex. */
+       bool add_edge(vertex_descriptor v, const edge_property_type& ep)
+       {
+               m_edges.push_back(Edge(v, ep));
+               return true;
+       }
+
+       /** Remove the edge to v from this vertex. */
+       void remove_edge(vertex_descriptor v)
+       {
+               m_edges.erase(remove(m_edges.begin(), m_edges.end(), v),
+                               m_edges.end());
+       }
+
+       /** Remove all out edges from this vertex. */
+       void clear_out_edges()
+       {
+               m_edges.clear();
+       }
+
+       /** Return the properties of the edge with target v. */
+       edge_property_type& operator[](vertex_descriptor v)
+       {
+               typename Edges::iterator it
+                       = find(m_edges.begin(), m_edges.end(), v);
+               assert(it != m_edges.end());
+               return it->get_property();
+       }
+
+       /** Return the properties of the edge with target v. */
+       const edge_property_type& operator[](vertex_descriptor v) const
+       {
+               typename Edges::const_iterator it
+                       = find(m_edges.begin(), m_edges.end(), v);
+               assert(it != m_edges.end());
+               return it->get_property();
+       }
+
+       /** Return true if edge (u,v) exists. */
+       bool edge(vertex_descriptor v) const
+       {
+               return count(m_edges.begin(), m_edges.end(), v) > 0;
+       }
+
+       /** Remove edges that satisfy the predicate. */
+       template <typename Predicate>
+       void remove_edge_if(vertex_descriptor u, Predicate predicate)
+       {
+               typename Edges::iterator out = m_edges.begin();
+               for (typename Edges::iterator it = m_edges.begin();
+                               it != m_edges.end(); ++it) {
+                       if (!predicate(edge_descriptor(u, it->target()))) {
+                               if (out != it)
+                                       *out = *it;
+                               ++out;
+                       }
+               }
+               m_edges.erase(out, m_edges.end());
+       }
+
+  private:
+       Edges m_edges;
+       vertex_property_type m_prop;
+};
+
+/** A directed edge. */
+class Edge
+{
+  public:
+       explicit Edge(vertex_descriptor v, const edge_property_type& ep)
+               : m_target(v), m_ep(ep) { }
+
+       /** Returns the target vertex of this edge. */
+       vertex_descriptor target() const { return m_target; }
+
+       /** Return true if the target of this edge is v. */
+       bool operator ==(const vertex_descriptor& v) const
+       {
+               return m_target == v;
+       }
+
+       edge_property_type& get_property() { return m_ep; }
+       const edge_property_type& get_property() const { return m_ep; }
+
+  private:
+       /** The target vertex of this edge. */
+       vertex_descriptor m_target;
+       edge_property_type m_ep;
+};
+
+  public:
+       /** Create an empty graph. */
+       UndirectedGraph() { }
+
+       /** Create a graph with n vertices and zero edges. */
+       UndirectedGraph(vertices_size_type n) : m_vertices(n) { }
+
+       /** Swap this graph with graph x. */
+       void swap(UndirectedGraph& x)
+       {
+               m_vertices.swap(x.m_vertices);
+               m_removed.swap(x.m_removed);
+       }
+
+       /** Return properties of vertex u. */
+       const vertex_property_type& operator[](vertex_descriptor u) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               return m_vertices[ui].get_property();
+       }
+
+       /** Returns an iterator-range to the vertices. */
+       std::pair<vertex_iterator, vertex_iterator> vertices() const
+       {
+               return make_pair(vertex_iterator(0),
+                       vertex_iterator(num_vertices()));
+       }
+
+       /** Remove all the edges and vertices from this graph. */
+       void clear() { m_vertices.clear(); m_removed.clear(); }
+
+       /** Add a vertex to this graph. */
+       vertex_descriptor add_vertex(
+                       const vertex_property_type& vp = vertex_property_type())
+       {
+               m_vertices.push_back(Vertex(vp));
+               return vertex_descriptor(num_vertices() - 1);
+       }
+
+       /** Returns an iterator-range to the out edges of vertex u. */
+       std::pair<out_edge_iterator, out_edge_iterator>
+       out_edges(vertex_descriptor u) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               return m_vertices[ui].out_edges(u);
+       }
+
+       /** Returns an iterator-range to the adjacent vertices of
+        * vertex u. */
+       std::pair<adjacency_iterator, adjacency_iterator>
+       adjacent_vertices(vertex_descriptor u) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               return m_vertices[ui].adjacent_vertices();
+       }
+
+       /** Adds edge (u,v) to this graph. */
+       std::pair<edge_descriptor, bool>
+       add_edge(vertex_descriptor u, vertex_descriptor v,
+                       const edge_property_type& ep = edge_property_type())
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               vertices_size_type vi = get(vertex_index, *this, v);
+               assert(vi < num_vertices());
+               m_vertices[vi].add_edge(u, ep);
+               return make_pair(edge_descriptor(u, v),
+                               m_vertices[ui].add_edge(v, ep));
+       }
+
+       /** Remove the edge (u,v) from this graph. */
+       void remove_edge(vertex_descriptor u, vertex_descriptor v)
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               vertices_size_type vi = get(vertex_index, *this, v);
+               assert(vi < num_vertices());
+               m_vertices[ui].remove_edge(v);
+               m_vertices[ui].remove_edge(u);
+       }
+
+       /** Remove the edge e from this graph. */
+       void remove_edge(edge_descriptor e)
+       {
+               remove_edge(e.first, e.second);
+       }
+
+#if 0
+       /** Remove all out edges from vertex u. */
+       void clear_out_edges(vertex_descriptor u)
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               m_vertices[ui].clear_out_edges();
+       }
+#endif
+
+       /** Remove all edges to and from vertex u from this graph.
+        * O(V+E) */
+       void clear_vertex(vertex_descriptor u)
+       {
+               std::pair<adjacency_iterator, adjacency_iterator>
+                       adj = adjacent_vertices(u);
+               for (adjacency_iterator v = adj.first; v != adj.second; ++v)
+                       remove_edge(*v, u);
+       }
+
+       /** Set the vertex_removed property. */
+       void put(vertex_removed_t, vertex_descriptor u, bool flag)
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               if (ui >= m_removed.size())
+                       m_removed.resize(ui + 1);
+               m_removed[ui] = flag;
+       }
+
+       /** Remove vertex u from this graph. It is assumed that there
+        * are no edges to or from vertex u. It is best to call
+        * clear_vertex before remove_vertex.
+        */
+       void remove_vertex(vertex_descriptor u)
+       {
+               put(vertex_removed, u, true);
+       }
+
+       /** Return the number of vertices. */
+       vertices_size_type num_vertices() const
+       {
+               return m_vertices.size();
+       }
+
+       /** Return the number of edges. */
+       edges_size_type num_edges() const
+       {
+               edges_size_type n = 0;
+               std::pair<vertex_iterator, vertex_iterator> vit = vertices();
+               for (vertex_iterator v = vit.first; v != vit.second; ++v)
+                       n += out_degree(*v);
+               /* should have (u, v) and (v, u) versions for each edge */
+               assert(n % 2 == 0);
+               return n / 2;
+       }
+
+       /** Return the out degree of vertex u. */
+       degree_size_type out_degree(vertex_descriptor u) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               return m_vertices[ui].out_degree();
+       }
+
+       /** Return the nth vertex. */
+       static vertex_descriptor vertex(vertices_size_type n)
+       {
+               return vertex_descriptor(n);
+       }
+
+       /** Iterate through the edges of this graph. */
+       std::pair<edge_iterator, edge_iterator> edges() const
+       {
+               std::pair<vertex_iterator, vertex_iterator> vit = vertices();
+               return make_pair(edge_iterator(this, vit.first),
+                               edge_iterator(this, vit.second));
+       }
+
+       /** Return the edge (u,v) if it exists and a flag indicating
+        * whether the edge exists.
+        */
+       std::pair<edge_descriptor, bool> edge(
+                       vertex_descriptor u, vertex_descriptor v) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               assert(ui < num_vertices());
+               return make_pair(edge_descriptor(u, v),
+                               m_vertices[ui].edge(v));
+       }
+
+       /** Return properties of edge e. */
+       edge_property_type& operator[](edge_descriptor e)
+       {
+               vertices_size_type ui = get(vertex_index, *this, e.first);
+               assert(ui < num_vertices());
+               return m_vertices[ui][e.second];
+       }
+
+       /** Return properties of edge e. */
+       const edge_property_type& operator[](edge_descriptor e) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, e.first);
+               assert(ui < num_vertices());
+               return m_vertices[ui][e.second];
+       }
+
+       /** Remove edges that satisfy the predicate. */
+       template <typename Predicate>
+       void remove_edge_if(Predicate predicate)
+       {
+               unsigned i = 0;
+               for (typename Vertices::iterator it = m_vertices.begin();
+                               it != m_vertices.end(); ++it)
+                       it->remove_edge_if(vertex(i++), predicate);
+       }
+
+       /** Return true if this vertex has been removed. */
+       bool is_removed(vertex_descriptor u) const
+       {
+               vertices_size_type ui = get(vertex_index, *this, u);
+               return ui < m_removed.size() ? m_removed[ui] : false;
+       }
+
+       /** Set the name (usually contig ID) for a given vertex_descriptor */
+       void put(vertex_name_t, vertex_descriptor u, const 
Dictionary::name_type& name)
+       {
+               m_vertexNames.put(u, name);
+       }
+
+       /** Find a vertex_descriptor by name (usually contig ID) */
+       vertex_descriptor find_vertex(const Dictionary::name_type& name) const
+       {
+               return m_vertexNames.getIndex(name);
+       }
+
+  private:
+       UndirectedGraph& operator =(const UndirectedGraph& x);
+
+       /** The set of vertices. */
+       Vertices m_vertices;
+
+       /** Bidirectional map of names to vertex_descriptors */
+       Dictionary m_vertexNames;
+
+       /** Flags indicating vertices that have been removed. */
+       std::vector<bool> m_removed;
+};
+
+namespace std {
+       template <typename VertexProp, typename EdgeProp>
+       inline void swap(UndirectedGraph<VertexProp, EdgeProp>& a,
+                       UndirectedGraph<VertexProp, EdgeProp>& b) { a.swap(b); }
+}
+
+// IncidenceGraph
+
+template <typename VP, typename EP>
+std::pair<
+       typename UndirectedGraph<VP, EP>::out_edge_iterator,
+       typename UndirectedGraph<VP, EP>::out_edge_iterator>
+out_edges(
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               const UndirectedGraph<VP, EP>& g)
+{
+       return g.out_edges(u);
+}
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::degree_size_type
+out_degree(
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               const UndirectedGraph<VP, EP>& g)
+{
+       return g.out_degree(u);
+}
+
+// AdjacencyGraph
+
+template <typename VP, typename EP>
+std::pair<
+       typename UndirectedGraph<VP, EP>::adjacency_iterator,
+       typename UndirectedGraph<VP, EP>::adjacency_iterator>
+adjacent_vertices(
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               const UndirectedGraph<VP, EP>& g)
+{
+       return g.adjacent_vertices(u);
+}
+
+// VertexListGraph
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertices_size_type
+num_vertices(const UndirectedGraph<VP, EP>& g)
+{
+       return g.num_vertices();
+}
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertex_descriptor
+vertex(typename UndirectedGraph<VP, EP>::vertices_size_type ui, const 
UndirectedGraph<VP, EP>& g)
+{
+       return g.vertex(ui);
+}
+
+template <typename VP, typename EP>
+std::pair<typename UndirectedGraph<VP, EP>::vertex_iterator,
+       typename UndirectedGraph<VP, EP>::vertex_iterator>
+vertices(const UndirectedGraph<VP, EP>& g)
+{
+       return g.vertices();
+}
+
+// EdgeListGraph
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::edges_size_type
+num_edges(const UndirectedGraph<VP, EP>& g)
+{
+       return g.num_edges();
+}
+
+template <typename VP, typename EP>
+std::pair<typename UndirectedGraph<VP, EP>::edge_iterator,
+       typename UndirectedGraph<VP, EP>::edge_iterator>
+edges(const UndirectedGraph<VP, EP>& g)
+{
+       return g.edges();
+}
+
+// AdjacencyMatrix
+
+template <typename VP, typename EP>
+std::pair<typename UndirectedGraph<VP, EP>::edge_descriptor, bool>
+edge(
+       typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+       typename UndirectedGraph<VP, EP>::vertex_descriptor v,
+       const UndirectedGraph<VP, EP>& g)
+{
+       return g.edge(u, v);
+}
+
+// VertexMutableGraph
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertex_descriptor
+add_vertex(UndirectedGraph<VP, EP>& g)
+{
+       return g.add_vertex();
+}
+
+template <typename VP, typename EP>
+void
+remove_vertex(
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               UndirectedGraph<VP, EP>& g)
+{
+       g.remove_vertex(u);
+}
+
+// EdgeMutableGraph
+
+template <typename VP, typename EP>
+void
+clear_vertex(
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               UndirectedGraph<VP, EP>& g)
+{
+       g.clear_vertex(u);
+}
+
+template <typename VP, typename EP>
+std::pair<typename UndirectedGraph<VP, EP>::edge_descriptor, bool>
+add_edge(
+       typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+       typename UndirectedGraph<VP, EP>::vertex_descriptor v,
+       UndirectedGraph<VP, EP>& g)
+{
+       return g.add_edge(u, v);
+}
+
+template <typename VP, typename EP>
+void
+remove_edge(
+       typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+       typename UndirectedGraph<VP, EP>::vertex_descriptor v,
+       UndirectedGraph<VP, EP>& g)
+{
+       g.remove_edge(u, v);
+}
+
+template <typename VP, typename EP>
+void
+remove_edge(
+               typename UndirectedGraph<VP, EP>::edge_descriptor e,
+               UndirectedGraph<VP, EP>& g)
+{
+       g.remove_edge(e);
+}
+
+// MutableIncidenceGraph
+
+template <typename VP, typename EP>
+void
+clear_out_edges(
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               UndirectedGraph<VP, EP>& g)
+{
+       g.clear_out_edges(u);
+}
+
+// MutableEdgeListGraph
+
+template <typename VP, typename EP, class Predicate>
+void
+remove_edge_if(Predicate predicate, UndirectedGraph<VP, EP>& g)
+{
+       g.remove_edge_if(predicate);
+}
+
+// PropertyGraph
+
+/** Return true if this vertex has been removed. */
+template <typename VP, typename EP>
+bool get(vertex_removed_t, const UndirectedGraph<VP, EP>& g,
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u)
+{
+       return g.is_removed(u);
+}
+
+template <typename VP, typename EP>
+void put(vertex_removed_t tag, UndirectedGraph<VP, EP>& g,
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+               bool flag)
+{
+       g.put(tag, u, flag);
+}
+
+/** Return the properties of the edge of iterator eit. */
+template <typename VP, typename EP>
+const typename UndirectedGraph<VP, EP>::edge_property_type&
+get(edge_bundle_t, const UndirectedGraph<VP, EP>&,
+               typename UndirectedGraph<VP, EP>::out_edge_iterator eit)
+{
+       return eit.get_property();
+}
+
+// PropertyGraph
+
+template <typename VP, typename EP>
+const VP&
+get(vertex_bundle_t, const UndirectedGraph<VP, EP>& g,
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u)
+{
+       return g[u];
+}
+
+template <typename VP, typename EP>
+const EP&
+get(edge_bundle_t, const UndirectedGraph<VP, EP>& g,
+               typename UndirectedGraph<VP, EP>::edge_descriptor e)
+{
+       return g[e];
+}
+
+// PropertyGraph vertex_index
+
+#if 0
+namespace boost {
+template <typename VP, typename EP>
+struct property_map<UndirectedGraph<VP, EP>, vertex_index_t>
+{
+       typedef ContigNodeIndexMap type;
+       typedef type const_type;
+};
+}
+
+template <typename VP, typename EP>
+ContigNodeIndexMap
+get(vertex_index_t, const UndirectedGraph<VP, EP>&)
+{
+       return ContigNodeIndexMap();
+}
+
+template <typename VP, typename EP>
+ContigNodeIndexMap::reference
+get(vertex_index_t tag, const UndirectedGraph<VP, EP>& g,
+               typename UndirectedGraph<VP, EP>::vertex_descriptor u)
+{
+       return get(get(tag, g), u);
+}
+#endif
+
+// VertexMutablePropertyGraph
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertex_descriptor
+add_vertex(const VP& vp, UndirectedGraph<VP, EP>& g)
+{
+       return g.add_vertex(vp);
+}
+
+// EdgeMutablePropertyGraph
+
+template <typename VP, typename EP>
+std::pair<typename UndirectedGraph<VP, EP>::edge_descriptor, bool>
+add_edge(
+       typename UndirectedGraph<VP, EP>::vertex_descriptor u,
+       typename UndirectedGraph<VP, EP>::vertex_descriptor v,
+       const typename UndirectedGraph<VP, EP>::edge_property_type& ep,
+       UndirectedGraph<VP, EP>& g)
+{
+       return g.add_edge(u, v, ep);
+}
+
+// NamedGraph
+
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertex_descriptor
+find_vertex(const std::string& name, const UndirectedGraph<VP, EP>& g)
+{
+       /* return find_vertex(name, g_contigNames); */
+       return g.find_vertex(name);
+}
+
+#if 0
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertex_descriptor
+find_vertex(const std::string& name, bool sense,
+               const UndirectedGraph<VP, EP>&)
+{
+       return find_vertex(name, sense, g_contigNames);
+}
+#endif
+
+/**
+ * Get the index of a vertex in UndirectedGraph's
+ * internal data structures (vertex list and
+ * vertex_descriptor => vertex_name map).
+ */
+template <typename VP, typename EP>
+typename UndirectedGraph<VP, EP>::vertices_size_type
+get(vertex_index_t, const UndirectedGraph<VP, EP>&,
+       typename UndirectedGraph<VP, EP>::vertex_descriptor u)
+{
+       /*
+        * For UndirectedGraph, vertex_index and vertex_descriptor
+        * are always the same, where `vertex_index` indicates the position of
+        * the vertex in UndirectedGraph's vertex list (`m_vertices` above)
+        * and also the position of the vertex in the
+        * vertex_name <=> vertex_descriptor map (`m_vertexNames` above).
+        *
+        * For DirectedGraph, vertex_index and vertex_descriptor are
+        * different types (unsigned and ContigNode, respectively), because
+        * vertex names end with "+" or "-".
+        */
+       return u;
+}
+
+/**
+ * Set the name for a vertex.  This is a std::string and usually
+ * stores the contig ID.
+ */
+template <typename VP, typename EP>
+void put(vertex_name_t tag, UndirectedGraph<VP, EP>& g,
+       typename UndirectedGraph<VP, EP>::vertex_descriptor& u,
+       const Dictionary::name_type& name)
+{
+       g.put(tag, u, name);
+}
+
+#endif
diff --git a/Konnector/DBGBloom.h b/Konnector/DBGBloom.h
index e3defdd..d72c033 100644
--- a/Konnector/DBGBloom.h
+++ b/Konnector/DBGBloom.h
@@ -346,6 +346,15 @@ in_degree(typename graph_traits<Graph>::vertex_descriptor 
u,
 
 template <typename Graph>
 static inline
+typename graph_traits<Graph>::degree_size_type
+degree(typename graph_traits<Graph>::vertex_descriptor u,
+       const Graph& g)
+{
+       return in_degree(u, g) + out_degree(u, g);
+}
+
+template <typename Graph>
+static inline
 std::pair<typename graph_traits<Graph>::in_edge_iterator,
        typename graph_traits<Graph>::in_edge_iterator>
 in_edges(
diff --git a/README.md b/README.md
index 4765389..272a82e 100644
--- a/README.md
+++ b/README.md
@@ -248,21 +248,27 @@ Assembling using a Bloom filter de Bruijn graph
 =========================================
 
 Assemblies may be performed using a _Bloom filter de Bruijn graph_, which
-typically reduces memory requirements by an order of magnitude. In order to
-assemble in Bloom filter mode, the user must specify 3 additional parameters:
-`B` (Bloom filter size), `H` (number of Bloom filter hash functions), and `kc`
-(minimum k-mer count threshold). Valid size units for the `B` parameter are 
'k',
-'M', 'G'. If no unit is specified, bytes are assumed. For example, the 
following
-will run a E. coli assembly with a Bloom filter size of 100 MB, 3 hash
-functions, a minimum k-mer count threshold of 3, and verbose logging:
+typically reduces memory requirements by an order of magnitude. To assemble in
+Bloom filter mode, the user must specify 3 additional parameters: `B` (Bloom
+filter size in bytes), `H` (number of Bloom filter hash functions), and `kc`
+(minimum k-mer count threshold). `B` is the overall memory budget for the Bloom
+filter assembler, and may be specified with unit suffixes 'k' (kilobytes), 'M'
+(megabytes), 'G' (gigabytes). If no units are specified bytes are assumed. For
+example, the following will run a E. coli assembly with an overall memory 
budget
+of 100 megabytes, 3 hash functions, a minimum k-mer count threshold of 3, with
+verbose logging enabled:
 
        abyss-pe name=ecoli k=64 in='reads1.fa reads2.fa' B=100M H=3 kc=3 v=-v
 
 At the current time, the user must calculate suitable values for `B` and `H` on
 their own, and finding the best value for `kc` may require experimentation
-(optimal values are typically in the range of 2-4). Users are recommended to
-target a Bloom filter false positive rate (FPR) that is less than 5%, as
-reported by the assembly log when using the `v=-v` option (verbose level 1).
+(optimal values are typically in the range of 2-4). Internally, the Bloom 
filter
+assembler divides the memory budget (`B`) equally across (`kc` + 1) Bloom
+filters, where `kc` Bloom filters are used for the cascading Bloom filter and
+one additional Bloom filter is used to track k-mers that have previously been
+included in contigs. Users are recommended to target a Bloom filter false
+positive rate (FPR) that is less than 5%, as reported by the assembly log when
+using the `v=-v` option (verbose level 1).
 
 Assembling using a paired de Bruijn graph
 =========================================
diff --git a/Unittest/DBG/LoadAlgorithmTest.cpp 
b/Unittest/DBG/LoadAlgorithmTest.cpp
index 8de2f39..d31e825 100644
--- a/Unittest/DBG/LoadAlgorithmTest.cpp
+++ b/Unittest/DBG/LoadAlgorithmTest.cpp
@@ -1,3 +1,4 @@
+#include "config.h"
 #include "Assembly/SequenceCollection.h"
 #include "Assembly/DBG.h"
 #include "Assembly/AssemblyAlgorithms.h"
diff --git a/Unittest/Graph/DotIOTest.cpp b/Unittest/Graph/DotIOTest.cpp
new file mode 100644
index 0000000..9a2083d
--- /dev/null
+++ b/Unittest/Graph/DotIOTest.cpp
@@ -0,0 +1,115 @@
+#include "Common/ContigID.h"
+#include "Common/Dictionary.h"
+#include "Graph/GraphIO.h"
+#include "Graph/DotIO.h"
+#include "Graph/UndirectedGraph.h"
+#include "Graph/DirectedGraph.h"
+#include "Graph/Properties.h"
+#include <boost/tuple/tuple.hpp>
+#include <gtest/gtest.h>
+#include <string>
+#include <sstream>
+
+using namespace std;
+
+typedef UndirectedGraph<NoProperty, NoProperty> UGraph;
+typedef boost::graph_traits<UGraph>::vertex_descriptor UV;
+typedef boost::graph_traits<UGraph>::edge_descriptor UE;
+typedef boost::graph_traits<UGraph>::edge_iterator UEIt;
+
+typedef DirectedGraph<NoProperty, NoProperty> DGraph;
+typedef boost::graph_traits<DGraph>::vertex_descriptor DV;
+typedef boost::graph_traits<DGraph>::edge_descriptor DE;
+typedef boost::graph_traits<DGraph>::edge_iterator DEIt;
+
+TEST(DotIOTest, UndirectedGraph)
+{
+       /* reset state of global contig ID map */
+       g_contigNames.clear();
+
+       string graphviz;
+       stringstream ss;
+
+       /* undirected graph, unquoted IDs */
+
+       graphviz =
+               "graph {\n"
+               "     a;\n"
+               "     b;\n"
+               "     a -- b;\n"
+               "}\n";
+
+       ss << graphviz;
+       ASSERT_TRUE(ss.good());
+
+       UGraph g;
+       read_dot(ss, g, DisallowParallelEdges());
+       ASSERT_TRUE(!ss.fail());
+
+       /* check that correct graph structure was created */
+
+       ASSERT_EQ(2u, num_vertices(g));
+       UV a = find_vertex("a", g);
+       ASSERT_LT(a, num_vertices(g));
+       UV b = find_vertex("b", g);
+       ASSERT_LT(b, num_vertices(g));
+
+       ASSERT_EQ(1u, num_edges(g));
+       UEIt ueit, ueit_end;
+       boost::tie(ueit, ueit_end) = edges(g);
+       ASSERT_NE(ueit, ueit_end);
+       UE e = UE(a, b);
+       ASSERT_EQ(e, *ueit);
+       ASSERT_TRUE(source(*ueit, g) == a || target(*ueit, g) == a);
+       ASSERT_TRUE(source(*ueit, g) == b || target(*ueit, g) == b);
+       ++ueit;
+       ASSERT_EQ(ueit, ueit_end);
+
+}
+
+TEST(DotIOTest, DirectedGraph)
+{
+       /* reset state of global contig ID map */
+       g_contigNames.clear();
+
+       string graphviz;
+       stringstream ss;
+
+       /* directed graph, quoted IDs */
+
+       graphviz =
+               "digraph {\n"
+               "     \"1+\";\n"
+               "     \"1-\";\n"
+               "     \"2+\";\n"
+               "     \"2-\";\n"
+               "     \"1+\" -> \"2-\";\n"
+               "}\n";
+
+       ss << graphviz;
+       ASSERT_TRUE(ss.good());
+
+       DGraph g;
+       read_dot(ss, g, DisallowParallelEdges());
+       ASSERT_TRUE(!ss.fail());
+
+       /* check that correct graph structure was created */
+
+       ASSERT_EQ(4u, num_vertices(g));
+       DV v1 = find_vertex("1+", g);
+       ASSERT_LT(v1.index(), num_vertices(g));
+       DV v2 = find_vertex("2-", g);
+       ASSERT_LT(v2.index(), num_vertices(g));
+
+       ASSERT_EQ(1u, num_edges(g));
+       DEIt ueit, ueit_end;
+       boost::tie(ueit, ueit_end) = edges(g);
+       ASSERT_NE(ueit, ueit_end);
+       DE e = DE(v1, v2);
+       ASSERT_EQ(e, *ueit);
+       ASSERT_TRUE(source(*ueit, g) == v1);
+       ASSERT_TRUE(target(*ueit, g) == v2);
+       ++ueit;
+       ASSERT_EQ(ueit, ueit_end);
+
+}
diff --git a/Unittest/Graph/UndirectedGraphTest.cpp 
b/Unittest/Graph/UndirectedGraphTest.cpp
new file mode 100644
index 0000000..0f3f295
--- /dev/null
+++ b/Unittest/Graph/UndirectedGraphTest.cpp
@@ -0,0 +1,54 @@
+#include "Common/Hash.h"
+#include "Graph/UndirectedGraph.h"
+#include "Graph/Properties.h"
+#include <boost/tuple/tuple.hpp>
+#include <gtest/gtest.h>
+#include <string>
+#include <sstream>
+
+using namespace std;
+
+typedef UndirectedGraph<NoProperty, NoProperty> Graph;
+typedef boost::graph_traits<Graph>::vertex_descriptor V;
+typedef boost::graph_traits<Graph>::edge_descriptor E;
+typedef boost::graph_traits<Graph>::edge_iterator EdgeIterator;
+
+TEST(UndirectedGraphTest, edgeComparison)
+{
+       Graph g;
+       V u = add_vertex(NoProperty(), g);
+       V v = add_vertex(NoProperty(), g);
+       E uv = E(u, v);
+       E vu = E(v, u);
+       ASSERT_EQ(uv, vu);
+       ASSERT_EQ(uv.hashCode(), vu.hashCode());
+}
+
+TEST(UndirectedGraphTest, edges)
+{
+       Graph g;
+
+       V u = add_vertex(NoProperty(), g);
+       V v = add_vertex(NoProperty(), g);
+
+       /*
+        * Internally, both edge orientations (u, v) and (v, u) are
+        * added to the graph data structures.  Make sure that
+        * this isn't exposed externally and that we only see one edge.
+        */
+
+       E e;
+       bool inserted;
+       boost::tie(e, inserted) = add_edge(u, v, NoProperty(), g);
+       ASSERT_TRUE(inserted);
+       ASSERT_EQ(1u, num_edges(g));
+
+       /* make sure iterator only visits one version of the edge */
+
+       EdgeIterator eit, eit_end;
+       boost::tie(eit, eit_end) = edges(g);
+       ASSERT_NE(eit, eit_end);
+       ASSERT_EQ(e, *eit);
+       ++eit;
+       ASSERT_EQ(eit, eit_end);
+}
diff --git a/Unittest/Makefile.am b/Unittest/Makefile.am
index da0980f..b8770ca 100644
--- a/Unittest/Makefile.am
+++ b/Unittest/Makefile.am
@@ -5,6 +5,7 @@
 AM_CXXFLAGS += $(PTHREAD_CFLAGS) -Wno-error
 AM_LDFLAGS = $(PTHREAD_LIBS)
 AM_CPPFLAGS = \
+       -DGTEST_USE_OWN_TR1_TUPLE=0 \
        -I$(top_srcdir) \
        -I$(top_srcdir)/lib/gtest-1.7.0/include
 LDADD = $(top_builddir)/lib/gtest-1.7.0/libgtest_main.a
@@ -83,6 +84,20 @@ graph_ExtendPath_SOURCES = Graph/ExtendPathTest.cpp
 graph_ExtendPath_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/Common
 graph_ExtendPath_LDADD = $(top_builddir)/Common/libcommon.a $(LDADD)
 
+check_PROGRAMS += graph_DotIO
+graph_DotIO_SOURCES = Graph/DotIOTest.cpp
+graph_DotIO_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/Common
+graph_DotIO_LDADD = \
+       $(top_builddir)/Assembly/libassembly.a \
+       $(top_builddir)/DataLayer/libdatalayer.a \
+       $(top_builddir)/Common/libcommon.a \
+       $(LDADD)
+
+check_PROGRAMS += graph_UndirectedGraph
+graph_UndirectedGraph_SOURCES = Graph/UndirectedGraphTest.cpp
+# graph_UndirectedGraph_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/Common
+# graph_UndirectedGraph_LDADD = $(top_builddir)/Common/libcommon.a $(LDADD)
+
 check_PROGRAMS += Konnector_konnector
 Konnector_konnector_SOURCES = \
        Konnector/konnectorTest.cpp
diff --git a/configure.ac b/configure.ac
index 884852b..4b8df12 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.62)
-AC_INIT(ABySS, 2.0.1, [email protected], abyss,
+AC_INIT(ABySS, 2.0.2, [email protected], abyss,
                http://www.bcgsc.ca/platform/bioinfo/software/abyss)
 m4_include(m4/m4_ax_pthread.m4)
 AM_INIT_AUTOMAKE(1.9.6 foreign subdir-objects)
@@ -55,6 +55,17 @@ AC_CHECK_TYPE([std::tr1::hash<int>],
        AC_DEFINE(HAVE_STD_TR1_HASH, [1],
                [Define if the system provides std::tr1::hash]),
        [], [#include <tr1/functional>])
+AC_CHECK_TYPE([std::tr1::tuple<int>],
+       AC_DEFINE(HAVE_STD_TR1_TUPLE, [1],
+               [Define if the system provides std::tr1::tuple]),
+       [], [#include <tr1/tuple>])
+if test "x$ac_cv_type_std__tr1__tuple_int_" = "xyes"; then
+       # Avoid double-declaration of std::tr1::tuple by boost.
+       # See 
http://stackoverflow.com/questions/1156003/c-namespace-collision-with-gtest-and-boost
+       # for explanation.
+       AC_DEFINE(BOOST_HAS_TR1_TUPLE, [1],
+       [Define to disable declaration of std::tr1::tuple by boost])
+fi
 AC_LANG_POP([C++])
 
 # Checks for library functions.
diff --git a/doc/ABYSS.1 b/doc/ABYSS.1
index 14a9f69..8f3a30a 100644
--- a/doc/ABYSS.1
+++ b/doc/ABYSS.1
@@ -1,4 +1,4 @@
-.TH ABYSS "1" "2015-May" "ABYSS (ABySS) 2.0.1" "User Commands"
+.TH ABYSS "1" "2015-May" "ABYSS (ABySS) 2.0.2" "User Commands"
 .SH NAME
 ABYSS \- assemble short reads into contigs
 .SH SYNOPSIS
diff --git a/doc/abyss-pe.1 b/doc/abyss-pe.1
index fb94fe7..e6af3d7 100644
--- a/doc/abyss-pe.1
+++ b/doc/abyss-pe.1
@@ -1,4 +1,4 @@
-.TH abyss-pe "1" "2015-May" "abyss-pe (ABySS) 2.0.1" "User Commands"
+.TH abyss-pe "1" "2015-May" "abyss-pe (ABySS) 2.0.2" "User Commands"
 .SH NAME
 abyss-pe - assemble reads into contigs
 .SH SYNOPSIS
diff --git a/doc/abyss-tofastq.1 b/doc/abyss-tofastq.1
index 4250191..d8fd0ea 100644
--- a/doc/abyss-tofastq.1
+++ b/doc/abyss-tofastq.1
@@ -1,4 +1,4 @@
-.TH abyss-tofastq "1" "2015-May" "ABySS 2.0.1" "User Commands"
+.TH abyss-tofastq "1" "2015-May" "ABySS 2.0.2" "User Commands"
 .SH NAME
 abyss-tofastq \- convert various file formats to FASTQ format
 .br
diff --git a/doc/flowchart.graffle b/doc/flowchart.graffle
index a695117..73a03b0 100644
--- a/doc/flowchart.graffle
+++ b/doc/flowchart.graffle
@@ -5198,7 +5198,7 @@
 {\colortbl;\red255\green255\blue255;}
 
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\pardirnatural\qc
 
-\f0\b\fs28 \cf0 ABySS paired-end pipeline version 2.0.1}</string>
+\f0\b\fs28 \cf0 ABySS paired-end pipeline version 2.0.2}</string>
                                <key>VerticalPad</key>
                                <integer>0</integer>
                        </dict>

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/debian-med/abyss.git

_______________________________________________
debian-med-commit mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/debian-med-commit

Reply via email to