Index: src/java/org/apache/lucene/search/Explanation.java
===================================================================
--- src/java/org/apache/lucene/search/Explanation.java	(revision 807187)
+++ src/java/org/apache/lucene/search/Explanation.java	(working copy)
@@ -124,4 +124,9 @@
 
     return buffer.toString();
   }
+  
+  public static abstract class IdfExplain {
+    abstract float getIdf();
+    abstract String explain();
+  }
 }
Index: src/java/org/apache/lucene/search/PhraseQuery.java
===================================================================
--- src/java/org/apache/lucene/search/PhraseQuery.java	(revision 807187)
+++ src/java/org/apache/lucene/search/PhraseQuery.java	(working copy)
@@ -24,6 +24,7 @@
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermPositions;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Explanation.IdfExplain;
 import org.apache.lucene.util.ToStringUtils;
 
 /** A Query that matches documents containing a particular sequence of terms.
@@ -112,12 +113,14 @@
     private float idf;
     private float queryNorm;
     private float queryWeight;
+    private String termExp;
 
     public PhraseWeight(Searcher searcher)
       throws IOException {
       this.similarity = getSimilarity(searcher);
-
-      idf = similarity.idf(terms, searcher);
+      IdfExplain simExp = similarity.idfExplain(terms, searcher);
+      termExp = simExp.explain();
+      idf = simExp.getIdf();
     }
 
     public String toString() { return "weight(" + PhraseQuery.this + ")"; }
@@ -158,33 +161,29 @@
 
     }
 
-    public Explanation explain(IndexReader reader, int doc)
-      throws IOException {
+    public Explanation explain(IndexReader reader, int doc) throws IOException {
 
       Explanation result = new Explanation();
-      result.setDescription("weight("+getQuery()+" in "+doc+"), product of:");
+      result.setDescription("weight(" + getQuery() + " in " + doc
+          + "), product of:");
 
       StringBuffer docFreqs = new StringBuffer();
       StringBuffer query = new StringBuffer();
       query.append('\"');
+      docFreqs.append(termExp);
       for (int i = 0; i < terms.size(); i++) {
         if (i != 0) {
-          docFreqs.append(" ");
           query.append(" ");
         }
 
-        Term term = (Term)terms.get(i);
-
-        docFreqs.append(term.text());
-        docFreqs.append("=");
-        docFreqs.append(reader.docFreq(term));
+        Term term = (Term) terms.get(i);
 
         query.append(term.text());
       }
       query.append('\"');
 
-      Explanation idfExpl =
-        new Explanation(idf, "idf(" + field + ": " + docFreqs + ")");
+      Explanation idfExpl = new Explanation(idf, "idf(" + field + ":"
+          + docFreqs + ")");
 
       // explain query weight
       Explanation queryExpl = new Explanation();
@@ -195,19 +194,18 @@
         queryExpl.addDetail(boostExpl);
       queryExpl.addDetail(idfExpl);
 
-      Explanation queryNormExpl = new Explanation(queryNorm,"queryNorm");
+      Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
       queryExpl.addDetail(queryNormExpl);
 
-      queryExpl.setValue(boostExpl.getValue() *
-                         idfExpl.getValue() *
-                         queryNormExpl.getValue());
+      queryExpl.setValue(boostExpl.getValue() * idfExpl.getValue()
+          * queryNormExpl.getValue());
 
       result.addDetail(queryExpl);
 
       // explain field weight
       Explanation fieldExpl = new Explanation();
-      fieldExpl.setDescription("fieldWeight("+field+":"+query+" in "+doc+
-                               "), product of:");
+      fieldExpl.setDescription("fieldWeight(" + field + ":" + query + " in "
+          + doc + "), product of:");
 
       Scorer scorer = scorer(reader, true, false);
       if (scorer == null) {
@@ -219,15 +217,15 @@
 
       Explanation fieldNormExpl = new Explanation();
       byte[] fieldNorms = reader.norms(field);
-      float fieldNorm =
-        fieldNorms!=null ? Similarity.decodeNorm(fieldNorms[doc]) : 1.0f;
+      float fieldNorm = fieldNorms != null ? Similarity
+          .decodeNorm(fieldNorms[doc]) : 1.0f;
       fieldNormExpl.setValue(fieldNorm);
-      fieldNormExpl.setDescription("fieldNorm(field="+field+", doc="+doc+")");
+      fieldNormExpl.setDescription("fieldNorm(field=" + field + ", doc=" + doc
+          + ")");
       fieldExpl.addDetail(fieldNormExpl);
 
-      fieldExpl.setValue(tfExpl.getValue() *
-                         idfExpl.getValue() *
-                         fieldNormExpl.getValue());
+      fieldExpl.setValue(tfExpl.getValue() * idfExpl.getValue()
+          * fieldNormExpl.getValue());
 
       result.addDetail(fieldExpl);
 
Index: src/java/org/apache/lucene/search/Similarity.java
===================================================================
--- src/java/org/apache/lucene/search/Similarity.java	(revision 807187)
+++ src/java/org/apache/lucene/search/Similarity.java	(working copy)
@@ -19,6 +19,7 @@
 
 import org.apache.lucene.index.FieldInvertState;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Explanation.IdfExplain;
 import org.apache.lucene.util.SmallFloat;
 
 import java.io.IOException;
@@ -482,6 +483,22 @@
   public float idf(Term term, Searcher searcher) throws IOException {
     return idf(searcher.docFreq(term), searcher.maxDoc());
   }
+  
+  public IdfExplain idfExplain(Term term, Searcher searcher) throws IOException {
+    final int df = searcher.docFreq(term);
+    final int max = searcher.maxDoc();
+
+    return new IdfExplain() {
+        //@Override
+        public String explain() {
+          return "idf(docFreq=" + df +
+          ", maxDocs=" + max + ")";
+        }
+        //@Override
+        public float getIdf() {
+          return idf(df, max);
+        }};
+   }
 
   /** Computes a score factor for a phrase.
    *
@@ -500,6 +517,33 @@
     }
     return idf;
   }
+  
+  public IdfExplain idfExplain(Collection terms, Searcher searcher) throws IOException {
+
+    final int max = searcher.maxDoc();
+    float idf = 0.0f;
+    final StringBuffer exp = new StringBuffer();
+    Iterator i = terms.iterator();
+    while (i.hasNext()) {
+      Term term = (Term)i.next();
+      final int df = searcher.docFreq(term);
+      idf += idf(df, max);
+      exp.append(" " + term.text() + "=" + df);
+    }
+    final float fIdf = idf;
+    return new IdfExplain() {
+      
+      //@Override
+      float getIdf() {
+        return fIdf;
+      }
+      
+      //@Override
+      String explain() {
+        return exp.toString();
+      }
+    };
+  }
 
   /** Computes a score factor based on a term's document frequency (the number
    * of documents which contain the term).  This value is multiplied by the
Index: src/java/org/apache/lucene/search/TermQuery.java
===================================================================
--- src/java/org/apache/lucene/search/TermQuery.java	(revision 807187)
+++ src/java/org/apache/lucene/search/TermQuery.java	(working copy)
@@ -23,6 +23,7 @@
 import org.apache.lucene.index.Term;
 import org.apache.lucene.index.TermDocs;
 import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.search.Explanation.IdfExplain;
 import org.apache.lucene.util.ToStringUtils;
 
 /** A Query that matches documents containing a term.
@@ -37,11 +38,14 @@
     private float idf;
     private float queryNorm;
     private float queryWeight;
+    private String tfIdfExp;
 
     public TermWeight(Searcher searcher)
       throws IOException {
       this.similarity = getSimilarity(searcher);
-      idf = similarity.idf(term, searcher); // compute idf
+      IdfExplain idfSim = similarity.idfExplain(term, searcher);
+      tfIdfExp = idfSim.explain();
+      idf = idfSim.getIdf();
     }
 
     public String toString() { return "weight(" + TermQuery.this + ")"; }
@@ -75,8 +79,7 @@
       ComplexExplanation result = new ComplexExplanation();
       result.setDescription("weight("+getQuery()+" in "+doc+"), product of:");
 
-      Explanation expl = new Explanation(idf, "idf(docFreq=" + reader.docFreq(term) +
-            ", maxDocs=" + reader.maxDoc() + ")");
+      Explanation expl = new Explanation(idf, tfIdfExp);
 
       // explain query weight
       Explanation queryExpl = new Explanation();

