// Copyright 2004-9 Trustees of Indiana University

// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)

//
// read_graphviz_new.cpp - 
//   Initialize a model of the BGL's MutableGraph concept and an associated
//  collection of property maps using a graph expressed in the GraphViz
// DOT Language.  
//
//   Based on the grammar found at:
//   http://www.graphviz.org/cvs/doc/info/lang.html
//
//   Jeremiah rewrite used grammar found at:
//   http://www.graphviz.org/doc/info/lang.html
//   and page 34 or http://www.graphviz.org/pdf/dotguide.pdf
//
//   See documentation for this code at: 
//     http://www.boost.org/libs/graph/doc/read-graphviz.html
//

// Author: Jeremiah Willcock
//         Ronald Garcia
//

#define BOOST_GRAPH_SOURCE
#include <boost/ref.hpp>
#include <boost/function/function2.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/algorithm/string/case_conv.hpp>
#include <algorithm>
#include <exception> // for std::exception
#include <string>
#include <vector>
#include <set>
#include <utility>
#include <map>
#include <iostream>
#include <cstdlib>
#include <boost/throw_exception.hpp>
#include <boost/regex.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/graph/dll_import_export.hpp>
#include <boost/graph/graphviz.hpp>

namespace boost {

namespace read_graphviz_detail {
  struct token {
    enum token_type {
      kw_strict,
      kw_graph,
      kw_digraph,
      kw_node,
      kw_edge,
      kw_subgraph,
      left_brace,
      right_brace,
      semicolon,
      equal,
      left_bracket,
      right_bracket,
      comma,
      colon,
      dash_greater,
      dash_dash,
      plus,
      left_paren,
      right_paren,
      at,
      identifier,
      quoted_string, // Only used internally in tokenizer
      eof,
      invalid
    };
    token_type type;
    std::string normalized_value; // May have double-quotes removed and/or some escapes replaced
    token(token_type type, const std::string& normalized_value)
      : type(type), normalized_value(normalized_value) {}
    token(): type(invalid), normalized_value("") {}
    friend std::ostream& operator<<(std::ostream& o, const token& t) {
      switch (t.type) {
        case token::kw_strict: o << "<strict>"; break;
        case token::kw_graph: o << "<graph>"; break;
        case token::kw_digraph: o << "<digraph>"; break;
        case token::kw_node: o << "<node>"; break;
        case token::kw_edge: o << "<edge>"; break;
        case token::kw_subgraph: o << "<subgraph>"; break;
        case token::left_brace: o << "<left_brace>"; break;
        case token::right_brace: o << "<right_brace>"; break;
        case token::semicolon: o << "<semicolon>"; break;
        case token::equal: o << "<equal>"; break;
        case token::left_bracket: o << "<left_bracket>"; break;
        case token::right_bracket: o << "<right_bracket>"; break;
        case token::comma: o << "<comma>"; break;
        case token::colon: o << "<colon>"; break;
        case token::dash_greater: o << "<dash-greater>"; break;
        case token::dash_dash: o << "<dash-dash>"; break;
        case token::plus: o << "<plus>"; break;
        case token::left_paren: o << "<left_paren>"; break;
        case token::right_paren: o << "<right_paren>"; break;
        case token::at: o << "<at>"; break;
        case token::identifier: o << "<identifier>"; break;
        case token::quoted_string: o << "<quoted_string>"; break;
        case token::eof: o << "<eof>"; break;
        default: o << "<invalid type>"; break;
      }
      o << " '" << t.normalized_value << "'";
      return o;
    }
  };

  bad_graphviz_syntax lex_error(const std::string& errmsg, char bad_char) {
    if (bad_char == '\0') {
      return bad_graphviz_syntax(errmsg + " (at end of input)");
    } else {
      return bad_graphviz_syntax(errmsg + " (char is '" + bad_char + "')");
    }
  }

  bad_graphviz_syntax parse_error(const std::string& errmsg, const token& bad_token) {
    return bad_graphviz_syntax(errmsg + " (token is \"" + boost::lexical_cast<std::string>(bad_token) + "\")");
  }

  struct tokenizer {
    std::string::const_iterator begin, end;
    std::vector<token> lookahead;
    // Precomputed regexes
    boost::regex stuff_to_skip;
    boost::regex basic_id_token;
    boost::regex punctuation_token;
    boost::regex number_token;
    boost::regex quoted_string_token;
    boost::regex xml_tag_token;
    boost::regex cdata;

