package mclint.patterns;

import java.util.Map;

import ast.ASTNode;
import ast.Expr;
import ast.List;
import ast.Stmt;

public class Match {
  private UnparsedPattern pattern;
  private ASTNode<?> tree;
  private Map<Character, ASTNode<?>> bindings;
  
  Match(ASTNode<?> tree, Map<Character, ASTNode<?>> bindings, UnparsedPattern pattern) {
    this.tree = tree;
    this.bindings = bindings;
    this.pattern = pattern;
  }
  
  public ASTNode<?> getMatchingNode() {
    return tree;
  }
  
  public ASTNode<?> getBoundNode(char var) {
    return bindings.get(var);
  }
  
  public <T extends ASTNode<?>> T getBoundNode(char var, Class<T> clazz) {
    return clazz.cast(getBoundNode(var));
  }
  
  public List<?> getBoundList(char var) {
    return getBoundNode(var, List.class);
  }
  
  public Stmt getBoundStmt(char var) {
    return getBoundNode(var, Stmt.class);
  }
  
  public Expr getBoundExpr(char var) {
    return getBoundNode(var, Expr.class);
  }
  
  public UnparsedPattern getPattern() {
    return pattern;
  }
  
  private String getBindingsAsString() {
    StringBuilder sb = new StringBuilder("{");
    boolean first = true;
    for (Map.Entry<Character, ASTNode<?>> binding : bindings.entrySet()) {
      if (!first) {
        sb.append(", ");
      }
      first = false;
      sb.append(binding.getKey());
      sb.append(": ");
      if (binding.getValue() instanceof ast.List) {
        for (int i = 0; i < binding.getValue().getNumChild(); ++i) {
          if (i != 0) {
            sb.append(", ");
          }
          sb.append(binding.getValue().getChild(i).getPrettyPrinted());
        }
      } else {
        sb.append(binding.getValue().getPrettyPrinted());
      }
    }
    sb.append("}");
    return sb.toString();
  }
  
  @Override
  public String toString() {
    return String.format("Match %s against %s\nBindings: %s", pattern.asString(),
        tree.getPrettyPrinted(), getBindingsAsString()); 
  }
}

@@ -114,16 +114,178 @@
 .Stmt;%0A%0A
+import com.google.common.base.Function;%0Aimport com.google.common.base.Joiner;%0Aimport com.google.common.collect.Iterables;%0Aimport com.google.common.collect.Maps;%0A%0A
 public c
@@ -1203,347 +1203,514 @@
 ate 
-String getBindingsAsString() %7B%0A    StringBuilder sb = new StringBuilder(%22%7B%22);%0A    boolean first = true;%0A    for (Map.Entry%3CCharacter, ASTNode%3C?%3E%3E binding : bindings.entrySet()) %7B
+static Function%3CASTNode%3C?%3E, String%3E prettyPrintFunction() %7B%0A    return new Function%3CASTNode%3C?%3E, String%3E() %7B%0A      @Override public String apply(ASTNode%3C?%3E node) %7B%0A        return node.getPrettyPrinted();%0A      %7D%0A    %7D;
 %0A  
+%7D%0A
   
+%0A
   
-if (!first) %7B%0A        sb.append(%22,
+private String getBindingsAsString() %7B%0A    return String.format(%22%7B%25s%7D%22, Joiner.on(%22, %22).withKeyValueSeparator(%22:
  %22)
-;
 %0A      
-%7D%0A      first = false;%0A      sb.append(binding.getKey());%0A      sb.append(%22: %22);%0A      if (binding.getValue()
+  .join(Maps.transformValues(bindings, new Function%3CASTNode%3C?%3E, String%3E() %7B%0A          @Override public String apply(ASTNode%3C?%3E node) %7B%0A            if (!(node
  ins
@@ -1726,16 +1726,17 @@
 st.List)
+)
  %7B%0A     
@@ -1742,121 +1742,102 @@
     
-for (int i = 0; i %3C binding.getValue().getNumChild(); ++i) %7B%0A          if (i != 0) %7B%0A            sb.append(%22, 
+      return node.getPrettyPrinted();%0A            %7D%0A            @SuppressWarnings(%22unchecked
 %22)
-;
 %0A   
@@ -1847,80 +1847,85 @@
     
-%7D%0A          sb.append(binding.getValue().getChild(i).getPrettyPrinted())
+  ast.List%3C? extends ASTNode%3C?%3E%3E list = (ast.List%3C? extends ASTNode%3C?%3E%3E) node
 ;%0A  
@@ -1934,79 +1934,87 @@
     
-%7D%0A
     
-  %7D else %7B%0A        sb.append(binding.getValue().getPrettyPrinted(
+return Joiner.on(%22, %22).join(Iterables.transform(list, prettyPrintFunction()
 ));%0A
@@ -2015,26 +2015,24 @@
 ()));%0A      
-%7D%0A
     %7D%0A    sb
@@ -2033,56 +2033,22 @@
     
-sb.append(%22%7D%22);%0A    return sb.toString(
+    %7D))
 );%0A  %7D%0A
-  
 %0A  @

Rewrite Match#getBindingsAsString using Guava