 */
 let stmt_list : Parser<String, String>.Function = 
     fix { stmt_list in
-        let subgraph_id = %("subgraph") ++ ignore(whitespace*) ++ ID|? ++ ignore(whitespace*)
-        let subgraph = subgraph_id ++ %("{") ++ ignore(whitespace*) ++ stmt_list ++ ignore(whitespace*) ++ %("}") 
+        let subgraph_id = %("subgraph") ++ ignore(whitespace*) ++ id|? ++ ignore(whitespace*)
+        let subgraph = subgraph_id|? ++ %("{") ++ ignore(whitespace*) ++ stmt_list ++ ignore(whitespace*) ++ %("}") 
             |> map { "\($0)" }  // Render.
         let stmt = node_stmt | edge_stmt | attr_stmt | id_stmt | subgraph
+//        let a = stmt.flatMap()
             |> map { "\($0)" }  // Render.
         let stmt_list = stmt ++ ignore(whitespace*) ++ (%(";"))|? ++ ignore(whitespace*) ++ stmt_list* 
             |> map { (stmt, rem) in "\(stmt) \(rem.0) \(rem.1)" }

## _graph_ : [ "strict" ] ("graph" | "digraph") [ ID ] '{' stmt_list '}'
We can now define the root of our grammar, **graph**
*/
let graph_id = (%("strict"))|? ++ (%("graph") | %("digraph")) ++ ignore(whitespace*) ++ ID|? 

let graph = graph_id ++ spaces ++ %leftBrace ++ ignore(whitespace*) ++ stmt_list ++ ignore(whitespace*) ++ %rightBrace ++ spaces
/*:
## DotParser Tests
*/
println(simpleGraphDotString)
simpleGraphDotString == "digraph G { \n    Hello -> World \n}\n"

let graph_id_test_parser = graph_id ++ any* |> map { (a, b) in "\(a)" }
let output8 = parse(graph_id_test_parser, simpleGraphDotString).result

        return self.either(ifLeft: {"\($0)"}, ifRight: {"\($0)"})
    }
}

/*:
 Dot Abstract Syntax Tree
 
*/

typealias ID = String

struct Attribute {
    let name: String
    let value: String
}

enum AttributeStatement {
    case Graph([Attribute])
    case Node([Attribute])
    case Edge([Attribute])
}

enum EdgeOp {
    case Directed
    case Undirected
}

enum Statement {
    case Node(id: ID, [Attribute])
//: FIXME: Doesn't support `Source -> Next -> Target` sequences of node and edges.
//: FIXME: `Edge` doesn't support `Subgraph` source and target
    case Edge(source: ID, edgeop: EdgeOp, target: ID)
    case Attr(AttributeStatement)
    case Property(Attribute)
    case Subgraph(id: ID?, stmt_list: [Statement])
}

enum Graph {
    case Directed(id: String?, stmt_list: [Statement])
    case Undirected(id: String?, stmt_list: [Statement])
}

//: Literal Characters and Strings
let space = " "
let underscore = "_"