    tokenizer(const std::string& str) : begin(str.begin()), end(str.end())
    {
      std::string end_of_token = "(?=(?:\\W))";
      std::string whitespace = "(?:\\s+)";
      std::string slash_slash_comment = "(?://.*$)";
      std::string slash_star_comment = "(?:/\\*.*?\\*/)";
      std::string hash_comment = "(?:^#.*?$)";
      std::string backslash_newline = "(?:[\\\\][\\n])";
      stuff_to_skip = "\\A(?:" + whitespace + "|" +
                                 slash_slash_comment + "|" +
                                 slash_star_comment + "|" +
                                 hash_comment + "|" +
                                 backslash_newline + ")*";
      basic_id_token = "\\A([[:alpha:]_](?:\\w*))";
      punctuation_token = "\\A([][{};=,:+()@]|[-][>-])";
      number_token = "\\A([-]?(?:(?:\\.\\d+)|(?:\\d+(?:\\.\\d*)?)))";
      quoted_string_token = "\\A(\"(?:[^\"\\\\]|(?:[\\\\].))*\")";
      xml_tag_token = "\\A<(/?)(?:[^!?'\"]|(?:'[^']*?')|(?:\"[^\"]*?\"))*?(/?)>";
      cdata = "\\A\\Q<![CDATA[\\E.*?\\Q]]>\\E";
    }

    void skip() {
      boost::match_results<std::string::const_iterator> results;
#ifndef NDEBUG
      bool found =
#endif
        boost::regex_search(begin, end, results, stuff_to_skip);
#ifndef NDEBUG
      assert (found);
#endif
      boost::sub_match<std::string::const_iterator> sm1 = results.suffix();
      assert (sm1.second == end);
      begin = sm1.first;
    }

    token get_token_raw() {
      if (!lookahead.empty()) {
        token t = lookahead.front();
        lookahead.erase(lookahead.begin());
        return t;
      }
      skip();
      if (begin == end) return token(token::eof, "");
      // Look for keywords first
      bool found;
      boost::match_results<std::string::const_iterator> results;
      found = boost::regex_search(begin, end, results, basic_id_token);
      if (found) {
        std::string str = results[1].str();
        std::string str_lower = boost::algorithm::to_lower_copy(str);
        begin = results.suffix().first;
        if (str_lower == "strict") {
          return token(token::kw_strict, str);
        } else if (str_lower == "graph") {
          return token(token::kw_graph, str);
        } else if (str_lower == "digraph") {
          return token(token::kw_digraph, str);
        } else if (str_lower == "node") {
          return token(token::kw_node, str);
        } else if (str_lower == "edge") {
          return token(token::kw_edge, str);
        } else if (str_lower == "subgraph") {
          return token(token::kw_subgraph, str);
        } else {
          return token(token::identifier, str);
        }
      }
      found = boost::regex_search(begin, end, results, punctuation_token);
      if (found) {
        std::string str = results[1].str();
        begin = results.suffix().first;
        switch (str[0]) {
          case '[': return token(token::left_bracket, str);
          case ']': return token(token::right_bracket, str);
          case '{': return token(token::left_brace, str);
          case '}': return token(token::right_brace, str);
          case ';': return token(token::semicolon, str);
          case '=': return token(token::equal, str);
          case ',': return token(token::comma, str);
          case ':': return token(token::colon, str);
          case '+': return token(token::plus, str);
          case '(': return token(token::left_paren, str);
          case ')': return token(token::right_paren, str);
          case '@': return token(token::at, str);
          case '-': {
            switch (str[1]) {
              case '-': return token(token::dash_dash, str);
              case '>': return token(token::dash_greater, str);
              default: assert (!"Definition of punctuation_token does not match switch statement");
            }
          }
          default: assert (!"Definition of punctuation_token does not match switch statement");
        }
      }
      found = boost::regex_search(begin, end, results, number_token);
      if (found) {
        std::string str = results[1].str();
        begin = results.suffix().first;
        return token(token::identifier, str);
      }
      found = boost::regex_search(begin, end, results, quoted_string_token);
      if (found) {
        std::string str = results[1].str();
        begin = results.suffix().first;
        // Remove the beginning and ending quotes
        assert (str.size() >= 2);
        str.erase(str.begin());
        str.erase(str.end() - 1);
        // Unescape quotes in the middle, but nothing else (see format spec)
        for (size_t i = 0; i + 1 < str.size() /* May change */; ++i) {
          if (str[i] == '\\' && str[i + 1] == '"') {
            str.erase(str.begin() + i);
            // Don't need to adjust i
          } else if (str[i] == '\\' && str[i + 1] == '\n') {
            str.erase(str.begin() + i);
            str.erase(str.begin() + i);
            --i; // Invert ++ that will be applied
          }
        }
        return token(token::quoted_string, str);
      }
      if (*begin == '<') {
        std::string::const_iterator saved_begin = begin;
        int counter = 0;
        do {
          if (begin == end) throw_lex_error("Unclosed HTML string");
          if (*begin != '<') {
            ++begin;
            continue;
          }
          found = boost::regex_search(begin, end, results, xml_tag_token);
          if (found) {
            begin = results.suffix().first;
            if (results[1].str() == "/") { // Close tag
              --counter;
            } else if (results[2].str() == "/") { // Empty tag
            } else { // Open tag
              ++counter;
            }
            continue;
          }
          found = boost::regex_search(begin, end, results, cdata);
          if (found) {
            begin = results.suffix().first;
            continue;
          }
          throw_lex_error("Invalid contents in HTML string");
        } while (counter > 0);
        return token(token::identifier, std::string(saved_begin, begin));
      } else {
        throw_lex_error("Invalid character");
        return token();
      }
    }

