Index: MultiFieldQueryParser.java
===================================================================
--- MultiFieldQueryParser.java	(revision 408508)
+++ MultiFieldQueryParser.java	(working copy)
@@ -17,252 +17,481 @@
  */
 
 import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.MultiPhraseQuery;
-import org.apache.lucene.search.PhraseQuery;
-import org.apache.lucene.search.Query;
+import org.apache.lucene.search.*;
 
 import java.util.Vector;
+import java.util.Arrays;
 
 /**
  * A QueryParser which constructs queries to search multiple fields.
  *
- * @author <a href="mailto:kelvin@relevanz.com">Kelvin Tan</a>, Daniel Naber
+ * @author <a href="mailto:kelvin@relevanz.com">Kelvin Tan</a>
+ * @author Daniel Naber
+ * @author Karl Wettin
  * @version $Revision$
  */
-public class MultiFieldQueryParser extends QueryParser
-{
-  
-  private String[] fields;
+public class MultiFieldQueryParser extends QueryParser {
 
-  /**
-   * Creates a MultiFieldQueryParser.
-   *
-   * <p>It will, when parse(String query)
-   * is called, construct a query like this (assuming the query consists of
-   * two terms and you specify the two fields <code>title</code> and <code>body</code>):</p>
-   * 
-   * <code>
-   * (title:term1 body:term1) (title:term2 body:term2)
-   * </code>
-   *
-   * <p>When setDefaultOperator(AND_OPERATOR) is set, the result will be:</p>
-   *  
-   * <code>
-   * +(title:term1 body:term1) +(title:term2 body:term2)
-   * </code>
-   * 
-   * <p>In other words, all the query's terms must appear, but it doesn't matter in
-   * what fields they appear.</p>
-   */
-  public MultiFieldQueryParser(String[] fields, Analyzer analyzer) {
-    super(null, analyzer);
-    this.fields = fields;
-  }
-  
-  protected Query getFieldQuery(String field, String queryText, int slop) throws ParseException {
-    if (field == null) {
-      Vector clauses = new Vector();
-      for (int i = 0; i < fields.length; i++) {
-        Query q = super.getFieldQuery(fields[i], queryText);
-        if (q != null) {
-          if (q instanceof PhraseQuery) {
-            ((PhraseQuery) q).setSlop(slop);
-          }
-          if (q instanceof MultiPhraseQuery) {
-            ((MultiPhraseQuery) q).setSlop(slop);
-          }
-          clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
+    private FieldSetting[] fields;
+
+    /**
+     * Creates a MultiFieldQueryParser.
+     *
+     * <p>It will, when parse(String query)
+     * is called, construct a query like this (assuming the query consists of
+     * two terms and you specify the two fields <code>title</code> and <code>body</code>):</p>
+     *
+     * <code>
+     * (title:term1 body:term1) (title:term2 body:term2)
+     * </code>
+     *
+     * <p>When setDefaultOperator(AND_OPERATOR) is set, the result will be:</p>
+     *
+     * <code>
+     * +(title:term1 body:term1) +(title:term2 body:term2)
+     * </code>
+     *
+     * <p>In other words, all the query's terms must appear, but it doesn't matter in
+     * what fields they appear.</p>
+     */
+    public MultiFieldQueryParser(FieldSetting[] fields, Analyzer analyzer) {
+        super(null, analyzer);
+        this.fields = fields;
+    }
+
+    public MultiFieldQueryParser(String[] fields, Analyzer analyzer) {
+        super(null, analyzer);
+        FieldSetting[] fieldSettings = new FieldSetting[fields.length];
+        for (int i = 0; i < fields.length; i++) {
+            fieldSettings[i] = new FieldSetting(fields[i]);
         }
-      }
-      if (clauses.size() == 0)  // happens for stopwords
-        return null;
-      return getBooleanQuery(clauses, true);
+        this.fields = fieldSettings;
     }
-    return super.getFieldQuery(field, queryText);
-  }
-  
 
-  protected Query getFieldQuery(String field, String queryText) throws ParseException {
-    return getFieldQuery(field, queryText, 0);
-  }
 
+    protected Query getFieldQuery(String field, String queryText, int slop) throws ParseException {
+        if (field == null) {
+            Vector clauses = new Vector();
+            for (int i = 0; i < fields.length; i++) {
+                Query q = super.getFieldQuery(fields[i].field, queryText);
+                if (q != null) {
+                    q.setBoost(q.getBoost() * fields[i].boostMultiplier);
+                    if (q instanceof PhraseQuery) {
+                        ((PhraseQuery) q).setSlop(slop);
+                    }
+                    if (q instanceof MultiPhraseQuery) {
+                        ((MultiPhraseQuery) q).setSlop(slop);
+                    }
+                    clauses.add(new BooleanClause(q, BooleanClause.Occur.SHOULD));
+                }
+            }
+            if (clauses.size() == 0)  // happens for stopwords
+                return null;
+            return getBooleanQuery(clauses, true);
+        }
+        return super.getFieldQuery(field, queryText);
+    }
 
-  protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException
-  {
-    if (field == null) {
-      Vector clauses = new Vector();
-      for (int i = 0; i < fields.length; i++) {
-        clauses.add(new BooleanClause(super.getFuzzyQuery(fields[i], termStr, minSimilarity),
-            BooleanClause.Occur.SHOULD));
-      }
-      return getBooleanQuery(clauses, true);
+
+    protected Query getFieldQuery(String field, String queryText) throws ParseException {
+        return getFieldQuery(field, queryText, 0);
     }
-    return super.getFuzzyQuery(field, termStr, minSimilarity);
-  }
 
-  protected Query getPrefixQuery(String field, String termStr) throws ParseException
-  {
-    if (field == null) {
-      Vector clauses = new Vector();
-      for (int i = 0; i < fields.length; i++) {
-        clauses.add(new BooleanClause(super.getPrefixQuery(fields[i], termStr),
-            BooleanClause.Occur.SHOULD));
-      }
-      return getBooleanQuery(clauses, true);
+    /**
+     * @deprecated use {@link #getFieldQuery(String, String)}
+     */
+    protected Query getFieldQuery(String field, Analyzer analyzer, String queryText)
+            throws ParseException {
+        return getFieldQuery(field, queryText);
     }
-    return super.getPrefixQuery(field, termStr);
-  }
 
-  protected Query getWildcardQuery(String field, String termStr) throws ParseException {
-    if (field == null) {
-      Vector clauses = new Vector();
-      for (int i = 0; i < fields.length; i++) {
-        clauses.add(new BooleanClause(super.getWildcardQuery(fields[i], termStr),
-            BooleanClause.Occur.SHOULD));
-      }
-      return getBooleanQuery(clauses, true);
+    /**
+     * @deprecated use {@link #getFuzzyQuery(String, String, float)}
+     */
+    protected Query getFuzzyQuery(String field, String termStr) throws ParseException {
+        return getFuzzyQuery(field, termStr, fuzzyMinSim);
     }
-    return super.getWildcardQuery(field, termStr);
-  }
 
- 
-  protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive) throws ParseException {
-    if (field == null) {
-      Vector clauses = new Vector();
-      for (int i = 0; i < fields.length; i++) {
-        clauses.add(new BooleanClause(super.getRangeQuery(fields[i], part1, part2, inclusive),
-            BooleanClause.Occur.SHOULD));
-      }
-      return getBooleanQuery(clauses, true);
+    protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws ParseException {
+        if (field == null) {
+            Vector clauses = new Vector();
+            for (int i = 0; i < fields.length; i++) {
+                clauses.add(new BooleanClause(super.getFuzzyQuery(fields[i].field, termStr, minSimilarity),
+                        BooleanClause.Occur.SHOULD));
+            }
+            return getBooleanQuery(clauses, true);
+        }
+        return super.getFuzzyQuery(field, termStr, minSimilarity);
     }
-    return super.getRangeQuery(field, part1, part2, inclusive);
-  }
- 
 
+    protected Query getPrefixQuery(String field, String termStr) throws ParseException {
+        if (field == null) {
+            Vector clauses = new Vector();
+            for (int i = 0; i < fields.length; i++) {
+                clauses.add(new BooleanClause(super.getPrefixQuery(fields[i].field, termStr),
+                        BooleanClause.Occur.SHOULD));
+            }
+            return getBooleanQuery(clauses, true);
+        }
+        return super.getPrefixQuery(field, termStr);
+    }
 
+    protected Query getWildcardQuery(String field, String termStr) throws ParseException {
+        if (field == null) {
+            Vector clauses = new Vector();
+            for (int i = 0; i < fields.length; i++) {
+                clauses.add(new BooleanClause(super.getWildcardQuery(fields[i].field, termStr),
+                        BooleanClause.Occur.SHOULD));
+            }
+            return getBooleanQuery(clauses, true);
+        }
+        return super.getWildcardQuery(field, termStr);
+    }
 
-  /**
-   * Parses a query which searches on the fields specified.
-   * <p>
-   * If x fields are specified, this effectively constructs:
-   * <pre>
-   * <code>
-   * (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
-   * </code>
-   * </pre>
-   * @param queries Queries strings to parse
-   * @param fields Fields to search on
-   * @param analyzer Analyzer to use
-   * @throws ParseException if query parsing fails
-   * @throws IllegalArgumentException if the length of the queries array differs
-   *  from the length of the fields array
-   */
-  public static Query parse(String[] queries, String[] fields,
-      Analyzer analyzer) throws ParseException
-  {
-    if (queries.length != fields.length)
-      throw new IllegalArgumentException("queries.length != fields.length");
-    BooleanQuery bQuery = new BooleanQuery();
-    for (int i = 0; i < fields.length; i++)
-    {
-      QueryParser qp = new QueryParser(fields[i], analyzer);
-      Query q = qp.parse(queries[i]);
-      bQuery.add(q, BooleanClause.Occur.SHOULD);
+    /** @throws ParseException
+     * @deprecated use {@link #getRangeQuery(String, String, String, boolean)}
+     */
+    protected Query getRangeQuery(String field, Analyzer analyzer,
+                                  String part1, String part2, boolean inclusive) throws ParseException {
+        return getRangeQuery(field, part1, part2, inclusive);
     }
-    return bQuery;
-  }
 
+    protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive) throws ParseException {
+        if (field == null) {
+            Vector clauses = new Vector();
+            for (int i = 0; i < fields.length; i++) {
+                clauses.add(new BooleanClause(super.getRangeQuery(fields[i].field, part1, part2, inclusive),
+                        BooleanClause.Occur.SHOULD));
+            }
+            return getBooleanQuery(clauses, true);
+        }
+        return super.getRangeQuery(field, part1, part2, inclusive);
+    }
 
-  /**
-   * Parses a query, searching on the fields specified.
-   * Use this if you need to specify certain fields as required,
-   * and others as prohibited.
-   * <p><pre>
-   * Usage:
-   * <code>
-   * String[] fields = {"filename", "contents", "description"};
-   * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
-   *                BooleanClause.Occur.MUST,
-   *                BooleanClause.Occur.MUST_NOT};
-   * MultiFieldQueryParser.parse("query", fields, flags, analyzer);
-   * </code>
-   * </pre>
-   *<p>
-   * The code above would construct a query:
-   * <pre>
-   * <code>
-   * (filename:query) +(contents:query) -(description:query)
-   * </code>
-   * </pre>
-   *
-   * @param query Query string to parse
-   * @param fields Fields to search on
-   * @param flags Flags describing the fields
-   * @param analyzer Analyzer to use
-   * @throws ParseException if query parsing fails
-   * @throws IllegalArgumentException if the length of the fields array differs
-   *  from the length of the flags array
-   */
-  public static Query parse(String query, String[] fields,
-      BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
-    if (fields.length != flags.length)
-      throw new IllegalArgumentException("fields.length != flags.length");
-    BooleanQuery bQuery = new BooleanQuery();
-    for (int i = 0; i < fields.length; i++) {
-      QueryParser qp = new QueryParser(fields[i], analyzer);
-      Query q = qp.parse(query);
-      bQuery.add(q, flags[i]);
+
+    /** @deprecated */
+    public static final int NORMAL_FIELD = 0;
+    /** @deprecated */
+    public static final int REQUIRED_FIELD = 1;
+    /** @deprecated */
+    public static final int PROHIBITED_FIELD = 2;
+
+    /**
+     * @deprecated use {@link #MultiFieldQueryParser(FieldSetting[], Analyzer)} instead
+     */
+    public MultiFieldQueryParser(QueryParserTokenManager tm) {
+        super(tm);
     }
-    return bQuery;
-  }
 
-  
-  /**
-   * Parses a query, searching on the fields specified.
-   * Use this if you need to specify certain fields as required,
-   * and others as prohibited.
-   * <p><pre>
-   * Usage:
-   * <code>
-   * String[] query = {"query1", "query2", "query3"};
-   * String[] fields = {"filename", "contents", "description"};
-   * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
-   *                BooleanClause.Occur.MUST,
-   *                BooleanClause.Occur.MUST_NOT};
-   * MultiFieldQueryParser.parse(query, fields, flags, analyzer);
-   * </code>
-   * </pre>
-   *<p>
-   * The code above would construct a query:
-   * <pre>
-   * <code>
-   * (filename:query1) +(contents:query2) -(description:query3)
-   * </code>
-   * </pre>
-   *
-   * @param queries Queries string to parse
-   * @param fields Fields to search on
-   * @param flags Flags describing the fields
-   * @param analyzer Analyzer to use
-   * @throws ParseException if query parsing fails
-   * @throws IllegalArgumentException if the length of the queries, fields,
-   *  and flags array differ
-   */
-  public static Query parse(String[] queries, String[] fields, BooleanClause.Occur[] flags,
-      Analyzer analyzer) throws ParseException
-  {
-    if (!(queries.length == fields.length && queries.length == flags.length))
-      throw new IllegalArgumentException("queries, fields, and flags array have have different length");
-    BooleanQuery bQuery = new BooleanQuery();
-    for (int i = 0; i < fields.length; i++)
-    {
-      QueryParser qp = new QueryParser(fields[i], analyzer);
-      Query q = qp.parse(queries[i]);
-      bQuery.add(q, flags[i]);
+    /**
+     * @deprecated use {@link #MultiFieldQueryParser(FieldSetting[], Analyzer)} instead
+     */
+    public MultiFieldQueryParser(CharStream stream) {
+        super(stream);
     }
-    return bQuery;
-  }
 
+    /**
+     * @deprecated use {@link #MultiFieldQueryParser(FieldSetting[], Analyzer)} instead
+     */
+    public MultiFieldQueryParser(String f, Analyzer a) {
+        super(f, a);
+    }
+
+    /**
+     * Parses a query which searches on the fields specified.
+     * <p>
+     * If x fields are specified, this effectively constructs:
+     * <pre>
+     * <code>
+     * (field1:query1) (field2:query2) (field3:query3)...(fieldx:queryx)
+     * </code>
+     * </pre>
+     * @param queries Queries strings to parse
+     * @param fields Fields to search on
+     * @param analyzer Analyzer to use
+     * @throws ParseException if query parsing fails
+     * @throws TokenMgrError if query parsing fails
+     * @throws IllegalArgumentException if the length of the queries array differs
+     *  from the length of the fields array
+     */
+    public static Query parse(String[] queries, String[] fields,
+                              Analyzer analyzer) throws ParseException {
+        if (queries.length != fields.length)
+            throw new IllegalArgumentException("queries.length != fields.length");
+        BooleanQuery bQuery = new BooleanQuery();
+        for (int i = 0; i < fields.length; i++) {
+            QueryParser qp = new QueryParser(fields[i], analyzer);
+            Query q = qp.parse(queries[i]);
+            bQuery.add(q, BooleanClause.Occur.SHOULD);
+        }
+        return bQuery;
+    }
+
+    /**
+     * Parses a query, searching on the fields specified.
+     * Use this if you need to specify certain fields as required,
+     * and others as prohibited.
+     * <p><pre>
+     * Usage:
+     * <code>
+     * String[] fields = {"filename", "contents", "description"};
+     * int[] flags = {MultiFieldQueryParser.NORMAL_FIELD,
+     *                MultiFieldQueryParser.REQUIRED_FIELD,
+     *                MultiFieldQueryParser.PROHIBITED_FIELD,};
+     * parse(query, fields, flags, analyzer);
+     * </code>
+     * </pre>
+     *<p>
+     * The code above would construct a query:
+     * <pre>
+     * <code>
+     * (filename:query) +(contents:query) -(description:query)
+     * </code>
+     * </pre>
+     *
+     * @param query Query string to parse
+     * @param fields Fields to search on
+     * @param flags Flags describing the fields
+     * @param analyzer Analyzer to use
+     * @throws ParseException if query parsing fails
+     * @throws TokenMgrError if query parsing fails
+     * @throws IllegalArgumentException if the length of the fields array differs
+     *  from the length of the flags array
+     * @deprecated use {@link #parse(String, String[], BooleanClause.Occur[], Analyzer)} instead
+     */
+    public static Query parse(String query, String[] fields, int[] flags,
+                              Analyzer analyzer) throws ParseException {
+        if (fields.length != flags.length)
+            throw new IllegalArgumentException("fields.length != flags.length");
+        BooleanQuery bQuery = new BooleanQuery();
+        for (int i = 0; i < fields.length; i++) {
+            QueryParser qp = new QueryParser(fields[i], analyzer);
+            Query q = qp.parse(query);
+            int flag = flags[i];
+            switch (flag) {
+                case REQUIRED_FIELD:
+                    bQuery.add(q, BooleanClause.Occur.MUST);
+                    break;
+                case PROHIBITED_FIELD:
+                    bQuery.add(q, BooleanClause.Occur.MUST_NOT);
+                    break;
+                default:
+                    bQuery.add(q, BooleanClause.Occur.SHOULD);
+                    break;
+            }
+        }
+        return bQuery;
+    }
+
+    /**
+     * Parses a query, searching on the fields specified.
+     * Use this if you need to specify certain fields as required,
+     * and others as prohibited.
+     * <p><pre>
+     * Usage:
+     * <code>
+     * String[] fields = {"filename", "contents", "description"};
+     * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
+     *                BooleanClause.Occur.MUST,
+     *                BooleanClause.Occur.MUST_NOT};
+     * MultiFieldQueryParser.parse("query", fields, flags, analyzer);
+     * </code>
+     * </pre>
+     *<p>
+     * The code above would construct a query:
+     * <pre>
+     * <code>
+     * (filename:query) +(contents:query) -(description:query)
+     * </code>
+     * </pre>
+     *
+     * @param query Query string to parse
+     * @param fields Fields to search on
+     * @param flags Flags describing the fields
+     * @param analyzer Analyzer to use
+     * @throws ParseException if query parsing fails
+     * @throws TokenMgrError if query parsing fails
+     * @throws IllegalArgumentException if the length of the fields array differs
+     *  from the length of the flags array
+     */
+    public static Query parse(String query, String[] fields,
+                              BooleanClause.Occur[] flags, Analyzer analyzer) throws ParseException {
+        if (fields.length != flags.length)
+            throw new IllegalArgumentException("fields.length != flags.length");
+        BooleanQuery bQuery = new BooleanQuery();
+        for (int i = 0; i < fields.length; i++) {
+            QueryParser qp = new QueryParser(fields[i], analyzer);
+            Query q = qp.parse(query);
+            bQuery.add(q, flags[i]);
+        }
+        return bQuery;
+    }
+
+    /**
+     * Parses a query, searching on the fields specified. Use this if you need to
+     * specify certain fields as required, and others as prohibited.
+     * <p>
+     * <pre>
+     *  Usage:
+     * <code>
+     * String[] fields = { &quot;filename&quot;, &quot;contents&quot;, &quot;description&quot; };
+     * int[] flags = { MultiFieldQueryParser.NORMAL_FIELD,
+     *     MultiFieldQueryParser.REQUIRED_FIELD,
+     *     MultiFieldQueryParser.PROHIBITED_FIELD, };
+     * parse(query, fields, flags, analyzer);
+     * </code>
+     * </pre>
+     *
+     * <p>
+     * The code above would construct a query:
+     * <pre>
+     * <code>
+     *  (filename:query1) +(contents:query2) -(description:query3)
+     * </code>
+     * </pre>
+     *
+     * @param queries Queries string to parse
+     * @param fields Fields to search on
+     * @param flags Flags describing the fields
+     * @param analyzer Analyzer to use
+     * @throws ParseException if query parsing fails
+     * @throws TokenMgrError if query parsing fails
+     * @throws IllegalArgumentException if the length of the queries, fields, and flags array differ
+     * @deprecated use {@link #parse(String[], String[], BooleanClause.Occur[], Analyzer)} instead
+     */
+    public static Query parse(String[] queries, String[] fields, int[] flags,
+                              Analyzer analyzer) throws ParseException {
+        if (!(queries.length == fields.length && queries.length == flags.length))
+            throw new IllegalArgumentException("queries, fields, and flags array have have different length");
+        BooleanQuery bQuery = new BooleanQuery();
+        for (int i = 0; i < fields.length; i++) {
+            QueryParser qp = new QueryParser(fields[i], analyzer);
+            Query q = qp.parse(queries[i]);
+            int flag = flags[i];
+            switch (flag) {
+                case REQUIRED_FIELD:
+                    bQuery.add(q, BooleanClause.Occur.MUST);
+                    break;
+                case PROHIBITED_FIELD:
+                    bQuery.add(q, BooleanClause.Occur.MUST_NOT);
+                    break;
+                default:
+                    bQuery.add(q, BooleanClause.Occur.SHOULD);
+                    break;
+            }
+        }
+        return bQuery;
+    }
+
+    /**
+     * Parses a query, searching on the fields specified.
+     * Use this if you need to specify certain fields as required,
+     * and others as prohibited.
+     * <p><pre>
+     * Usage:
+     * <code>
+     * String[] query = {"query1", "query2", "query3"};
+     * String[] fields = {"filename", "contents", "description"};
+     * BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
+     *                BooleanClause.Occur.MUST,
+     *                BooleanClause.Occur.MUST_NOT};
+     * MultiFieldQueryParser.parse(query, fields, flags, analyzer);
+     * </code>
+     * </pre>
+     *<p>
+     * The code above would construct a query:
+     * <pre>
+     * <code>
+     * (filename:query1) +(contents:query2) -(description:query3)
+     * </code>
+     * </pre>
+     *
+     * @param queries Queries string to parse
+     * @param fields Fields to search on
+     * @param flags Flags describing the fields
+     * @param analyzer Analyzer to use
+     * @throws ParseException if query parsing fails
+     * @throws TokenMgrError if query parsing fails
+     * @throws IllegalArgumentException if the length of the queries, fields,
+     *  and flags array differ
+     */
+    public static Query parse(String[] queries, String[] fields, BooleanClause.Occur[] flags,
+                              Analyzer analyzer) throws ParseException {
+        if (!(queries.length == fields.length && queries.length == flags.length))
+            throw new IllegalArgumentException("queries, fields, and flags array have have different length");
+        BooleanQuery bQuery = new BooleanQuery();
+        for (int i = 0; i < fields.length; i++) {
+            QueryParser qp = new QueryParser(fields[i], analyzer);
+            Query q = qp.parse(queries[i]);
+            bQuery.add(q, flags[i]);
+        }
+        return bQuery;
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final MultiFieldQueryParser that = (MultiFieldQueryParser) o;
+        return Arrays.equals(fields, that.fields);
+    }
+
+    public int hashCode() {
+        return Arrays.hashCode(fields);
+    }
+
+    /**
+     * Used to store settings per field name.
+     *
+     * @author Karl Wettin
+     * @version $Revision$
+     */
+        public static class FieldSetting {
+
+        /**
+         * <p>The value the boost of all created queries aimed at this field name will be multiplied with.</p>
+         * <p>Defaults to 1f.</p>*/
+        private float boostMultiplier = 1f;
+        private String field;
+
+        /**
+         * @param field Field name this setting is aimed at.
+         * @param boostMultiplier The value the boost of all created queries aimed at this field name will be multiplied with.
+         */
+        public FieldSetting(String field, float boostMultiplier) {
+            this.field = field;
+            this.boostMultiplier = boostMultiplier;
+        }
+
+        /**
+         * <p>Boost multiplier defaults to 1f</p>
+         * @param field Field name this setting is aimed at.
+         */
+        public FieldSetting(String field) {
+            this.field = field;
+        }
+
+        /**
+         * @param o
+         * @return true if field and boost multiplier equals.
+         */
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            final FieldSetting that = (FieldSetting) o;
+
+            if (Float.compare(that.boostMultiplier, boostMultiplier) != 0) return false;
+            return field.equals(that.field);
+        }
+
+        public int hashCode() {
+            int result;
+            result = boostMultiplier != +0.0f ? Float.floatToIntBits(boostMultiplier) : 0;
+            result = 29 * result + field.hashCode();
+            return result;
+        }
+
+    }
+
 }
