protected AugmentScorer(
     BoboIndexReader reader, Scorer innerScorer, ScoreAugmentFunction func, JSONObject jsonParms)
     throws IOException {
   super(innerScorer.getSimilarity());
   _innerScorer = innerScorer;
   _func = func;
   _func.initializeReader(reader, jsonParms);
 }
 public ScoreAugmentQuery(Query query, ScoreAugmentFunction func, JSONObject jsonParam)
     throws JSONException {
   super(query);
   _func = func;
   _func.initializeGlobal(jsonParam);
   _jsonParam = jsonParam;
   if (_func == null) throw new IllegalArgumentException("augment function cannot be null");
 }
 @Override
 protected Scorer createScorer(
     Scorer innerScorer, IndexReader reader, boolean scoreDocsInOrder, boolean topScorer)
     throws IOException {
   if (reader instanceof BoboIndexReader) {
     return new AugmentScorer((BoboIndexReader) reader, innerScorer, _func.getCopy(), _jsonParam);
   } else {
     throw new IllegalStateException("reader not instance of " + BoboIndexReader.class);
   }
 }
  @Override
  protected Explanation createExplain(Explanation innerExplain, IndexReader reader, int doc)
      throws IOException {
    if (reader instanceof BoboIndexReader) {
      Explanation finalExpl = new Explanation();
      finalExpl.addDetail(innerExplain);

      _func.initializeReader((BoboIndexReader) reader, _jsonParam);

      float innerValue = innerExplain.getValue();
      float value = 0;
      if (_func.useInnerScore()) value = _func.newScore(innerValue, doc);
      else value = _func.newScore(doc);

      finalExpl.setValue(value);
      finalExpl.setDescription("Custom score: " + _func.getExplainString(innerValue, doc));
      return finalExpl;
    } else {
      throw new IllegalStateException("reader not instance of " + BoboIndexReader.class);
    }
  }
 @Override
 public float score() throws IOException {
   return (_func.useInnerScore())
       ? _func.newScore(_innerScorer.score(), _innerScorer.docID())
       : _func.newScore(_innerScorer.docID());
 }