    token peek_token_raw() {
      if (lookahead.empty()) {
        token t = get_token_raw();
        lookahead.push_back(t);
      }
      return lookahead.front();
    }

    token get_token() { // Handle string concatenation
      token t = get_token_raw();
      if (t.type != token::quoted_string) return t;
      std::string str = t.normalized_value;
      while (peek_token_raw().type == token::plus) {
        get_token_raw();
        token t2 = get_token_raw();
        if (t2.type != token::quoted_string) {
          throw_lex_error("Must have quoted string after string concatenation");
        }
        str += t2.normalized_value;
      }
      return token(token::identifier, str); // Note that quoted_string does not get passed to the parser
    }

    void throw_lex_error(const std::string& errmsg) {
      boost::throw_exception(lex_error(errmsg, (begin == end ? '\0' : *begin)));
    }
  };

  struct edge_endpoint {
    bool is_subgraph;
    node_and_port node_ep;
    subgraph_name subgraph_ep;

    static edge_endpoint node(const node_and_port& ep) {
      edge_endpoint r;
      r.is_subgraph = false;
      r.node_ep = ep;
      return r;
    }

    static edge_endpoint subgraph(const subgraph_name& ep) {
      edge_endpoint r;
      r.is_subgraph = true;
      r.subgraph_ep = ep;
      return r;
    }
  };

  struct node_or_subgraph_ref {
    bool is_subgraph;
    std::string name; // Name for subgraphs or nodes, "___root___" for root graph
  };

  static node_or_subgraph_ref noderef(const node_name& n) {
    node_or_subgraph_ref r;
    r.is_subgraph = false;
    r.name = n;
    return r;
  }

  static node_or_subgraph_ref subgraphref(const subgraph_name& n) {
    node_or_subgraph_ref r;
    r.is_subgraph = true;
    r.name = n;
    return r;
  }

  typedef std::vector<node_or_subgraph_ref> subgraph_member_list;

  struct subgraph_info {
    properties def_node_props;
    properties def_edge_props;
    subgraph_member_list members;
  };

  struct parser {
    tokenizer the_tokenizer;
    std::vector<token> lookahead;
    parser_result& r;
    std::map<subgraph_name, subgraph_info> subgraphs;
    std::string current_subgraph_name;
    int sgcounter; // Counter for anonymous subgraphs
    std::set<std::pair<node_name, node_name> > existing_edges; // Used for checking in strict graphs

    subgraph_info& current() {return subgraphs[current_subgraph_name];}
    properties& current_graph_props() {return r.graph_props[current_subgraph_name];}
    subgraph_member_list& current_members() {return current().members;}

