Index: lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java	(revision 1343966)
+++ lucene/join/src/java/org/apache/lucene/search/join/ToParentBlockJoinQuery.java	(revision )
@@ -26,6 +26,7 @@
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.IndexWriter;       // javadocs
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.ComplexExplanation;
 import org.apache.lucene.search.DocIdSet;
 import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
@@ -191,11 +192,15 @@
     }
 
     @Override
-    public Explanation explain(AtomicReaderContext reader, int doc) throws IOException {
-      // TODO
-      throw new UnsupportedOperationException(getClass().getName() +
-                                              " cannot explain match on parent document");
+    public Explanation explain(AtomicReaderContext context, int doc) throws IOException {
+      BlockJoinScorer scorer = (BlockJoinScorer) scorer(context, true, false, context.reader().getLiveDocs());
+      if (scorer != null) {
+        if (scorer.advance(doc) == doc) {
+          return scorer.explain(context.docBase);
-    }
+        }
+      }
+      return new ComplexExplanation(false, 0.0f, "Not a match");
+    }
 
     @Override
     public boolean scoresDocsOutOfOrder() {
@@ -209,6 +214,7 @@
     private final ScoreMode scoreMode;
     private final Bits acceptDocs;
     private int parentDoc = -1;
+    private int prevParentDoc;
     private float parentScore;
     private int nextChildDoc;
 
@@ -365,7 +371,7 @@
         return nextDoc();
       }
 
-      final int prevParentDoc = parentBits.prevSetBit(parentTarget-1);
+      prevParentDoc = parentBits.prevSetBit(parentTarget-1);
 
       //System.out.println("  rolled back to prevParentDoc=" + prevParentDoc + " vs parentDoc=" + parentDoc);
       assert prevParentDoc >= parentDoc;
@@ -383,6 +389,15 @@
       //System.out.println("  return nextParentDoc=" + nd);
       return nd;
     }
+
+    public Explanation explain(int docBase) throws IOException {
+      int start = docBase + prevParentDoc + 1; // +1 b/c prevParentDoc is previous parent doc
+      int end = docBase + parentDoc - 1; // -1 b/c parentDoc is parent doc
+      return new ComplexExplanation(
+          true, score(), String.format("Score based on child doc range from %d to %d", start, end)
+      );
+    }
+
   }
 
   @Override
