class ASTMetric extends NodeVisitor implements MetricInterface {
  polyglot.ast.Node astNode;
  String className = null; // name of Class being currently processed

  public ASTMetric(polyglot.ast.Node astNode) {
    this.astNode = astNode;
    reset();
  }

  /*
   * Taking care of the change in classes within a polyglot ast
   */
  public final NodeVisitor enter(Node n) {
    if (n instanceof ClassDecl) {
      className = ((ClassDecl) n).name();
      System.out.println("Starting processing: " + className);
    }
    return this;
  }

  /*
   * When we leave a classDecl all the metrics for this classDecl must be stored and the metrics reset
   *
   * This is done by invoking the addMetrics abstract method
   */

  public final Node leave(Node parent, Node old, Node n, NodeVisitor v) {<FILL_FUNCTION_BODY>}

  public abstract void reset();

  public abstract void addMetrics(ClassData data);

  /*
   * Should be used to execute the traversal which will find the metric being calculated
   */
  public final void execute() {
    astNode.visit(this);
    // Testing testing testing
    System.out.println("\n\n\n PRETTY P{RINTING");
    if (this instanceof StmtSumWeightedByDepth) {
      metricPrettyPrinter p = new metricPrettyPrinter(this);
      p.printAst(astNode, new CodeWriter(System.out, 80));
    }
  }

  public void printAstMetric(Node n, CodeWriter w) {

  }

  /*
   * Returns the classData object if one if present in the globals Metrics List otherwise creates new adds to globals metric
   * list and returns that
   */
  public final ClassData getClassData() {
    if (className == null) {
      throw new RuntimeException("className is null");
    }

    Iterator<ClassData> it = G.v().ASTMetricsData.iterator();
    while (it.hasNext()) {
      ClassData tempData = it.next();

      if (tempData.classNameEquals(className)) {
        return tempData;
      }
    }
    ClassData data = new ClassData(className);
    G.v().ASTMetricsData.add(data);
    return data;
  }
}

    if (n instanceof ClassDecl) {
      if (className == null) {
        throw new RuntimeException("className is null");
      }

      System.out.println("Done with class " + className);

      // get the classData object for this class
      ClassData data = getClassData();
      addMetrics(data);
      reset();
    }
    return leave(old, n, v);
  
<methods>public void <init>() ,public polyglot.visit.NodeVisitor begin() ,public polyglot.visit.NodeVisitor enter(polyglot.ast.Node) ,public polyglot.visit.NodeVisitor enter(polyglot.ast.Node, polyglot.ast.Node) ,public void finish() ,public void finish(polyglot.ast.Node) ,public polyglot.ast.Node leave(polyglot.ast.Node, polyglot.ast.Node, polyglot.visit.NodeVisitor) ,public polyglot.ast.Node leave(polyglot.ast.Node, polyglot.ast.Node, polyglot.ast.Node, polyglot.visit.NodeVisitor) ,public polyglot.ast.Node override(polyglot.ast.Node) ,public polyglot.ast.Node override(polyglot.ast.Node, polyglot.ast.Node) ,public java.lang.String toString() ,public polyglot.ast.Node visitEdge(polyglot.ast.Node, polyglot.ast.Node) <variables>