    parser(const std::string& gr, parser_result& result)
        : the_tokenizer(gr), lookahead(), r(result), sgcounter(0) {
      current_subgraph_name = "___root___";
      current() = subgraph_info(); // Initialize root graph
      current_graph_props().clear();
      current_members().clear();
    }

    token get() {
      if (lookahead.empty()) {
        token t = the_tokenizer.get_token();
        return t;
      } else {
        token t = lookahead.front();
        lookahead.erase(lookahead.begin());
        return t;
      }
    }

    token peek() {
      if (lookahead.empty()) {
        lookahead.push_back(the_tokenizer.get_token());
      }
      return lookahead.front();
    }

    void error(const std::string& str) {
      boost::throw_exception(parse_error(str, peek()));
    }

    void parse_graph(bool want_directed) {
      bool is_strict = false;
      bool is_directed = false;
      std::string name;
      if (peek().type == token::kw_strict) {get(); is_strict = true;}
      switch (peek().type) {
        case token::kw_graph: is_directed = false; break;
        case token::kw_digraph: is_directed = true; break;
        default: error("Wanted \"graph\" or \"digraph\"");
      }
      r.graph_is_directed = is_directed; // Used to check edges
      r.graph_is_strict = is_strict;
      if (want_directed != r.graph_is_directed) {
        if (want_directed) {
          boost::throw_exception(boost::undirected_graph_error());
        } else {
          boost::throw_exception(boost::directed_graph_error());
        }
      }
      get();
      switch (peek().type) {
        case token::identifier: name = peek().normalized_value; get(); break;
        case token::left_brace: break;
        default: error("Wanted a graph name or left brace");
      }
      if (peek().type == token::left_brace) get(); else error("Wanted a left brace to start the graph");
      parse_stmt_list();
      if (peek().type == token::right_brace) get(); else error("Wanted a right brace to end the graph");
      if (peek().type == token::eof) {} else error("Wanted end of file");
    }

    void parse_stmt_list() {
      while (true) {
        if (peek().type == token::right_brace) return;
        parse_stmt();
        if (peek().type == token::semicolon) get();
      }
    }

    void parse_stmt() {
      switch (peek().type) {
        case token::kw_node:
        case token::kw_edge:
        case token::kw_graph: parse_attr_stmt(); break;
        case token::kw_subgraph:
        case token::left_brace:
        case token::identifier: {
          token id = get();
          if (id.type == token::identifier && peek().type == token::equal) { // Graph property
            get();
            if (peek().type != token::identifier) error("Wanted identifier as right side of =");
            token id2 = get();
            current_graph_props()[id.normalized_value] = id2.normalized_value;
          } else {
            edge_endpoint ep = parse_endpoint_rest(id);
            if (peek().type == token::dash_dash || peek().type == token::dash_greater) { // Edge
              parse_edge_stmt(ep);
            } else {
              if (!ep.is_subgraph) { // Only nodes can have attribute lists
                // This node already exists because of its first mention
                // (properties set to defaults by parse_node_and_port, called
                // by parse_endpoint_rest)
                properties this_node_props;
                if (peek().type == token::left_bracket) {
                  parse_attr_list(this_node_props);
                }
                for (properties::const_iterator i = this_node_props.begin();
                     i != this_node_props.end(); ++i) {
                  // Override old properties with same names
                  r.nodes[ep.node_ep.name][i->first] = i->second;
                }
                current_members().push_back(noderef(ep.node_ep.name));
              } else {
                current_members().push_back(subgraphref(ep.subgraph_ep));
              }
            }
          }
          break;
        }
        default: error("Invalid start token for statement");
      }
    }

    void parse_attr_stmt() {
      switch (get().type) {
        case token::kw_graph: parse_attr_list(current_graph_props()); break;
        case token::kw_node: parse_attr_list(current().def_node_props); break;
        case token::kw_edge: parse_attr_list(current().def_edge_props); break;
        default: assert (!"Bad attr_stmt case");
      }
    }

    edge_endpoint parse_endpoint() {
      switch (peek().type) {
        case token::kw_subgraph:
        case token::left_brace:
        case token::identifier: {
          token first = get();
          return parse_endpoint_rest(first);
        }
        default: {
          error("Wanted \"subgraph\", \"{\", or identifier to start node or subgraph");
          return edge_endpoint();
        }
      }
    }

