BooleanScorer(Similarity similarity, int minNrShouldMatch,
      List<Scorer> optionalScorers, List<Scorer> prohibitedScorers) throws IOException {
    super(similarity);
    this.minNrShouldMatch = minNrShouldMatch;

    if (optionalScorers != null && optionalScorers.size() > 0) {
      for (Scorer scorer : optionalScorers) {
        maxCoord++;
        if (scorer.nextDoc() != NO_MORE_DOCS) {
          scorers = new SubScorer(scorer, false, false, bucketTable.newCollector(0), scorers);
        }
      }
    }
    
    if (prohibitedScorers != null && prohibitedScorers.size() > 0) {
      for (Scorer scorer : prohibitedScorers) {
        int mask = nextMask;
        nextMask = nextMask << 1;
        prohibitedMask |= mask;                     // update prohibited mask
        if (scorer.nextDoc() != NO_MORE_DOCS) {
          scorers = new SubScorer(scorer, false, true, bucketTable.newCollector(mask), scorers);
        }
      }
    }

    coordFactors = new float[maxCoord];
    Similarity sim = getSimilarity();
    for (int i = 0; i < maxCoord; i++) {
      coordFactors[i] = sim.coord(i, maxCoord - 1); 
    }
  }