@Override
  public int score(LeafCollector collector, Bits acceptDocs, int min, int maxDoc)
      throws IOException {
    if (min != 0) {
      throw new IllegalArgumentException("min must be 0, got " + min);
    }
    if (maxDoc != Integer.MAX_VALUE) {
      throw new IllegalArgumentException("maxDoc must be Integer.MAX_VALUE");
    }
    // if (DEBUG) {
    //  System.out.println("\nscore: reader=" + context.reader());
    // }
    // System.out.println("score r=" + context.reader());
    FakeScorer scorer = new FakeScorer();
    collector.setScorer(scorer);
    if (drillDownCollector != null) {
      drillDownLeafCollector = drillDownCollector.getLeafCollector(context);
      drillDownLeafCollector.setScorer(scorer);
    } else {
      drillDownLeafCollector = null;
    }
    for (DocsAndCost dim : dims) {
      dim.sidewaysLeafCollector = dim.sidewaysCollector.getLeafCollector(context);
      dim.sidewaysLeafCollector.setScorer(scorer);
    }

    // TODO: if we ever allow null baseScorer ... it will
    // mean we DO score docs out of order ... hmm, or if we
    // change up the order of the conjuntions below
    assert baseScorer != null;

    // some scorers, eg ReqExlScorer, can hit NPE if cost is called after nextDoc
    long baseQueryCost = baseScorer.cost();

    final int numDims = dims.length;

    long drillDownCost = 0;
    for (int dim = 0; dim < numDims; dim++) {
      drillDownCost += dims[dim].approximation.cost();
    }

    long drillDownAdvancedCost = 0;
    if (numDims > 1) {
      drillDownAdvancedCost = dims[1].approximation.cost();
    }

    // Position all scorers to their first matching doc:
    baseScorer.nextDoc();
    for (DocsAndCost dim : dims) {
      dim.approximation.nextDoc();
    }

    /*
    System.out.println("\nbaseDocID=" + baseScorer.docID() + " est=" + estBaseHitCount);
    System.out.println("  maxDoc=" + context.reader().maxDoc());
    System.out.println("  maxCost=" + maxCost);
    System.out.println("  dims[0].freq=" + dims[0].freq);
    if (numDims > 1) {
      System.out.println("  dims[1].freq=" + dims[1].freq);
    }
    */

    if (scoreSubDocsAtOnce || baseQueryCost < drillDownCost / 10) {
      // System.out.println("queryFirst: baseScorer=" + baseScorer + " disis.length=" + disis.length
      // + " bits.length=" + bits.length);
      doQueryFirstScoring(acceptDocs, collector, dims);
    } else if (numDims > 1 && drillDownAdvancedCost < baseQueryCost / 10) {
      // System.out.println("drillDownAdvance");
      doDrillDownAdvanceScoring(acceptDocs, collector, dims);
    } else {
      // System.out.println("union");
      doUnionScoring(acceptDocs, collector, dims);
    }

    return Integer.MAX_VALUE;
  }
 @Override
 public long cost() {
   return baseScorer.cost();
 }