    edge_endpoint parse_endpoint_rest(const token& first_token) {
      switch (first_token.type) {
        case token::kw_subgraph:
        case token::left_brace: return edge_endpoint::subgraph(parse_subgraph(first_token));
        default: return edge_endpoint::node(parse_node_and_port(first_token));
      }
    }

    subgraph_name parse_subgraph(const token& first_token) {
      std::string name;
      bool is_anonymous = true;
      if (first_token.type == token::kw_subgraph) {
        if (peek().type == token::identifier) {
          name = get().normalized_value;
          is_anonymous = false;
        }
      }
      if (is_anonymous) {
        name = "___subgraph_" +
                 boost::lexical_cast<std::string>(++sgcounter);
      }
      if (subgraphs.find(name) == subgraphs.end()) {
        subgraphs[name] = current(); // Initialize properties and defaults
        subgraphs[name].members.clear(); // Except member list
      }
      if (first_token.type == token::kw_subgraph && peek().type != token::left_brace) {
        if (is_anonymous) error("Subgraph reference needs a name");
        return name;
      }
      subgraph_name old_sg = current_subgraph_name;
      current_subgraph_name = name;
      if (peek().type == token::left_brace) get(); else error("Wanted left brace to start subgraph");
      parse_stmt_list();
      if (peek().type == token::right_brace) get(); else error("Wanted right brace to end subgraph");
      current_subgraph_name = old_sg;
      return name;
    }

    node_and_port parse_node_and_port(const token& name) {
      // A node ID is a node name, followed optionally by a port angle and a
      // port location (in either order); a port location is either :id,
      // :id:id, or :(id,id); the last two forms are treated as equivalent
      // although I am not sure about that.
      node_and_port id;
      id.name = name.normalized_value;
      parse_more:
      switch (peek().type) {
        case token::at: {
          get();
          if (peek().type != token::identifier) error("Wanted identifier as port angle");
          if (id.angle != "") error("Duplicate port angle");
          id.angle = get().normalized_value;
          goto parse_more;
        }
        case token::colon: {
          get();
          if (!id.location.empty()) error("Duplicate port location");
          switch (peek().type) {
            case token::identifier: {
              id.location.push_back(get().normalized_value);
              switch (peek().type) {
                case token::colon: {
                  get();
                  if (peek().type != token::identifier) error("Wanted identifier as port location");
                  id.location.push_back(get().normalized_value);
                  goto parse_more;
                }
                default: goto parse_more;
              }
            }
            case token::left_paren: {
              get();
              if (peek().type != token::identifier) error("Wanted identifier as first element of port location");
              id.location.push_back(get().normalized_value);
              if (peek().type != token::comma) error("Wanted comma between parts of port location");
              get();
              if (peek().type != token::identifier) error("Wanted identifier as second element of port location");
              id.location.push_back(get().normalized_value);
              if (peek().type != token::right_paren) error("Wanted right parenthesis to close port location");
              get();
              goto parse_more;
            }
            default: error("Wanted identifier or left parenthesis as start of port location");
          }
        }
        default: break;
      }
      if (r.nodes.find(id.name) == r.nodes.end()) { // First mention
        r.nodes[id.name] = current().def_node_props;
      }
      return id;
    }

    void parse_edge_stmt(const edge_endpoint& lhs) {
      std::vector<edge_endpoint> nodes_in_chain(1, lhs);
      while (true) {
        bool leave_loop = true;
        switch (peek().type) {
          case token::dash_dash: {
            if (r.graph_is_directed) error("Using -- in directed graph");
            get();
            nodes_in_chain.push_back(parse_endpoint());
            leave_loop = false;
            break;
          }
          case token::dash_greater: {
            if (!r.graph_is_directed) error("Using -> in undirected graph");
            get();
            nodes_in_chain.push_back(parse_endpoint());
            leave_loop = false;
            break;
          }
          default: leave_loop = true; break;
        }
        if (leave_loop) break;
      }
      properties this_edge_props = current().def_edge_props;
      if (peek().type == token::left_bracket) parse_attr_list(this_edge_props);
      assert (nodes_in_chain.size() >= 2); // Should be in node parser otherwise
      for (size_t i = 0; i + 1 < nodes_in_chain.size(); ++i) {
        do_orig_edge(nodes_in_chain[i], nodes_in_chain[i + 1], this_edge_props);
      }
    }

