Index: src/java/org/apache/lucene/search/BooleanQuery.java
===================================================================
--- src/java/org/apache/lucene/search/BooleanQuery.java	(revision 813200)
+++ src/java/org/apache/lucene/search/BooleanQuery.java	(working copy)
@@ -188,7 +188,7 @@
     public Query getQuery() { return BooleanQuery.this; }
     public float getValue() { return getBoost(); }
 
-    public float sumOfSquaredWeights() throws IOException {
+    public float sumOfSquaredWeights() {
       float sum = 0.0f;
       for (int i = 0 ; i < weights.size(); i++) {
         BooleanClause c = (BooleanClause)clauses.get(i);
Index: src/java/org/apache/lucene/search/ConstantScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/ConstantScoreQuery.java	(revision 813200)
+++ src/java/org/apache/lucene/search/ConstantScoreQuery.java	(working copy)
@@ -67,7 +67,7 @@
       return queryWeight;
     }
 
-    public float sumOfSquaredWeights() throws IOException {
+    public float sumOfSquaredWeights() {
       queryWeight = getBoost();
       return queryWeight * queryWeight;
     }
Index: src/java/org/apache/lucene/search/DefaultSimilarity.java
===================================================================
--- src/java/org/apache/lucene/search/DefaultSimilarity.java	(revision 813200)
+++ src/java/org/apache/lucene/search/DefaultSimilarity.java	(working copy)
@@ -1,5 +1,7 @@
 package org.apache.lucene.search;
 
+import java.io.IOException;
+
 import org.apache.lucene.index.FieldInvertState;
 
 /**
@@ -49,6 +51,12 @@
   public float queryNorm(float sumOfSquaredWeights) {
     return (float)(1.0 / Math.sqrt(sumOfSquaredWeights));
   }
+  
+  /** Implemented as <code>1/sqrt(sumOfSquaredWeights)</code>. 
+   * @throws IOException */
+  public float queryNorm(Weight weight) {
+    return (float)(1.0 / Math.sqrt(weight.sumOfSquaredWeights()));
+  }
 
   /** Implemented as <code>sqrt(freq)</code>. */
   public float tf(float freq) {
Index: src/java/org/apache/lucene/search/DisjunctionMaxQuery.java
===================================================================
--- src/java/org/apache/lucene/search/DisjunctionMaxQuery.java	(revision 813200)
+++ src/java/org/apache/lucene/search/DisjunctionMaxQuery.java	(working copy)
@@ -114,7 +114,7 @@
     public float getValue() { return getBoost(); }
 
     /* Compute the sub of squared weights of us applied to our subqueries.  Used for normalization. */
-    public float sumOfSquaredWeights() throws IOException {
+    public float sumOfSquaredWeights() {
       float max = 0.0f, sum = 0.0f;
       for (Iterator iter = weights.iterator(); iter.hasNext();) {
         float sub = ((Weight) iter.next()).sumOfSquaredWeights();
Index: src/java/org/apache/lucene/search/FilteredQuery.java
===================================================================
--- src/java/org/apache/lucene/search/FilteredQuery.java	(revision 813200)
+++ src/java/org/apache/lucene/search/FilteredQuery.java	(working copy)
@@ -66,7 +66,7 @@
         
       // pass these methods through to enclosed query's weight
       public float getValue() { return value; }
-      public float sumOfSquaredWeights() throws IOException { 
+      public float sumOfSquaredWeights() { 
         return weight.sumOfSquaredWeights() * getBoost() * getBoost(); 
       }
       public void normalize (float v) { 
Index: src/java/org/apache/lucene/search/Query.java
===================================================================
--- src/java/org/apache/lucene/search/Query.java	(revision 813200)
+++ src/java/org/apache/lucene/search/Query.java	(working copy)
@@ -97,8 +97,7 @@
   public Weight weight(Searcher searcher) throws IOException {
     Query query = searcher.rewrite(this);
     Weight weight = query.createWeight(searcher);
-    float sum = weight.sumOfSquaredWeights();
-    float norm = getSimilarity(searcher).queryNorm(sum);
+    float norm = getSimilarity(searcher).queryNorm(weight);
     weight.normalize(norm);
     return weight;
   }
Index: src/java/org/apache/lucene/search/Similarity.java
===================================================================
--- src/java/org/apache/lucene/search/Similarity.java	(revision 813200)
+++ src/java/org/apache/lucene/search/Similarity.java	(working copy)
@@ -384,7 +384,7 @@
    * @see org.apache.lucene.document.Field#setBoost(float)
    */
   public abstract float lengthNorm(String fieldName, int numTokens);
-
+  
   /** Computes the normalization value for a query given the sum of the squared
    * weights of each of the query terms.  This value is multiplied into the
    * weight of each query term. While the classic query normalization factor is
@@ -397,9 +397,26 @@
    *
    * @param sumOfSquaredWeights the sum of the squares of query term weights
    * @return a normalization factor for query weights
+   * @deprecated use {@link #queryNorm(Weight)}
    */
   public abstract float queryNorm(float sumOfSquaredWeights);
 
+  /** Computes the normalization value for a query given the sum of the squared
+   * weights of each of the query terms.  This value is multiplied into the
+   * weight of each query term. While the classic query normalization factor is
+   * computed as 1/sqrt(sumOfSquaredWeights), other implementations might
+   * completely ignore sumOfSquaredWeights (ie return 1).
+   *
+   * <p>This does not affect ranking, but the default implementation does make scores
+   * from different queries more comparable than they would be by eliminating the
+   * magnitude of the Query vector as a factor in the score.
+   *
+   * @param weight the Query Weight
+   * @return a normalization factor for query weights
+   * @throws IOException 
+   */
+  public abstract float queryNorm(Weight weight);
+
   /** Encodes a normalization factor for storage in an index.
    *
    * <p>The encoding uses a three-bit mantissa, a five-bit exponent, and
Index: src/java/org/apache/lucene/search/SimilarityDelegator.java
===================================================================
--- src/java/org/apache/lucene/search/SimilarityDelegator.java	(revision 813200)
+++ src/java/org/apache/lucene/search/SimilarityDelegator.java	(working copy)
@@ -45,6 +45,10 @@
   public float queryNorm(float sumOfSquaredWeights) {
     return delegee.queryNorm(sumOfSquaredWeights);
   }
+  
+  public float queryNorm(Weight weight) {
+    return delegee.queryNorm(weight);
+  }
 
   public float tf(float freq) {
     return delegee.tf(freq);
Index: src/java/org/apache/lucene/search/Weight.java
===================================================================
--- src/java/org/apache/lucene/search/Weight.java	(revision 813200)
+++ src/java/org/apache/lucene/search/Weight.java	(working copy)
@@ -100,7 +100,7 @@
       boolean topScorer) throws IOException;
   
   /** The sum of squared weights of contained query clauses. */
-  public abstract float sumOfSquaredWeights() throws IOException;
+  public abstract float sumOfSquaredWeights();
 
   /**
    * Returns true iff this implementation scores docs only out of order. This
Index: src/java/org/apache/lucene/search/function/CustomScoreQuery.java
===================================================================
--- src/java/org/apache/lucene/search/function/CustomScoreQuery.java	(revision 813200)
+++ src/java/org/apache/lucene/search/function/CustomScoreQuery.java	(working copy)
@@ -298,7 +298,7 @@
     }
 
     /*(non-Javadoc) @see org.apache.lucene.search.Weight#sumOfSquaredWeights() */
-    public float sumOfSquaredWeights() throws IOException {
+    public float sumOfSquaredWeights() {
       float sum = subQueryWeight.sumOfSquaredWeights();
       for(int i = 0; i < valSrcWeights.length; i++) {
         if (qStrict) {
Index: src/java/org/apache/lucene/search/function/ValueSourceQuery.java
===================================================================
--- src/java/org/apache/lucene/search/function/ValueSourceQuery.java	(revision 813200)
+++ src/java/org/apache/lucene/search/function/ValueSourceQuery.java	(working copy)
@@ -82,7 +82,7 @@
     }
 
     /*(non-Javadoc) @see org.apache.lucene.search.Weight#sumOfSquaredWeights() */
-    public float sumOfSquaredWeights() throws IOException {
+    public float sumOfSquaredWeights() {
       queryWeight = getBoost();
       return queryWeight * queryWeight;
     }
Index: src/java/org/apache/lucene/search/spans/SpanWeight.java
===================================================================
--- src/java/org/apache/lucene/search/spans/SpanWeight.java	(revision 813200)
+++ src/java/org/apache/lucene/search/spans/SpanWeight.java	(working copy)
@@ -52,7 +52,7 @@
   public Query getQuery() { return query; }
   public float getValue() { return value; }
 
-  public float sumOfSquaredWeights() throws IOException {
+  public float sumOfSquaredWeights() {
     queryWeight = idf * query.getBoost();         // compute query weight
     return queryWeight * queryWeight;             // square it
   }
Index: src/test/org/apache/lucene/index/TestOmitTf.java
===================================================================
--- src/test/org/apache/lucene/index/TestOmitTf.java	(revision 813200)
+++ src/test/org/apache/lucene/index/TestOmitTf.java	(working copy)
@@ -33,6 +33,7 @@
 import org.apache.lucene.search.Searcher;
 import org.apache.lucene.search.Similarity;
 import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.Weight;
 import org.apache.lucene.search.BooleanClause.Occur;
 import org.apache.lucene.store.Directory;
 import org.apache.lucene.store.MockRAMDirectory;
@@ -43,6 +44,7 @@
   public static class SimpleSimilarity extends Similarity {
     public float lengthNorm(String field, int numTerms) { return 1.0f; }
     public float queryNorm(float sumOfSquaredWeights) { return 1.0f; }
+    public float queryNorm(Weight weight) { return 1.0f; }
     
     public float tf(float freq) { return freq; }
     
Index: src/test/org/apache/lucene/search/JustCompileSearch.java
===================================================================
--- src/test/org/apache/lucene/search/JustCompileSearch.java	(revision 813200)
+++ src/test/org/apache/lucene/search/JustCompileSearch.java	(working copy)
@@ -375,6 +375,10 @@
     public float lengthNorm(String fieldName, int numTokens) {
       throw new UnsupportedOperationException(UNSUPPORTED_MSG);
     }
+    
+    public float queryNorm(Weight weight) {
+      throw new UnsupportedOperationException(UNSUPPORTED_MSG);
+    }
 
     public float queryNorm(float sumOfSquaredWeights) {
       throw new UnsupportedOperationException(UNSUPPORTED_MSG);
@@ -446,7 +450,7 @@
       throw new UnsupportedOperationException(UNSUPPORTED_MSG);
     }
 
-    public float sumOfSquaredWeights() throws IOException {
+    public float sumOfSquaredWeights() {
       throw new UnsupportedOperationException(UNSUPPORTED_MSG);
     }
 
Index: src/test/org/apache/lucene/search/TestSimilarity.java
===================================================================
--- src/test/org/apache/lucene/search/TestSimilarity.java	(revision 813200)
+++ src/test/org/apache/lucene/search/TestSimilarity.java	(working copy)
@@ -48,6 +48,7 @@
     public float idf(Collection terms, Searcher searcher) { return 1.0f; }
     public float idf(int docFreq, int numDocs) { return 1.0f; }
     public float coord(int overlap, int maxOverlap) { return 1.0f; }
+    public float queryNorm(Weight weight) { return 1.0f; }
   }
 
   public void testSimilarity() throws Exception {

