protected void visitCell(final HashSetChartCell cell) {
    final int start = cell.start(), end = cell.end();
    Collection<Production> possibleProds;
    ChartEdge edge;
    final ChartEdge[] bestEdges = new ChartEdge[grammar.numNonTerms()]; // inits to null

    // final int maxEdgesToAdd = (int) opts.param2;
    final int maxEdgesToAdd = Integer.MAX_VALUE;

    for (int mid = start + 1; mid <= end - 1; mid++) { // mid point
      final HashSetChartCell leftCell = chart.getCell(start, mid);
      final HashSetChartCell rightCell = chart.getCell(mid, end);
      for (final int leftNT : leftCell.getLeftChildNTs()) {
        for (final int rightNT : rightCell.getRightChildNTs()) {
          possibleProds = grammar.getBinaryProductionsWithChildren(leftNT, rightNT);
          if (possibleProds != null) {
            for (final Production p : possibleProds) {
              edge = chart.new ChartEdge(p, leftCell, rightCell);
              addEdgeToArray(edge, bestEdges);
            }
          }
        }
      }
    }

    addBestEdgesToChart(cell, bestEdges, maxEdgesToAdd);
  }
  protected void setSpanMaxEdgeFOM(
      final HashSetChartCell leftCell, final HashSetChartCell rightCell) {
    ChartEdge edge;
    final int start = leftCell.start(), end = rightCell.end();
    float bestFOM = maxEdgeFOM[start][end];

    // System.out.println(" setSpanMax: " + leftCell + " && " + rightCell);

    Collection<Production> possibleProds;
    for (final int leftNT : leftCell.getLeftChildNTs()) {
      for (final int rightNT : rightCell.getRightChildNTs()) {
        possibleProds = grammar.getBinaryProductionsWithChildren(leftNT, rightNT);
        if (possibleProds != null) {
          for (final Production p : possibleProds) {
            // final float prob = p.prob + leftCell.getInside(leftNT) +
            // rightCell.getInside(rightNT);
            edge = chart.new ChartEdge(p, leftCell, rightCell);
            // System.out.println(" considering: " + edge);
            if (edge.fom > bestFOM) {
              bestFOM = edge.fom;
            }
          }
        }
      }
    }

    if (bestFOM > maxEdgeFOM[start][end]) {
      final HashSetChartCell parentCell = chart.getCell(start, end);
      // if (maxEdgeFOM[start][end] > Float.NEGATIVE_INFINITY) {
      // spanAgenda.remove(parentCell);
      // }
      maxEdgeFOM[start][end] = bestFOM;
      parentCell.fom = bestFOM;
      // spanAgenda.add(parentCell);
      // System.out.println(" addingSpan: " + parentCell);
    }
  }