    // Do an edge from the file, the edge may need to be expanded if it connects to a subgraph
    void do_orig_edge(const edge_endpoint& src, const edge_endpoint& tgt, const properties& props) {
      std::set<node_and_port> sources = get_recursive_members(src);
      std::set<node_and_port> targets = get_recursive_members(tgt);
      for (std::set<node_and_port>::const_iterator i = sources.begin(); i != sources.end(); ++i) {
        for (std::set<node_and_port>::const_iterator j = targets.begin(); j != targets.end(); ++j) {
          do_edge(*i, *j, props);
        }
      }
    }

    // Get nodes in an edge_endpoint, recursively
    std::set<node_and_port> get_recursive_members(const edge_endpoint& orig_ep) {
      std::set<node_and_port> result;
      std::vector<edge_endpoint> worklist(1, orig_ep);
      std::set<subgraph_name> done;
      while (!worklist.empty()) {
        edge_endpoint ep = worklist.back();
        worklist.pop_back();
        if (ep.is_subgraph) {
          if (done.find(ep.subgraph_ep) == done.end()) {
            done.insert(ep.subgraph_ep);
            std::map<subgraph_name, subgraph_info>::const_iterator
              info_i = subgraphs.find(ep.subgraph_ep);
            if (info_i != subgraphs.end()) {
              const subgraph_member_list& members = info_i->second.members;
              for (subgraph_member_list::const_iterator i = members.begin();
                   i != members.end(); ++i) {
                node_or_subgraph_ref ref = *i;
                if (ref.is_subgraph) {
                  worklist.push_back(edge_endpoint::subgraph(ref.name));
                } else {
                  node_and_port np;
                  np.name = ref.name;
                  worklist.push_back(edge_endpoint::node(np));
                }
              }
            }
          }
        } else {
          result.insert(ep.node_ep);
        }
      }
      return result;
    }

    // Do a fixed-up edge, with only nodes as endpoints
    void do_edge(const node_and_port& src, const node_and_port& tgt, const properties& props) {
      if (r.graph_is_strict) {
        if (src.name == tgt.name) return;
        std::pair<node_name, node_name> tag(src.name, tgt.name);
        if (existing_edges.find(tag) != existing_edges.end()) {
          return; // Parallel edge
        }
        existing_edges.insert(tag);
      }
      edge_info e;
      e.source = src;
      e.target = tgt;
      e.props = props;
      r.edges.push_back(e);
    }

    void parse_attr_list(properties& props) {
      while (true) {
        if (peek().type == token::left_bracket) get(); else error("Wanted left bracket to start attribute list");
        while (true) {
          switch (peek().type) {
            case token::right_bracket: break;
            case token::identifier: {
              std::string lhs = get().normalized_value;
              std::string rhs = "true";
              if (peek().type == token::equal) {
                get();
                if (peek().type != token::identifier) error("Wanted identifier as value of attributed");
                rhs = get().normalized_value;
              }
              props[lhs] = rhs;
              break;
            }
            default: error("Wanted identifier as name of attribute");
          }
          if (peek().type == token::comma) {get(); continue;}
          break;
        }
        if (peek().type == token::right_bracket) get(); else error("Wanted right bracket to end attribute list");
        if (peek().type != token::left_bracket) break;
      }
    }
  };

  void parse_graphviz_from_string(const std::string& str, parser_result& result, bool want_directed) {
    parser p(str, result);
    p.parse_graph(want_directed);
  }

  // Some debugging stuff
  std::ostream& operator<<(std::ostream& o, const node_and_port& n) {
    o << n.name;
    for (size_t i = 0; i < n.location.size(); ++i) {
      o << ":" << n.location[i];
    }
    if (!n.angle.empty()) o << "@" << n.angle;
    return o;
  }

  // Can't be operator<< because properties is just an std::map
  std::string props_to_string(const properties& props) {
    std::string result = "[";
    for (properties::const_iterator i = props.begin(); i != props.end(); ++i) {
      if (i != props.begin()) result += ", ";
      result += i->first + "=" + i->second;
    }
    result += "]";
    return result;
  }

  void translate_results_to_graph(const parser_result& r, ::boost::detail::graph::mutate_graph* mg) {
    typedef boost::detail::graph::node_t vertex;
    typedef boost::detail::graph::edge_t edge;
    for (std::map<node_name, properties>::const_iterator i = r.nodes.begin(); i != r.nodes.end(); ++i) {
      // std::cerr << i->first << " " << props_to_string(i->second) << std::endl;
      mg->do_add_vertex(i->first);
      for (properties::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
        mg->set_node_property(j->first, i->first, j->second);
      }
    }
    for (std::vector<edge_info>::const_iterator i = r.edges.begin(); i != r.edges.end(); ++i) {
      const edge_info& ei = *i;
      // std::cerr << ei.source << " -> " << ei.target << " " << props_to_string(ei.props) << std::endl;
      edge e = edge::new_edge();
      mg->do_add_edge(e, ei.source.name, ei.target.name);
      for (properties::const_iterator j = ei.props.begin(); j != ei.props.end(); ++j) {
        mg->set_edge_property(j->first, e, j->second);
      }
    }
    std::map<subgraph_name, properties>::const_iterator root_graph_props_i = r.graph_props.find("___root___");
    assert (root_graph_props_i != r.graph_props.end()); // Should not happen
    const properties& root_graph_props = root_graph_props_i->second;
    // std::cerr << "ending graph " << props_to_string(root_graph_props) << std::endl;
    for (properties::const_iterator i = root_graph_props.begin(); i != root_graph_props.end(); ++i) {
      mg->set_graph_property(i->first, i->second);
    }
  }

} // end namespace read_graphviz_detail

namespace detail {
  namespace graph {

    BOOST_GRAPH_DECL bool read_graphviz_new(const std::string& str, boost::detail::graph::mutate_graph* mg) {
      read_graphviz_detail::parser_result parsed_file;
      read_graphviz_detail::parse_graphviz_from_string(str, parsed_file, mg->is_directed());
      read_graphviz_detail::translate_results_to_graph(parsed_file, mg);
      return true;
    }

  } // end namespace graph
} // end namespace detail

} // end namespace boost

// GraphViz format notes (tested using "dot version 1.13 (v16) (Mon August 23,
// 2004)", grammar from references in read_graphviz_new.hpp):

// Subgraphs don't nest (all a0 subgraphs are the same thing), but a node or
// subgraph can have multiple parents (sources online say that the layout
// algorithms can't handle non-tree structures of clusters, but it seems to
// read them the same from the file).  The containment relation is required to
// be a DAG, though; it appears that a node or subgraph can't be moved into an
// ancestor of a subgraph where it already was (we don't enforce that but do a
// DFS when finding members to prevent cycles).  Nodes get their properties by
// when they are first mentioned, and can only have them overridden after that
// by explicit properties on that particular node.  Closing and reopening the
// same subgraph name adds to its members, and graph properties and node/edge
// defaults are preserved in that subgraph.  The members of a subgraph used in
// an edge are gathered when the edge is read, even if new members are added to
// the subgraph later.  Ports are allowed in a lot more places in the grammar
// than Dot uses.  For example, declaring a node seems to ignore ports, and I
// don't think it's possible to set properties on a particular port.  Adding an
// edge between two ports on the same node seems to make Dot unhappy (crashed
// for me).

// Test graph for GraphViz behavior on strange combinations of subgraphs and
// such.  I don't have anywhere else to put this file.

#if 0
dIGRaph foo {
  node [color=blue]
  subgraph a -> b
  subgraph a {c}
  subgraph a -> d
  subgraph a {node [color=red]; e}
  subgraph a -> f
  subgraph a {g} -> h
  subgraph a {node [color=green]; i} -> j
  subgraph a {node [color=yellow]}

  subgraph a0 {node [color=black]; subgraph a1 {node [color=white]}}
  node [color=pink] zz
  subgraph a0 {x1}
  subgraph a0 {subgraph a1 {x2}}

  subgraph a0 -> x3
  subgraph a0 {subgraph a1 -> x3}
  x3
  subgraph a0 {subgraph a0 {node [color=xxx]; x2} x7}
  x2 [color=yyy]
  subgraph cluster_ax {foo; subgraph a0}
  subgraph a0 {foo2}
  subgraph cluster_ax {foo3}
  // subgraph a0 -> subgraph a0

  bgcolor=yellow
  subgraph cluster_a2 {y1}
  // y1:n -> y1:(s,3)@se
  y1@se [color=green]
  y1@n [color=red]
}
#endif
