Index: lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/SmartChineseWordTokenFilterFactory.java
===================================================================
--- lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/SmartChineseWordTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/SmartChineseWordTokenFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.cn.smart.WordTokenFilter;
@@ -32,6 +34,15 @@
  * @lucene.experimental
  */
 public class SmartChineseWordTokenFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new SmartChineseWordTokenFilterFactory */
+  public SmartChineseWordTokenFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenFilter create(TokenStream input) {
       return new WordTokenFilter(input);
Index: lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/SmartChineseSentenceTokenizerFactory.java
===================================================================
--- lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/SmartChineseSentenceTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/smartcn/src/java/org/apache/lucene/analysis/cn/smart/SmartChineseSentenceTokenizerFactory.java	(working copy)
@@ -18,6 +18,7 @@
  */
 
 import java.io.Reader;
+import java.util.Map;
 
 import org.apache.lucene.analysis.util.TokenizerFactory;
 import org.apache.lucene.util.AttributeSource.AttributeFactory;
@@ -27,6 +28,15 @@
  * @lucene.experimental
  */
 public class SmartChineseSentenceTokenizerFactory extends TokenizerFactory {
+  
+  /** Creates a new SmartChineseSentenceTokenizerFactory */
+  public SmartChineseSentenceTokenizerFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public SentenceTokenizer create(AttributeFactory factory, Reader input) {
     return new SentenceTokenizer(factory, input);
Index: lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/morfologik/MorfologikFilterFactory.java
===================================================================
--- lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/morfologik/MorfologikFilterFactory.java	(revision 1462646)
+++ lucene/analysis/morfologik/src/java/org/apache/lucene/analysis/morfologik/MorfologikFilterFactory.java	(working copy)
@@ -25,7 +25,6 @@
 
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.morfologik.MorfologikFilter;
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
@@ -52,24 +51,10 @@
   /** Schema attribute. */
   public static final String DICTIONARY_SCHEMA_ATTRIBUTE = "dictionary";
   
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public MorfologikFilterFactory() {}
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public TokenStream create(TokenStream ts) {
-    return new MorfologikFilter(ts, dictionary, luceneMatchVersion);
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    String dictionaryName = args.get(DICTIONARY_SCHEMA_ATTRIBUTE);
+  /** Creates a new MorfologikFilterFactory */
+  public MorfologikFilterFactory(Map<String,String> args) {
+    super(args);
+    String dictionaryName = args.remove(DICTIONARY_SCHEMA_ATTRIBUTE);
     if (dictionaryName != null && !dictionaryName.isEmpty()) {
       try {
         DICTIONARY dictionary = DICTIONARY.valueOf(dictionaryName.toUpperCase(Locale.ROOT));
@@ -81,5 +66,13 @@
             + dictionaryName);
       }
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
+
+  @Override
+  public TokenStream create(TokenStream ts) {
+    return new MorfologikFilter(ts, dictionary, luceneMatchVersion);
+  }
 }
Index: lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/DoubleMetaphoneFilterFactory.java
===================================================================
--- lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/DoubleMetaphoneFilterFactory.java	(revision 1462646)
+++ lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/DoubleMetaphoneFilterFactory.java	(working copy)
@@ -21,19 +21,17 @@
 
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.phonetic.DoubleMetaphoneFilter;
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link DoubleMetaphoneFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_dblmtphn" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.DoubleMetaphoneFilterFactory" inject="true" maxCodeLength="4"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class DoubleMetaphoneFilterFactory extends TokenFilterFactory
 {
@@ -44,20 +42,16 @@
   /** default maxCodeLength if not specified */
   public static final int DEFAULT_MAX_CODE_LENGTH = 4;
 
-  private boolean inject = true;
-  private int maxCodeLength = DEFAULT_MAX_CODE_LENGTH;
+  private final boolean inject;
+  private final int maxCodeLength;
 
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public DoubleMetaphoneFilterFactory() {}
-
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-
-    inject = getBoolean(INJECT, true);
-
-    if (args.get(MAX_CODE_LENGTH) != null) {
-      maxCodeLength = Integer.parseInt(args.get(MAX_CODE_LENGTH));
+  /** Creates a new DoubleMetaphoneFilterFactory */
+  public DoubleMetaphoneFilterFactory(Map<String,String> args) {
+    super(args);
+    inject = getBoolean(args, INJECT, true);
+    maxCodeLength = getInt(args, MAX_CODE_LENGTH, DEFAULT_MAX_CODE_LENGTH);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
     }
   }
 
Index: lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/BeiderMorseFilterFactory.java
===================================================================
--- lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/BeiderMorseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/BeiderMorseFilterFactory.java	(working copy)
@@ -27,12 +27,11 @@
 import org.apache.commons.codec.language.bm.RuleType;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.phonetic.BeiderMorseFilter;
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link BeiderMorseFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_bm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -42,37 +41,35 @@
  *     &lt;/filter&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class BeiderMorseFilterFactory extends TokenFilterFactory {
-  private PhoneticEngine engine;
-  private LanguageSet languageSet;
+  private final PhoneticEngine engine;
+  private final LanguageSet languageSet;
   
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public BeiderMorseFilterFactory() {}
-  
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    
+  /** Creates a new BeiderMorseFilterFactory */
+  public BeiderMorseFilterFactory(Map<String,String> args) {
+    super(args);
     // PhoneticEngine = NameType + RuleType + concat
     // we use common-codec's defaults: GENERIC + APPROX + true
-    String nameTypeArg = args.get("nameType");
+    String nameTypeArg = args.remove("nameType");
     NameType nameType = (nameTypeArg == null) ? NameType.GENERIC : NameType.valueOf(nameTypeArg);
 
-    String ruleTypeArg = args.get("ruleType");
+    String ruleTypeArg = args.remove("ruleType");
     RuleType ruleType = (ruleTypeArg == null) ? RuleType.APPROX : RuleType.valueOf(ruleTypeArg);
     
-    boolean concat = getBoolean("concat", true);
+    boolean concat = getBoolean(args, "concat", true);
     engine = new PhoneticEngine(nameType, ruleType, concat);
     
     // LanguageSet: defaults to automagic, otherwise a comma-separated list.
-    String languageSetArg = args.get("languageSet");
+    String languageSetArg = args.remove("languageSet");
     if (languageSetArg == null || languageSetArg.equals("auto")) {
       languageSet = null;
     } else {
       languageSet = LanguageSet.from(new HashSet<String>(Arrays.asList(languageSetArg.split(","))));
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java
===================================================================
--- lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java	(revision 1462646)
+++ lucene/analysis/phonetic/src/java/org/apache/lucene/analysis/phonetic/PhoneticFilterFactory.java	(working copy)
@@ -27,7 +27,6 @@
 import org.apache.commons.codec.Encoder;
 import org.apache.commons.codec.language.*;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
 import org.apache.lucene.analysis.util.ResourceLoader;
 import org.apache.lucene.analysis.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
@@ -49,7 +48,7 @@
  *  support this then specifying this is an error.</dd>
  * </dl>
  *
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_phonetic" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -59,9 +58,7 @@
  * 
  * @see PhoneticFilter
  */
-public class PhoneticFilterFactory extends TokenFilterFactory
-  implements ResourceLoaderAware
-{
+public class PhoneticFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   /** parameter name: either a short name or a full class name */
   public static final String ENCODER = "encoder";
   /** parameter name: true if encoded tokens should be added as synonyms */
@@ -82,33 +79,40 @@
     registry.put("ColognePhonetic".toUpperCase(Locale.ROOT), ColognePhonetic.class);
   }
 
-  boolean inject = true; //accessed by the test
-  private String name = null;
+  final boolean inject; //accessed by the test
+  private final String name;
+  private final Integer maxCodeLength;
   private Class<? extends Encoder> clazz = null;
   private Method setMaxCodeLenMethod = null;
-  private Integer maxCodeLength = null;
   
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public PhoneticFilterFactory() {}
+  /** Creates a new PhoneticFilterFactory */
+  public PhoneticFilterFactory(Map<String,String> args) {
+    super(args);
+    inject = getBoolean(args, INJECT, true);
+    name = args.remove(ENCODER);
+    if (name == null) {
+      throw new IllegalArgumentException("Missing required parameter: " + ENCODER
+                                       + " [" + registry.keySet() + "]");
+    }
+    String v = args.remove(MAX_CODE_LENGTH);
+    if (v != null) {
+      maxCodeLength = Integer.valueOf(v);
+    } else {
+      maxCodeLength = null;
+    }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-
-    inject = getBoolean(INJECT, true);
-
-    String name = args.get( ENCODER );
-    if( name == null ) {
-      throw new IllegalArgumentException("Missing required parameter: " + ENCODER
-          + " [" + registry.keySet() + "]");
-    }
     clazz = registry.get(name.toUpperCase(Locale.ROOT));
     if( clazz == null ) {
       clazz = resolveEncoder(name, loader);
     }
 
-    String v = args.get(MAX_CODE_LENGTH);
-    if (v != null) {
-      maxCodeLength = Integer.valueOf(v);
+    if (maxCodeLength != null) {
       try {
         setMaxCodeLenMethod = clazz.getMethod("setMaxCodeLen", int.class);
       } catch (Exception e) {
Index: lucene/analysis/stempel/src/java/org/apache/lucene/analysis/stempel/StempelPolishStemFilterFactory.java
===================================================================
--- lucene/analysis/stempel/src/java/org/apache/lucene/analysis/stempel/StempelPolishStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/stempel/src/java/org/apache/lucene/analysis/stempel/StempelPolishStemFilterFactory.java	(working copy)
@@ -17,11 +17,12 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.pl.PolishAnalyzer;
 import org.apache.lucene.analysis.stempel.StempelFilter;
 import org.apache.lucene.analysis.stempel.StempelStemmer;
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
@@ -29,8 +30,13 @@
  */
 public class StempelPolishStemFilterFactory extends TokenFilterFactory {  
   
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public StempelPolishStemFilterFactory() {}
+  /** Creates a new StempelPolishStemFilterFactory */
+  public StempelPolishStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public TokenStream create(TokenStream input) {
Index: lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUTransformFilterFactory.java
===================================================================
--- lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUTransformFilterFactory.java	(revision 1462646)
+++ lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUTransformFilterFactory.java	(working copy)
@@ -38,22 +38,19 @@
  * @see Transliterator
  */
 public class ICUTransformFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
-  private Transliterator transliterator;
+  private final Transliterator transliterator;
   
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public ICUTransformFilterFactory() {}
-  
   // TODO: add support for custom rules
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    String id = args.get("id");
+  /** Creates a new ICUTransformFilterFactory */
+  public ICUTransformFilterFactory(Map<String,String> args) {
+    super(args);
+    String id = args.remove("id");
     if (id == null) {
       throw new IllegalArgumentException("id is required.");
     }
     
     int dir;
-    String direction = args.get("direction");
+    String direction = args.remove("direction");
     if (direction == null || direction.equalsIgnoreCase("forward"))
       dir = Transliterator.FORWARD;
     else if (direction.equalsIgnoreCase("reverse"))
@@ -62,6 +59,9 @@
       throw new IllegalArgumentException("invalid direction: " + direction);
     
     transliterator = Transliterator.getInstance(id, dir);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java
===================================================================
--- lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/segmentation/ICUTokenizerFactory.java	(working copy)
@@ -25,7 +25,6 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
 import org.apache.lucene.analysis.util.ResourceLoader;
 import org.apache.lucene.analysis.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.util.TokenizerFactory;
@@ -75,21 +74,17 @@
  *                rulefiles="Latn:my.Latin.rules.rbbi,Cyrl:my.Cyrillic.rules.rbbi"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ICUTokenizerFactory extends TokenizerFactory implements ResourceLoaderAware {
   static final String RULEFILES = "rulefiles";
-  private Map<Integer,String> tailored;
+  private final Map<Integer,String> tailored;
   private ICUTokenizerConfig config;
   
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public ICUTokenizerFactory() {}
-
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  /** Creates a new ICUTokenizerFactory */
+  public ICUTokenizerFactory(Map<String,String> args) {
+    super(args);
     tailored = new HashMap<Integer,String>();
-    String rulefilesArg = args.get(RULEFILES);
+    String rulefilesArg = args.remove(RULEFILES);
     if (rulefilesArg != null) {
       List<String> scriptAndResourcePaths = splitFileNames(rulefilesArg);
       for (String scriptAndResourcePath : scriptAndResourcePaths) {
@@ -99,6 +94,9 @@
         tailored.put(UCharacter.getPropertyValueEnum(UProperty.SCRIPT, scriptCode), resourcePath);
       }
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUFoldingFilterFactory.java
===================================================================
--- lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUFoldingFilterFactory.java	(revision 1462646)
+++ lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUFoldingFilterFactory.java	(working copy)
@@ -1,11 +1,5 @@
 package org.apache.lucene.analysis.icu;
 
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.icu.ICUFoldingFilter;
-import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
-import org.apache.lucene.analysis.util.MultiTermAwareComponent;
-import org.apache.lucene.analysis.util.TokenFilterFactory;
-
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -23,11 +17,33 @@
  * limitations under the License.
  */
 
-/** Factory for {@link ICUFoldingFilter} */
+import java.util.Map;
+
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.icu.ICUFoldingFilter;
+import org.apache.lucene.analysis.util.AbstractAnalysisFactory; // javadocs
+import org.apache.lucene.analysis.util.MultiTermAwareComponent;
+import org.apache.lucene.analysis.util.TokenFilterFactory;
+
+/** 
+ * Factory for {@link ICUFoldingFilter}.
+ * <pre class="prettyprint">
+ * &lt;fieldType name="text_folded" class="solr.TextField" positionIncrementGap="100"&gt;
+ *   &lt;analyzer&gt;
+ *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
+ *     &lt;filter class="solr.ICUFoldingFilterFactory"/&gt;
+ *   &lt;/analyzer&gt;
+ * &lt;/fieldType&gt;</pre>
+ */
 public class ICUFoldingFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
 
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public ICUFoldingFilterFactory() {}
+  /** Creates a new ICUFoldingFilterFactory */
+  public ICUFoldingFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public TokenStream create(TokenStream input) {
Index: lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUNormalizer2FilterFactory.java
===================================================================
--- lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUNormalizer2FilterFactory.java	(revision 1462646)
+++ lucene/analysis/icu/src/java/org/apache/lucene/analysis/icu/ICUNormalizer2FilterFactory.java	(working copy)
@@ -46,22 +46,19 @@
  * @see FilteredNormalizer2
  */
 public class ICUNormalizer2FilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
-  private Normalizer2 normalizer;
+  private final Normalizer2 normalizer;
 
-  /** Sole constructor. See {@link AbstractAnalysisFactory} for initialization lifecycle. */
-  public ICUNormalizer2FilterFactory() {}
-
-  // TODO: support custom normalization
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    String name = args.get("name");
+  /** Creates a new ICUNormalizer2FilterFactory */
+  public ICUNormalizer2FilterFactory(Map<String,String> args) {
+    super(args);
+    String name = args.remove("name");
     if (name == null)
       name = "nfkc_cf";
-    String mode = args.get("mode");
+    String mode = args.remove("mode");
     if (mode == null)
       mode = "compose";
     
+    Normalizer2 normalizer;
     if (mode.equals("compose"))
       normalizer = Normalizer2.getInstance(null, name, Normalizer2.Mode.COMPOSE);
     else if (mode.equals("decompose"))
@@ -69,7 +66,7 @@
     else 
       throw new IllegalArgumentException("Invalid mode: " + mode);
     
-    String filter = args.get("filter");
+    String filter = args.remove("filter");
     if (filter != null) {
       UnicodeSet set = new UnicodeSet(filter);
       if (!set.isEmpty()) {
@@ -77,7 +74,13 @@
         normalizer = new FilteredNormalizer2(normalizer, set);
       }
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+    this.normalizer = normalizer;
   }
+
+  // TODO: support custom normalization
   
   @Override
   public TokenStream create(TokenStream input) {
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/cz/TestCzechStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/cz/TestCzechStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/cz/TestCzechStemFilterFactory.java	(working copy)
@@ -20,23 +20,31 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Czech stem filter factory is working.
  */
-public class TestCzechStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestCzechStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually stems text.
    */
   public void testStemming() throws Exception {
     Reader reader = new StringReader("angličtí");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    CzechStemFilterFactory factory = new CzechStemFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("CzechStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "anglick" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("CzechStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/TestMultiWordSynonyms.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/TestMultiWordSynonyms.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/TestMultiWordSynonyms.java	(working copy)
@@ -17,31 +17,26 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.synonym.SynonymFilterFactory;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
 
-import java.io.IOException;
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * @since solr 1.4
  */
-public class TestMultiWordSynonyms extends BaseTokenStreamTestCase {
+public class TestMultiWordSynonyms extends BaseTokenStreamFactoryTestCase {
   
-  public void testMultiWordSynonyms() throws IOException {
-    SynonymFilterFactory factory = new SynonymFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("synonyms", "synonyms.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(new StringMockResourceLoader("a b c,d"));
-    TokenStream ts = factory.create(new MockTokenizer(new StringReader("a e"), MockTokenizer.WHITESPACE, false));
+  public void testMultiWordSynonyms() throws Exception {
+    Reader reader = new StringReader("a e");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Synonym", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("a b c,d"),
+        "synonyms", "synonyms.txt").create(stream);
     // This fails because ["e","e"] is the value of the token stream
-    assertTokenStreamContents(ts, new String[] { "a", "e" });
+    assertTokenStreamContents(stream, new String[] { "a", "e" });
   }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/TestSynonymFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/TestSynonymFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/synonym/TestSynonymFilterFactory.java	(working copy)
@@ -17,42 +17,46 @@
  * limitations under the License.
  */
 
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.synonym.SynonymFilter;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
 
-public class TestSynonymFilterFactory extends BaseTokenStreamTestCase {
+public class TestSynonymFilterFactory extends BaseTokenStreamFactoryTestCase {
   /** test that we can parse and use the solr syn file */
   public void testSynonyms() throws Exception {
-    SynonymFilterFactory factory = new SynonymFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("synonyms", "synonyms.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(new ClasspathResourceLoader(getClass()));
-    TokenStream ts = factory.create(new MockTokenizer(new StringReader("GB"), MockTokenizer.WHITESPACE, false));
-    assertTrue(ts instanceof SynonymFilter);
-    assertTokenStreamContents(ts, 
+    Reader reader = new StringReader("GB");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Synonym", "synonyms", "synonyms.txt").create(stream);
+    assertTrue(stream instanceof SynonymFilter);
+    assertTokenStreamContents(stream, 
         new String[] { "GB", "gib", "gigabyte", "gigabytes" },
         new int[] { 1, 0, 0, 0 });
   }
   
   /** if the synonyms are completely empty, test that we still analyze correctly */
   public void testEmptySynonyms() throws Exception {
-    SynonymFilterFactory factory = new SynonymFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("synonyms", "synonyms.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(new StringMockResourceLoader("")); // empty file!
-    TokenStream ts = factory.create(new MockTokenizer(new StringReader("GB"), MockTokenizer.WHITESPACE, false));
-    assertTokenStreamContents(ts, new String[] { "GB" });
+    Reader reader = new StringReader("GB");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Synonym", TEST_VERSION_CURRENT, 
+        new StringMockResourceLoader(""), // empty file!
+        "synonyms", "synonyms.txt").create(stream);
+    assertTokenStreamContents(stream, new String[] { "GB" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Synonym", 
+          "synonyms", "synonyms.txt", 
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestElisionFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestElisionFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestElisionFilterFactory.java	(working copy)
@@ -19,35 +19,21 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
-import org.apache.lucene.analysis.util.ResourceLoader;
 
 /**
  * Simple tests to ensure the French elision filter factory is working.
  */
-public class TestElisionFilterFactory extends BaseTokenStreamTestCase {
+public class TestElisionFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually normalizes text.
    */
   public void testElision() throws Exception {
     Reader reader = new StringReader("l'avion");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    ElisionFilterFactory factory = new ElisionFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("articles", "frenchArticles.txt");
-    factory.init(args);
-    factory.inform(loader);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Elision", "articles", "frenchArticles.txt").create(stream);
     assertTokenStreamContents(stream, new String[] { "avion" });
   }
   
@@ -56,14 +42,8 @@
    */
   public void testDefaultArticles() throws Exception {
     Reader reader = new StringReader("l'avion");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    ElisionFilterFactory factory = new ElisionFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    factory.inform(loader);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Elision").create(stream);
     assertTokenStreamContents(stream, new String[] { "avion" });
   }
   
@@ -72,17 +52,20 @@
    */
   public void testCaseInsensitive() throws Exception {
     Reader reader = new StringReader("L'avion");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    ElisionFilterFactory factory = new ElisionFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("articles", "frenchArticles.txt");
-    args.put("ignoreCase", "true");
-    factory.init(args);
-    factory.inform(loader);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Elision",
+        "articles", "frenchArticles.txt",
+        "ignoreCase", "true").create(stream);
     assertTokenStreamContents(stream, new String[] { "avion" });
   }
   
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Elision", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/util/BaseTokenStreamFactoryTestCase.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/util/BaseTokenStreamFactoryTestCase.java	(revision 0)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/util/BaseTokenStreamFactoryTestCase.java	(working copy)
@@ -0,0 +1,87 @@
+package org.apache.lucene.analysis.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.lucene.analysis.BaseTokenStreamTestCase;
+import org.apache.lucene.util.Version;
+
+/** Base class for testing tokenstream factories */
+// TODO: this has to be here, since the abstract factories are not in lucene-core,
+// so test-framework doesnt know about them...
+// this also means we currently cannot use this in other analysis modules :(
+// TODO: maybe after we improve the abstract factory/SPI apis, they can sit in core and resolve this.
+public abstract class BaseTokenStreamFactoryTestCase extends BaseTokenStreamTestCase {
+  
+  private AbstractAnalysisFactory analysisFactory(Class<? extends AbstractAnalysisFactory> clazz, Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception {
+    if (keysAndValues.length % 2 == 1) {
+      throw new IllegalArgumentException("invalid keysAndValues map");
+    }
+    Map<String,String> args = new HashMap<String,String>();
+    for (int i = 0; i < keysAndValues.length; i += 2) {
+      String previous = args.put(keysAndValues[i], keysAndValues[i+1]);
+      assertNull("duplicate values for key: " + keysAndValues[i], previous);
+    }
+    if (matchVersion != null) {
+      String previous = args.put("luceneMatchVersion", matchVersion.toString());
+      assertNull("duplicate values for key: luceneMatchVersion", previous);
+    }
+    AbstractAnalysisFactory factory = null;
+    try {
+      factory = clazz.getConstructor(Map.class).newInstance(args);
+    } catch (InvocationTargetException e) {
+      // to simplify tests that check for illegal parameters
+      if (e.getCause() instanceof IllegalArgumentException) {
+        throw (IllegalArgumentException) e.getCause();
+      } else {
+        throw e;
+      }
+    }
+    if (factory instanceof ResourceLoaderAware) {
+      ((ResourceLoaderAware) factory).inform(loader);
+    }
+    return factory;
+  }
+  
+  protected TokenizerFactory tokenizerFactory(String name, String... keysAndValues) throws Exception {
+    return tokenizerFactory(name, TEST_VERSION_CURRENT, new ClasspathResourceLoader(getClass()), keysAndValues);
+  }
+  
+  protected TokenizerFactory tokenizerFactory(String name, Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception {
+    return (TokenizerFactory) analysisFactory(TokenizerFactory.lookupClass(name), matchVersion, loader, keysAndValues);
+  }
+  
+  protected TokenFilterFactory tokenFilterFactory(String name, String... keysAndValues) throws Exception {
+    return tokenFilterFactory(name, TEST_VERSION_CURRENT, new ClasspathResourceLoader(getClass()), keysAndValues);
+  }
+  
+  protected TokenFilterFactory tokenFilterFactory(String name, Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception {
+    return (TokenFilterFactory) analysisFactory(TokenFilterFactory.lookupClass(name), matchVersion, loader, keysAndValues);
+  }
+  
+  protected CharFilterFactory charFilterFactory(String name, String... keysAndValues) throws Exception {
+    return charFilterFactory(name, TEST_VERSION_CURRENT, new ClasspathResourceLoader(getClass()), keysAndValues);
+  }
+  
+  protected CharFilterFactory charFilterFactory(String name, Version matchVersion, ResourceLoader loader, String... keysAndValues) throws Exception {
+    return (CharFilterFactory) analysisFactory(CharFilterFactory.lookupClass(name), matchVersion, loader, keysAndValues);
+  }
+}

Property changes on: lucene/analysis/common/src/test/org/apache/lucene/analysis/util/BaseTokenStreamFactoryTestCase.java
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/util/StringMockResourceLoader.java	(working copy)
@@ -28,14 +28,23 @@
   public StringMockResourceLoader(String text) {
     this.text = text;
   }
+  
+  @Override
+  public <T> Class<? extends T> findClass(String cname, Class<T> expectedType) {
+    try {
+      return Class.forName(cname).asSubclass(expectedType);
+    } catch (Exception e) {
+      throw new RuntimeException("Cannot load class: " + cname, e);
+    }
+  }
 
   @Override
   public <T> T newInstance(String cname, Class<T> expectedType) {
+    Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      Class<? extends T> clazz = Class.forName(cname).asSubclass(expectedType);
       return clazz.newInstance();
     } catch (Exception e) {
-      throw new RuntimeException(e);
+      throw new RuntimeException("Cannot create instance: " + cname, e);
     }
   }
 
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestFilesystemResourceLoader.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestFilesystemResourceLoader.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestFilesystemResourceLoader.java	(working copy)
@@ -53,8 +53,8 @@
     );
     assertTrue(set.contains("you"));
     // try to load a class; we use string comparison because classloader may be different...
-    assertEquals("org.apache.lucene.analysis.en.KStemFilterFactory",
-        rl.newInstance("org.apache.lucene.analysis.en.KStemFilterFactory", TokenFilterFactory.class).getClass().getName());
+    assertEquals("org.apache.lucene.analysis.util.RollingCharBuffer",
+        rl.newInstance("org.apache.lucene.analysis.util.RollingCharBuffer", Object.class).getClass().getName());
     // theoretically classes should also be loadable:
     IOUtils.closeWhileHandlingException(rl.openResource("java/lang/String.class"));
   }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestAnalysisSPILoader.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestAnalysisSPILoader.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/util/TestAnalysisSPILoader.java	(working copy)
@@ -17,6 +17,9 @@
  * limitations under the License.
  */
 
+import java.util.HashMap;
+import java.util.Map;
+
 import org.apache.lucene.analysis.charfilter.HTMLStripCharFilterFactory;
 import org.apache.lucene.analysis.core.LowerCaseFilterFactory;
 import org.apache.lucene.analysis.core.WhitespaceTokenizerFactory;
@@ -25,22 +28,28 @@
 
 public class TestAnalysisSPILoader extends LuceneTestCase {
   
+  private Map<String,String> versionArgOnly() {
+    return new HashMap<String,String>() {{
+      put("luceneMatchVersion", TEST_VERSION_CURRENT.toString());
+    }};
+  }
+  
   public void testLookupTokenizer() {
-    assertSame(WhitespaceTokenizerFactory.class, TokenizerFactory.forName("Whitespace").getClass());
-    assertSame(WhitespaceTokenizerFactory.class, TokenizerFactory.forName("WHITESPACE").getClass());
-    assertSame(WhitespaceTokenizerFactory.class, TokenizerFactory.forName("whitespace").getClass());
+    assertSame(WhitespaceTokenizerFactory.class, TokenizerFactory.forName("Whitespace", versionArgOnly()).getClass());
+    assertSame(WhitespaceTokenizerFactory.class, TokenizerFactory.forName("WHITESPACE", versionArgOnly()).getClass());
+    assertSame(WhitespaceTokenizerFactory.class, TokenizerFactory.forName("whitespace", versionArgOnly()).getClass());
   }
   
   public void testBogusLookupTokenizer() {
     try {
-      TokenizerFactory.forName("sdfsdfsdfdsfsdfsdf");
+      TokenizerFactory.forName("sdfsdfsdfdsfsdfsdf", new HashMap<String,String>());
       fail();
     } catch (IllegalArgumentException expected) {
       //
     }
     
     try {
-      TokenizerFactory.forName("!(**#$U*#$*");
+      TokenizerFactory.forName("!(**#$U*#$*", new HashMap<String,String>());
       fail();
     } catch (IllegalArgumentException expected) {
       //
@@ -74,25 +83,25 @@
   }
   
   public void testLookupTokenFilter() {
-    assertSame(LowerCaseFilterFactory.class, TokenFilterFactory.forName("Lowercase").getClass());
-    assertSame(LowerCaseFilterFactory.class, TokenFilterFactory.forName("LOWERCASE").getClass());
-    assertSame(LowerCaseFilterFactory.class, TokenFilterFactory.forName("lowercase").getClass());
+    assertSame(LowerCaseFilterFactory.class, TokenFilterFactory.forName("Lowercase", versionArgOnly()).getClass());
+    assertSame(LowerCaseFilterFactory.class, TokenFilterFactory.forName("LOWERCASE", versionArgOnly()).getClass());
+    assertSame(LowerCaseFilterFactory.class, TokenFilterFactory.forName("lowercase", versionArgOnly()).getClass());
     
-    assertSame(RemoveDuplicatesTokenFilterFactory.class, TokenFilterFactory.forName("RemoveDuplicates").getClass());
-    assertSame(RemoveDuplicatesTokenFilterFactory.class, TokenFilterFactory.forName("REMOVEDUPLICATES").getClass());
-    assertSame(RemoveDuplicatesTokenFilterFactory.class, TokenFilterFactory.forName("removeduplicates").getClass());
+    assertSame(RemoveDuplicatesTokenFilterFactory.class, TokenFilterFactory.forName("RemoveDuplicates", versionArgOnly()).getClass());
+    assertSame(RemoveDuplicatesTokenFilterFactory.class, TokenFilterFactory.forName("REMOVEDUPLICATES", versionArgOnly()).getClass());
+    assertSame(RemoveDuplicatesTokenFilterFactory.class, TokenFilterFactory.forName("removeduplicates", versionArgOnly()).getClass());
   }
   
   public void testBogusLookupTokenFilter() {
     try {
-      TokenFilterFactory.forName("sdfsdfsdfdsfsdfsdf");
+      TokenFilterFactory.forName("sdfsdfsdfdsfsdfsdf", new HashMap<String,String>());
       fail();
     } catch (IllegalArgumentException expected) {
       //
     }
     
     try {
-      TokenFilterFactory.forName("!(**#$U*#$*");
+      TokenFilterFactory.forName("!(**#$U*#$*", new HashMap<String,String>());
       fail();
     } catch (IllegalArgumentException expected) {
       //
@@ -131,21 +140,21 @@
   }
   
   public void testLookupCharFilter() {
-    assertSame(HTMLStripCharFilterFactory.class, CharFilterFactory.forName("HTMLStrip").getClass());
-    assertSame(HTMLStripCharFilterFactory.class, CharFilterFactory.forName("HTMLSTRIP").getClass());
-    assertSame(HTMLStripCharFilterFactory.class, CharFilterFactory.forName("htmlstrip").getClass());
+    assertSame(HTMLStripCharFilterFactory.class, CharFilterFactory.forName("HTMLStrip", versionArgOnly()).getClass());
+    assertSame(HTMLStripCharFilterFactory.class, CharFilterFactory.forName("HTMLSTRIP", versionArgOnly()).getClass());
+    assertSame(HTMLStripCharFilterFactory.class, CharFilterFactory.forName("htmlstrip", versionArgOnly()).getClass());
   }
   
   public void testBogusLookupCharFilter() {
     try {
-      CharFilterFactory.forName("sdfsdfsdfdsfsdfsdf");
+      CharFilterFactory.forName("sdfsdfsdfdsfsdfsdf", new HashMap<String,String>());
       fail();
     } catch (IllegalArgumentException expected) {
       //
     }
     
     try {
-      CharFilterFactory.forName("!(**#$U*#$*");
+      CharFilterFactory.forName("!(**#$U*#$*", new HashMap<String,String>());
       fail();
     } catch (IllegalArgumentException expected) {
       //
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/commongrams/TestCommonGramsFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/commongrams/TestCommonGramsFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/commongrams/TestCommonGramsFilterFactory.java	(working copy)
@@ -17,37 +17,30 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.core.TestStopFilter;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.CharArraySet;
 import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.analysis.util.ResourceLoader;
 
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
 
 /**
  * Tests pretty much copied from StopFilterFactoryTest We use the test files
  * used by the StopFilterFactoryTest TODO: consider creating separate test files
  * so this won't break if stop filter test files change
  **/
-public class TestCommonGramsFilterFactory extends BaseTokenStreamTestCase {
+public class TestCommonGramsFilterFactory extends BaseTokenStreamFactoryTestCase {
 
   public void testInform() throws Exception {
     ResourceLoader loader = new ClasspathResourceLoader(TestStopFilter.class);
     assertTrue("loader is null and it shouldn't be", loader != null);
-    CommonGramsFilterFactory factory = new CommonGramsFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("words", "stop-1.txt");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    CommonGramsFilterFactory factory = (CommonGramsFilterFactory) tokenFilterFactory("CommonGrams", TEST_VERSION_CURRENT, loader, 
+        "words", "stop-1.txt", 
+        "ignoreCase", "true");
     CharArraySet words = factory.getCommonWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 2,
@@ -55,11 +48,9 @@
     assertTrue(factory.isIgnoreCase() + " does not equal: " + true, factory
         .isIgnoreCase() == true);
 
-    factory = new CommonGramsFilterFactory();
-    args.put("words", "stop-1.txt, stop-2.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    factory = (CommonGramsFilterFactory) tokenFilterFactory("CommonGrams", TEST_VERSION_CURRENT, loader, 
+        "words", "stop-1.txt, stop-2.txt", 
+        "ignoreCase", "true");
     words = factory.getCommonWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 4,
@@ -67,12 +58,10 @@
     assertTrue(factory.isIgnoreCase() + " does not equal: " + true, factory
         .isIgnoreCase() == true);
 
-    factory = new CommonGramsFilterFactory();
-    args.put("words", "stop-snowball.txt");
-    args.put("format", "snowball");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    factory = (CommonGramsFilterFactory) tokenFilterFactory("CommonGrams", TEST_VERSION_CURRENT, loader, 
+        "words", "stop-snowball.txt", 
+        "format", "snowball", 
+        "ignoreCase", "true");
     words = factory.getCommonWords();
     assertEquals(8, words.size());
     assertTrue(words.contains("he"));
@@ -89,13 +78,7 @@
    * If no words are provided, then a set of english default stopwords is used.
    */
   public void testDefaults() throws Exception {
-    ResourceLoader loader = new ClasspathResourceLoader(TestStopFilter.class);
-    assertTrue("loader is null and it shouldn't be", loader != null);
-    CommonGramsFilterFactory factory = new CommonGramsFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    factory.inform(loader);
+    CommonGramsFilterFactory factory = (CommonGramsFilterFactory) tokenFilterFactory("CommonGrams");
     CharArraySet words = factory.getCommonWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue(words.contains("the"));
@@ -104,4 +87,14 @@
     assertTokenStreamContents(stream, 
         new String[] { "testing", "testing_the", "the", "the_factory", "factory" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("CommonGrams", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/commongrams/TestCommonGramsQueryFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/commongrams/TestCommonGramsQueryFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/commongrams/TestCommonGramsQueryFilterFactory.java	(working copy)
@@ -17,37 +17,30 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.core.TestStopFilter;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.CharArraySet;
 import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.analysis.util.ResourceLoader;
 
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
 
 /**
  * Tests pretty much copied from StopFilterFactoryTest We use the test files
  * used by the StopFilterFactoryTest TODO: consider creating separate test files
  * so this won't break if stop filter test files change
  **/
-public class TestCommonGramsQueryFilterFactory extends BaseTokenStreamTestCase {
+public class TestCommonGramsQueryFilterFactory extends BaseTokenStreamFactoryTestCase {
 
   public void testInform() throws Exception {
     ResourceLoader loader = new ClasspathResourceLoader(TestStopFilter.class);
     assertTrue("loader is null and it shouldn't be", loader != null);
-    CommonGramsQueryFilterFactory factory = new CommonGramsQueryFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("words", "stop-1.txt");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    CommonGramsQueryFilterFactory factory = (CommonGramsQueryFilterFactory) tokenFilterFactory("CommonGramsQuery", TEST_VERSION_CURRENT, loader, 
+        "words", "stop-1.txt", 
+        "ignoreCase", "true");
     CharArraySet words = factory.getCommonWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 2,
@@ -55,11 +48,9 @@
     assertTrue(factory.isIgnoreCase() + " does not equal: " + true, factory
         .isIgnoreCase() == true);
 
-    factory = new CommonGramsQueryFilterFactory();
-    args.put("words", "stop-1.txt, stop-2.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    factory = (CommonGramsQueryFilterFactory) tokenFilterFactory("CommonGramsQuery", TEST_VERSION_CURRENT, loader, 
+        "words", "stop-1.txt, stop-2.txt", 
+        "ignoreCase", "true");
     words = factory.getCommonWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 4,
@@ -67,12 +58,10 @@
     assertTrue(factory.isIgnoreCase() + " does not equal: " + true, factory
         .isIgnoreCase() == true);
 
-    factory = new CommonGramsQueryFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    args.put("words", "stop-snowball.txt");
-    args.put("format", "snowball");
-    factory.init(args);
-    factory.inform(loader);
+    factory = (CommonGramsQueryFilterFactory) tokenFilterFactory("CommonGramsQuery", TEST_VERSION_CURRENT, loader, 
+        "words", "stop-snowball.txt", 
+        "format", "snowball", 
+        "ignoreCase", "true");
     words = factory.getCommonWords();
     assertEquals(8, words.size());
     assertTrue(words.contains("he"));
@@ -89,13 +78,7 @@
    * If no words are provided, then a set of english default stopwords is used.
    */
   public void testDefaults() throws Exception {
-    ResourceLoader loader = new ClasspathResourceLoader(TestStopFilter.class);
-    assertTrue("loader is null and it shouldn't be", loader != null);
-    CommonGramsQueryFilterFactory factory = new CommonGramsQueryFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    factory.inform(loader);
+    CommonGramsQueryFilterFactory factory = (CommonGramsQueryFilterFactory) tokenFilterFactory("CommonGramsQuery");
     CharArraySet words = factory.getCommonWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue(words.contains("the"));
@@ -104,4 +87,14 @@
     assertTokenStreamContents(stream, 
         new String[] { "testing_the", "the_factory" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("CommonGramsQuery", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/charfilter/TestHTMLStripCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/charfilter/TestHTMLStripCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/charfilter/TestHTMLStripCharFilterFactory.java	(working copy)
@@ -17,28 +17,24 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.*;
+import org.apache.lucene.analysis.MockTokenizer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure this factory is working
  */
-public class TestHTMLStripCharFilterFactory extends BaseTokenStreamTestCase {
+public class TestHTMLStripCharFilterFactory extends BaseTokenStreamFactoryTestCase {
 
 
-  public void testNothingChanged() throws IOException {
+  public void testNothingChanged() throws Exception {
     //                             11111111112
     //                   012345678901234567890
     final String text = "this is only a test.";
-    HTMLStripCharFilterFactory factory = new HTMLStripCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("escapedTags", "a, Title");
-    factory.init(args);
-    CharFilter cs = factory.create(new StringReader(text));
+    Reader cs = charFilterFactory("HTMLStrip", "escapedTags", "a, Title").create(new StringReader(text));
     TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "this", "is", "only", "a", "test." },
@@ -46,14 +42,11 @@
         new int[] { 4, 7, 12, 14, 20 });
   }
 
-  public void testNoEscapedTags() throws IOException {
+  public void testNoEscapedTags() throws Exception {
     //                             11111111112222222222333333333344
     //                   012345678901234567890123456789012345678901
     final String text = "<u>this</u> is <b>only</b> a <I>test</I>.";
-    HTMLStripCharFilterFactory factory = new HTMLStripCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    factory.init(args);
-    CharFilter cs = factory.create(new StringReader(text));
+    Reader cs = charFilterFactory("HTMLStrip").create(new StringReader(text));
     TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "this", "is", "only", "a", "test." },
@@ -61,15 +54,11 @@
         new int[] { 11, 14, 26, 28, 41 });
   }
 
-  public void testEscapedTags() throws IOException {
+  public void testEscapedTags() throws Exception {
     //                             11111111112222222222333333333344
     //                   012345678901234567890123456789012345678901
     final String text = "<u>this</u> is <b>only</b> a <I>test</I>.";
-    HTMLStripCharFilterFactory factory = new HTMLStripCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("escapedTags", "U i");
-    factory.init(args);
-    CharFilter cs = factory.create(new StringReader(text));
+    Reader cs = charFilterFactory("HTMLStrip", "escapedTags", "U i").create(new StringReader(text));
     TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "<u>this</u>", "is", "only", "a", "<I>test</I>." },
@@ -77,15 +66,11 @@
         new int[] { 11, 14, 26, 28, 41 });
   }
 
-  public void testSeparatorOnlyEscapedTags() throws IOException {
+  public void testSeparatorOnlyEscapedTags() throws Exception {
     //                             11111111112222222222333333333344
     //                   012345678901234567890123456789012345678901
     final String text = "<u>this</u> is <b>only</b> a <I>test</I>.";
-    HTMLStripCharFilterFactory factory = new HTMLStripCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("escapedTags", ",, , ");
-    factory.init(args);
-    CharFilter cs = factory.create(new StringReader(text));
+    Reader cs = charFilterFactory("HTMLStrip", "escapedTags", ",, , ").create(new StringReader(text));
     TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "this", "is", "only", "a", "test." },
@@ -93,15 +78,11 @@
         new int[] { 11, 14, 26, 28, 41 });
   }
 
-  public void testEmptyEscapedTags() throws IOException {
+  public void testEmptyEscapedTags() throws Exception {
     //                             11111111112222222222333333333344
     //                   012345678901234567890123456789012345678901
     final String text = "<u>this</u> is <b>only</b> a <I>test</I>.";
-    HTMLStripCharFilterFactory factory = new HTMLStripCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("escapedTags", "");
-    factory.init(args);
-    CharFilter cs = factory.create(new StringReader(text));
+    Reader cs = charFilterFactory("HTMLStrip", "escapedTags", "").create(new StringReader(text));
     TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "this", "is", "only", "a", "test." },
@@ -109,19 +90,25 @@
         new int[] { 11, 14, 26, 28, 41 });
   }
 
-  public void testSingleEscapedTag() throws IOException {
+  public void testSingleEscapedTag() throws Exception {
     //                             11111111112222222222333333333344
     //                   012345678901234567890123456789012345678901
     final String text = "<u>this</u> is <b>only</b> a <I>test</I>.";
-    HTMLStripCharFilterFactory factory = new HTMLStripCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("escapedTags", ", B\r\n\t");
-    factory.init(args);
-    CharFilter cs = factory.create(new StringReader(text));
+    Reader cs = charFilterFactory("HTMLStrip", "escapedTags", ", B\r\n\t").create(new StringReader(text));
     TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "this", "is", "<b>only</b>", "a", "test." },
         new int[] {  3, 12, 15, 27, 32 },
         new int[] { 11, 14, 26, 28, 41 });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      charFilterFactory("HTMLStrip", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/charfilter/TestMappingCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/charfilter/TestMappingCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/charfilter/TestMappingCharFilterFactory.java	(working copy)
@@ -17,12 +17,14 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.util.LuceneTestCase;
+import java.util.HashMap;
 
-public class TestMappingCharFilterFactory extends LuceneTestCase {
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
+
+public class TestMappingCharFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testParseString() throws Exception {
 
-    MappingCharFilterFactory f = new MappingCharFilterFactory();
+    MappingCharFilterFactory f = new MappingCharFilterFactory(new HashMap<String,String>());
 
     try {
       f.parseString( "\\" );
@@ -49,4 +51,14 @@
     }
     catch( NumberFormatException expected ){}
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      charFilterFactory("Mapping", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/sv/TestSwedishLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/sv/TestSwedishLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/sv/TestSwedishLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Swedish Light stem factory is working.
  */
-public class TestSwedishLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestSwedishLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("äpplen äpple");
-    SwedishLightStemFilterFactory factory = new SwedishLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("SwedishLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "äppl", "äppl" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("SwedishLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestAllAnalyzersHaveFactories.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestAllAnalyzersHaveFactories.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestAllAnalyzersHaveFactories.java	(working copy)
@@ -21,8 +21,10 @@
 import java.io.StringReader;
 import java.lang.reflect.Modifier;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.IdentityHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.lucene.analysis.CachingTokenFilter;
@@ -115,31 +117,35 @@
         continue;
       }
       
+      Map<String,String> args = new HashMap<String,String>();
+      args.put("luceneMatchVersion", TEST_VERSION_CURRENT.toString());
+      
       if (Tokenizer.class.isAssignableFrom(c)) {
         String clazzName = c.getSimpleName();
         assertTrue(clazzName.endsWith("Tokenizer"));
         String simpleName = clazzName.substring(0, clazzName.length() - 9);
-        TokenizerFactory instance = TokenizerFactory.forName(simpleName);
-        assertNotNull(instance);
+        TokenizerFactory instance = null;
         try {
-          instance.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-          instance.init(Collections.<String,String>emptyMap());
+          instance = TokenizerFactory.forName(simpleName, args);
+          assertNotNull(instance);
           if (instance instanceof ResourceLoaderAware) {
             ((ResourceLoaderAware) instance).inform(loader);
           }
           assertSame(c, instance.create(new StringReader("")).getClass());
         } catch (IllegalArgumentException e) {
+          if (!e.getMessage().contains("SPI")) {
+            throw e;
+          }
           // TODO: For now pass because some factories have not yet a default config that always works
         }
       } else if (TokenFilter.class.isAssignableFrom(c)) {
         String clazzName = c.getSimpleName();
         assertTrue(clazzName.endsWith("Filter"));
         String simpleName = clazzName.substring(0, clazzName.length() - (clazzName.endsWith("TokenFilter") ? 11 : 6));
-        TokenFilterFactory instance = TokenFilterFactory.forName(simpleName);
-        assertNotNull(instance);
+        TokenFilterFactory instance = null; 
         try {
-          instance.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-          instance.init(Collections.<String,String>emptyMap());
+          instance = TokenFilterFactory.forName(simpleName, args);
+          assertNotNull(instance);
           if (instance instanceof ResourceLoaderAware) {
             ((ResourceLoaderAware) instance).inform(loader);
           }
@@ -149,17 +155,19 @@
             assertSame(c, createdClazz);
           }
         } catch (IllegalArgumentException e) {
+          if (!e.getMessage().contains("SPI")) {
+            throw e;
+          }
           // TODO: For now pass because some factories have not yet a default config that always works
         }
       } else if (CharFilter.class.isAssignableFrom(c)) {
         String clazzName = c.getSimpleName();
         assertTrue(clazzName.endsWith("CharFilter"));
         String simpleName = clazzName.substring(0, clazzName.length() - 10);
-        CharFilterFactory instance = CharFilterFactory.forName(simpleName);
-        assertNotNull(instance);
+        CharFilterFactory instance = null;
         try {
-          instance.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-          instance.init(Collections.<String,String>emptyMap());
+          instance = CharFilterFactory.forName(simpleName, args);
+          assertNotNull(instance);
           if (instance instanceof ResourceLoaderAware) {
             ((ResourceLoaderAware) instance).inform(loader);
           }
@@ -169,6 +177,9 @@
             assertSame(c, createdClazz);
           }
         } catch (IllegalArgumentException e) {
+          if (!e.getMessage().contains("SPI")) {
+            throw e;
+          }
           // TODO: For now pass because some factories have not yet a default config that always works
         }
       }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestFactories.java	(working copy)
@@ -19,7 +19,10 @@
 
 import java.io.IOException;
 import java.io.Reader;
-import java.util.Collections;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.BaseTokenStreamTestCase;
@@ -27,7 +30,6 @@
 import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
 import org.apache.lucene.analysis.util.CharFilterFactory;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.analysis.util.MultiTermAwareComponent;
 import org.apache.lucene.analysis.util.ResourceLoaderAware;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
@@ -59,8 +61,9 @@
   }
   
   private void doTestTokenizer(String tokenizer) throws IOException {
-    TokenizerFactory factory = TokenizerFactory.forName(tokenizer);
-    if (initialize(factory)) {
+    Class<? extends TokenizerFactory> factoryClazz = TokenizerFactory.lookupClass(tokenizer);
+    TokenizerFactory factory = (TokenizerFactory) initialize(factoryClazz);
+    if (factory != null) {
       // we managed to fully create an instance. check a few more things:
       
       // if it implements MultiTermAware, sanity check its impl
@@ -78,8 +81,9 @@
   }
   
   private void doTestTokenFilter(String tokenfilter) throws IOException {
-    TokenFilterFactory factory = TokenFilterFactory.forName(tokenfilter);
-    if (initialize(factory)) {
+    Class<? extends TokenFilterFactory> factoryClazz = TokenFilterFactory.lookupClass(tokenfilter);
+    TokenFilterFactory factory = (TokenFilterFactory) initialize(factoryClazz);
+    if (factory != null) {
       // we managed to fully create an instance. check a few more things:
       
       // if it implements MultiTermAware, sanity check its impl
@@ -97,8 +101,9 @@
   }
   
   private void doTestCharFilter(String charfilter) throws IOException {
-    CharFilterFactory factory = CharFilterFactory.forName(charfilter);
-    if (initialize(factory)) {
+    Class<? extends CharFilterFactory> factoryClazz = CharFilterFactory.lookupClass(charfilter);
+    CharFilterFactory factory = (CharFilterFactory) initialize(factoryClazz);
+    if (factory != null) {
       // we managed to fully create an instance. check a few more things:
       
       // if it implements MultiTermAware, sanity check its impl
@@ -116,36 +121,44 @@
   }
   
   /** tries to initialize a factory with no arguments */
-  private boolean initialize(AbstractAnalysisFactory factory) throws IOException {
-    boolean success = false;
+  private AbstractAnalysisFactory initialize(Class<? extends AbstractAnalysisFactory> factoryClazz) throws IOException {
+    Map<String,String> args = new HashMap<String,String>();
+    args.put("luceneMatchVersion", TEST_VERSION_CURRENT.toString());
+    Constructor<? extends AbstractAnalysisFactory> ctor;
     try {
-      factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-      factory.init(Collections.<String,String>emptyMap());
-      if (factory instanceof ResourceLoaderAware) {
-        ResourceLoaderAware resourceLoaderAware = (ResourceLoaderAware) factory;
-          resourceLoaderAware.inform(new ClasspathResourceLoader(factory.getClass()));
+      ctor = factoryClazz.getConstructor(Map.class);
+    } catch (Exception e) {
+      throw new RuntimeException("factory '" + factoryClazz + "' does not have a proper ctor!");
+    }
+    
+    AbstractAnalysisFactory factory = null;
+    try {
+      factory = ctor.newInstance(args);
+    } catch (InstantiationException e) {
+      throw new RuntimeException(e);
+    } catch (IllegalAccessException e) {
+      throw new RuntimeException(e);
+    } catch (InvocationTargetException e) {
+      if (e.getCause() instanceof IllegalArgumentException) {
+        // its ok if we dont provide the right parameters to throw this
+        return null;
       }
-      success = true;
-    } catch (IllegalArgumentException ignored) {
-      // its ok if we dont provide the right parameters to throw this
     }
     
     if (factory instanceof ResourceLoaderAware) {
-      success = false;
       try {
         ((ResourceLoaderAware) factory).inform(new StringMockResourceLoader(""));
-        success = true;
       } catch (IOException ignored) {
         // its ok if the right files arent available or whatever to throw this
       } catch (IllegalArgumentException ignored) {
         // is this ok? I guess so
       }
     }
-    return success;
+    return factory;
   }
   
   // some silly classes just so we can use checkRandomData
-  private TokenizerFactory assertingTokenizer = new TokenizerFactory() {
+  private TokenizerFactory assertingTokenizer = new TokenizerFactory(new HashMap<String,String>()) {
     @Override
     public MockTokenizer create(AttributeFactory factory, Reader input) {
       return new MockTokenizer(factory, input);
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestTypeTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestTypeTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestTypeTokenFilterFactory.java	(working copy)
@@ -17,88 +17,73 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.NumericTokenStream;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
-import org.apache.lucene.analysis.util.ResourceLoader;
-import org.junit.Test;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
+import org.apache.lucene.analysis.util.TokenFilterFactory;
 
-import java.util.HashMap;
-import java.util.Map;
 import java.util.Set;
 
 /**
  * Testcase for {@link TypeTokenFilterFactory}
  */
-public class TestTypeTokenFilterFactory extends BaseTokenStreamTestCase {
+public class TestTypeTokenFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-  @Test
   public void testInform() throws Exception {
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    TypeTokenFilterFactory factory = new TypeTokenFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("types", "stoptypes-1.txt");
-    args.put("enablePositionIncrements", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    TypeTokenFilterFactory factory = (TypeTokenFilterFactory) tokenFilterFactory("Type",
+        "types", "stoptypes-1.txt",
+        "enablePositionIncrements", "true");
     Set<String> types = factory.getStopTypes();
     assertTrue("types is null and it shouldn't be", types != null);
     assertTrue("types Size: " + types.size() + " is not: " + 2, types.size() == 2);
     assertTrue("enablePositionIncrements was set to true but not correctly parsed", factory.isEnablePositionIncrements());
 
-    factory = new TypeTokenFilterFactory();
-    args.put("types", "stoptypes-1.txt, stoptypes-2.txt");
-    args.put("enablePositionIncrements", "false");
-    args.put("useWhitelist","true");
-    factory.init(args);
-    factory.inform(loader);
+    factory = (TypeTokenFilterFactory) tokenFilterFactory("Type",
+        "types", "stoptypes-1.txt, stoptypes-2.txt",
+        "enablePositionIncrements", "false",
+        "useWhitelist", "true");
     types = factory.getStopTypes();
     assertTrue("types is null and it shouldn't be", types != null);
     assertTrue("types Size: " + types.size() + " is not: " + 4, types.size() == 4);
     assertTrue("enablePositionIncrements was set to false but not correctly parsed", !factory.isEnablePositionIncrements());
   }
 
-  @Test
   public void testCreationWithBlackList() throws Exception {
-    TypeTokenFilterFactory typeTokenFilterFactory = new TypeTokenFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("types", "stoptypes-1.txt, stoptypes-2.txt");
-    args.put("enablePositionIncrements", "false");
-    typeTokenFilterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    typeTokenFilterFactory.init(args);
+    TokenFilterFactory factory = tokenFilterFactory("Type",
+        "types", "stoptypes-1.txt, stoptypes-2.txt",
+        "enablePositionIncrements", "false");
     NumericTokenStream input = new NumericTokenStream();
     input.setIntValue(123);
-    typeTokenFilterFactory.create(input);
+    factory.create(input);
   }
   
-  @Test
-    public void testCreationWithWhiteList() throws Exception {
-      TypeTokenFilterFactory typeTokenFilterFactory = new TypeTokenFilterFactory();
-      Map<String, String> args = new HashMap<String, String>();
-      args.put("types", "stoptypes-1.txt, stoptypes-2.txt");
-      args.put("enablePositionIncrements", "false");
-      args.put("useWhitelist","true");
-      typeTokenFilterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-      typeTokenFilterFactory.init(args);
-      NumericTokenStream input = new NumericTokenStream();
-      input.setIntValue(123);
-      typeTokenFilterFactory.create(input);
-    }
+  public void testCreationWithWhiteList() throws Exception {
+    TokenFilterFactory factory = tokenFilterFactory("Type",
+        "types", "stoptypes-1.txt, stoptypes-2.txt",
+        "enablePositionIncrements", "false",
+        "useWhitelist", "true");
+    NumericTokenStream input = new NumericTokenStream();
+    input.setIntValue(123);
+    factory.create(input);
+  }
 
-  @Test
   public void testMissingTypesParameter() throws Exception {
     try {
-      TypeTokenFilterFactory typeTokenFilterFactory = new TypeTokenFilterFactory();
-      Map<String, String> args = new HashMap<String, String>();
-      args.put("enablePositionIncrements", "false");
-      typeTokenFilterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-      typeTokenFilterFactory.init(args);
-      typeTokenFilterFactory.inform(new ClasspathResourceLoader(getClass()));
+      tokenFilterFactory("Type", "enablePositionIncrements", "false");
       fail("not supplying 'types' parameter should cause an IllegalArgumentException");
     } catch (IllegalArgumentException e) {
       // everything ok
     }
   }
-
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Type", 
+          "types", "stoptypes-1.txt", 
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/core/TestStopFilterFactory.java	(working copy)
@@ -17,51 +17,36 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.CharArraySet;
 import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.analysis.util.ResourceLoader;
 
-import java.util.Map;
-import java.util.HashMap;
+public class TestStopFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-/**
- *
- *
- **/
-public class TestStopFilterFactory extends BaseTokenStreamTestCase {
-
   public void testInform() throws Exception {
     ResourceLoader loader = new ClasspathResourceLoader(getClass());
     assertTrue("loader is null and it shouldn't be", loader != null);
-    StopFilterFactory factory = new StopFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("words", "stop-1.txt");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    StopFilterFactory factory = (StopFilterFactory) tokenFilterFactory("Stop",
+        "words", "stop-1.txt",
+        "ignoreCase", "true");
     CharArraySet words = factory.getStopWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 2, words.size() == 2);
     assertTrue(factory.isIgnoreCase() + " does not equal: " + true, factory.isIgnoreCase() == true);
 
-    factory = new StopFilterFactory();
-    args.put("words", "stop-1.txt, stop-2.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    factory = (StopFilterFactory) tokenFilterFactory("Stop",
+        "words", "stop-1.txt, stop-2.txt",
+        "ignoreCase", "true");
     words = factory.getStopWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 4, words.size() == 4);
     assertTrue(factory.isIgnoreCase() + " does not equal: " + true, factory.isIgnoreCase() == true);
 
-    factory = new StopFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    args.put("words", "stop-snowball.txt");
-    args.put("format", "snowball");
-    factory.init(args);
-    factory.inform(loader);
+    factory = (StopFilterFactory) tokenFilterFactory("Stop",
+        "words", "stop-snowball.txt",
+        "format", "snowball",
+        "ignoreCase", "true");
     words = factory.getStopWords();
     assertEquals(8, words.size());
     assertTrue(words.contains("he"));
@@ -73,4 +58,14 @@
     assertTrue(words.contains("hers"));
     assertTrue(words.contains("herself"));
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Stop", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanNormalizationFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the German normalization factory is working.
  */
-public class TestGermanNormalizationFilterFactory extends BaseTokenStreamTestCase {
+public class TestGermanNormalizationFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("weißbier");
-    GermanNormalizationFilterFactory factory = new GermanNormalizationFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GermanNormalization").create(stream);
     assertTokenStreamContents(stream, new String[] { "weissbier" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GermanNormalization", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the German light stem factory is working.
  */
-public class TestGermanLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestGermanLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("häuser");
-    GermanLightStemFilterFactory factory = new GermanLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GermanLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "haus" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GermanLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanStemFilterFactory.java	(working copy)
@@ -20,23 +20,31 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the German stem filter factory is working.
  */
-public class TestGermanStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestGermanStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually stems text.
    */
   public void testStemming() throws Exception {
     Reader reader = new StringReader("Tischen");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    GermanStemFilterFactory factory = new GermanStemFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GermanStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "tisch" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GermanStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/de/TestGermanMinimalStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the German minimal stem factory is working.
  */
-public class TestGermanMinimalStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestGermanMinimalStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("bilder");
-    GermanMinimalStemFilterFactory factory = new GermanMinimalStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GermanMinimalStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "bild" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GermanMinimalStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/hi/TestHindiFilters.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/hi/TestHindiFilters.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/hi/TestHindiFilters.java	(working copy)
@@ -19,33 +19,21 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.in.IndicNormalizationFilterFactory;
-import org.apache.lucene.analysis.standard.StandardTokenizerFactory;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Hindi filter Factories are working.
  */
-public class TestHindiFilters extends BaseTokenStreamTestCase {
+public class TestHindiFilters extends BaseTokenStreamFactoryTestCase {
   /**
    * Test IndicNormalizationFilterFactory
    */
   public void testIndicNormalizer() throws Exception {
     Reader reader = new StringReader("ত্‍ अाैर");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    IndicNormalizationFilterFactory filterFactory = new IndicNormalizationFilterFactory();
-    filterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    filterFactory.init(args);
-    Tokenizer tokenizer = factory.create(reader);
-    TokenStream stream = filterFactory.create(tokenizer);
+    TokenStream stream = tokenizerFactory("Standard").create(reader);
+    stream = tokenFilterFactory("IndicNormalization").create(stream);
     assertTokenStreamContents(stream, new String[] { "ৎ", "और" });
   }
   
@@ -54,17 +42,9 @@
    */
   public void testHindiNormalizer() throws Exception {
     Reader reader = new StringReader("क़िताब");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    IndicNormalizationFilterFactory indicFilterFactory = new IndicNormalizationFilterFactory();
-    HindiNormalizationFilterFactory hindiFilterFactory = new HindiNormalizationFilterFactory();
-    hindiFilterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    hindiFilterFactory.init(args);
-    Tokenizer tokenizer = factory.create(reader);
-    TokenStream stream = indicFilterFactory.create(tokenizer);
-    stream = hindiFilterFactory.create(stream);
+    TokenStream stream = tokenizerFactory("Standard").create(reader);
+    stream = tokenFilterFactory("IndicNormalization").create(stream);
+    stream = tokenFilterFactory("HindiNormalization").create(stream);
     assertTokenStreamContents(stream, new String[] {"किताब"});
   }
   
@@ -73,19 +53,34 @@
    */
   public void testStemmer() throws Exception {
     Reader reader = new StringReader("किताबें");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    IndicNormalizationFilterFactory indicFilterFactory = new IndicNormalizationFilterFactory();
-    HindiNormalizationFilterFactory hindiFilterFactory = new HindiNormalizationFilterFactory();
-    HindiStemFilterFactory stemFactory = new HindiStemFilterFactory();
-    stemFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    stemFactory.init(args);
-    Tokenizer tokenizer = factory.create(reader);
-    TokenStream stream = indicFilterFactory.create(tokenizer);
-    stream = hindiFilterFactory.create(stream);
-    stream = stemFactory.create(stream);
+    TokenStream stream = tokenizerFactory("Standard").create(reader);
+    stream = tokenFilterFactory("IndicNormalization").create(stream);
+    stream = tokenFilterFactory("HindiNormalization").create(stream);
+    stream = tokenFilterFactory("HindiStem").create(stream);
     assertTokenStreamContents(stream, new String[] {"किताब"});
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("IndicNormalization", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("HindiNormalization", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("HindiStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenPositionFilterFactory.java	(working copy)
@@ -16,69 +16,69 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.shingle.ShingleFilter;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
-public class TestLimitTokenPositionFilterFactory extends BaseTokenStreamTestCase {
+public class TestLimitTokenPositionFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-  public void testMaxPosition1() throws IOException {
-    LimitTokenPositionFilterFactory factory = new LimitTokenPositionFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put(LimitTokenPositionFilterFactory.MAX_TOKEN_POSITION_KEY, "1");
-    factory.init(args);
-    String test = "A1 B2 C3 D4 E5 F6";
-    MockTokenizer tok = new MockTokenizer(new StringReader(test), MockTokenizer.WHITESPACE, false);
+  public void testMaxPosition1() throws Exception {
+    Reader reader = new StringReader("A1 B2 C3 D4 E5 F6");
+    MockTokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
     // LimitTokenPositionFilter doesn't consume the entire stream that it wraps
-    tok.setEnableChecks(false);
-    TokenStream stream = factory.create(tok);
+    tokenizer.setEnableChecks(false);
+    TokenStream stream = tokenizer;
+    stream = tokenFilterFactory("LimitTokenPosition",
+        "maxTokenPosition", "1").create(stream);
     assertTokenStreamContents(stream, new String[] { "A1" });
   }
   
-  public void testMissingParam() {
-    LimitTokenPositionFilterFactory factory = new LimitTokenPositionFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    IllegalArgumentException iae = null;
+  public void testMissingParam() throws Exception {
     try {
-      factory.init(args);
+      tokenFilterFactory("LimitTokenPosition");
+      fail();
     } catch (IllegalArgumentException e) {
       assertTrue("exception doesn't mention param: " + e.getMessage(),
           0 < e.getMessage().indexOf(LimitTokenPositionFilterFactory.MAX_TOKEN_POSITION_KEY));
-      iae = e;
     }
-    assertNotNull("no exception thrown", iae);
   }
 
-  public void testMaxPosition1WithShingles() throws IOException {
-    LimitTokenPositionFilterFactory factory = new LimitTokenPositionFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put(LimitTokenPositionFilterFactory.MAX_TOKEN_POSITION_KEY, "1");
-    factory.init(args);
-    String input = "one two three four five";
-    MockTokenizer tok = new MockTokenizer(new StringReader(input), MockTokenizer.WHITESPACE, false);
+  public void testMaxPosition1WithShingles() throws Exception {
+    Reader reader = new StringReader("one two three four five");
+    MockTokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
     // LimitTokenPositionFilter doesn't consume the entire stream that it wraps
-    tok.setEnableChecks(false);
-    ShingleFilter shingleFilter = new ShingleFilter(tok, 2, 3);
-    shingleFilter.setOutputUnigrams(true);
-    TokenStream stream = factory.create(shingleFilter);
+    tokenizer.setEnableChecks(false);
+    TokenStream stream = tokenizer;
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "2",
+        "maxShingleSize", "3",
+        "outputUnigrams", "true").create(stream);
+    stream = tokenFilterFactory("LimitTokenPosition",
+        "maxTokenPosition", "1").create(stream);
     assertTokenStreamContents(stream, new String[] { "one", "one two", "one two three" });
   }
   
-  public void testConsumeAllTokens() throws IOException {
-    LimitTokenPositionFilterFactory factory = new LimitTokenPositionFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put(LimitTokenPositionFilterFactory.MAX_TOKEN_POSITION_KEY, "3");
-    args.put(LimitTokenPositionFilterFactory.CONSUME_ALL_TOKENS_KEY, "true");
-    factory.init(args);
-    String test = "A1 B2 C3 D4 E5 F6";
-    MockTokenizer tok = new MockTokenizer(new StringReader(test), MockTokenizer.WHITESPACE, false);
-    TokenStream stream = factory.create(tok);
+  public void testConsumeAllTokens() throws Exception {
+    Reader reader = new StringReader("A1 B2 C3 D4 E5 F6");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("LimitTokenPosition",
+        "maxTokenPosition", "3",
+        "consumeAllTokens", "true").create(stream);
     assertTokenStreamContents(stream, new String[] { "A1", "B2", "C3" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("LimitTokenPosition", 
+          "maxTokenPosition", "3", 
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTrimFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTrimFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestTrimFilterFactory.java	(working copy)
@@ -17,24 +17,31 @@
  * limitations under the License.
  */
 
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure this factory is working
  */
-public class TestTrimFilterFactory extends BaseTokenStreamTestCase {
+public class TestTrimFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testTrimming() throws Exception {
-    TrimFilterFactory factory = new TrimFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("updateOffsets", "false");
-    factory.init(args);
-    TokenStream ts = factory.create(new MockTokenizer(new StringReader("trim me    "), MockTokenizer.KEYWORD, false));
-    assertTokenStreamContents(ts, new String[] { "trim me" });
+    Reader reader = new StringReader("trim me    ");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Trim").create(stream);
+    assertTokenStreamContents(stream, new String[] { "trim me" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Trim", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestCapitalizationFilterFactory.java	(working copy)
@@ -17,127 +17,188 @@
  * limitations under the License.
  */
 
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
-/**
- * 
- */
-public class TestCapitalizationFilterFactory extends BaseTokenStreamTestCase {
+public class TestCapitalizationFilterFactory extends BaseTokenStreamFactoryTestCase {
   
-  public void testCapitalization() throws Exception 
-  {
-    Map<String,String> args = new HashMap<String, String>();
-    args.put( CapitalizationFilterFactory.KEEP, "and the it BIG" );
-    args.put( CapitalizationFilterFactory.ONLY_FIRST_WORD, "true" );  
-    
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init( args );
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("kiTTEN"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "Kitten" });
-    
-    factory.forceFirstLetter = true;
-
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("and"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "And" });
-
-    //first is forced, but it's not a keep word, either
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("AnD"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "And" });
-
-    factory.forceFirstLetter = false;
-
-    //first is not forced, but it's not a keep word, either
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("AnD"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "And" });
-
-    factory.forceFirstLetter = true;
-    
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("big"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "Big" });
-    
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("BIG"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "BIG" });
-
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("Hello thEre my Name is Ryan"), MockTokenizer.KEYWORD, false)),
-        new String[] { "Hello there my name is ryan" });
-        
-    // now each token
-    factory.onlyFirstWord = false;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("Hello thEre my Name is Ryan"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "Hello", "There", "My", "Name", "Is", "Ryan" });
-    
-    // now only the long words
-    factory.minWordLength = 3;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("Hello thEre my Name is Ryan"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "Hello", "There", "my", "Name", "is", "Ryan" });
-    
-    // without prefix
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("McKinley"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "Mckinley" });
-    
-    // Now try some prefixes
-    factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    args.put( "okPrefix", "McK" );  // all words
-    factory.init( args );
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("McKinley"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "McKinley" });
-    
-    // now try some stuff with numbers
-    factory.forceFirstLetter = false;
-    factory.onlyFirstWord = false;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("1st 2nd third"), MockTokenizer.WHITESPACE, false)),
-        new String[] { "1st", "2nd", "Third" });
-    
-    factory.forceFirstLetter = true;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("the The the"), MockTokenizer.KEYWORD, false)),
-        new String[] { "The The the" });
+  public void testCapitalization() throws Exception {
+    Reader reader = new StringReader("kiTTEN");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Kitten" });
   }
+  
+  public void testCapitalization2() throws Exception {
+    Reader reader = new StringReader("and");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "And" });
+  }
+  
+  /** first is forced, but it's not a keep word, either */
+  public void testCapitalization3() throws Exception {
+    Reader reader = new StringReader("AnD");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "And" });
+  }
+  
+  public void testCapitalization4() throws Exception {
+    Reader reader = new StringReader("AnD");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "false").create(stream);
+    assertTokenStreamContents(stream, new String[] { "And" });
+  }
+  
+  public void testCapitalization5() throws Exception {
+    Reader reader = new StringReader("big");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Big" });
+  }
+  
+  public void testCapitalization6() throws Exception {
+    Reader reader = new StringReader("BIG");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "BIG" });
+  }
+  
+  public void testCapitalization7() throws Exception {
+    Reader reader = new StringReader("Hello thEre my Name is Ryan");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Hello there my name is ryan" });
+  }
+  
+  public void testCapitalization8() throws Exception {
+    Reader reader = new StringReader("Hello thEre my Name is Ryan");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "false",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Hello", "There", "My", "Name", "Is", "Ryan" });
+  }
+  
+  public void testCapitalization9() throws Exception {
+    Reader reader = new StringReader("Hello thEre my Name is Ryan");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "false",
+        "minWordLength", "3",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Hello", "There", "my", "Name", "is", "Ryan" });
+  }
+  
+  public void testCapitalization10() throws Exception {
+    Reader reader = new StringReader("McKinley");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "false",
+        "minWordLength", "3",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Mckinley" });
+  }
+  
+  /** using "McK" as okPrefix */
+  public void testCapitalization11() throws Exception {
+    Reader reader = new StringReader("McKinley");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "false",
+        "minWordLength", "3",
+        "okPrefix", "McK",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "McKinley" });
+  }
+  
+  /** test with numbers */
+  public void testCapitalization12() throws Exception {
+    Reader reader = new StringReader("1st 2nd third");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "false",
+        "minWordLength", "3",
+        "okPrefix", "McK",
+        "forceFirstLetter", "false").create(stream);
+    assertTokenStreamContents(stream, new String[] { "1st", "2nd", "Third" });
+  }
+  
+  public void testCapitalization13() throws Exception {
+    Reader reader = new StringReader("the The the");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "and the it BIG",
+        "onlyFirstWord", "false",
+        "minWordLength", "3",
+        "okPrefix", "McK",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "The The the" });
+  }
 
   public void testKeepIgnoreCase() throws Exception {
-    Map<String,String> args = new HashMap<String, String>();
-    args.put( CapitalizationFilterFactory.KEEP, "kitten" );
-    args.put( CapitalizationFilterFactory.KEEP_IGNORE_CASE, "true" );
-    args.put( CapitalizationFilterFactory.ONLY_FIRST_WORD, "true" );
+    Reader reader = new StringReader("kiTTEN");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "kitten",
+        "keepIgnoreCase", "true",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "true").create(stream);
 
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init( args );
-    factory.forceFirstLetter = true;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("kiTTEN"), MockTokenizer.KEYWORD, false)),
-        new String[] { "KiTTEN" });
+    assertTokenStreamContents(stream, new String[] { "KiTTEN" });
+  }
+  
+  public void testKeepIgnoreCase2() throws Exception {
+    Reader reader = new StringReader("kiTTEN");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "kitten",
+        "keepIgnoreCase", "true",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "false").create(stream);
 
-    factory.forceFirstLetter = false;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("kiTTEN"), MockTokenizer.KEYWORD, false)),
-        new String[] { "kiTTEN" });
+    assertTokenStreamContents(stream, new String[] { "kiTTEN" });
+  }
+  
+  public void testKeepIgnoreCase3() throws Exception {
+    Reader reader = new StringReader("kiTTEN");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keepIgnoreCase", "true",
+        "onlyFirstWord", "true",
+        "forceFirstLetter", "false").create(stream);
 
-    factory.keep = null;
-    assertTokenStreamContents(factory.create(
-        new MockTokenizer(new StringReader("kiTTEN"), MockTokenizer.KEYWORD, false)),
-        new String[] { "Kitten" });
+    assertTokenStreamContents(stream, new String[] { "Kitten" });
   }
   
   /**
@@ -146,16 +207,12 @@
    * This is very weird when combined with ONLY_FIRST_WORD!!!
    */
   public void testMinWordLength() throws Exception {
-    Map<String,String> args = new HashMap<String,String>();
-    args.put(CapitalizationFilterFactory.ONLY_FIRST_WORD, "true");
-    args.put(CapitalizationFilterFactory.MIN_WORD_LENGTH, "5");
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer tokenizer = new MockTokenizer(new StringReader(
-        "helo testing"), MockTokenizer.WHITESPACE, false);
-    TokenStream ts = factory.create(tokenizer);
-    assertTokenStreamContents(ts, new String[] {"helo", "Testing"});
+    Reader reader = new StringReader("helo testing");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "onlyFirstWord", "true",
+        "minWordLength", "5").create(stream);
+    assertTokenStreamContents(stream, new String[] { "helo", "Testing" });
   }
   
   /**
@@ -163,30 +220,22 @@
    * in each token (it should do nothing)
    */
   public void testMaxWordCount() throws Exception {
-    Map<String,String> args = new HashMap<String,String>();
-    args.put(CapitalizationFilterFactory.MAX_WORD_COUNT, "2");
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer tokenizer = new MockTokenizer(new StringReader(
-        "one two three four"), MockTokenizer.WHITESPACE, false);
-    TokenStream ts = factory.create(tokenizer);
-    assertTokenStreamContents(ts, new String[] {"One", "Two", "Three", "Four"});
+    Reader reader = new StringReader("one two three four");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "maxWordCount", "2").create(stream);
+    assertTokenStreamContents(stream, new String[] { "One", "Two", "Three", "Four" });
   }
   
   /**
    * Test CapitalizationFilterFactory's maxWordCount option when exceeded
    */
   public void testMaxWordCount2() throws Exception {
-    Map<String,String> args = new HashMap<String,String>();
-    args.put(CapitalizationFilterFactory.MAX_WORD_COUNT, "2");
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer tokenizer = new MockTokenizer(new StringReader(
-        "one two three four"), MockTokenizer.KEYWORD, false);
-    TokenStream ts = factory.create(tokenizer);
-    assertTokenStreamContents(ts, new String[] {"one two three four"});
+    Reader reader = new StringReader("one two three four");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.KEYWORD, false);
+    stream = tokenFilterFactory("Capitalization",
+        "maxWordCount", "2").create(stream);
+    assertTokenStreamContents(stream, new String[] { "one two three four" });
   }
   
   /**
@@ -195,29 +244,32 @@
    * This is weird, it is not really a max, but inclusive (look at 'is')
    */
   public void testMaxTokenLength() throws Exception {
-    Map<String,String> args = new HashMap<String,String>();
-    args.put(CapitalizationFilterFactory.MAX_TOKEN_LENGTH, "2");
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer tokenizer = new MockTokenizer(new StringReader(
-        "this is a test"), MockTokenizer.WHITESPACE, false);
-    TokenStream ts = factory.create(tokenizer);
-    assertTokenStreamContents(ts, new String[] {"this", "is", "A", "test"});
+    Reader reader = new StringReader("this is a test");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "maxTokenLength", "2").create(stream);
+    assertTokenStreamContents(stream, new String[] { "this", "is", "A", "test" });
   }
   
   /**
    * Test CapitalizationFilterFactory's forceFirstLetter option
    */
-  public void testForceFirstLetter() throws Exception {
-    Map<String,String> args = new HashMap<String,String>();
-    args.put(CapitalizationFilterFactory.KEEP, "kitten");
-    args.put(CapitalizationFilterFactory.FORCE_FIRST_LETTER, "true");
-    CapitalizationFilterFactory factory = new CapitalizationFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer tokenizer = new MockTokenizer(new StringReader("kitten"), MockTokenizer.WHITESPACE, false);
-    TokenStream ts = factory.create(tokenizer);
-    assertTokenStreamContents(ts, new String[] {"Kitten"});
+  public void testForceFirstLetterWithKeep() throws Exception {
+    Reader reader = new StringReader("kitten");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Capitalization",
+        "keep", "kitten",
+        "forceFirstLetter", "true").create(stream);
+    assertTokenStreamContents(stream, new String[] { "Kitten" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Capitalization", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestRemoveDuplicatesTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestRemoveDuplicatesTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestRemoveDuplicatesTokenFilterFactory.java	(working copy)
@@ -17,54 +17,24 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
+import org.apache.lucene.analysis.CannedTokenStream;
 import org.apache.lucene.analysis.Token;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
-import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
-import java.util.Iterator;
-import java.util.Arrays;
-
 /** Simple tests to ensure this factory is working */
-public class TestRemoveDuplicatesTokenFilterFactory extends BaseTokenStreamTestCase {
+public class TestRemoveDuplicatesTokenFilterFactory extends BaseTokenStreamFactoryTestCase {
 
   public static Token tok(int pos, String t, int start, int end) {
     Token tok = new Token(t,start,end);
     tok.setPositionIncrement(pos);
     return tok;
   }
-  public static Token tok(int pos, String t) {
-    return tok(pos, t, 0,0);
-  }
 
-  public void testDups(final String expected, final Token... tokens)
-    throws Exception {
-
-    final Iterator<Token> toks = Arrays.asList(tokens).iterator();
-    RemoveDuplicatesTokenFilterFactory factory = new RemoveDuplicatesTokenFilterFactory();
-    final TokenStream ts = factory.create
-      (new TokenStream() {
-          CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
-          OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
-          PositionIncrementAttribute posIncAtt = addAttribute(PositionIncrementAttribute.class);
-          @Override
-          public boolean incrementToken() {
-            if (toks.hasNext()) {
-              clearAttributes();
-              Token tok = toks.next();
-              termAtt.setEmpty().append(tok);
-              offsetAtt.setOffset(tok.startOffset(), tok.endOffset());
-              posIncAtt.setPositionIncrement(tok.getPositionIncrement());
-              return true;
-            } else {
-              return false;
-            }
-          }
-        });
-    
-    assertTokenStreamContents(ts, expected.split("\\s"));   
+  public void testDups(final String expected, final Token... tokens) throws Exception {
+    TokenStream stream = new CannedTokenStream(tokens);
+    stream = tokenFilterFactory("RemoveDuplicates").create(stream);
+    assertTokenStreamContents(stream, expected.split("\\s"));   
   }
  
   public void testSimpleDups() throws Exception {
@@ -77,4 +47,14 @@
              ,tok(1,"E",21, 25)
              ); 
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("RemoveDuplicates", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeepFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeepFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeepFilterFactory.java	(working copy)
@@ -17,45 +17,38 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.CharArraySet;
 import org.apache.lucene.analysis.util.ClasspathResourceLoader;
 import org.apache.lucene.analysis.util.ResourceLoader;
 
-import java.util.Map;
-import java.util.HashMap;
+public class TestKeepFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-/**
- *
- *
- **/
-public class TestKeepFilterFactory extends BaseTokenStreamTestCase {
-
   public void testInform() throws Exception {
     ResourceLoader loader = new ClasspathResourceLoader(getClass());
     assertTrue("loader is null and it shouldn't be", loader != null);
-    KeepWordFilterFactory factory = new KeepWordFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("words", "keep-1.txt");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    KeepWordFilterFactory factory = (KeepWordFilterFactory) tokenFilterFactory("KeepWord",
+        "words", "keep-1.txt",
+        "ignoreCase", "true");
     CharArraySet words = factory.getWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 2, words.size() == 2);
 
-
-    factory = new KeepWordFilterFactory();
-    args.put("words", "keep-1.txt, keep-2.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    factory = (KeepWordFilterFactory) tokenFilterFactory("KeepWord",
+        "words", "keep-1.txt, keep-2.txt",
+        "ignoreCase", "true");
     words = factory.getWords();
     assertTrue("words is null and it shouldn't be", words != null);
     assertTrue("words Size: " + words.size() + " is not: " + 4, words.size() == 4);
-
-
-
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("KeepWord", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
\ No newline at end of file
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestKeywordMarkerFilterFactory.java	(working copy)
@@ -17,114 +17,89 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
-import org.apache.lucene.analysis.en.PorterStemFilter;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
 
 /**
  * Simple tests to ensure the keyword marker filter factory is working.
  */
-public class TestKeywordMarkerFilterFactory extends BaseTokenStreamTestCase {
+public class TestKeywordMarkerFilterFactory extends BaseTokenStreamFactoryTestCase {
   
-  public void testKeywords() throws IOException {
+  public void testKeywords() throws Exception {
     Reader reader = new StringReader("dogs cats");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    KeywordMarkerFilterFactory factory = new KeywordMarkerFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    ResourceLoader loader = new StringMockResourceLoader("cats");
-    args.put("protected", "protwords.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    
-    TokenStream ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "dog", "cats" });
-    
-    
-    reader = new StringReader("dogs cats");
-    tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    factory = new KeywordMarkerFilterFactory();
-    args = new HashMap<String,String>();
-    
-    args.put("pattern", "cats|Dogs");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(null);
-    
-    ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "dog", "cats" });
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KeywordMarker", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("cats"),
+        "protected", "protwords.txt").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
+    assertTokenStreamContents(stream, new String[] { "dog", "cats" });
   }
   
-  public void testKeywordsMixed() throws IOException {
+  public void testKeywords2() throws Exception {
+    Reader reader = new StringReader("dogs cats");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KeywordMarker",
+        "pattern", "cats|Dogs").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
+    assertTokenStreamContents(stream, new String[] { "dog", "cats" });
+  }
+  
+  public void testKeywordsMixed() throws Exception {
     Reader reader = new StringReader("dogs cats birds");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    KeywordMarkerFilterFactory factory = new KeywordMarkerFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    ResourceLoader loader = new StringMockResourceLoader("cats");
-    args.put("protected", "protwords.txt");
-    args.put("pattern", "birds|Dogs");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    
-    TokenStream ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "dog", "cats", "birds" });
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KeywordMarker", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("cats"),
+        "protected", "protwords.txt",
+        "pattern", "birds|Dogs").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
+    assertTokenStreamContents(stream, new String[] { "dog", "cats", "birds" });
   }
   
-  public void testKeywordsCaseInsensitive() throws IOException {
+  public void testKeywordsCaseInsensitive() throws Exception {
     Reader reader = new StringReader("dogs cats Cats");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    KeywordMarkerFilterFactory factory = new KeywordMarkerFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    ResourceLoader loader = new StringMockResourceLoader("cats");
-    args.put("protected", "protwords.txt");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    
-    TokenStream ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "dog", "cats", "Cats" });
-    
-    reader = new StringReader("dogs cats Cats");
-    tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    factory = new KeywordMarkerFilterFactory();
-    args = new HashMap<String,String>();
-    
-    args.put("pattern", "Cats");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(null);
-    
-    ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "dog", "cats", "Cats" });
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KeywordMarker", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("cats"),
+        "protected", "protwords.txt",
+        "ignoreCase", "true").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
+    assertTokenStreamContents(stream, new String[] { "dog", "cats", "Cats" });
   }
   
-  public void testKeywordsCaseInsensitiveMixed() throws IOException {
+  public void testKeywordsCaseInsensitive2() throws Exception {
+    Reader reader = new StringReader("dogs cats Cats");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KeywordMarker",
+        "pattern", "Cats",
+        "ignoreCase", "true").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);;
+    assertTokenStreamContents(stream, new String[] { "dog", "cats", "Cats" });
+  }
+  
+  public void testKeywordsCaseInsensitiveMixed() throws Exception {
     Reader reader = new StringReader("dogs cats Cats Birds birds");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    KeywordMarkerFilterFactory factory = new KeywordMarkerFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    ResourceLoader loader = new StringMockResourceLoader("cats");
-    args.put("protected", "protwords.txt");
-    args.put("pattern", "birds");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    
-    TokenStream ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "dog", "cats", "Cats", "Birds", "birds" });
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KeywordMarker", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("cats"),
+        "protected", "protwords.txt",
+        "pattern", "birds",
+        "ignoreCase", "true").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
+    assertTokenStreamContents(stream, new String[] { "dog", "cats", "Cats", "Birds", "birds" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("KeywordMarker", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLimitTokenCountFilterFactory.java	(working copy)
@@ -16,40 +16,46 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
-public class TestLimitTokenCountFilterFactory extends BaseTokenStreamTestCase {
+public class TestLimitTokenCountFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-  public void test() throws IOException {
-    LimitTokenCountFilterFactory factory = new LimitTokenCountFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put(LimitTokenCountFilterFactory.MAX_TOKEN_COUNT_KEY, "3");
-    factory.init(args);
-    String test = "A1 B2 C3 D4 E5 F6";
-    MockTokenizer tok = new MockTokenizer(new StringReader(test), MockTokenizer.WHITESPACE, false);
+  public void test() throws Exception {
+    Reader reader = new StringReader("A1 B2 C3 D4 E5 F6");
+    MockTokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
     // LimitTokenCountFilter doesn't consume the entire stream that it wraps
-    tok.setEnableChecks(false); 
-    TokenStream stream = factory.create(tok);
+    tokenizer.setEnableChecks(false);
+    TokenStream stream = tokenizer;
+    stream = tokenFilterFactory("LimitTokenCount",
+        "maxTokenCount", "3").create(stream);
     assertTokenStreamContents(stream, new String[] { "A1", "B2", "C3" });
+  }
 
+  public void testRequired() throws Exception {
     // param is required
-    factory = new LimitTokenCountFilterFactory();
-    args = new HashMap<String, String>();
-    IllegalArgumentException iae = null;
     try {
-      factory.init(args);
+      tokenFilterFactory("LimitTokenCount");
+      fail();
     } catch (IllegalArgumentException e) {
       assertTrue("exception doesn't mention param: " + e.getMessage(),
                  0 < e.getMessage().indexOf(LimitTokenCountFilterFactory.MAX_TOKEN_COUNT_KEY));
-      iae = e;
     }
-    assertNotNull("no exception thrown", iae);
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("LimitTokenCount", 
+          "maxTokenCount", "3", 
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestStemmerOverrideFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestStemmerOverrideFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestStemmerOverrideFilterFactory.java	(working copy)
@@ -17,53 +17,49 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
-import org.apache.lucene.analysis.en.PorterStemFilter;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
 
 /**
  * Simple tests to ensure the stemmer override filter factory is working.
  */
-public class TestStemmerOverrideFilterFactory extends BaseTokenStreamTestCase {
-  public void testKeywords() throws IOException {
+public class TestStemmerOverrideFilterFactory extends BaseTokenStreamFactoryTestCase {
+  public void testKeywords() throws Exception {
     // our stemdict stems dogs to 'cat'
     Reader reader = new StringReader("testing dogs");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    StemmerOverrideFilterFactory factory = new StemmerOverrideFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    ResourceLoader loader = new StringMockResourceLoader("dogs\tcat");
-    args.put("dictionary", "stemdict.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    
-    TokenStream ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "test", "cat" });
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("StemmerOverride", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("dogs\tcat"),
+        "dictionary", "stemdict.txt").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
+
+    assertTokenStreamContents(stream, new String[] { "test", "cat" });
   }
   
-  public void testKeywordsCaseInsensitive() throws IOException {
+  public void testKeywordsCaseInsensitive() throws Exception {
     Reader reader = new StringReader("testing DoGs");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    StemmerOverrideFilterFactory factory = new StemmerOverrideFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    ResourceLoader loader = new StringMockResourceLoader("dogs\tcat");
-    args.put("dictionary", "stemdict.txt");
-    args.put("ignoreCase", "true");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("StemmerOverride", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("dogs\tcat"),
+        "dictionary", "stemdict.txt",
+        "ignoreCase", "true").create(stream);
+    stream = tokenFilterFactory("PorterStem").create(stream);
     
-    TokenStream ts = new PorterStemFilter(factory.create(tokenizer));
-    assertTokenStreamContents(ts, new String[] { "test", "cat" });
+    assertTokenStreamContents(stream, new String[] { "test", "cat" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("StemmerOverride", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/miscellaneous/TestLengthFilterFactory.java	(working copy)
@@ -16,35 +16,44 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
-public class TestLengthFilterFactory extends BaseTokenStreamTestCase {
+public class TestLengthFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-  public void test() throws IOException {
-    LengthFilterFactory factory = new LengthFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put(LengthFilterFactory.MIN_KEY, String.valueOf(4));
-    args.put(LengthFilterFactory.MAX_KEY, String.valueOf(10));
-    // default: args.put("enablePositionIncrements", "false");
-    factory.init(args);
-    String test = "foo foobar super-duper-trooper";
-    TokenStream stream = factory.create(new MockTokenizer(new StringReader(test), MockTokenizer.WHITESPACE, false));
+  public void test() throws Exception {
+    Reader reader = new StringReader("foo foobar super-duper-trooper");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Length",
+        "min", "4",
+        "max", "10").create(stream);
     assertTokenStreamContents(stream, new String[] { "foobar" }, new int[] { 1 });
+  }
 
-    factory = new LengthFilterFactory();
-    args = new HashMap<String, String>();
-    args.put(LengthFilterFactory.MIN_KEY, String.valueOf(4));
-    args.put(LengthFilterFactory.MAX_KEY, String.valueOf(10));
-    args.put("enablePositionIncrements", "true");
-    factory.init(args);
-    stream = factory.create(new MockTokenizer(new StringReader(test), MockTokenizer.WHITESPACE, false));
+  public void testPositionIncrements() throws Exception {
+    Reader reader = new StringReader("foo foobar super-duper-trooper");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Length",
+        "min", "4",
+        "max", "10",
+        "enablePositionIncrements", "true").create(stream);
     assertTokenStreamContents(stream, new String[] { "foobar" }, new int[] { 2 });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Length", 
+          "min", "4", 
+          "max", "5", 
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
\ No newline at end of file
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/ngram/TestNGramFilters.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/ngram/TestNGramFilters.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/ngram/TestNGramFilters.java	(working copy)
@@ -19,146 +19,158 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the NGram filter factories are working.
  */
-public class TestNGramFilters extends BaseTokenStreamTestCase {
+public class TestNGramFilters extends BaseTokenStreamFactoryTestCase {
   /**
    * Test NGramTokenizerFactory
    */
   public void testNGramTokenizer() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    NGramTokenizerFactory factory = new NGramTokenizerFactory();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("NGram").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { "t", "e", "s", "t", "te", "es", "st" });
   }
+
   /**
    * Test NGramTokenizerFactory with min and max gram options
    */
   public void testNGramTokenizer2() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minGramSize", "2");
-    args.put("maxGramSize", "3");
-    NGramTokenizerFactory factory = new NGramTokenizerFactory();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("NGram",
+        "minGramSize", "2",
+        "maxGramSize", "3").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { "te", "es", "st", "tes", "est" });
   }
+
   /**
    * Test the NGramFilterFactory
    */
   public void testNGramFilter() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    NGramFilterFactory factory = new NGramFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("NGram").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "t", "e", "s", "t", "te", "es", "st" });
   }
+
   /**
    * Test the NGramFilterFactory with min and max gram options
    */
   public void testNGramFilter2() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minGramSize", "2");
-    args.put("maxGramSize", "3");
-    NGramFilterFactory factory = new NGramFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("NGram",
+        "minGramSize", "2",
+        "maxGramSize", "3").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "te", "es", "st", "tes", "est" });
   }
+
   /**
    * Test EdgeNGramTokenizerFactory
    */
   public void testEdgeNGramTokenizer() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    EdgeNGramTokenizerFactory factory = new EdgeNGramTokenizerFactory();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("EdgeNGram").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { "t" });
   }
+
   /**
    * Test EdgeNGramTokenizerFactory with min and max gram size
    */
   public void testEdgeNGramTokenizer2() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minGramSize", "1");
-    args.put("maxGramSize", "2");
-    EdgeNGramTokenizerFactory factory = new EdgeNGramTokenizerFactory();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("EdgeNGram",
+        "minGramSize", "1",
+        "maxGramSize", "2").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { "t", "te" });
   }
+
   /**
    * Test EdgeNGramTokenizerFactory with side option
    */
   public void testEdgeNGramTokenizer3() throws Exception {
     Reader reader = new StringReader("ready");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("side", "back");
-    EdgeNGramTokenizerFactory factory = new EdgeNGramTokenizerFactory();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("EdgeNGram",
+        "side", "back").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { "y" });
   }
+
   /**
    * Test EdgeNGramFilterFactory
    */
   public void testEdgeNGramFilter() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    EdgeNGramFilterFactory factory = new EdgeNGramFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("EdgeNGram").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "t" });
   }
+
   /**
    * Test EdgeNGramFilterFactory with min and max gram size
    */
   public void testEdgeNGramFilter2() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minGramSize", "1");
-    args.put("maxGramSize", "2");
-    EdgeNGramFilterFactory factory = new EdgeNGramFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("EdgeNGram",
+        "minGramSize", "1",
+        "maxGramSize", "2").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "t", "te" });
   }
+
   /**
    * Test EdgeNGramFilterFactory with side option
    */
   public void testEdgeNGramFilter3() throws Exception {
     Reader reader = new StringReader("ready");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("side", "back");
-    EdgeNGramFilterFactory factory = new EdgeNGramFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("EdgeNGram",
+        "side", "back").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "y" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenizerFactory("NGram", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenizerFactory("EdgeNGram", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("NGram", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("EdgeNGram", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/th/TestThaiWordFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/th/TestThaiWordFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/th/TestThaiWordFilterFactory.java	(working copy)
@@ -19,32 +19,36 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
 import org.apache.lucene.analysis.th.ThaiWordFilter;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Thai word filter factory is working.
  */
-public class TestThaiWordFilterFactory extends BaseTokenStreamTestCase {
+public class TestThaiWordFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually decomposes text.
    */
   public void testWordBreak() throws Exception {
     assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiWordFilter.DBBI_AVAILABLE);
     Reader reader = new StringReader("การที่ได้ต้องแสดงว่างานดี");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    ThaiWordFilterFactory factory = new ThaiWordFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("ThaiWord").create(stream);
     assertTokenStreamContents(stream, new String[] {"การ", "ที่", "ได้",
         "ต้อง", "แสดง", "ว่า", "งาน", "ดี"});
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    assumeTrue("JRE does not support Thai dictionary-based BreakIterator", ThaiWordFilter.DBBI_AVAILABLE);
+    try {
+      tokenFilterFactory("ThaiWord", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/reverse/TestReverseStringFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/reverse/TestReverseStringFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/reverse/TestReverseStringFilterFactory.java	(working copy)
@@ -19,29 +19,32 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Reverse string filter factory is working.
  */
-public class TestReverseStringFilterFactory extends BaseTokenStreamTestCase {
+public class TestReverseStringFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually reverses text.
    */
   public void testReversing() throws Exception {
     Reader reader = new StringReader("simple test");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    ReverseStringFilterFactory factory = new ReverseStringFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("ReverseString").create(stream);
     assertTokenStreamContents(stream, new String[] { "elpmis", "tset" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("ReverseString", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/hu/TestHungarianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/hu/TestHungarianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/hu/TestHungarianLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Hungarian light stem factory is working.
  */
-public class TestHungarianLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestHungarianLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("házakat");
-    HungarianLightStemFilterFactory factory = new HungarianLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("HungarianLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "haz" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("HungarianLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/snowball/TestSnowballPorterFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/snowball/TestSnowballPorterFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/snowball/TestSnowballPorterFilterFactory.java	(working copy)
@@ -16,74 +16,56 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.util.StringMockResourceLoader;
 import org.tartarus.snowball.ext.EnglishStemmer;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
 
-public class TestSnowballPorterFilterFactory extends BaseTokenStreamTestCase {
+public class TestSnowballPorterFilterFactory extends BaseTokenStreamFactoryTestCase {
 
-  public void test() throws IOException {
+  public void test() throws Exception {
+    String text = "The fledgling banks were counting on a big boom in banking";
     EnglishStemmer stemmer = new EnglishStemmer();
-    String[] test = {"The", "fledgling", "banks", "were", "counting", "on", "a", "big", "boom", "in", "banking"};
+    String[] test = text.split("\\s");
     String[] gold = new String[test.length];
     for (int i = 0; i < test.length; i++) {
       stemmer.setCurrent(test[i]);
       stemmer.stem();
       gold[i] = stemmer.getCurrent();
     }
-
-    SnowballPorterFilterFactory factory = new SnowballPorterFilterFactory();
-    Map<String, String> args = new HashMap<String, String>();
-    args.put("language", "English");
-
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(new StringMockResourceLoader(""));
-    Tokenizer tokenizer = new MockTokenizer(
-        new StringReader(join(test, ' ')), MockTokenizer.WHITESPACE, false);
-    TokenStream stream = factory.create(tokenizer);
+    
+    Reader reader = new StringReader(text);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("SnowballPorter", "language", "English").create(stream);
     assertTokenStreamContents(stream, gold);
   }
   
-  String join(String[] stuff, char sep) {
-    StringBuilder sb = new StringBuilder();
-    for (int i = 0; i < stuff.length; i++) {
-      if (i > 0) {
-        sb.append(sep);
-      }
-      sb.append(stuff[i]);
-    }
-    return sb.toString();
-  }
-  
   /**
    * Test the protected words mechanism of SnowballPorterFilterFactory
    */
   public void testProtected() throws Exception {
-    SnowballPorterFilterFactory factory = new SnowballPorterFilterFactory();
-    ResourceLoader loader = new StringMockResourceLoader("ridding");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("protected", "protwords.txt");
-    args.put("language", "English");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
     Reader reader = new StringReader("ridding of some stemming");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("SnowballPorter", TEST_VERSION_CURRENT,
+        new StringMockResourceLoader("ridding"),
+        "protected", "protwords.txt",
+        "language", "English").create(stream);
+
     assertTokenStreamContents(stream, new String[] { "ridding", "of", "some", "stem" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("SnowballPorter", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
 
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/lv/TestLatvianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/lv/TestLatvianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/lv/TestLatvianStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Latvian stem factory is working.
  */
-public class TestLatvianStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestLatvianStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("tirgiem tirgus");
-    LatvianStemFilterFactory factory = new LatvianStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("LatvianStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "tirg", "tirg" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("LatvianStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseMinimalStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Portuguese Minimal stem factory is working.
  */
-public class TestPortugueseMinimalStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestPortugueseMinimalStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("questões");
-    PortugueseMinimalStemFilterFactory factory = new PortugueseMinimalStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("PortugueseMinimalStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "questão" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("PortugueseMinimalStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Portuguese Light stem factory is working.
  */
-public class TestPortugueseLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestPortugueseLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("evidentemente");
-    PortugueseLightStemFilterFactory factory = new PortugueseLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("PortugueseLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "evident" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("PortugueseLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/pt/TestPortugueseStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Portuguese stem factory is working.
  */
-public class TestPortugueseStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestPortugueseStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("maluquice");
-    PortugueseStemFilterFactory factory = new PortugueseStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("PortugueseStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "maluc" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("PortugueseStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/tr/TestTurkishLowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/tr/TestTurkishLowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/tr/TestTurkishLowerCaseFilterFactory.java	(working copy)
@@ -20,23 +20,31 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Turkish lowercase filter factory is working.
  */
-public class TestTurkishLowerCaseFilterFactory extends BaseTokenStreamTestCase {
+public class TestTurkishLowerCaseFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually lowercases text.
    */
   public void testCasing() throws Exception {
     Reader reader = new StringReader("AĞACI");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    TurkishLowerCaseFilterFactory factory = new TurkishLowerCaseFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("TurkishLowerCase").create(stream);
     assertTokenStreamContents(stream, new String[] { "ağacı" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("TurkishLowerCase", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/id/TestIndonesianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/id/TestIndonesianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/id/TestIndonesianStemFilterFactory.java	(working copy)
@@ -19,28 +19,22 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Indonesian stem filter factory is working.
  */
-public class TestIndonesianStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestIndonesianStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually stems text.
    */
   public void testStemming() throws Exception {
     Reader reader = new StringReader("dibukukannya");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    IndonesianStemFilterFactory factory = new IndonesianStemFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    factory.init(args);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("IndonesianStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "buku" });
   }
   
@@ -49,12 +43,18 @@
    */
   public void testStemmingInflectional() throws Exception {
     Reader reader = new StringReader("dibukukannya");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    IndonesianStemFilterFactory factory = new IndonesianStemFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("stemDerivational", "false");
-    factory.init(args);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("IndonesianStem", "stemDerivational", "false").create(stream);
     assertTokenStreamContents(stream, new String[] { "dibukukan" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("IndonesianStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/el/TestGreekLowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/el/TestGreekLowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/el/TestGreekLowerCaseFilterFactory.java	(working copy)
@@ -19,29 +19,32 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Greek lowercase filter factory is working.
  */
-public class TestGreekLowerCaseFilterFactory extends BaseTokenStreamTestCase {
+public class TestGreekLowerCaseFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually lowercases (and a bit more) greek text.
    */
   public void testNormalization() throws Exception {
     Reader reader = new StringReader("Μάϊος ΜΆΪΟΣ");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    GreekLowerCaseFilterFactory factory = new GreekLowerCaseFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GreekLowerCase").create(stream);
     assertTokenStreamContents(stream, new String[] { "μαιοσ", "μαιοσ" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GreekLowerCase", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/el/TestGreekStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/el/TestGreekStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/el/TestGreekStemFilterFactory.java	(working copy)
@@ -20,22 +20,29 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.el.GreekLowerCaseFilter;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Greek stem filter factory is working.
  */
-public class TestGreekStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestGreekStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("άνθρωπος");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    TokenStream normalized = new GreekLowerCaseFilter(TEST_VERSION_CURRENT, tokenizer);
-    GreekStemFilterFactory factory = new GreekStemFilterFactory();
-    TokenStream stream = factory.create(normalized);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GreekLowerCase").create(stream);
+    stream = tokenFilterFactory("GreekStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "ανθρωπ" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GreekStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestKStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestKStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestKStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the kstem filter factory is working.
  */
-public class TestKStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestKStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("bricks");
-    KStemFilterFactory factory = new KStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("KStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "brick" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("KStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestEnglishMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestEnglishMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestEnglishMinimalStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the English minimal stem factory is working.
  */
-public class TestEnglishMinimalStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestEnglishMinimalStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("bricks");
-    EnglishMinimalStemFilterFactory factory = new EnglishMinimalStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("EnglishMinimalStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "brick" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("EnglishMinimalStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestPorterStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestPorterStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/en/TestPorterStemFilterFactory.java	(working copy)
@@ -20,23 +20,31 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Porter stem filter factory is working.
  */
-public class TestPorterStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestPorterStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually stems text.
    */
   public void testStemming() throws Exception {
     Reader reader = new StringReader("dogs");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    PorterStemFilterFactory factory = new PorterStemFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("PorterStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "dog" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("PorterStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/ar/TestArabicFilters.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/ar/TestArabicFilters.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/ar/TestArabicFilters.java	(working copy)
@@ -19,34 +19,23 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.fa.PersianCharFilterFactory;
-import org.apache.lucene.analysis.standard.StandardTokenizerFactory;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Arabic filter Factories are working.
  */
-public class TestArabicFilters extends BaseTokenStreamTestCase {
+public class TestArabicFilters extends BaseTokenStreamFactoryTestCase {
   
   /**
    * Test ArabicNormalizationFilterFactory
    */
   public void testNormalizer() throws Exception {
     Reader reader = new StringReader("الذين مَلكت أيمانكم");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    ArabicNormalizationFilterFactory filterFactory = new ArabicNormalizationFilterFactory();
-    filterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    filterFactory.init(args);
-    Tokenizer tokenizer = factory.create(reader);
-    TokenStream stream = filterFactory.create(tokenizer);
+    Tokenizer tokenizer = tokenizerFactory("Standard").create(reader);
+    TokenStream stream = tokenFilterFactory("ArabicNormalization").create(tokenizer);
     assertTokenStreamContents(stream, new String[] {"الذين", "ملكت", "ايمانكم"});
   }
   
@@ -55,17 +44,9 @@
    */
   public void testStemmer() throws Exception {
     Reader reader = new StringReader("الذين مَلكت أيمانكم");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    ArabicNormalizationFilterFactory normFactory = new ArabicNormalizationFilterFactory();
-    normFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    ArabicStemFilterFactory stemFactory = new ArabicStemFilterFactory();
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    normFactory.init(args);
-    Tokenizer tokenizer = factory.create(reader);
-    TokenStream stream = normFactory.create(tokenizer);
-    stream = stemFactory.create(stream);
+    Tokenizer tokenizer = tokenizerFactory("Standard").create(reader);
+    TokenStream stream = tokenFilterFactory("ArabicNormalization").create(tokenizer);
+    stream = tokenFilterFactory("ArabicStem").create(stream);
     assertTokenStreamContents(stream, new String[] {"ذين", "ملكت", "ايمانكم"});
   }
   
@@ -73,13 +54,32 @@
    * Test PersianCharFilterFactory
    */
   public void testPersianCharFilter() throws Exception {
-    Reader reader = new StringReader("می‌خورد");
-    PersianCharFilterFactory charfilterFactory = new PersianCharFilterFactory();
-    StandardTokenizerFactory tokenizerFactory = new StandardTokenizerFactory();
-    tokenizerFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    tokenizerFactory.init(args);
-    TokenStream stream = tokenizerFactory.create(charfilterFactory.create(reader));
-    assertTokenStreamContents(stream, new String[] { "می", "خورد" });
+    Reader reader = charFilterFactory("Persian").create(new StringReader("می‌خورد"));
+    Tokenizer tokenizer = tokenizerFactory("Standard").create(reader);
+    assertTokenStreamContents(tokenizer, new String[] { "می", "خورد" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("ArabicNormalization", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("Arabicstem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      charFilterFactory("Persian", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/wikipedia/TestWikipediaTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/wikipedia/TestWikipediaTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/wikipedia/TestWikipediaTokenizerFactory.java	(working copy)
@@ -17,22 +17,20 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 import org.apache.lucene.analysis.wikipedia.WikipediaTokenizer;
 
 /**
  * Simple tests to ensure the wikipedia tokenizer is working.
  */
-public class TestWikipediaTokenizerFactory extends BaseTokenStreamTestCase {
-  public void testTokenizer() throws IOException {
+public class TestWikipediaTokenizerFactory extends BaseTokenStreamFactoryTestCase {
+  public void testTokenizer() throws Exception {
     Reader reader = new StringReader("This is a [[Category:foo]]");
-    WikipediaTokenizerFactory factory = new WikipediaTokenizerFactory();
-    Tokenizer tokenizer = factory.create(reader);
+    Tokenizer tokenizer = tokenizerFactory("Wikipedia").create(reader);
     assertTokenStreamContents(tokenizer,
         new String[] { "This", "is", "a", "foo" },
         new int[] { 0, 5, 8, 21 },
@@ -40,4 +38,14 @@
         new String[] { "<ALPHANUM>", "<ALPHANUM>", "<ALPHANUM>", WikipediaTokenizer.CATEGORY },
         new int[] { 1, 1, 1, 1, });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenizerFactory("Wikipedia", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/es/TestSpanishLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/es/TestSpanishLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/es/TestSpanishLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Spanish Light stem factory is working.
  */
-public class TestSpanishLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestSpanishLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("sociedades");
-    SpanishLightStemFilterFactory factory = new SpanishLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("SpanishLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "sociedad" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("SpanishLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/it/TestItalianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/it/TestItalianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/it/TestItalianLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Italian light stem factory is working.
  */
-public class TestItalianLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestItalianLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("ragazzo ragazzi");
-    ItalianLightStemFilterFactory factory = new ItalianLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("ItalianLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "ragazz", "ragazz" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("ItalianLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/compound/TestDictionaryCompoundWordTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/compound/TestDictionaryCompoundWordTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/compound/TestDictionaryCompoundWordTokenFilterFactory.java	(working copy)
@@ -19,36 +19,36 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
-import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Dictionary compound filter factory is working.
  */
-public class TestDictionaryCompoundWordTokenFilterFactory extends BaseTokenStreamTestCase {
+public class TestDictionaryCompoundWordTokenFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually decompounds text.
    */
   public void testDecompounding() throws Exception {
     Reader reader = new StringReader("I like to play softball");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    DictionaryCompoundWordTokenFilterFactory factory = new DictionaryCompoundWordTokenFilterFactory();
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("dictionary", "compoundDictionary.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("DictionaryCompoundWord", 
+        "dictionary", "compoundDictionary.txt").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "I", "like", "to", "play", "softball", "soft", "ball" });
   }
   
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("DictionaryCompoundWord", 
+          "dictionary", "compoundDictionary.txt", 
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/compound/TestHyphenationCompoundWordTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/compound/TestHyphenationCompoundWordTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/compound/TestHyphenationCompoundWordTokenFilterFactory.java	(working copy)
@@ -19,35 +19,24 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
-import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Hyphenation compound filter factory is working.
  */
-public class TestHyphenationCompoundWordTokenFilterFactory extends BaseTokenStreamTestCase {
+public class TestHyphenationCompoundWordTokenFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the factory works with hyphenation grammar+dictionary: using default options.
    */
   public void testHyphenationWithDictionary() throws Exception {
     Reader reader = new StringReader("min veninde som er lidt af en læsehest");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    HyphenationCompoundWordTokenFilterFactory factory = new HyphenationCompoundWordTokenFilterFactory();
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("hyphenator", "da_UTF8.xml");
-    args.put("dictionary", "da_compoundDictionary.txt");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("HyphenationCompoundWord", 
+        "hyphenator", "da_UTF8.xml",
+        "dictionary", "da_compoundDictionary.txt").create(stream);
     
     assertTokenStreamContents(stream, 
         new String[] { "min", "veninde", "som", "er", "lidt", "af", "en", "læsehest", "læse", "hest" },
@@ -62,20 +51,26 @@
    */
   public void testHyphenationOnly() throws Exception {
     Reader reader = new StringReader("basketballkurv");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    HyphenationCompoundWordTokenFilterFactory factory = new HyphenationCompoundWordTokenFilterFactory();
-    ResourceLoader loader = new ClasspathResourceLoader(getClass());
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("hyphenator", "da_UTF8.xml");
-    args.put("minSubwordSize", "2");
-    args.put("maxSubwordSize", "4");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(loader);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("HyphenationCompoundWord", 
+        "hyphenator", "da_UTF8.xml",
+        "minSubwordSize", "2",
+        "maxSubwordSize", "4").create(stream);
     
     assertTokenStreamContents(stream,
         new String[] { "basketballkurv", "ba", "sket", "bal", "ball", "kurv" }
     );
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("HyphenationCompoundWord", 
+          "hyphenator", "da_UTF8.xml",
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/fa/TestPersianNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/fa/TestPersianNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/fa/TestPersianNormalizationFilterFactory.java	(working copy)
@@ -20,23 +20,31 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Persian normalization factory is working.
  */
-public class TestPersianNormalizationFilterFactory extends BaseTokenStreamTestCase {
+public class TestPersianNormalizationFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually normalizes persian text.
    */
   public void testNormalization() throws Exception {
     Reader reader = new StringReader("های");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    PersianNormalizationFilterFactory factory = new PersianNormalizationFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("PersianNormalization").create(stream);
     assertTokenStreamContents(stream, new String[] { "هاي" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("PersianNormalization", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/bg/TestBulgarianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/bg/TestBulgarianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/bg/TestBulgarianStemFilterFactory.java	(working copy)
@@ -20,23 +20,32 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Bulgarian stem filter factory is working.
  */
-public class TestBulgarianStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestBulgarianStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually stems text.
    */
   public void testStemming() throws Exception {
     Reader reader = new StringReader("компютри");
     Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    BulgarianStemFilterFactory factory = new BulgarianStemFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = tokenFilterFactory("BulgarianStem").create(tokenizer);
     assertTokenStreamContents(stream, new String[] { "компютр" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("BulgarianStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/fi/TestFinnishLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/fi/TestFinnishLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/fi/TestFinnishLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Finnish light stem factory is working.
  */
-public class TestFinnishLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestFinnishLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("aseistettujen");
-    FinnishLightStemFilterFactory factory = new FinnishLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("FinnishLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "aseistet" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("FinnishLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestUAX29URLEmailTokenizerFactory.java	(working copy)
@@ -19,73 +19,50 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
-import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * A few tests based on org.apache.lucene.analysis.TestUAX29URLEmailTokenizer
  */
 
-public class TestUAX29URLEmailTokenizerFactory extends BaseTokenStreamTestCase {
+public class TestUAX29URLEmailTokenizerFactory extends BaseTokenStreamFactoryTestCase {
 
   public void testUAX29URLEmailTokenizer() throws Exception {
     Reader reader = new StringReader("Wha\u0301t's this thing do?");
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"Wha\u0301t's", "this", "thing", "do" });
+        new String[] { "Wha\u0301t's", "this", "thing", "do" });
   }
   
   public void testArabic() throws Exception {
     Reader reader = new StringReader("الفيلم الوثائقي الأول عن ويكيبيديا يسمى \"الحقيقة بالأرقام: قصة ويكيبيديا\" (بالإنجليزية: Truth in Numbers: The Wikipedia Story)، سيتم إطلاقه في 2008.");
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"الفيلم", "الوثائقي", "الأول", "عن", "ويكيبيديا", "يسمى", "الحقيقة", "بالأرقام", "قصة", "ويكيبيديا",
+        new String[] { "الفيلم", "الوثائقي", "الأول", "عن", "ويكيبيديا", "يسمى", "الحقيقة", "بالأرقام", "قصة", "ويكيبيديا",
         "بالإنجليزية", "Truth", "in", "Numbers", "The", "Wikipedia", "Story", "سيتم", "إطلاقه", "في", "2008"  });
   }
   
   public void testChinese() throws Exception {
     Reader reader = new StringReader("我是中国人。 １２３４ Ｔｅｓｔｓ ");
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"我", "是", "中", "国", "人", "１２３４", "Ｔｅｓｔｓ"});
+        new String[] { "我", "是", "中", "国", "人", "１２３４", "Ｔｅｓｔｓ" });
   }
 
   public void testKorean() throws Exception {
     Reader reader = new StringReader("안녕하세요 한글입니다");
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"안녕하세요", "한글입니다"});
+        new String[] { "안녕하세요", "한글입니다" });
   }
     
   public void testHyphen() throws Exception {
     Reader reader = new StringReader("some-dashed-phrase");
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"some", "dashed", "phrase"});
+        new String[] { "some", "dashed", "phrase" });
   }
 
   // Test with some URLs from TestUAX29URLEmailTokenizer's 
@@ -105,11 +82,7 @@
         + " blah Sirrah woof "
         + "http://[a42:a7b6::]/qSmxSUU4z/%52qVl4\n";
     Reader reader = new StringReader(textWithURLs);
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { 
           "http://johno.jsmf.net/knowhow/ngrams/index.php?table=en-dickens-word-2gram&paragraphs=50&length=200&no-ads=on",
@@ -147,11 +120,7 @@
          + "lMahAA.j/5.RqUjS745.DtkcYdi@d2-4gb-l6.ae\n"
          + "lv'p@tqk.vj5s0tgl.0dlu7su3iyiaz.dqso.494.3hb76.XN--MGBAAM7A8H\n";
     Reader reader = new StringReader(textWithEmails);
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail").create(reader);
     assertTokenStreamContents(stream, 
         new String[] { 
           "some", "extra", "Words", "thrown", "in", "here",
@@ -180,13 +149,19 @@
     String longWord = builder.toString();
     String content = "one two three " + longWord + " four five six";
     Reader reader = new StringReader(content);
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("maxTokenLength", "1000");
-    UAX29URLEmailTokenizerFactory factory = new UAX29URLEmailTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("UAX29URLEmail",
+        "maxTokenLength", "1000").create(reader);
     assertTokenStreamContents(stream, 
         new String[] {"one", "two", "three", longWord, "four", "five", "six" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenizerFactory("UAX29URLEmail", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestStandardFactories.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestStandardFactories.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/standard/TestStandardFactories.java	(working copy)
@@ -19,36 +19,24 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
-import org.apache.lucene.analysis.core.KeywordTokenizerFactory;
-import org.apache.lucene.analysis.core.LetterTokenizerFactory;
-import org.apache.lucene.analysis.core.LowerCaseTokenizerFactory;
-import org.apache.lucene.analysis.core.WhitespaceTokenizerFactory;
-import org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilterFactory;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the standard lucene factories are working.
  */
-public class TestStandardFactories extends BaseTokenStreamTestCase {
+public class TestStandardFactories extends BaseTokenStreamFactoryTestCase {
   /**
    * Test StandardTokenizerFactory
    */
   public void testStandardTokenizer() throws Exception {
     Reader reader = new StringReader("Wha\u0301t's this thing do?");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("Standard").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"Wha\u0301t's", "this", "thing", "do" });
+        new String[] { "Wha\u0301t's", "this", "thing", "do" });
   }
   
   public void testStandardTokenizerMaxTokenLength() throws Exception {
@@ -59,14 +47,10 @@
     String longWord = builder.toString();
     String content = "one two three " + longWord + " four five six";
     Reader reader = new StringReader(content);
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("maxTokenLength", "1000");
-    StandardTokenizerFactory factory = new StandardTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    Tokenizer stream = tokenizerFactory("Standard",
+        "maxTokenLength", "1000").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"one", "two", "three", longWord, "four", "five", "six" });
+        new String[] { "one", "two", "three", longWord, "four", "five", "six" });
   }
   
   /**
@@ -74,13 +58,9 @@
    */
   public void testClassicTokenizer() throws Exception {
     Reader reader = new StringReader("What's this thing do?");
-    ClassicTokenizerFactory factory = new ClassicTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("Classic").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"What's", "this", "thing", "do" });
+        new String[] { "What's", "this", "thing", "do" });
   }
   
   public void testClassicTokenizerMaxTokenLength() throws Exception {
@@ -91,14 +71,10 @@
     String longWord = builder.toString();
     String content = "one two three " + longWord + " four five six";
     Reader reader = new StringReader(content);
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("maxTokenLength", "1000");
-    ClassicTokenizerFactory factory = new ClassicTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    Tokenizer stream = tokenizerFactory("Classic",
+        "maxTokenLength", "1000").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"one", "two", "three", longWord, "four", "five", "six" });
+        new String[] { "one", "two", "three", longWord, "four", "five", "six" });
   }
   
   /**
@@ -106,17 +82,10 @@
    */
   public void testStandardFilter() throws Exception {
     Reader reader = new StringReader("What's this thing do?");
-    ClassicTokenizerFactory factory = new ClassicTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    ClassicFilterFactory filterFactory = new ClassicFilterFactory();
-    filterFactory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    filterFactory.init(args);
-    Tokenizer tokenizer = factory.create(reader);
-    TokenStream stream = filterFactory.create(tokenizer);
+    TokenStream stream = tokenizerFactory("Classic").create(reader);
+    stream = tokenFilterFactory("Classic").create(stream);
     assertTokenStreamContents(stream, 
-        new String[] {"What", "this", "thing", "do"});
+        new String[] { "What", "this", "thing", "do" });
   }
   
   /**
@@ -124,13 +93,9 @@
    */
   public void testKeywordTokenizer() throws Exception {
     Reader reader = new StringReader("What's this thing do?");
-    KeywordTokenizerFactory factory = new KeywordTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("Keyword").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"What's this thing do?"});
+        new String[] { "What's this thing do?" });
   }
   
   /**
@@ -138,13 +103,9 @@
    */
   public void testWhitespaceTokenizer() throws Exception {
     Reader reader = new StringReader("What's this thing do?");
-    WhitespaceTokenizerFactory factory = new WhitespaceTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("Whitespace").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"What's", "this", "thing", "do?"});
+        new String[] { "What's", "this", "thing", "do?" });
   }
   
   /**
@@ -152,13 +113,9 @@
    */
   public void testLetterTokenizer() throws Exception {
     Reader reader = new StringReader("What's this thing do?");
-    LetterTokenizerFactory factory = new LetterTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("Letter").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"What", "s", "this", "thing", "do"});
+        new String[] { "What", "s", "this", "thing", "do" });
   }
   
   /**
@@ -166,13 +123,9 @@
    */
   public void testLowerCaseTokenizer() throws Exception {
     Reader reader = new StringReader("What's this thing do?");
-    LowerCaseTokenizerFactory factory = new LowerCaseTokenizerFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    Tokenizer stream = factory.create(reader);
+    TokenStream stream = tokenizerFactory("LowerCase").create(reader);
     assertTokenStreamContents(stream, 
-        new String[] {"what", "s", "this", "thing", "do"});
+        new String[] { "what", "s", "this", "thing", "do" });
   }
   
   /**
@@ -180,12 +133,67 @@
    */
   public void testASCIIFolding() throws Exception {
     Reader reader = new StringReader("Česká");
-    Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    ASCIIFoldingFilterFactory factory = new ASCIIFoldingFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("ASCIIFolding").create(stream);
     assertTokenStreamContents(stream, new String[] { "Ceska" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenizerFactory("Standard", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenizerFactory("Classic", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenizerFactory("Whitespace", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenizerFactory("Letter", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenizerFactory("LowerCase", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("ASCIIFolding", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("Standard", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+    
+    try {
+      tokenFilterFactory("Classic", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/br/TestBrazilianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/br/TestBrazilianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/br/TestBrazilianStemFilterFactory.java	(working copy)
@@ -20,23 +20,32 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.Tokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Brazilian stem filter factory is working.
  */
-public class TestBrazilianStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestBrazilianStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Ensure the filter actually stems and normalizes text.
    */
   public void testStemming() throws Exception {
     Reader reader = new StringReader("Brasília");
     Tokenizer tokenizer = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
-    BrazilianStemFilterFactory factory = new BrazilianStemFilterFactory();
-    TokenStream stream = factory.create(tokenizer);
+    TokenStream stream = tokenFilterFactory("BrazilianStem").create(tokenizer);
     assertTokenStreamContents(stream, new String[] { "brasil" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("BrazilianStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/fr/TestFrenchMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/fr/TestFrenchMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/fr/TestFrenchMinimalStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the French minimal stem factory is working.
  */
-public class TestFrenchMinimalStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestFrenchMinimalStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("chevaux");
-    FrenchMinimalStemFilterFactory factory = new FrenchMinimalStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("FrenchMinimalStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "cheval" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("FrenchMinimalStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/fr/TestFrenchLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/fr/TestFrenchLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/fr/TestFrenchLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the French light stem factory is working.
  */
-public class TestFrenchLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestFrenchLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("administrativement");
-    FrenchLightStemFilterFactory factory = new FrenchLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("FrenchLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "administratif" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("FrenchLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/payloads/TestDelimitedPayloadTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/payloads/TestDelimitedPayloadTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/payloads/TestDelimitedPayloadTokenFilterFactory.java	(working copy)
@@ -17,64 +17,64 @@
  * limitations under the License.
  */
 
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.payloads.DelimitedPayloadTokenFilter;
-import org.apache.lucene.analysis.payloads.FloatEncoder;
 import org.apache.lucene.analysis.payloads.PayloadHelper;
 import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
-import org.apache.lucene.analysis.util.ResourceLoader;
-import org.apache.lucene.analysis.util.StringMockResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
-public class TestDelimitedPayloadTokenFilterFactory extends BaseTokenStreamTestCase {
+public class TestDelimitedPayloadTokenFilterFactory extends BaseTokenStreamFactoryTestCase {
 
   public void testEncoder() throws Exception {
-    Map<String,String> args = new HashMap<String, String>();
-    args.put(DelimitedPayloadTokenFilterFactory.ENCODER_ATTR, "float");
-    DelimitedPayloadTokenFilterFactory factory = new DelimitedPayloadTokenFilterFactory();
-    factory.init(args);
-    ResourceLoader loader = new StringMockResourceLoader("solr/collection1");
-    factory.inform(loader);
+    Reader reader = new StringReader("the|0.1 quick|0.1 red|0.1");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("DelimitedPayload", "encoder", "float").create(stream);
 
-    TokenStream input = new MockTokenizer(new StringReader("the|0.1 quick|0.1 red|0.1"), MockTokenizer.WHITESPACE, false);
-    DelimitedPayloadTokenFilter tf = factory.create(input);
-    tf.reset();
-    while (tf.incrementToken()){
-      PayloadAttribute payAttr = tf.getAttribute(PayloadAttribute.class);
-      assertTrue("payAttr is null and it shouldn't be", payAttr != null);
+    stream.reset();
+    while (stream.incrementToken()) {
+      PayloadAttribute payAttr = stream.getAttribute(PayloadAttribute.class);
+      assertNotNull(payAttr);
       byte[] payData = payAttr.getPayload().bytes;
-      assertTrue("payData is null and it shouldn't be", payData != null);
-      assertTrue("payData is null and it shouldn't be", payData != null);
+      assertNotNull(payData);
       float payFloat = PayloadHelper.decodeFloat(payData);
-      assertTrue(payFloat + " does not equal: " + 0.1f, payFloat == 0.1f);
+      assertEquals(0.1f, payFloat, 0.0f);
     }
+    stream.end();
+    stream.close();
   }
 
   public void testDelim() throws Exception {
-    Map<String,String> args = new HashMap<String, String>();
-    args.put(DelimitedPayloadTokenFilterFactory.ENCODER_ATTR, FloatEncoder.class.getName());
-    args.put(DelimitedPayloadTokenFilterFactory.DELIMITER_ATTR, "*");
-    DelimitedPayloadTokenFilterFactory factory = new DelimitedPayloadTokenFilterFactory();
-    factory.init(args);
-    ResourceLoader loader = new StringMockResourceLoader("solr/collection1");
-    factory.inform(loader);
-
-    TokenStream input = new MockTokenizer(new StringReader("the*0.1 quick*0.1 red*0.1"), MockTokenizer.WHITESPACE, false);
-    DelimitedPayloadTokenFilter tf = factory.create(input);
-    tf.reset();
-    while (tf.incrementToken()){
-      PayloadAttribute payAttr = tf.getAttribute(PayloadAttribute.class);
-      assertTrue("payAttr is null and it shouldn't be", payAttr != null);
+    Reader reader = new StringReader("the*0.1 quick*0.1 red*0.1");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("DelimitedPayload",
+        "encoder", "float",
+        "delimiter", "*").create(stream);
+    stream.reset();
+    while (stream.incrementToken()) {
+      PayloadAttribute payAttr = stream.getAttribute(PayloadAttribute.class);
+      assertNotNull(payAttr);
       byte[] payData = payAttr.getPayload().bytes;
-      assertTrue("payData is null and it shouldn't be", payData != null);
+      assertNotNull(payData);
       float payFloat = PayloadHelper.decodeFloat(payData);
-      assertTrue(payFloat + " does not equal: " + 0.1f, payFloat == 0.1f);
+      assertEquals(0.1f, payFloat, 0.0f);
     }
+    stream.end();
+    stream.close();
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("DelimitedPayload", 
+          "encoder", "float",
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
 
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/no/TestNorwegianMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/no/TestNorwegianMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/no/TestNorwegianMinimalStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Norwegian Minimal stem factory is working.
  */
-public class TestNorwegianMinimalStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestNorwegianMinimalStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("eple eplet epler eplene eplets eplenes");
-    NorwegianMinimalStemFilterFactory factory = new NorwegianMinimalStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("NorwegianMinimalStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "epl", "epl", "epl", "epl", "epl", "epl" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("NorwegianMinimalStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/no/TestNorwegianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/no/TestNorwegianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/no/TestNorwegianLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Norwegian Light stem factory is working.
  */
-public class TestNorwegianLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestNorwegianLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("epler eple");
-    NorwegianLightStemFilterFactory factory = new NorwegianLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("NorwegianLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "epl", "epl" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("NorwegianLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternTokenizerFactory.java	(working copy)
@@ -17,25 +17,31 @@
  * limitations under the License.
  */
 
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /** Simple Tests to ensure this factory is working */
-public class TestPatternTokenizerFactory extends BaseTokenStreamTestCase {
+public class TestPatternTokenizerFactory extends BaseTokenStreamFactoryTestCase {
   public void testFactory() throws Exception {
-    final String INPUT = "Günther Günther is here";
-
+    final Reader reader = new StringReader("Günther Günther is here");
     // create PatternTokenizer
-    Map<String,String> args = new HashMap<String, String>();
-    args.put( PatternTokenizerFactory.PATTERN, "[,;/\\s]+" );
-    PatternTokenizerFactory tokFactory = new PatternTokenizerFactory();
-    tokFactory.init( args );
-    TokenStream stream = tokFactory.create( new StringReader(INPUT) );
+    TokenStream stream = tokenizerFactory("Pattern", "pattern", "[,;/\\s]+").create(reader);
     assertTokenStreamContents(stream,
         new String[] { "Günther", "Günther", "is", "here" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenizerFactory("Pattern",
+          "pattern", "something",
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceCharFilterFactory.java	(working copy)
@@ -17,31 +17,27 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.*;
+import org.apache.lucene.analysis.MockTokenizer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure this factory is working
  */
-public class TestPatternReplaceCharFilterFactory extends BaseTokenStreamTestCase {
+public class TestPatternReplaceCharFilterFactory extends BaseTokenStreamFactoryTestCase {
   
   //           1111
   // 01234567890123
   // this is test.
-  public void testNothingChange() throws IOException {
-    final String BLOCK = "this is test.";
-    PatternReplaceCharFilterFactory factory = new PatternReplaceCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("pattern", "(aa)\\s+(bb)\\s+(cc)");
-    args.put("replacement", "$1$2$3");
-    factory.init(args);
-    CharFilter cs = factory.create(
-          new StringReader( BLOCK ) );
-    TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
+  public void testNothingChange() throws Exception {
+    Reader reader = new StringReader("this is test.");
+    reader = charFilterFactory("PatternReplace",
+        "pattern", "(aa)\\s+(bb)\\s+(cc)",
+        "replacement", "$1$2$3").create(reader);
+    TokenStream ts = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "this", "is", "test." },
         new int[] { 0, 5, 8 },
@@ -50,37 +46,38 @@
   
   // 012345678
   // aa bb cc
-  public void testReplaceByEmpty() throws IOException {
-    final String BLOCK = "aa bb cc";
-    PatternReplaceCharFilterFactory factory = new PatternReplaceCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("pattern", "(aa)\\s+(bb)\\s+(cc)");
-    factory.init(args);
-    CharFilter cs = factory.create(
-          new StringReader( BLOCK ) );
-    TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
-    ts.reset();
-    assertFalse(ts.incrementToken());
-    ts.end();
-    ts.close();
+  public void testReplaceByEmpty() throws Exception {
+    Reader reader = new StringReader("aa bb cc");
+    reader = charFilterFactory("PatternReplace",
+        "pattern", "(aa)\\s+(bb)\\s+(cc)").create(reader);
+    TokenStream ts = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    assertTokenStreamContents(ts, new String[] {});
   }
   
   // 012345678
   // aa bb cc
   // aa#bb#cc
-  public void test1block1matchSameLength() throws IOException {
-    final String BLOCK = "aa bb cc";
-    PatternReplaceCharFilterFactory factory = new PatternReplaceCharFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("pattern", "(aa)\\s+(bb)\\s+(cc)");
-    args.put("replacement", "$1#$2#$3");
-    factory.init(args);
-    CharFilter cs = factory.create(
-          new StringReader( BLOCK ) );
-    TokenStream ts = new MockTokenizer(cs, MockTokenizer.WHITESPACE, false);
+  public void test1block1matchSameLength() throws Exception {
+    Reader reader = new StringReader("aa bb cc");
+    reader = charFilterFactory("PatternReplace",
+        "pattern", "(aa)\\s+(bb)\\s+(cc)",
+        "replacement", "$1#$2#$3").create(reader);
+    TokenStream ts = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
     assertTokenStreamContents(ts,
         new String[] { "aa#bb#cc" },
         new int[] { 0 },
         new int[] { 8 });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      charFilterFactory("PatternReplace",
+          "pattern", "something",
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/pattern/TestPatternReplaceFilterFactory.java	(working copy)
@@ -17,30 +17,38 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
+import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
 /**
  * Simple tests to ensure this factory is working
  */
-public class TestPatternReplaceFilterFactory extends BaseTokenStreamTestCase {
+public class TestPatternReplaceFilterFactory extends BaseTokenStreamFactoryTestCase {
 
   public void testReplaceAll() throws Exception {
-    String input = "aabfooaabfooabfoob ab caaaaaaaaab";
-    PatternReplaceFilterFactory factory = new PatternReplaceFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("pattern", "a*b");
-    args.put("replacement", "-");
-    factory.init(args);
-    TokenStream ts = factory.create
-            (new MockTokenizer(new StringReader(input), MockTokenizer.WHITESPACE, false));
+    Reader reader = new StringReader("aabfooaabfooabfoob ab caaaaaaaaab");
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("PatternReplace",
+        "pattern", "a*b",
+        "replacement", "-").create(stream);
                    
-    assertTokenStreamContents(ts, 
+    assertTokenStreamContents(stream, 
         new String[] { "-foo-foo-foo-", "-", "c-" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("PatternReplace",
+          "pattern", "something",
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/ru/TestRussianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/ru/TestRussianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/ru/TestRussianLightStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Russian light stem factory is working.
  */
-public class TestRussianLightStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestRussianLightStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("журналы");
-    RussianLightStemFilterFactory factory = new RussianLightStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("RussianLightStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "журнал" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("RussianLightStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/ga/TestIrishLowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/ga/TestIrishLowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/ga/TestIrishLowerCaseFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Irish lowercase filter factory is working.
  */
-public class TestIrishLowerCaseFilterFactory extends BaseTokenStreamTestCase {
+public class TestIrishLowerCaseFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testCasing() throws Exception {
     Reader reader = new StringReader("nAthair tUISCE hARD");
-    IrishLowerCaseFilterFactory factory = new IrishLowerCaseFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("IrishLowerCase").create(stream);
     assertTokenStreamContents(stream, new String[] { "n-athair", "t-uisce", "hard" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("IrishLowerCase", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/TestShingleFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/TestShingleFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/shingle/TestShingleFilterFactory.java	(working copy)
@@ -19,28 +19,25 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Shingle filter factory works.
  */
-public class TestShingleFilterFactory extends BaseTokenStreamTestCase {
+public class TestShingleFilterFactory extends BaseTokenStreamFactoryTestCase {
   /**
    * Test the defaults
    */
   public void testDefaults() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
-    assertTokenStreamContents(stream, new String[] {"this", "this is", "is",
-        "is a", "a", "a test", "test"});
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle").create(stream);
+    assertTokenStreamContents(stream, 
+        new String[] { "this", "this is", "is", "is a", "a", "a test", "test" }
+    );
   }
   
   /**
@@ -48,11 +45,9 @@
    */
   public void testNoUnigrams() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("outputUnigrams", "false");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "outputUnigrams", "false").create(stream);
     assertTokenStreamContents(stream,
         new String[] {"this is", "is a", "a test"});
   }
@@ -62,14 +57,13 @@
    */
   public void testMaxShingleSize() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("maxShingleSize", "3");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "maxShingleSize", "3").create(stream);
     assertTokenStreamContents(stream, 
-        new String[] {"this", "this is", "this is a", "is",
-        "is a", "is a test", "a", "a test", "test"});
+        new String[] { "this", "this is", "this is a", "is", 
+                       "is a", "is a test", "a", "a test", "test" }
+    );
   }
 
   /**
@@ -77,15 +71,14 @@
    */
   public void testMinShingleSize() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minShingleSize", "3");
-    args.put("maxShingleSize", "4");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "3",
+        "maxShingleSize", "4").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this", "this is a", "this is a test",
-        "is", "is a test", "a", "test" });
+                       "is", "is a test", "a", "test" }
+    );
   }
 
   /**
@@ -93,13 +86,11 @@
    */
   public void testMinShingleSizeNoUnigrams() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minShingleSize", "3");
-    args.put("maxShingleSize", "4");
-    args.put("outputUnigrams", "false");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "3",
+        "maxShingleSize", "4",
+        "outputUnigrams", "false").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this is a", "this is a test", "is a test" });
   }
@@ -109,12 +100,10 @@
    */
   public void testEqualMinAndMaxShingleSize() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minShingleSize", "3");
-    args.put("maxShingleSize", "3");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "3",
+        "maxShingleSize", "3").create(stream);
     assertTokenStreamContents(stream, 
          new String[] { "this", "this is a", "is", "is a test", "a", "test" });
   }
@@ -124,13 +113,11 @@
    */
   public void testEqualMinAndMaxShingleSizeNoUnigrams() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minShingleSize", "3");
-    args.put("maxShingleSize", "3");
-    args.put("outputUnigrams", "false");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "3",
+        "maxShingleSize", "3",
+        "outputUnigrams", "false").create(stream);
     assertTokenStreamContents(stream,
         new String[] { "this is a", "is a test" });
   }
@@ -140,14 +127,13 @@
    */
   public void testTokenSeparator() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("tokenSeparator", "=BLAH=");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "tokenSeparator", "=BLAH=").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this", "this=BLAH=is", "is", "is=BLAH=a", 
-        "a", "a=BLAH=test", "test" });
+                       "a", "a=BLAH=test", "test" }
+    );
   }
 
   /**
@@ -155,12 +141,10 @@
    */
   public void testTokenSeparatorNoUnigrams() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("tokenSeparator", "=BLAH=");
-    args.put("outputUnigrams", "false");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "tokenSeparator", "=BLAH=",
+        "outputUnigrams", "false").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this=BLAH=is", "is=BLAH=a", "a=BLAH=test" });
   }
@@ -170,11 +154,9 @@
    */
   public void testEmptyTokenSeparator() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("tokenSeparator", "");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "tokenSeparator", "").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this", "thisis", "is", "isa", "a", "atest", "test" });
   }
@@ -185,17 +167,16 @@
    */
   public void testMinShingleSizeAndTokenSeparator() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minShingleSize", "3");
-    args.put("maxShingleSize", "4");
-    args.put("tokenSeparator", "=BLAH=");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "3",
+        "maxShingleSize", "4",
+        "tokenSeparator", "=BLAH=").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this", "this=BLAH=is=BLAH=a", 
-        "this=BLAH=is=BLAH=a=BLAH=test", "is", 
-        "is=BLAH=a=BLAH=test", "a", "test" });
+                       "this=BLAH=is=BLAH=a=BLAH=test", "is", 
+                       "is=BLAH=a=BLAH=test", "a", "test" }
+    );
   }
 
   /**
@@ -205,17 +186,16 @@
    */
   public void testMinShingleSizeAndTokenSeparatorNoUnigrams() throws Exception {
     Reader reader = new StringReader("this is a test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("minShingleSize", "3");
-    args.put("maxShingleSize", "4");
-    args.put("tokenSeparator", "=BLAH=");
-    args.put("outputUnigrams", "false");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "minShingleSize", "3",
+        "maxShingleSize", "4",
+        "tokenSeparator", "=BLAH=",
+        "outputUnigrams", "false").create(stream);
     assertTokenStreamContents(stream, 
         new String[] { "this=BLAH=is=BLAH=a", "this=BLAH=is=BLAH=a=BLAH=test", 
-        "is=BLAH=a=BLAH=test", });
+                       "is=BLAH=a=BLAH=test", }
+    );
   }
 
   /**
@@ -228,12 +208,20 @@
    */
   public void testOutputUnigramsIfNoShingles() throws Exception {
     Reader reader = new StringReader("test");
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("outputUnigrams", "false");
-    args.put("outputUnigramsIfNoShingles", "true");
-    ShingleFilterFactory factory = new ShingleFilterFactory();
-    factory.init(args);
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("Shingle",
+        "outputUnigrams", "false",
+        "outputUnigramsIfNoShingles", "true").create(stream);
     assertTokenStreamContents(stream, new String[] { "test" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("Shingle", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/hunspell/TestHunspellStemFilterFactory.java	(working copy)
@@ -19,29 +19,33 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.util.ClasspathResourceLoader;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Hunspell stemmer loads from factory
  */
-public class TestHunspellStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestHunspellStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
-    HunspellStemFilterFactory factory = new HunspellStemFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("dictionary", "test.dic");
-    args.put("affix", "test.aff");
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    factory.init(args);
-    factory.inform(new ClasspathResourceLoader(getClass()));
-    
     Reader reader = new StringReader("abc");
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("HunspellStem",
+        "dictionary", "test.dic",
+        "affix", "test.aff").create(stream);
     assertTokenStreamContents(stream, new String[] { "ab" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("HunspellStem",
+          "dictionary", "test.dic",
+          "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Galician stem factory is working.
  */
-public class TestGalicianStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestGalicianStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("cariñosa");
-    GalicianStemFilterFactory factory = new GalicianStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GalicianStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "cariñ" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GalicianStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/gl/TestGalicianMinimalStemFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the Galician plural stem factory is working.
  */
-public class TestGalicianMinimalStemFilterFactory extends BaseTokenStreamTestCase {
+public class TestGalicianMinimalStemFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testStemming() throws Exception {
     Reader reader = new StringReader("elefantes");
-    GalicianMinimalStemFilterFactory factory = new GalicianMinimalStemFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("GalicianMinimalStem").create(stream);
     assertTokenStreamContents(stream, new String[] { "elefante" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("GalicianMinimalStem", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/cjk/TestCJKWidthFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/cjk/TestCJKWidthFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/cjk/TestCJKWidthFilterFactory.java	(working copy)
@@ -20,18 +20,28 @@
 import java.io.Reader;
 import java.io.StringReader;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.MockTokenizer;
 import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the CJKWidthFilterFactory is working
  */
-public class TestCJKWidthFilterFactory extends BaseTokenStreamTestCase {
+public class TestCJKWidthFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void test() throws Exception {
     Reader reader = new StringReader("Ｔｅｓｔ １２３４");
-    CJKWidthFilterFactory factory = new CJKWidthFilterFactory();
-    TokenStream stream = factory.create(new MockTokenizer(reader, MockTokenizer.WHITESPACE, false));
+    TokenStream stream = new MockTokenizer(reader, MockTokenizer.WHITESPACE, false);
+    stream = tokenFilterFactory("CJKWidth").create(stream);
     assertTokenStreamContents(stream, new String[] { "Test", "1234" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("CJKWidth", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/test/org/apache/lucene/analysis/cjk/TestCJKBigramFilterFactory.java
===================================================================
--- lucene/analysis/common/src/test/org/apache/lucene/analysis/cjk/TestCJKBigramFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/test/org/apache/lucene/analysis/cjk/TestCJKBigramFilterFactory.java	(working copy)
@@ -19,49 +19,48 @@
 
 import java.io.Reader;
 import java.io.StringReader;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
 
-import org.apache.lucene.analysis.BaseTokenStreamTestCase;
 import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.standard.StandardTokenizer;
+import org.apache.lucene.analysis.util.BaseTokenStreamFactoryTestCase;
 
 /**
  * Simple tests to ensure the CJK bigram factory is working.
  */
-public class TestCJKBigramFilterFactory extends BaseTokenStreamTestCase {
+public class TestCJKBigramFilterFactory extends BaseTokenStreamFactoryTestCase {
   public void testDefaults() throws Exception {
     Reader reader = new StringReader("多くの学生が試験に落ちた。");
-    CJKBigramFilterFactory factory = new CJKBigramFilterFactory();
-    factory.setLuceneMatchVersion(TEST_VERSION_CURRENT);
-    Map<String, String> args = Collections.emptyMap();
-    factory.init(args);
-    TokenStream stream = factory.create(new StandardTokenizer(TEST_VERSION_CURRENT, reader));
+    TokenStream stream = tokenizerFactory("standard").create(reader);
+    stream = tokenFilterFactory("CJKBigram").create(stream);
     assertTokenStreamContents(stream,
         new String[] { "多く", "くの", "の学", "学生", "生が", "が試", "試験", "験に", "に落", "落ち", "ちた" });
   }
   
   public void testHanOnly() throws Exception {
     Reader reader = new StringReader("多くの学生が試験に落ちた。");
-    CJKBigramFilterFactory factory = new CJKBigramFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("hiragana", "false");
-    factory.init(args);
-    TokenStream stream = factory.create(new StandardTokenizer(TEST_VERSION_CURRENT, reader));
+    TokenStream stream = tokenizerFactory("standard").create(reader);
+    stream = tokenFilterFactory("CJKBigram", 
+        "hiragana", "false").create(stream);
     assertTokenStreamContents(stream,
         new String[] { "多", "く", "の",  "学生", "が",  "試験", "に",  "落", "ち", "た" });
   }
   
   public void testHanOnlyUnigrams() throws Exception {
     Reader reader = new StringReader("多くの学生が試験に落ちた。");
-    CJKBigramFilterFactory factory = new CJKBigramFilterFactory();
-    Map<String,String> args = new HashMap<String,String>();
-    args.put("hiragana", "false");
-    args.put("outputUnigrams", "true");
-    factory.init(args);
-    TokenStream stream = factory.create(new StandardTokenizer(TEST_VERSION_CURRENT, reader));
+    TokenStream stream = tokenizerFactory("standard").create(reader);
+    stream = tokenFilterFactory("CJKBigram", 
+        "hiragana", "false", 
+        "outputUnigrams", "true").create(stream);
     assertTokenStreamContents(stream,
         new String[] { "多", "く", "の",  "学", "学生", "生", "が",  "試", "試験", "験", "に",  "落", "ち", "た" });
   }
+  
+  /** Test that bogus arguments result in exception */
+  public void testBogusArguments() throws Exception {
+    try {
+      tokenFilterFactory("CJKBigram", "bogusArg", "bogusValue");
+      fail();
+    } catch (IllegalArgumentException expected) {
+      assertTrue(expected.getMessage().contains("Unknown parameters"));
+    }
+  }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/fi/FinnishLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/fi/FinnishLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/fi/FinnishLightStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.fi.FinnishLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link FinnishLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_filgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.FinnishLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class FinnishLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new FinnishLightStemFilterFactory */
+  public FinnishLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new FinnishLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/UAX29URLEmailTokenizerFactory.java	(working copy)
@@ -25,26 +25,25 @@
 
 /**
  * Factory for {@link UAX29URLEmailTokenizer}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_urlemail" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.UAX29URLEmailTokenizerFactory" maxTokenLength="255"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre> 
- *
- * 
  */
-
 public class UAX29URLEmailTokenizerFactory extends TokenizerFactory {
+  private final int maxTokenLength;
 
-  private int maxTokenLength;
-
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  /** Creates a new UAX29URLEmailTokenizerFactory */
+  public UAX29URLEmailTokenizerFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
-    maxTokenLength = getInt("maxTokenLength",
+    maxTokenLength = getInt(args, "maxTokenLength",
                             StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardFilterFactory.java	(working copy)
@@ -25,20 +25,23 @@
 
 /**
  * Factory for {@link StandardFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_stndrd" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.StandardFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class StandardFilterFactory extends TokenFilterFactory {
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  
+  /** Creates a new StandardFilterFactory */
+  public StandardFilterFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicTokenizerFactory.java	(working copy)
@@ -25,26 +25,25 @@
 
 /**
  * Factory for {@link ClassicTokenizer}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_clssc" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.ClassicTokenizerFactory" maxTokenLength="120"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
- *
  */
-
 public class ClassicTokenizerFactory extends TokenizerFactory {
+  private final int maxTokenLength;
 
-  private int maxTokenLength;
-
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  /** Creates a new ClassicTokenizerFactory */
+  public ClassicTokenizerFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
-    maxTokenLength = getInt("maxTokenLength", 
+    maxTokenLength = getInt(args, "maxTokenLength", 
                             StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/ClassicFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
@@ -24,17 +26,24 @@
 
 /**
  * Factory for {@link ClassicFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_clssc" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.ClassicTokenizerFactory"/&gt;
  *     &lt;filter class="solr.ClassicFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
- *
  */
 public class ClassicFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new ClassicFilterFactory */
+  public ClassicFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenFilter create(TokenStream input) {
     return new ClassicFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/standard/StandardTokenizerFactory.java	(working copy)
@@ -25,24 +25,24 @@
 
 /**
  * Factory for {@link StandardTokenizer}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_stndrd" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory" maxTokenLength="255"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre> 
- *
  */
-
 public class StandardTokenizerFactory extends TokenizerFactory {
+  private final int maxTokenLength;
   
-  private int maxTokenLength;
-  
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  /** Creates a new StandardTokenizerFactory */
+  public StandardTokenizerFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
-    maxTokenLength = getInt("maxTokenLength", StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
+    maxTokenLength = getInt(args, "maxTokenLength", StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/RemoveDuplicatesTokenFilterFactory.java	(working copy)
@@ -17,22 +17,32 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.miscellaneous.RemoveDuplicatesTokenFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link RemoveDuplicatesTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_rmdup" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.RemoveDuplicatesTokenFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class RemoveDuplicatesTokenFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new RemoveDuplicatesTokenFilterFactory */
+  public RemoveDuplicatesTokenFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public RemoveDuplicatesTokenFilter create(TokenStream input) {
     return new RemoveDuplicatesTokenFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeywordMarkerFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeywordMarkerFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeywordMarkerFilterFactory.java	(working copy)
@@ -18,6 +18,7 @@
  */
 
 import java.io.IOException;
+import java.util.Map;
 import java.util.regex.Pattern;
 
 import org.apache.lucene.analysis.miscellaneous.KeywordMarkerFilter;
@@ -26,34 +27,42 @@
 
 /**
  * Factory for {@link KeywordMarkerFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_keyword" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.KeywordMarkerFilterFactory" protected="protectedkeyword.txt" pattern="^.+er$" ignoreCase="false"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class KeywordMarkerFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   public static final String PROTECTED_TOKENS = "protected";
   public static final String PATTERN = "pattern";
+  private final String wordFiles;
+  private final String stringPattern;
+  private final boolean ignoreCase;
+  private Pattern pattern;
   private CharArraySet protectedWords;
-  private boolean ignoreCase;
-  private Pattern pattern;
   
+  /** Creates a new KeywordMarkerFilterFactory */
+  public KeywordMarkerFilterFactory(Map<String,String> args) {
+    super(args);
+    wordFiles = args.remove(PROTECTED_TOKENS);
+    stringPattern = args.remove(PATTERN);
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String wordFiles = args.get(PROTECTED_TOKENS);
-    String stringPattern = args.get(PATTERN);
-    ignoreCase = getBoolean("ignoreCase", false);
     if (wordFiles != null) {  
       protectedWords = getWordSet(loader, wordFiles, ignoreCase);
     }
     if (stringPattern != null) {
       pattern = ignoreCase ? Pattern.compile(stringPattern, Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE) : Pattern.compile(stringPattern);
     }
-    
   }
   
   public boolean isIgnoreCase() {
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/ASCIIFoldingFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/ASCIIFoldingFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/ASCIIFoldingFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
 import org.apache.lucene.analysis.util.MultiTermAwareComponent;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
@@ -25,16 +27,24 @@
 
 /** 
  * Factory for {@link ASCIIFoldingFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ascii" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.ASCIIFoldingFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ASCIIFoldingFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
+  
+  /** Creates a new ASCIIFoldingFilterFactory */
+  public ASCIIFoldingFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public ASCIIFoldingFilter create(TokenStream input) {
     return new ASCIIFoldingFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/HyphenatedWordsFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/HyphenatedWordsFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/HyphenatedWordsFilterFactory.java	(working copy)
@@ -17,22 +17,32 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.miscellaneous.HyphenatedWordsFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link HyphenatedWordsFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_hyphn" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.HyphenatedWordsFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class HyphenatedWordsFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new HyphenatedWordsFilterFactory */
+  public HyphenatedWordsFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public HyphenatedWordsFilter create(TokenStream input) {
     return new HyphenatedWordsFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/WordDelimiterFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/WordDelimiterFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/WordDelimiterFilterFactory.java	(working copy)
@@ -33,10 +33,9 @@
 
 import static org.apache.lucene.analysis.miscellaneous.WordDelimiterFilter.*;
 
-
 /**
  * Factory for {@link WordDelimiterFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_wd" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -46,66 +45,72 @@
  *             generateWordParts="1" generateNumberParts="1" stemEnglishPossessive="1"
  *             types="wdfftypes.txt" /&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class WordDelimiterFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   public static final String PROTECTED_TOKENS = "protected";
   public static final String TYPES = "types";
-  
-  @Override
-  public void inform(ResourceLoader loader) throws IOException {
-    String wordFiles = args.get(PROTECTED_TOKENS);
-    if (wordFiles != null) {  
-      protectedWords = getWordSet(loader, wordFiles, false);
-    }
-    String types = args.get(TYPES);
-    if (types != null) {
-      List<String> files = splitFileNames( types );
-      List<String> wlist = new ArrayList<String>();
-      for( String file : files ){
-        List<String> lines = getLines(loader, file.trim());
-        wlist.addAll( lines );
-      }
-      typeTable = parseTypes(wlist);
-    }
-  }
 
+  private final String wordFiles;
+  private final String types;
+  private final int flags;
+  byte[] typeTable = null;
   private CharArraySet protectedWords = null;
-  private int flags;
-  byte[] typeTable = null;
-
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    if (getInt("generateWordParts", 1) != 0) {
+  
+  /** Creates a new WordDelimiterFilterFactory */
+  public WordDelimiterFilterFactory(Map<String, String> args) {
+    super(args);
+    int flags = 0;
+    if (getInt(args, "generateWordParts", 1) != 0) {
       flags |= GENERATE_WORD_PARTS;
     }
-    if (getInt("generateNumberParts", 1) != 0) {
+    if (getInt(args, "generateNumberParts", 1) != 0) {
       flags |= GENERATE_NUMBER_PARTS;
     }
-    if (getInt("catenateWords", 0) != 0) {
+    if (getInt(args, "catenateWords", 0) != 0) {
       flags |= CATENATE_WORDS;
     }
-    if (getInt("catenateNumbers", 0) != 0) {
+    if (getInt(args, "catenateNumbers", 0) != 0) {
       flags |= CATENATE_NUMBERS;
     }
-    if (getInt("catenateAll", 0) != 0) {
+    if (getInt(args, "catenateAll", 0) != 0) {
       flags |= CATENATE_ALL;
     }
-    if (getInt("splitOnCaseChange", 1) != 0) {
+    if (getInt(args, "splitOnCaseChange", 1) != 0) {
       flags |= SPLIT_ON_CASE_CHANGE;
     }
-    if (getInt("splitOnNumerics", 1) != 0) {
+    if (getInt(args, "splitOnNumerics", 1) != 0) {
       flags |= SPLIT_ON_NUMERICS;
     }
-    if (getInt("preserveOriginal", 0) != 0) {
+    if (getInt(args, "preserveOriginal", 0) != 0) {
       flags |= PRESERVE_ORIGINAL;
     }
-    if (getInt("stemEnglishPossessive", 1) != 0) {
+    if (getInt(args, "stemEnglishPossessive", 1) != 0) {
       flags |= STEM_ENGLISH_POSSESSIVE;
     }
+    wordFiles = args.remove(PROTECTED_TOKENS);
+    types = args.remove(TYPES);
+    this.flags = flags;
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
+  
+  @Override
+  public void inform(ResourceLoader loader) throws IOException {
+    if (wordFiles != null) {  
+      protectedWords = getWordSet(loader, wordFiles, false);
+    }
+    if (types != null) {
+      List<String> files = splitFileNames( types );
+      List<String> wlist = new ArrayList<String>();
+      for( String file : files ){
+        List<String> lines = getLines(loader, file.trim());
+        wlist.addAll( lines );
+      }
+      typeTable = parseTypes(wlist);
+    }
+  }
 
   @Override
   public WordDelimiterFilter create(TokenStream input) {
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeepWordFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeepWordFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeepWordFilterFactory.java	(working copy)
@@ -17,63 +17,51 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.analysis.util.*;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.miscellaneous.KeepWordFilter;
+import org.apache.lucene.analysis.util.CharArraySet;
+import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.ResourceLoaderAware;
+import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 import java.util.Map;
-import java.util.Set;
 import java.io.IOException;
 
 /**
  * Factory for {@link KeepWordFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_keepword" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.KeepWordFilterFactory" words="keepwords.txt" ignoreCase="false" enablePositionIncrements="false"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class KeepWordFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
-
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  private final boolean ignoreCase;
+  private final boolean enablePositionIncrements;
+  private final String wordFiles;
+  private CharArraySet words;
+  
+  /** Creates a new KeepWordFilterFactory */
+  public KeepWordFilterFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    wordFiles = args.remove("words");
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    enablePositionIncrements = getBoolean(args, "enablePositionIncrements", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String wordFiles = args.get("words");
-    ignoreCase = getBoolean("ignoreCase", false);
-    enablePositionIncrements = getBoolean("enablePositionIncrements",false);
-
     if (wordFiles != null) {
       words = getWordSet(loader, wordFiles, ignoreCase);
     }
   }
 
-  private CharArraySet words;
-  private boolean ignoreCase;
-  private boolean enablePositionIncrements;
-
-  /**
-   * Set the keep word list.
-   * NOTE: if ignoreCase==true, the words are expected to be lowercase
-   */
-  public void setWords(Set<String> words) {
-    this.words = new CharArraySet(luceneMatchVersion, words, ignoreCase);
-  }
-
-  public void setIgnoreCase(boolean ignoreCase) {    
-    if (words != null && this.ignoreCase != ignoreCase) {
-      words = new CharArraySet(luceneMatchVersion, words, ignoreCase);
-    }
-    this.ignoreCase = ignoreCase;
-  }
-
   public boolean isEnablePositionIncrements() {
     return enablePositionIncrements;
   }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeywordRepeatFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeywordRepeatFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/KeywordRepeatFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
@@ -28,6 +30,15 @@
  * {@link RemoveDuplicatesTokenFilterFactory} later in the analysis chain.
  */
 public final class KeywordRepeatFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new KeywordRepeatFilterFactory */
+  public KeywordRepeatFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new KeywordRepeatFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LengthFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LengthFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LengthFilterFactory.java	(working copy)
@@ -25,32 +25,30 @@
 
 /**
  * Factory for {@link LengthFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_lngth" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LengthFilterFactory" min="0" max="1" enablePositionIncrements="false"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class LengthFilterFactory extends TokenFilterFactory {
-  int min,max;
-  boolean enablePositionIncrements;
+  final int min;
+  final int max;
+  final boolean enablePositionIncrements;
   public static final String MIN_KEY = "min";
   public static final String MAX_KEY = "max";
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    String minKey = args.get(MIN_KEY);
-    String maxKey = args.get(MAX_KEY);
-    if (minKey == null || maxKey == null) {
-      throw new IllegalArgumentException("Both " + MIN_KEY + " and " + MAX_KEY + " are mandatory");
+  /** Creates a new LengthFilterFactory */
+  public LengthFilterFactory(Map<String, String> args) {
+    super(args);
+    min = getInt(args, MIN_KEY, 0, false);
+    max = getInt(args, MAX_KEY, 0, false);
+    enablePositionIncrements = getBoolean(args, "enablePositionIncrements", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
     }
-    min=Integer.parseInt(minKey);
-    max=Integer.parseInt(maxKey);
-    enablePositionIncrements = getBoolean("enablePositionIncrements",false);
   }
   
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenCountFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenCountFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenCountFilterFactory.java	(working copy)
@@ -25,28 +25,32 @@
 
 /**
  * Factory for {@link LimitTokenCountFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_lngthcnt" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LimitTokenCountFilterFactory" maxTokenCount="10" consumeAllTokens="false" /&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
+ * &lt;/fieldType&gt;</pre>
  * <p>
- * The {@code consumeAllTokens} property is optional and defaults to {@code false}.  See {@link LimitTokenCountFilter} for an explanation of it's use.
+ * The {@code consumeAllTokens} property is optional and defaults to {@code false}.  
+ * See {@link LimitTokenCountFilter} for an explanation of it's use.
  */
 public class LimitTokenCountFilterFactory extends TokenFilterFactory {
 
   public static final String MAX_TOKEN_COUNT_KEY = "maxTokenCount";
   public static final String CONSUME_ALL_TOKENS_KEY = "consumeAllTokens";
-  int maxTokenCount;
-  boolean consumeAllTokens;
+  final int maxTokenCount;
+  final boolean consumeAllTokens;
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init( args );
-    maxTokenCount = getInt(MAX_TOKEN_COUNT_KEY);
-    consumeAllTokens = getBoolean(CONSUME_ALL_TOKENS_KEY, false);
+  /** Creates a new LimitTokenCountFilterFactory */
+  public LimitTokenCountFilterFactory(Map<String, String> args) {
+    super(args);
+    maxTokenCount = getInt(args, MAX_TOKEN_COUNT_KEY);
+    consumeAllTokens = getBoolean(args, CONSUME_ALL_TOKENS_KEY, false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenPositionFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenPositionFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/LimitTokenPositionFilterFactory.java	(working copy)
@@ -23,13 +23,13 @@
 
 /**
  * Factory for {@link LimitTokenPositionFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_limit_pos" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LimitTokenPositionFilterFactory" maxTokenPosition="3" consumeAllTokens="false" /&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
+ * &lt;/fieldType&gt;</pre>
  * <p>
  * The {@code consumeAllTokens} property is optional and defaults to {@code false}.  
  * See {@link LimitTokenPositionFilter} for an explanation of its use.
@@ -38,14 +38,17 @@
 
   public static final String MAX_TOKEN_POSITION_KEY = "maxTokenPosition";
   public static final String CONSUME_ALL_TOKENS_KEY = "consumeAllTokens";
-  int maxTokenPosition;
-  boolean consumeAllTokens;
+  final int maxTokenPosition;
+  final boolean consumeAllTokens;
 
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    maxTokenPosition = getInt(MAX_TOKEN_POSITION_KEY);
-    consumeAllTokens = getBoolean(CONSUME_ALL_TOKENS_KEY, false);
+  /** Creates a new LimitTokenPositionFilterFactory */
+  public LimitTokenPositionFilterFactory(Map<String,String> args) {
+    super(args);
+    maxTokenPosition = getInt(args, MAX_TOKEN_POSITION_KEY);
+    consumeAllTokens = getBoolean(args, CONSUME_ALL_TOKENS_KEY, false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/CapitalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/CapitalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/CapitalizationFilterFactory.java	(working copy)
@@ -44,7 +44,7 @@
  * "maxWordCount" - if the token contains more then maxWordCount words, the capitalization is
  * assumed to be correct.<br/>
  *
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_cptlztn" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -54,7 +54,6 @@
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
  *
- *
  * @since solr 1.3
  */
 public class CapitalizationFilterFactory extends TokenFilterFactory {
@@ -67,30 +66,24 @@
   public static final String ONLY_FIRST_WORD = "onlyFirstWord";
   public static final String FORCE_FIRST_LETTER = "forceFirstLetter";
 
-  //Map<String,String> keep = new HashMap<String, String>(); // not synchronized because it is only initialized once
   CharArraySet keep;
 
   Collection<char[]> okPrefix = Collections.emptyList(); // for Example: McK
 
-  int minWordLength = 0;  // don't modify capitalization for words shorter then this
-  int maxWordCount = CapitalizationFilter.DEFAULT_MAX_WORD_COUNT;
-  int maxTokenLength = CapitalizationFilter.DEFAULT_MAX_TOKEN_LENGTH;
-  boolean onlyFirstWord = true;
-  boolean forceFirstLetter = true; // make sure the first letter is capitol even if it is in the keep list
+  final int minWordLength;  // don't modify capitalization for words shorter then this
+  final int maxWordCount;
+  final int maxTokenLength;
+  final boolean onlyFirstWord;
+  final boolean forceFirstLetter; // make sure the first letter is capital even if it is in the keep list
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
+  /** Creates a new CapitalizationFilterFactory */
+  public CapitalizationFilterFactory(Map<String, String> args) {
+    super(args);
     assureMatchVersion();
-
-    String k = args.get(KEEP);
+    boolean ignoreCase = getBoolean(args, KEEP_IGNORE_CASE, false);
+    String k = args.remove(KEEP);
     if (k != null) {
       StringTokenizer st = new StringTokenizer(k);
-      boolean ignoreCase = false;
-      String ignoreStr = args.get(KEEP_IGNORE_CASE);
-      if ("true".equalsIgnoreCase(ignoreStr)) {
-        ignoreCase = true;
-      }
       keep = new CharArraySet(luceneMatchVersion, 10, ignoreCase);
       while (st.hasMoreTokens()) {
         k = st.nextToken().trim();
@@ -98,7 +91,7 @@
       }
     }
 
-    k = args.get(OK_PREFIX);
+    k = args.remove(OK_PREFIX);
     if (k != null) {
       okPrefix = new ArrayList<char[]>();
       StringTokenizer st = new StringTokenizer(k);
@@ -107,30 +100,14 @@
       }
     }
 
-    k = args.get(MIN_WORD_LENGTH);
-    if (k != null) {
-      minWordLength = Integer.valueOf(k);
+    minWordLength = getInt(args, MIN_WORD_LENGTH, 0);
+    maxWordCount = getInt(args, MAX_WORD_COUNT, CapitalizationFilter.DEFAULT_MAX_WORD_COUNT);
+    maxTokenLength = getInt(args, MAX_TOKEN_LENGTH, CapitalizationFilter.DEFAULT_MAX_TOKEN_LENGTH);
+    onlyFirstWord = getBoolean(args, ONLY_FIRST_WORD, true);
+    forceFirstLetter = getBoolean(args, FORCE_FIRST_LETTER, true);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
     }
-
-    k = args.get(MAX_WORD_COUNT);
-    if (k != null) {
-      maxWordCount = Integer.valueOf(k);
-    }
-
-    k = args.get(MAX_TOKEN_LENGTH);
-    if (k != null) {
-      maxTokenLength = Integer.valueOf(k);
-    }
-
-    k = args.get(ONLY_FIRST_WORD);
-    if (k != null) {
-      onlyFirstWord = Boolean.valueOf(k);
-    }
-
-    k = args.get(FORCE_FIRST_LETTER);
-    if (k != null) {
-      forceFirstLetter = Boolean.valueOf(k);
-    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/TrimFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/TrimFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/TrimFilterFactory.java	(working copy)
@@ -25,7 +25,7 @@
 
 /**
  * Factory for {@link TrimFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_trm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.NGramTokenizerFactory"/&gt;
@@ -37,15 +37,14 @@
  */
 public class TrimFilterFactory extends TokenFilterFactory {
   
-  protected boolean updateOffsets = false;
+  protected final boolean updateOffsets;
   
-  @Override
-  public void init(Map<String,String> args) {
-    super.init( args );
-    
-    String v = args.get( "updateOffsets" );
-    if (v != null) {
-      updateOffsets = Boolean.valueOf( v );
+  /** Creates a new TrimFilterFactory */
+  public TrimFilterFactory(Map<String,String> args) {
+    super(args);
+    updateOffsets = getBoolean(args, "updateOffsets", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
     }
   }
   
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/StemmerOverrideFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/StemmerOverrideFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/miscellaneous/StemmerOverrideFilterFactory.java	(working copy)
@@ -19,35 +19,42 @@
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Locale;
+import java.util.Map;
 
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.miscellaneous.StemmerOverrideFilter;
 import org.apache.lucene.analysis.miscellaneous.StemmerOverrideFilter.StemmerOverrideMap;
-import org.apache.lucene.analysis.util.*;
-import org.apache.lucene.util.BytesRef;
-import org.apache.lucene.util.CharsRef;
-import org.apache.lucene.util.fst.FST;
+import org.apache.lucene.analysis.util.ResourceLoader;
+import org.apache.lucene.analysis.util.ResourceLoaderAware;
+import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link StemmerOverrideFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_dicstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.StemmerOverrideFilterFactory" dictionary="dictionary.txt" ignoreCase="false"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class StemmerOverrideFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   private StemmerOverrideMap dictionary;
-  private boolean ignoreCase;
+  private final String dictionaryFiles;
+  private final boolean ignoreCase;
 
+  /** Creates a new StemmerOverrideFilterFactory */
+  public StemmerOverrideFilterFactory(Map<String,String> args) {
+    super(args);
+    dictionaryFiles = args.remove("dictionary");
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String dictionaryFiles = args.get("dictionary");
-    ignoreCase = getBoolean("ignoreCase", false);
     if (dictionaryFiles != null) {
       assureMatchVersion();
       List<String> files = splitFileNames(dictionaryFiles);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/br/BrazilianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/br/BrazilianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/br/BrazilianStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.br.BrazilianStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link BrazilianStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_brstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.BrazilianStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class BrazilianStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new BrazilianStemFilterFactory */
+  public BrazilianStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public BrazilianStemFilter create(TokenStream in) {
     return new BrazilianStemFilter(in);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramFilterFactory.java	(working copy)
@@ -24,37 +24,34 @@
 
 /**
  * Creates new instances of {@link EdgeNGramTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_edgngrm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.EdgeNGramFilterFactory" side="front" minGramSize="1" maxGramSize="1"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class EdgeNGramFilterFactory extends TokenFilterFactory {
-  private int maxGramSize = 0;
+  private final int maxGramSize;
+  private final int minGramSize;
+  private final String side;
 
-  private int minGramSize = 0;
+  /** Creates a new EdgeNGramFilterFactory */
+  public EdgeNGramFilterFactory(Map<String, String> args) {
+    super(args);
+    minGramSize = getInt(args, "minGramSize", EdgeNGramTokenFilter.DEFAULT_MIN_GRAM_SIZE);
+    maxGramSize = getInt(args, "maxGramSize", EdgeNGramTokenFilter.DEFAULT_MAX_GRAM_SIZE);
 
-  private String side;
-
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    String maxArg = args.get("maxGramSize");
-    maxGramSize = (maxArg != null ? Integer.parseInt(maxArg)
-        : EdgeNGramTokenFilter.DEFAULT_MAX_GRAM_SIZE);
-
-    String minArg = args.get("minGramSize");
-    minGramSize = (minArg != null ? Integer.parseInt(minArg)
-        : EdgeNGramTokenFilter.DEFAULT_MIN_GRAM_SIZE);
-
-    side = args.get("side");
-    if (side == null) {
+    String sideArg = args.remove("side");
+    if (sideArg == null) {
       side = EdgeNGramTokenFilter.Side.FRONT.getLabel();
+    } else {
+      side = sideArg;
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/NGramTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/NGramTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/NGramTokenizerFactory.java	(working copy)
@@ -26,27 +26,26 @@
 
 /**
  * Factory for {@link NGramTokenizer}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ngrm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.NGramTokenizerFactory" minGramSize="1" maxGramSize="2"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class NGramTokenizerFactory extends TokenizerFactory {
-  private int maxGramSize = 0;
-  private int minGramSize = 0;
-  
-  /** Initializes the n-gram min and max sizes and the side from which one should start tokenizing. */
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    String maxArg = args.get("maxGramSize");
-    maxGramSize = (maxArg != null ? Integer.parseInt(maxArg) : NGramTokenizer.DEFAULT_MAX_NGRAM_SIZE);
-    
-    String minArg = args.get("minGramSize");
-    minGramSize = (minArg != null ? Integer.parseInt(minArg) : NGramTokenizer.DEFAULT_MIN_NGRAM_SIZE);
+  private final int maxGramSize;
+  private final int minGramSize;
+
+  /** Creates a new NGramTokenizerFactory */
+  public NGramTokenizerFactory(Map<String, String> args) {
+    super(args);
+    minGramSize = getInt(args, "minGramSize", NGramTokenizer.DEFAULT_MIN_NGRAM_SIZE);
+    maxGramSize = getInt(args, "maxGramSize", NGramTokenizer.DEFAULT_MAX_NGRAM_SIZE);
+
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   /** Creates the {@link TokenStream} of n-grams from the given {@link Reader} and {@link AttributeFactory}. */
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/NGramFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/NGramFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/NGramFilterFactory.java	(working copy)
@@ -24,31 +24,27 @@
 
 /**
  * Factory for {@link NGramTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ngrm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="2"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class NGramFilterFactory extends TokenFilterFactory {
-  private int maxGramSize = 0;
+  private final int maxGramSize;
+  private final int minGramSize;
 
-  private int minGramSize = 0;
+  /** Creates a new NGramFilterFactory */
+  public NGramFilterFactory(Map<String, String> args) {
+    super(args);
+    minGramSize = getInt(args, "minGramSize", NGramTokenFilter.DEFAULT_MIN_NGRAM_SIZE);
+    maxGramSize = getInt(args, "maxGramSize", NGramTokenFilter.DEFAULT_MAX_NGRAM_SIZE);
 
-  /** Initialize the n-gram min and max sizes and the side from which one should start tokenizing. */
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    String maxArg = args.get("maxGramSize");
-    maxGramSize = (maxArg != null ? Integer.parseInt(maxArg)
-        : NGramTokenFilter.DEFAULT_MAX_NGRAM_SIZE);
-
-    String minArg = args.get("minGramSize");
-    minGramSize = (minArg != null ? Integer.parseInt(minArg)
-        : NGramTokenFilter.DEFAULT_MIN_NGRAM_SIZE);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramTokenizerFactory.java	(working copy)
@@ -25,34 +25,33 @@
 
 /**
  * Creates new instances of {@link EdgeNGramTokenizer}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_edgngrm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.EdgeNGramTokenizerFactory" side="front" minGramSize="1" maxGramSize="1"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class EdgeNGramTokenizerFactory extends TokenizerFactory {
-  private int maxGramSize = 0;
-  
-  private int minGramSize = 0;
-  
-  private String side;
-  
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    String maxArg = args.get("maxGramSize");
-    maxGramSize = (maxArg != null ? Integer.parseInt(maxArg) : EdgeNGramTokenizer.DEFAULT_MAX_GRAM_SIZE);
-    
-    String minArg = args.get("minGramSize");
-    minGramSize = (minArg != null ? Integer.parseInt(minArg) : EdgeNGramTokenizer.DEFAULT_MIN_GRAM_SIZE);
-    
-    side = args.get("side");
-    if (side == null) {
-      side = EdgeNGramTokenizer.Side.FRONT.getLabel();
+  private final int maxGramSize;
+  private final int minGramSize;
+  private final String side;
+
+  /** Creates a new EdgeNGramTokenizerFactory */
+  public EdgeNGramTokenizerFactory(Map<String, String> args) {
+    super(args);
+    minGramSize = getInt(args, "minGramSize", EdgeNGramTokenFilter.DEFAULT_MIN_GRAM_SIZE);
+    maxGramSize = getInt(args, "maxGramSize", EdgeNGramTokenFilter.DEFAULT_MAX_GRAM_SIZE);
+
+    String sideArg = args.remove("side");
+    if (sideArg == null) {
+      side = EdgeNGramTokenFilter.Side.FRONT.getLabel();
+    } else {
+      side = sideArg;
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchMinimalStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.fr.FrenchMinimalStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link FrenchMinimalStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_frminstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,10 +33,18 @@
  *     &lt;filter class="solr.ElisionFilterFactory"/&gt;
  *     &lt;filter class="solr.FrenchMinimalStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class FrenchMinimalStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new FrenchMinimalStemFilterFactory */
+  public FrenchMinimalStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new FrenchMinimalStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/fr/FrenchLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.fr.FrenchLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link FrenchLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_frlgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,10 +33,18 @@
  *     &lt;filter class="solr.ElisionFilterFactory"/&gt;
  *     &lt;filter class="solr.FrenchLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class FrenchLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new FrenchLightStemFilterFactory */
+  public FrenchLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new FrenchLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/reverse/ReverseStringFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/reverse/ReverseStringFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/reverse/ReverseStringFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.reverse.ReverseStringFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link ReverseStringFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_rvsstr" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -31,13 +33,21 @@
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
  *
- *
  * @since solr 1.4
  */
 public class ReverseStringFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new ReverseStringFilterFactory */
+  public ReverseStringFilterFactory(Map<String,String> args) {
+    super(args);
+    assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public ReverseStringFilter create(TokenStream in) {
-    assureMatchVersion();
     return new ReverseStringFilter(luceneMatchVersion,in);
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/TokenOffsetPayloadTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/TokenOffsetPayloadTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/TokenOffsetPayloadTokenFilterFactory.java	(working copy)
@@ -17,22 +17,32 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.payloads.TokenOffsetPayloadTokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link TokenOffsetPayloadTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_tokenoffset" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.TokenOffsetPayloadTokenFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class TokenOffsetPayloadTokenFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new TokenOffsetPayloadTokenFilterFactory */
+  public TokenOffsetPayloadTokenFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenOffsetPayloadTokenFilter create(TokenStream input) {
     return new TokenOffsetPayloadTokenFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/DelimitedPayloadTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/DelimitedPayloadTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/DelimitedPayloadTokenFilterFactory.java	(working copy)
@@ -30,24 +30,43 @@
 import java.util.Map;
 
 /**
- *
  * Factory for {@link DelimitedPayloadTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_dlmtd" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.DelimitedPayloadTokenFilterFactory" encoder="float" delimiter="|"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
- * 
  */
 public class DelimitedPayloadTokenFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   public static final String ENCODER_ATTR = "encoder";
   public static final String DELIMITER_ATTR = "delimiter";
 
+  private final String encoderClass;
+  private final char delimiter;
+
   private PayloadEncoder encoder;
-  private char delimiter = '|';
+  
+  /** Creates a new DelimitedPayloadTokenFilterFactory */
+  public DelimitedPayloadTokenFilterFactory(Map<String, String> args) {
+    super(args);
+    encoderClass = args.remove(ENCODER_ATTR);
+    if (encoderClass == null) {
+      throw new IllegalArgumentException("Parameter " + ENCODER_ATTR + " is mandatory");
+    }
+    String delim = args.remove(DELIMITER_ATTR);
+    if (delim == null) {
+      delimiter = '|';
+    } else if (delim.length() == 1) {
+      delimiter = delim.charAt(0);
+    } else {
+      throw new IllegalArgumentException("Delimiter must be one character only");
+    }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public DelimitedPayloadTokenFilter create(TokenStream input) {
@@ -55,16 +74,7 @@
   }
 
   @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-  }
-
-  @Override
   public void inform(ResourceLoader loader) {
-    String encoderClass = args.get(ENCODER_ATTR);
-    if (encoderClass == null) {
-      throw new IllegalArgumentException("Parameter " + ENCODER_ATTR + " is mandatory");
-    }
     if (encoderClass.equals("float")){
       encoder = new FloatEncoder();
     } else if (encoderClass.equals("integer")){
@@ -74,14 +84,5 @@
     } else {
       encoder = loader.newInstance(encoderClass, PayloadEncoder.class);
     }
-
-    String delim = args.get(DELIMITER_ATTR);
-    if (delim != null){
-      if (delim.length() == 1) {
-        delimiter = delim.charAt(0);
-      } else{
-        throw new IllegalArgumentException("Delimiter must be one character only");
-      }
-    }
   }
 }
\ No newline at end of file
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/NumericPayloadTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/NumericPayloadTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/NumericPayloadTokenFilterFactory.java	(working copy)
@@ -24,28 +24,32 @@
 
 /** 
  * Factory for {@link NumericPayloadTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_numpayload" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.NumericPayloadTokenFilterFactory" payload="24" typeMatch="word"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class NumericPayloadTokenFilterFactory extends TokenFilterFactory {
-  private float payload;
-  private String typeMatch;
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    String payloadArg = args.get("payload");
-    typeMatch = args.get("typeMatch");
+  private final float payload;
+  private final String typeMatch;
+  
+  /** Creates a new NumericPayloadTokenFilterFactory */
+  public NumericPayloadTokenFilterFactory(Map<String, String> args) {
+    super(args);
+    String payloadArg = args.remove("payload");
+    typeMatch = args.remove("typeMatch");
     if (payloadArg == null || typeMatch == null) {
       throw new IllegalArgumentException("Both payload and typeMatch are required");
     }
     payload = Float.parseFloat(payloadArg);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
+
   @Override
   public NumericPayloadTokenFilter create(TokenStream input) {
     return new NumericPayloadTokenFilter(input,payload,typeMatch);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/TypeAsPayloadTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/TypeAsPayloadTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/payloads/TypeAsPayloadTokenFilterFactory.java	(working copy)
@@ -17,22 +17,32 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.payloads.TypeAsPayloadTokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link TypeAsPayloadTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_typeaspayload" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.TypeAsPayloadTokenFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class TypeAsPayloadTokenFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new TypeAsPayloadTokenFilterFactory */
+  public TypeAsPayloadTokenFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TypeAsPayloadTokenFilter create(TokenStream input) {
     return new TypeAsPayloadTokenFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/no/NorwegianMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/no/NorwegianMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/no/NorwegianMinimalStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.no.NorwegianMinimalStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link NorwegianMinimalStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_svlgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -33,6 +35,15 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class NorwegianMinimalStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new NorwegianMinimalStemFilterFactory */
+  public NorwegianMinimalStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new NorwegianMinimalStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/no/NorwegianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/no/NorwegianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/no/NorwegianLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.no.NorwegianLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link NorwegianLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_svlgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -33,6 +35,15 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class NorwegianLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new NorwegianLightStemFilterFactory */
+  public NorwegianLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new NorwegianLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ru/RussianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ru/RussianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ru/RussianLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.ru.RussianLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link RussianLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_rulgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.RussianLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class RussianLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new RussianLightStemFilterFactory */
+  public RussianLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new RussianLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ga/IrishLowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ga/IrishLowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ga/IrishLowerCaseFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.ga.IrishLowerCaseFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,17 +27,24 @@
 
 /** 
  * Factory for {@link IrishLowerCaseFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ga" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.IrishLowerCaseFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class IrishLowerCaseFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
 
+  /** Creates a new IrishLowerCaseFilterFactory */
+  public IrishLowerCaseFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new IrishLowerCaseFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/hunspell/HunspellStemFilterFactory.java	(working copy)
@@ -22,6 +22,7 @@
 import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.hunspell.HunspellDictionary;
@@ -34,7 +35,7 @@
 /**
  * TokenFilterFactory that creates instances of {@link org.apache.lucene.analysis.hunspell.HunspellStemFilter}.
  * Example config for British English including a custom dictionary, case insensitive matching:
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;filter class=&quot;solr.HunspellStemFilterFactory&quot;
  *    dictionary=&quot;en_GB.dic,my_custom.dic&quot;
  *    affix=&quot;en_GB.aff&quot;
@@ -51,16 +52,32 @@
  * See <a href="http://wiki.apache.org/solr/Hunspell">http://wiki.apache.org/solr/Hunspell</a>
  */
 public class HunspellStemFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
-  
   private static final String PARAM_DICTIONARY = "dictionary";
   private static final String PARAM_AFFIX = "affix";
   private static final String PARAM_IGNORE_CASE = "ignoreCase";
   private static final String PARAM_STRICT_AFFIX_PARSING = "strictAffixParsing";
-  private static final String TRUE = "true";
-  private static final String FALSE = "false";
+
+  private final String dictionaryArg;
+  private final String affixFile;
+  private final boolean ignoreCase;
+  private final boolean strictAffixParsing;
+  private HunspellDictionary dictionary;
   
-  private HunspellDictionary dictionary;
-  private boolean ignoreCase = false;
+  /** Creates a new HunspellStemFilterFactory */
+  public HunspellStemFilterFactory(Map<String,String> args) {
+    super(args);
+    assureMatchVersion();
+    dictionaryArg = args.remove(PARAM_DICTIONARY);
+    if (dictionaryArg == null) {
+      throw new IllegalArgumentException("Parameter " + PARAM_DICTIONARY + " is mandatory.");
+    }
+    affixFile = args.remove(PARAM_AFFIX);
+    ignoreCase = getBoolean(args, PARAM_IGNORE_CASE, false);
+    strictAffixParsing = getBoolean(args, PARAM_STRICT_AFFIX_PARSING, true);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   /**
    * Loads the hunspell dictionary and affix files defined in the configuration
@@ -69,28 +86,8 @@
    */
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    assureMatchVersion();
-    String dictionaryArg = args.get(PARAM_DICTIONARY);
-    if (dictionaryArg == null) {
-      throw new IllegalArgumentException("Parameter " + PARAM_DICTIONARY + " is mandatory.");
-    }
-    String dictionaryFiles[] = args.get(PARAM_DICTIONARY).split(",");
-    String affixFile = args.get(PARAM_AFFIX);
-    String pic = args.get(PARAM_IGNORE_CASE);
-    if(pic != null) {
-      if(pic.equalsIgnoreCase(TRUE)) ignoreCase = true;
-      else if(pic.equalsIgnoreCase(FALSE)) ignoreCase = false;
-      else throw new IllegalArgumentException("Unknown value for " + PARAM_IGNORE_CASE + ": " + pic + ". Must be true or false");
-    }
+    String dictionaryFiles[] = dictionaryArg.split(",");
 
-    String strictAffixParsingParam = args.get(PARAM_STRICT_AFFIX_PARSING);
-    boolean strictAffixParsing = true;
-    if(strictAffixParsingParam != null) {
-      if(strictAffixParsingParam.equalsIgnoreCase(FALSE)) strictAffixParsing = false;
-      else if(strictAffixParsingParam.equalsIgnoreCase(TRUE)) strictAffixParsing = true;
-      else throw new IllegalArgumentException("Unknown value for " + PARAM_STRICT_AFFIX_PARSING + ": " + strictAffixParsingParam + ". Must be true or false");
-    }
-
     InputStream affix = null;
     List<InputStream> dictionaries = new ArrayList<InputStream>();
 
@@ -103,7 +100,7 @@
 
       this.dictionary = new HunspellDictionary(affix, dictionaries, luceneMatchVersion, ignoreCase, strictAffixParsing);
     } catch (ParseException e) {
-      throw new IOException("Unable to load hunspell data! [dictionary=" + args.get("dictionary") + ",affix=" + affixFile + "]", e);
+      throw new IOException("Unable to load hunspell data! [dictionary=" + dictionaryArg + ",affix=" + affixFile + "]", e);
     } finally {
       IOUtils.closeWhileHandlingException(affix);
       IOUtils.closeWhileHandlingException(dictionaries);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianMinimalStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.gl.GalicianMinimalStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link GalicianMinimalStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_glplural" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.GalicianMinimalStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class GalicianMinimalStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new GalicianMinimalStemFilterFactory */
+  public GalicianMinimalStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new GalicianMinimalStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/gl/GalicianStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.gl.GalicianStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link GalicianStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_glstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.GalicianStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class GalicianStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new GalicianStemFilterFactory */
+  public GalicianStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new GalicianStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/position/PositionFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/position/PositionFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/position/PositionFilterFactory.java	(working copy)
@@ -27,7 +27,7 @@
  * Factory for {@link PositionFilter}.
  * Set the positionIncrement of all tokens to the "positionIncrement", except the first return token which retains its
  * original positionIncrement value. The default positionIncrement value is zero.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_position" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -35,17 +35,19 @@
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
  *
- *
  * @see org.apache.lucene.analysis.position.PositionFilter
  * @since solr 1.4
  */
 public class PositionFilterFactory extends TokenFilterFactory {
-  private int positionIncrement;
+  private final int positionIncrement;
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    positionIncrement = getInt("positionIncrement", 0);
+  /** Creates a new PositionFilterFactory */
+  public PositionFilterFactory(Map<String,String> args) {
+    super(args);
+    positionIncrement = getInt(args, "positionIncrement", 0);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/wikipedia/WikipediaTokenizerFactory.java	(working copy)
@@ -19,21 +19,30 @@
 
 import java.io.Reader;
 import java.util.Collections;
+import java.util.Map;
 
 import org.apache.lucene.analysis.util.TokenizerFactory;
 import org.apache.lucene.util.AttributeSource.AttributeFactory;
 
 /** 
  * Factory for {@link WikipediaTokenizer}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_wiki" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WikipediaTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class WikipediaTokenizerFactory extends TokenizerFactory {
+  
+  /** Creates a new WikipediaTokenizerFactory */
+  public WikipediaTokenizerFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   // TODO: add support for WikipediaTokenizer's advanced options.
   @Override
   public WikipediaTokenizer create(AttributeFactory factory, Reader input) {
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/cz/CzechStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/cz/CzechStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/cz/CzechStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.cz.CzechStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
- *  Factory for {@link CzechStemFilter}.
- * <pre class="prettyprint" >
+ * Factory for {@link CzechStemFilter}.
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_czstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -33,6 +35,15 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class CzechStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new CzechStemFilterFactory */
+  public CzechStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new CzechStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/CharFilterFactory.java	(working copy)
@@ -18,6 +18,7 @@
  */
 
 import java.io.Reader;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.lucene.analysis.CharFilter;
@@ -32,8 +33,8 @@
       new AnalysisSPILoader<CharFilterFactory>(CharFilterFactory.class);
   
   /** looks up a charfilter by name from context classpath */
-  public static CharFilterFactory forName(String name) {
-    return loader.newInstance(name);
+  public static CharFilterFactory forName(String name, Map<String,String> args) {
+    return loader.newInstance(name, args);
   }
   
   /** looks up a charfilter class by name from context classpath */
@@ -61,6 +62,13 @@
     loader.reload(classloader);
   }
 
+  /**
+   * Initialize this factory via a set of key-value pairs.
+   */
+  protected CharFilterFactory(Map<String,String> args) {
+    super(args);
+  }
+
   /** Wraps the given Reader with a CharFilter. */
   public abstract Reader create(Reader input);
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenFilterFactory.java	(working copy)
@@ -17,6 +17,7 @@
  * limitations under the License.
  */
 
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.lucene.analysis.TokenStream;
@@ -32,8 +33,8 @@
           new String[] { "TokenFilterFactory", "FilterFactory" });
   
   /** looks up a tokenfilter by name from context classpath */
-  public static TokenFilterFactory forName(String name) {
-    return loader.newInstance(name);
+  public static TokenFilterFactory forName(String name, Map<String,String> args) {
+    return loader.newInstance(name, args);
   }
   
   /** looks up a tokenfilter class by name from context classpath */
@@ -60,6 +61,13 @@
   public static void reloadTokenFilters(ClassLoader classloader) {
     loader.reload(classloader);
   }
+  
+  /**
+   * Initialize this factory via a set of key-value pairs.
+   */
+  protected TokenFilterFactory(Map<String,String> args) {
+    super(args);
+  }
 
   /** Transform the specified input TokenStream */
   public abstract TokenStream create(TokenStream input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ClasspathResourceLoader.java	(working copy)
@@ -67,14 +67,23 @@
       throw new IOException("Resource not found: " + resource);
     return stream;
   }
+  
+  @Override
+  public <T> Class<? extends T> findClass(String cname, Class<T> expectedType) {
+    try {
+      return Class.forName(cname, true, loader).asSubclass(expectedType);
+    } catch (Exception e) {
+      throw new RuntimeException("Cannot load class: " + cname, e);
+    }
+  }
 
   @Override
   public <T> T newInstance(String cname, Class<T> expectedType) {
+    Class<? extends T> clazz = findClass(cname, expectedType);
     try {
-      final Class<? extends T> clazz = Class.forName(cname, true, loader).asSubclass(expectedType);
       return clazz.newInstance();
     } catch (Exception e) {
-      throw new RuntimeException("Cannot instantiate class: " + cname, e);
+      throw new RuntimeException("Cannot create instance: " + cname, e);
     }
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/FilesystemResourceLoader.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/FilesystemResourceLoader.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/FilesystemResourceLoader.java	(working copy)
@@ -91,4 +91,9 @@
   public <T> T newInstance(String cname, Class<T> expectedType) {
     return delegate.newInstance(cname, expectedType);
   }
+
+  @Override
+  public <T> Class<? extends T> findClass(String cname, Class<T> expectedType) {
+    return delegate.findClass(cname, expectedType);
+  }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AbstractAnalysisFactory.java	(working copy)
@@ -41,9 +41,7 @@
  * <p>
  * The typical lifecycle for a factory consumer is:
  * <ol>
- *   <li>Create factory via its a no-arg constructor
- *   <li>Set version emulation by calling {@link #setLuceneMatchVersion(Version)}
- *   <li>Calls {@link #init(Map)} passing arguments as key-value mappings.
+ *   <li>Create factory via its constructor (or via XXXFactory.forName)
  *   <li>(Optional) If the factory uses resources such as files, {@link ResourceLoaderAware#inform(ResourceLoader)} is called to initialize those resources.
  *   <li>Consumer calls create() to obtain instances.
  * </ol>
@@ -51,27 +49,21 @@
 public abstract class AbstractAnalysisFactory {
 
   /** The original args, before init() processes them */
-  private Map<String,String> originalArgs;
-  
-  /** The init args */
-  protected Map<String,String> args;
+  private final Map<String,String> originalArgs;
 
   /** the luceneVersion arg */
-  protected Version luceneMatchVersion = null;
+  protected final Version luceneMatchVersion;
 
   /**
    * Initialize this factory via a set of key-value pairs.
    */
-  public void init(Map<String,String> args) {
-    originalArgs = Collections.unmodifiableMap(args);
-    this.args = new HashMap<String,String>(args);
+  protected AbstractAnalysisFactory(Map<String,String> args) {
+    originalArgs = Collections.unmodifiableMap(new HashMap<String,String>(args));
+    String version = args.remove("luceneMatchVersion");
+    luceneMatchVersion = version == null ? null : Version.parseLeniently(version);
   }
-
-  public Map<String,String> getArgs() {
-    return args;
-  }
   
-  public Map<String,String> getOriginalArgs() {
+  public final Map<String,String> getOriginalArgs() {
     return originalArgs;
   }
 
@@ -85,24 +77,20 @@
     }
   }
 
-  public void setLuceneMatchVersion(Version luceneMatchVersion) {
-    this.luceneMatchVersion = luceneMatchVersion;
-  }
-
-  public Version getLuceneMatchVersion() {
+  public final Version getLuceneMatchVersion() {
     return this.luceneMatchVersion;
   }
 
-  protected int getInt(String name) {
-    return getInt(name, -1, false);
+  protected final int getInt(Map<String,String> args, String name) {
+    return getInt(args, name, -1, false);
   }
 
-  protected int getInt(String name, int defaultVal) {
-    return getInt(name, defaultVal, true);
+  protected final int getInt(Map<String,String> args, String name, int defaultVal) {
+    return getInt(args, name, defaultVal, true);
   }
 
-  protected int getInt(String name, int defaultVal, boolean useDefault) {
-    String s = args.get(name);
+  protected final int getInt(Map<String,String> args, String name, int defaultVal, boolean useDefault) {
+    String s = args.remove(name);
     if (s == null) {
       if (useDefault) {
         return defaultVal;
@@ -112,12 +100,12 @@
     return Integer.parseInt(s);
   }
 
-  protected boolean getBoolean(String name, boolean defaultVal) {
-    return getBoolean(name, defaultVal, true);
+  protected final boolean getBoolean(Map<String,String> args, String name, boolean defaultVal) {
+    return getBoolean(args, name, defaultVal, true);
   }
 
-  protected boolean getBoolean(String name, boolean defaultVal, boolean useDefault) {
-    String s = args.get(name);
+  protected final boolean getBoolean(Map<String,String> args, String name, boolean defaultVal, boolean useDefault) {
+    String s = args.remove(name);
     if (s==null) {
       if (useDefault) return defaultVal;
       throw new IllegalArgumentException("Configuration Error: missing parameter '" + name + "'");
@@ -128,13 +116,13 @@
   /**
    * Compiles a pattern for the value of the specified argument key <code>name</code> 
    */
-  protected Pattern getPattern(String name) {
+  protected final Pattern getPattern(Map<String,String> args, String name) {
     try {
-      String pat = args.get(name);
+      String pat = args.remove(name);
       if (null == pat) {
         throw new IllegalArgumentException("Configuration Error: missing parameter '" + name + "'");
       }
-      return Pattern.compile(args.get(name));
+      return Pattern.compile(pat);
     } catch (PatternSyntaxException e) {
       throw new IllegalArgumentException
         ("Configuration Error: '" + name + "' can not be parsed in " +
@@ -146,7 +134,7 @@
    * Returns as {@link CharArraySet} from wordFiles, which
    * can be a comma-separated list of filenames
    */
-  protected CharArraySet getWordSet(ResourceLoader loader,
+  protected final CharArraySet getWordSet(ResourceLoader loader,
       String wordFiles, boolean ignoreCase) throws IOException {
     assureMatchVersion();
     List<String> files = splitFileNames(wordFiles);
@@ -168,13 +156,13 @@
   /**
    * Returns the resource's lines (with content treated as UTF-8)
    */
-  protected List<String> getLines(ResourceLoader loader, String resource) throws IOException {
+  protected final List<String> getLines(ResourceLoader loader, String resource) throws IOException {
     return WordlistLoader.getLines(loader.openResource(resource), IOUtils.CHARSET_UTF_8);
   }
 
   /** same as {@link #getWordSet(ResourceLoader, String, boolean)},
    * except the input is in snowball format. */
-  protected CharArraySet getSnowballWordSet(ResourceLoader loader,
+  protected final CharArraySet getSnowballWordSet(ResourceLoader loader,
       String wordFiles, boolean ignoreCase) throws IOException {
     assureMatchVersion();
     List<String> files = splitFileNames(wordFiles);
@@ -209,7 +197,7 @@
    * @param fileNames the string containing file names
    * @return a list of file names with the escaping backslashed removed
    */
-  protected List<String> splitFileNames(String fileNames) {
+  protected final List<String> splitFileNames(String fileNames) {
     if (fileNames == null)
       return Collections.<String>emptyList();
 
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ElisionFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ElisionFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ElisionFilterFactory.java	(working copy)
@@ -18,12 +18,14 @@
  */
 
 import java.io.IOException;
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.fr.FrenchAnalyzer;
 
 /**
  * Factory for {@link ElisionFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_elsn" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -32,23 +34,29 @@
  *       articles="stopwordarticles.txt" ignoreCase="true"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ElisionFilterFactory extends TokenFilterFactory implements ResourceLoaderAware, MultiTermAwareComponent {
-
+  private final String articlesFile;
+  private final boolean ignoreCase;
   private CharArraySet articles;
 
+  /** Creates a new ElisionFilterFactory */
+  public ElisionFilterFactory(Map<String,String> args) {
+    super(args);
+    articlesFile = args.remove("articles");
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String articlesFile = args.get("articles");
-    boolean ignoreCase = getBoolean("ignoreCase", false);
-
-    if (articlesFile != null) {
+    if (articlesFile == null) {
+      articles = FrenchAnalyzer.DEFAULT_ARTICLES;
+    } else {
       articles = getWordSet(loader, articlesFile, ignoreCase);
     }
-    if (articles == null) {
-      articles = FrenchAnalyzer.DEFAULT_ARTICLES;
-    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ResourceLoader.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ResourceLoader.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/ResourceLoader.java	(working copy)
@@ -30,9 +30,15 @@
    */
   public InputStream openResource(String resource) throws IOException;
   
+  
   /**
-   * Creates a class of the name and expected type
+   * Finds class of the name and expected type
    */
+  public <T> Class<? extends T> findClass(String cname, Class<T> expectedType);
+  
+  /**
+   * Creates an instance of the name and expected type
+   */
   // TODO: fix exception handling
   public <T> T newInstance(String cname, Class<T> expectedType);
 }
\ No newline at end of file
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/AnalysisSPILoader.java	(working copy)
@@ -104,10 +104,10 @@
     this.services = Collections.unmodifiableMap(services);
   }
   
-  public S newInstance(String name) {
+  public S newInstance(String name, Map<String,String> args) {
     final Class<? extends S> service = lookupClass(name);
     try {
-      return service.newInstance();
+      return service.getConstructor(Map.class).newInstance(args);
     } catch (Exception e) {
       throw new IllegalArgumentException("SPI class of type "+clazz.getName()+" with name '"+name+"' cannot be instantiated. " +
             "This is likely due to a misconfiguration of the java class '" + service.getName() + "': ", e);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/util/TokenizerFactory.java	(working copy)
@@ -21,6 +21,7 @@
 import org.apache.lucene.util.AttributeSource.AttributeFactory;
 
 import java.io.Reader;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -33,8 +34,8 @@
       new AnalysisSPILoader<TokenizerFactory>(TokenizerFactory.class);
   
   /** looks up a tokenizer by name from context classpath */
-  public static TokenizerFactory forName(String name) {
-    return loader.newInstance(name);
+  public static TokenizerFactory forName(String name, Map<String,String> args) {
+    return loader.newInstance(name, args);
   }
   
   /** looks up a tokenizer class by name from context classpath */
@@ -61,6 +62,13 @@
   public static void reloadTokenizers(ClassLoader classloader) {
     loader.reload(classloader);
   }
+  
+  /**
+   * Initialize this factory via a set of key-value pairs.
+   */
+  protected TokenizerFactory(Map<String,String> args) {
+    super(args);
+  }
 
   /** Creates a TokenStream of the specified input using the default attribute factory. */
   public final Tokenizer create(Reader input) {
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/HTMLStripCharFilterFactory.java	(working copy)
@@ -28,20 +28,36 @@
 import java.util.regex.Pattern;
 
 /**
-* Factory for {@link HTMLStripCharFilter}. 
- * <pre class="prettyprint" >
+ * Factory for {@link HTMLStripCharFilter}. 
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_html" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;charFilter class="solr.HTMLStripCharFilterFactory" escapedTags="a, title" /&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
- public class HTMLStripCharFilterFactory extends CharFilterFactory {
+public class HTMLStripCharFilterFactory extends CharFilterFactory {
+  final Set<String> escapedTags;
+  static final Pattern TAG_NAME_PATTERN = Pattern.compile("[^\\s,]+");
   
-  Set<String> escapedTags = null;
-  Pattern TAG_NAME_PATTERN = Pattern.compile("[^\\s,]+");
+  /** Creates a new HTMLStripCharFilterFactory */
+  public HTMLStripCharFilterFactory(Map<String,String> args) {
+    super(args);
+    String escapedTagsArg = args.remove("escapedTags");
+    if (escapedTagsArg == null) {
+      escapedTags = null;
+    } else {
+      escapedTags = new HashSet<String>();
+      Matcher matcher = TAG_NAME_PATTERN.matcher(escapedTagsArg);
+      while (matcher.find()) {
+        escapedTags.add(matcher.group(0));
+      }
+    }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public HTMLStripCharFilter create(Reader input) {
@@ -53,19 +69,4 @@
     }
     return charFilter;
   }
-  
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    String escapedTagsArg = args.get("escapedTags");
-    if (null != escapedTagsArg) {
-      Matcher matcher = TAG_NAME_PATTERN.matcher(escapedTagsArg);
-      while (matcher.find()) {
-        if (null == escapedTags) {
-          escapedTags = new HashSet<String>();
-        }
-        escapedTags.add(matcher.group(0));
-      }
-    }
-  }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/MappingCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/MappingCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/charfilter/MappingCharFilterFactory.java	(working copy)
@@ -22,6 +22,7 @@
 import java.io.Reader;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -31,7 +32,7 @@
 
 /**
  * Factory for {@link MappingCharFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_map" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;charFilter class="solr.MappingCharFilterFactory" mapping="mapping.txt"/&gt;
@@ -39,21 +40,26 @@
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
  *
- *
  * @since Solr 1.4
- *
  */
 public class MappingCharFilterFactory extends CharFilterFactory implements
     ResourceLoaderAware, MultiTermAwareComponent {
 
   protected NormalizeCharMap normMap;
-  private String mapping;
+  private final String mapping;
 
+  /** Creates a new MappingCharFilterFactory */
+  public MappingCharFilterFactory(Map<String,String> args) {
+    super(args);
+    mapping = args.remove("mapping");
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+
   // TODO: this should use inputstreams from the loader, not File!
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    mapping = args.get("mapping");
-
     if (mapping != null) {
       List<String> wlist = null;
       File mappingFile = new File(mapping);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/sv/SwedishLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/sv/SwedishLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/sv/SwedishLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.sv.SwedishLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link SwedishLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_svlgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.SwedishLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class SwedishLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new SwedishLightStemFilterFactory */
+  public SwedishLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new SwedishLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/WhitespaceTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/WhitespaceTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/WhitespaceTokenizerFactory.java	(working copy)
@@ -25,19 +25,22 @@
 
 /**
  * Factory for {@link WhitespaceTokenizer}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ws" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class WhitespaceTokenizerFactory extends TokenizerFactory {
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+
+  /** Creates a new WhitespaceTokenizerFactory */
+  public WhitespaceTokenizerFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/TypeTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/TypeTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/TypeTokenFilterFactory.java	(working copy)
@@ -26,11 +26,12 @@
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
  * Factory class for {@link TypeTokenFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="chars" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -40,30 +41,37 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class TypeTokenFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
-
+  private final boolean useWhitelist;
+  private final boolean enablePositionIncrements;
+  private final String stopTypesFiles;
+  private Set<String> stopTypes;
+  
+  /** Creates a new TypeTokenFilterFactory */
+  public TypeTokenFilterFactory(Map<String,String> args) {
+    super(args);
+    stopTypesFiles = args.remove("types");
+    if (stopTypesFiles == null) {
+      throw new IllegalArgumentException("Missing required parameter: types.");
+    }
+    enablePositionIncrements = getBoolean(args, "enablePositionIncrements", false);
+    useWhitelist = getBoolean(args, "useWhitelist", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String stopTypesFiles = args.get("types");
-    enablePositionIncrements = getBoolean("enablePositionIncrements", false);
-    useWhitelist = getBoolean("useWhitelist", false);
-    if (stopTypesFiles != null) {
-      List<String> files = splitFileNames(stopTypesFiles);
-      if (files.size() > 0) {
-        stopTypes = new HashSet<String>();
-        for (String file : files) {
-          List<String> typesLines = getLines(loader, file.trim());
-          stopTypes.addAll(typesLines);
-        }
+    List<String> files = splitFileNames(stopTypesFiles);
+    if (files.size() > 0) {
+      stopTypes = new HashSet<String>();
+      for (String file : files) {
+        List<String> typesLines = getLines(loader, file.trim());
+        stopTypes.addAll(typesLines);
       }
-    } else {
-      throw new IllegalArgumentException("Missing required parameter: types.");
     }
   }
 
-  private boolean useWhitelist;
-  private Set<String> stopTypes;
-  private boolean enablePositionIncrements;
-
   public boolean isEnablePositionIncrements() {
     return enablePositionIncrements;
   }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LowerCaseTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LowerCaseTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LowerCaseTokenizerFactory.java	(working copy)
@@ -23,23 +23,27 @@
 import org.apache.lucene.util.AttributeSource.AttributeFactory;
 
 import java.io.Reader;
+import java.util.HashMap;
 import java.util.Map;
 
 /**
  * Factory for {@link LowerCaseTokenizer}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_lwrcase" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.LowerCaseTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class LowerCaseTokenizerFactory extends TokenizerFactory implements MultiTermAwareComponent {
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  
+  /** Creates a new LowerCaseTokenizerFactory */
+  public LowerCaseTokenizerFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
@@ -49,9 +53,6 @@
 
   @Override
   public AbstractAnalysisFactory getMultiTermComponent() {
-    LowerCaseFilterFactory filt = new LowerCaseFilterFactory();
-    filt.setLuceneMatchVersion(luceneMatchVersion);
-    filt.init(args);
-    return filt;
+    return new LowerCaseFilterFactory(new HashMap<String,String>(getOriginalArgs()));
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LetterTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LetterTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LetterTokenizerFactory.java	(working copy)
@@ -25,20 +25,22 @@
 
 /**
  * Factory for {@link LetterTokenizer}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_letter" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.LetterTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class LetterTokenizerFactory extends TokenizerFactory {
 
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  /** Creates a new LetterTokenizerFactory */
+  public LetterTokenizerFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/LowerCaseFilterFactory.java	(working copy)
@@ -27,20 +27,23 @@
 
 /**
  * Factory for {@link LowerCaseFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_lwrcase" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class LowerCaseFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  
+  /** Creates a new LowerCaseFilterFactory */
+  public LowerCaseFilterFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/StopFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/StopFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/StopFilterFactory.java	(working copy)
@@ -27,7 +27,7 @@
 
 /**
  * Factory for {@link StopFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_stop" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -35,24 +35,31 @@
  *             words="stopwords.txt" enablePositionIncrements="true"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class StopFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
-
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  private CharArraySet stopWords;
+  private final String stopWordFiles;
+  private final String format;
+  private final boolean ignoreCase;
+  private final boolean enablePositionIncrements;
+  
+  /** Creates a new StopFilterFactory */
+  public StopFilterFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    stopWordFiles = args.remove("words");
+    format = args.remove("format");
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    enablePositionIncrements = getBoolean(args, "enablePositionIncrements", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String stopWordFiles = args.get("words");
-    ignoreCase = getBoolean("ignoreCase",false);
-    enablePositionIncrements = getBoolean("enablePositionIncrements",false);
-
     if (stopWordFiles != null) {
-      if ("snowball".equalsIgnoreCase(args.get("format"))) {
+      if ("snowball".equalsIgnoreCase(format)) {
         stopWords = getSnowballWordSet(loader, stopWordFiles, ignoreCase);
       } else {
         stopWords = getWordSet(loader, stopWordFiles, ignoreCase);
@@ -62,10 +69,6 @@
     }
   }
 
-  private CharArraySet stopWords;
-  private boolean ignoreCase;
-  private boolean enablePositionIncrements;
-
   public boolean isEnablePositionIncrements() {
     return enablePositionIncrements;
   }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/core/KeywordTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/core/KeywordTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/core/KeywordTokenizerFactory.java	(working copy)
@@ -21,18 +21,27 @@
 import org.apache.lucene.util.AttributeSource.AttributeFactory;
 
 import java.io.Reader;
+import java.util.Map;
 
 /**
  * Factory for {@link KeywordTokenizer}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_keyword" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.KeywordTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre> 
- *
  */
 public class KeywordTokenizerFactory extends TokenizerFactory {
+  
+  /** Creates a new KeywordTokenizerFactory */
+  public KeywordTokenizerFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public KeywordTokenizer create(AttributeFactory factory, Reader input) {
     return new KeywordTokenizer(factory, input, KeywordTokenizer.DEFAULT_BUFFER_SIZE);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.de.GermanStemFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link GermanStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_destem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.GermanStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class GermanStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new GermanStemFilterFactory */
+  public GermanStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public GermanStemFilter create(TokenStream in) {
     return new GermanStemFilter(in);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanMinimalStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.de.GermanMinimalStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link GermanMinimalStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_deminstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.GermanMinimalStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class GermanMinimalStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new GermanMinimalStemFilterFactory */
+  public GermanMinimalStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new GermanMinimalStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanNormalizationFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.de.GermanNormalizationFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,7 +27,7 @@
 
 /**
  * Factory for {@link GermanNormalizationFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_denorm" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -36,6 +38,14 @@
  */
 public class GermanNormalizationFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
 
+  /** Creates a new GermanNormalizationFilterFactory */
+  public GermanNormalizationFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new GermanNormalizationFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/de/GermanLightStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.de.GermanLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link GermanLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_delgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.GermanLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class GermanLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new GermanLightStemFilterFactory */
+  public GermanLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new GermanLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/hi/HindiStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/hi/HindiStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/hi/HindiStemFilterFactory.java	(working copy)
@@ -17,22 +17,32 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.hi.HindiStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link HindiStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_histem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.HindiStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class HindiStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new HindiStemFilterFactory */
+  public HindiStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new HindiStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/hi/HindiNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/hi/HindiNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/hi/HindiNormalizationFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.hi.HindiNormalizationFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,16 +27,24 @@
 
 /** 
  * Factory for {@link HindiNormalizationFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_hinormal" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.HindiNormalizationFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class HindiNormalizationFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
+  
+  /** Creates a new HindiNormalizationFilterFactory */
+  public HindiNormalizationFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new HindiNormalizationFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/th/ThaiWordFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/th/ThaiWordFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/th/ThaiWordFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.th.ThaiWordFilter;
 
 import org.apache.lucene.analysis.TokenStream;
@@ -24,19 +26,27 @@
 
 /** 
  * Factory for {@link ThaiWordFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_thai" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.ThaiWordFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ThaiWordFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new ThaiWordFilterFactory */
+  public ThaiWordFilterFactory(Map<String,String> args) {
+    super(args);
+    assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public ThaiWordFilter create(TokenStream input) {
-    assureMatchVersion();
     return new ThaiWordFilter(luceneMatchVersion, input);
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/hu/HungarianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/hu/HungarianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/hu/HungarianLightStemFilterFactory.java	(working copy)
@@ -17,23 +17,33 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.hu.HungarianLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link HungarianLightStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_hulgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.HungarianLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class HungarianLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new HungarianLightStemFilterFactory */
+  public HungarianLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new HungarianLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternReplaceCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternReplaceCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternReplaceCharFilterFactory.java	(working copy)
@@ -27,7 +27,7 @@
 
 /**
  * Factory for {@link PatternReplaceCharFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ptnreplace" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;charFilter class="solr.PatternReplaceCharFilterFactory" 
@@ -36,26 +36,29 @@
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
  * 
- *
  * @since Solr 3.1
  */
 public class PatternReplaceCharFilterFactory extends CharFilterFactory {
-  
-  private Pattern p;
-  private String replacement;
+  private final Pattern pattern;
+  private final String replacement;
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init( args );
-    p = getPattern("pattern");
-    replacement = args.get( "replacement" );
-    if( replacement == null )
+  /** Creates a new PatternReplaceCharFilterFactory */
+  public PatternReplaceCharFilterFactory(Map<String, String> args) {
+    super(args);
+    pattern = getPattern(args, "pattern");
+    String v = args.remove("replacement");
+    if (v == null) {
       replacement = "";
-    // TODO: throw exception if you set maxBlockChars or blockDelimiters ?
+    } else {
+      replacement = v;
+    }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
   public CharFilter create(Reader input) {
-    return new PatternReplaceCharFilter( p, replacement, input );
+    return new PatternReplaceCharFilter(pattern, replacement, input);
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternReplaceFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternReplaceFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternReplaceFilterFactory.java	(working copy)
@@ -23,11 +23,10 @@
 
 import java.util.Map;
 import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
 
 /**
  * Factory for {@link PatternReplaceFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ptnreplace" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.KeywordTokenizerFactory"/&gt;
@@ -39,34 +38,32 @@
  * @see PatternReplaceFilter
  */
 public class PatternReplaceFilterFactory extends TokenFilterFactory {
-  Pattern p;
-  String replacement;
-  boolean all = true;
+  final Pattern pattern;
+  final String replacement;
+  final boolean replaceAll;
   
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    p = getPattern("pattern");
-    replacement = args.get("replacement");
+  /** Creates a new PatternReplaceFilterFactory */
+  public PatternReplaceFilterFactory(Map<String, String> args) {
+    super(args);
+    pattern = getPattern(args, "pattern");
+    replacement = args.remove("replacement");
     
-    String r = args.get("replace");
-    if (null != r) {
-      if (r.equals("all")) {
-        all = true;
-      } else {
-        if (r.equals("first")) {
-          all = false;
-        } else {
-          throw new IllegalArgumentException
-            ("Configuration Error: 'replace' must be 'first' or 'all' in "
-             + this.getClass().getName());
-        }
-      }
+    String v = args.remove("replace");
+    if (v == null || v.equals("all")) {
+      replaceAll = true;
+    } else if (v.equals("first")) {
+      replaceAll = false;
+    } else {
+      throw new IllegalArgumentException("Configuration Error: " +
+      		"'replace' must be 'first' or 'all' in " + getClass().getName());
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
-  }
   @Override
   public PatternReplaceFilter create(TokenStream input) {
-    return new PatternReplaceFilter(input, p, replacement, all);
+    return new PatternReplaceFilter(input, pattern, replacement, replaceAll);
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/pattern/PatternTokenizerFactory.java	(working copy)
@@ -17,7 +17,6 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
 import java.io.Reader;
 import java.util.Map;
 import java.util.regex.Pattern;
@@ -45,13 +44,13 @@
  *  pattern = \'([^\']+)\'
  *  group = 0
  *  input = aaa 'bbb' 'ccc'
- *</pre>
+ * </pre>
  * the output will be two tokens: 'bbb' and 'ccc' (including the ' marks).  With the same input
  * but using group=1, the output would be: bbb and ccc (no ' marks)
  * </p>
  * <p>NOTE: This Tokenizer does not output tokens that are of zero length.</p>
  *
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ptn" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.PatternTokenizerFactory" pattern="\'([^\']+)\'" group="1"/&gt;
@@ -60,30 +59,28 @@
  * 
  * @see PatternTokenizer
  * @since solr1.2
- *
  */
-public class PatternTokenizerFactory extends TokenizerFactory
-{
+public class PatternTokenizerFactory extends TokenizerFactory {
   public static final String PATTERN = "pattern";
   public static final String GROUP = "group";
  
-  protected Pattern pattern;
-  protected int group;
+  protected final Pattern pattern;
+  protected final int group;
   
-  /**
-   * Require a configured pattern
-   */
-  @Override
-  public void init(Map<String,String> args) 
-  {
-    super.init(args);
-    pattern = getPattern( PATTERN );
+  /** Creates a new PatternTokenizerFactory */
+  public PatternTokenizerFactory(Map<String,String> args) {
+    super(args);
+    pattern = getPattern(args, PATTERN);
     
-    group = -1;  // use 'split'
-    String g = args.get( GROUP );
-    if( g != null ) {
-      group = Integer.parseInt( g );
+    String v = args.remove(GROUP);
+    if (v == null) {
+      group = -1;  // use 'split'
+    } else {
+      group = Integer.parseInt(v);
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   /**
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java	(working copy)
@@ -31,7 +31,7 @@
  * Factory for {@link SnowballFilter}, with configurable language
  * <p>
  * Note: Use of the "Lovins" stemmer is not recommended, as it is implemented with reflection.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_snowballstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -39,26 +39,35 @@
  *     &lt;filter class="solr.SnowballPorterFilterFactory" protected="protectedkeyword.txt" language="English"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- * 
- *
  */
 public class SnowballPorterFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   public static final String PROTECTED_TOKENS = "protected";
 
-  private String language = "English";
+  private final String language;
+  private final String wordFiles;
   private Class<? extends SnowballProgram> stemClass;
   private CharArraySet protectedWords = null;
+  
+  /** Creates a new SnowballPorterFilterFactory */
+  public SnowballPorterFilterFactory(Map<String,String> args) {
+    super(args);
+    String cfgLanguage = args.remove("language");
+    if (cfgLanguage == null) {
+      language = "English";
+    } else {
+      language = cfgLanguage;
+    }
+    wordFiles = args.remove(PROTECTED_TOKENS);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String cfgLanguage = args.get("language");
-    if (cfgLanguage != null)
-      language = cfgLanguage;
-
     String className = "org.tartarus.snowball.ext." + language + "Stemmer";
     stemClass = loader.newInstance(className, SnowballProgram.class).getClass();
 
-    String wordFiles = args.get(PROTECTED_TOKENS);
     if (wordFiles != null) {
       protectedWords = getWordSet(loader, wordFiles, false);
     }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/lv/LatvianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/lv/LatvianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/lv/LatvianStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.lv.LatvianStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link LatvianStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_lvstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -33,6 +35,15 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class LatvianStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new LatvianStemFilterFactory */
+  public LatvianStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new LatvianStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.pt.PortugueseStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link PortugueseStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ptstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.PortugueseStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class PortugueseStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new PortugueseStemFilterFactory */
+  public PortugueseStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new PortugueseStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseMinimalStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.pt.PortugueseMinimalStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link PortugueseMinimalStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ptminstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.PortugueseMinimalStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class PortugueseMinimalStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new PortugueseMinimalStemFilterFactory */
+  public PortugueseMinimalStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new PortugueseMinimalStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/pt/PortugueseLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.pt.PortugueseLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link PortugueseLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_ptlgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.PortugueseLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class PortugueseLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new PortugueseLightStemFilterFactory */
+  public PortugueseLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new PortugueseLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/tr/TurkishLowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/tr/TurkishLowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/tr/TurkishLowerCaseFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tr.TurkishLowerCaseFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,16 +27,24 @@
 
 /** 
  * Factory for {@link TurkishLowerCaseFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_trlwr" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.TurkishLowerCaseFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class TurkishLowerCaseFilterFactory extends TokenFilterFactory  implements MultiTermAwareComponent {
+  
+  /** Creates a new TurkishLowerCaseFilterFactory */
+  public TurkishLowerCaseFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new TurkishLowerCaseFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/shingle/ShingleFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/shingle/ShingleFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/shingle/ShingleFilterFactory.java	(working copy)
@@ -25,7 +25,7 @@
 
 /** 
  * Factory for {@link ShingleFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_shingle" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -33,25 +33,24 @@
  *             outputUnigrams="true" outputUnigramsIfNoShingles="false" tokenSeparator=" "/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ShingleFilterFactory extends TokenFilterFactory {
-  private int minShingleSize;
-  private int maxShingleSize;
-  private boolean outputUnigrams;
-  private boolean outputUnigramsIfNoShingles;
-  private String tokenSeparator;
+  private final int minShingleSize;
+  private final int maxShingleSize;
+  private final boolean outputUnigrams;
+  private final boolean outputUnigramsIfNoShingles;
+  private final String tokenSeparator;
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    maxShingleSize = getInt("maxShingleSize", 
+  /** Creates a new ShingleFilterFactory */
+  public ShingleFilterFactory(Map<String, String> args) {
+    super(args);
+    maxShingleSize = getInt(args, "maxShingleSize", 
                             ShingleFilter.DEFAULT_MAX_SHINGLE_SIZE);
     if (maxShingleSize < 2) {
       throw new IllegalArgumentException("Invalid maxShingleSize (" + maxShingleSize
                               + ") - must be at least 2");
     }
-    minShingleSize = getInt("minShingleSize",
+    minShingleSize = getInt(args, "minShingleSize",
                             ShingleFilter.DEFAULT_MIN_SHINGLE_SIZE);
     if (minShingleSize < 2) {
       throw new IllegalArgumentException("Invalid minShingleSize (" + minShingleSize
@@ -62,12 +61,16 @@
                               + ") - must be no greater than maxShingleSize ("
                               + maxShingleSize + ")");
     }
-    outputUnigrams = getBoolean("outputUnigrams", true);
-    outputUnigramsIfNoShingles = getBoolean("outputUnigramsIfNoShingles", false);
+    outputUnigrams = getBoolean(args, "outputUnigrams", true);
+    outputUnigramsIfNoShingles = getBoolean(args, "outputUnigramsIfNoShingles", false);
     tokenSeparator = args.containsKey("tokenSeparator")
-                     ? args.get("tokenSeparator")
+                     ? args.remove("tokenSeparator")
                      : ShingleFilter.TOKEN_SEPARATOR;
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
+
   @Override
   public ShingleFilter create(TokenStream input) {
     ShingleFilter r = new ShingleFilter(input, minShingleSize, maxShingleSize);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/path/PathHierarchyTokenizerFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/path/PathHierarchyTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/path/PathHierarchyTokenizerFactory.java	(working copy)
@@ -39,7 +39,7 @@
  * <code>Books/Fic</code>...
  * </p>
  *
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="descendent_path" class="solr.TextField"&gt;
  *   &lt;analyzer type="index"&gt;
  *     &lt;tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" /&gt;
@@ -57,7 +57,7 @@
  * <code>Books/NonFic/Science/Physics/Theory</code> or 
  * <code>Books/NonFic/Law</code>.
  * </p>
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="descendent_path" class="solr.TextField"&gt;
  *   &lt;analyzer type="index"&gt;
  *     &lt;tokenizer class="solr.KeywordTokenizerFactory" /&gt;
@@ -69,59 +69,39 @@
  * </pre>
  */
 public class PathHierarchyTokenizerFactory extends TokenizerFactory {
+  private final char delimiter;
+  private final char replacement;
+  private final boolean reverse;
+  private final int skip;
   
-  private char delimiter;
-  private char replacement;
-  private boolean reverse = false;
-  private int skip =  PathHierarchyTokenizer.DEFAULT_SKIP;
+  /** Creates a new PathHierarchyTokenizerFactory */
+  public PathHierarchyTokenizerFactory(Map<String,String> args) {
+    super(args);
+    delimiter = getChar(args, "delimiter", PathHierarchyTokenizer.DEFAULT_DELIMITER);
+    replacement = getChar(args, "replace", delimiter);
+    reverse = getBoolean(args, "reverse", false);
+    skip = getInt(args, "skip", PathHierarchyTokenizer.DEFAULT_SKIP);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
   
-  /**
-   * Require a configured pattern
-   */
-  @Override
-  public void init(Map<String,String> args){
-    super.init( args );
-    
-    String v = args.get( "delimiter" );
-    if( v != null ){
-      if( v.length() != 1 ){
-        throw new IllegalArgumentException("delimiter should be a char. \"" + v + "\" is invalid");
+  private char getChar(Map<String,String> args, String name, char defaultValue) {
+    String v = args.remove(name);
+    if (v != null) {
+      if (v.length() != 1) {
+        throw new IllegalArgumentException(name + " should be a char. \"" + v + "\" is invalid");
+      } else {
+        return v.charAt(0);
       }
-      else{
-        delimiter = v.charAt(0);
-      }
+    } else {
+      return defaultValue;
     }
-    else{
-      delimiter = PathHierarchyTokenizer.DEFAULT_DELIMITER;
-    }
-    
-    v = args.get( "replace" );
-    if( v != null ){
-      if( v.length() != 1 ){
-        throw new IllegalArgumentException("replace should be a char. \"" + v + "\" is invalid");
-      }
-      else{
-        replacement = v.charAt(0);
-      }
-    }
-    else{
-      replacement = delimiter;
-    }
-    
-    v = args.get( "reverse" );
-    if( v != null ){
-      reverse = "true".equals( v );
-    }
-
-    v = args.get( "skip" );
-    if( v != null ){
-      skip = Integer.parseInt( v );
-    }
   }
 
   @Override
   public Tokenizer create(AttributeFactory factory, Reader input) {
-    if( reverse ) {
+    if (reverse) {
       return new ReversePathHierarchyTokenizer(factory, input, delimiter, replacement, skip);
     }
     return new PathHierarchyTokenizer(factory, input, delimiter, replacement, skip);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/id/IndonesianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/id/IndonesianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/id/IndonesianStemFilterFactory.java	(working copy)
@@ -25,7 +25,7 @@
 
 /** 
  * Factory for {@link IndonesianStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_idstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -33,15 +33,17 @@
  *     &lt;filter class="solr.IndonesianStemFilterFactory" stemDerivational="true"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class IndonesianStemFilterFactory extends TokenFilterFactory {
-  private boolean stemDerivational = true;
+  private final boolean stemDerivational;
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    stemDerivational = getBoolean("stemDerivational", true);
+  /** Creates a new IndonesianStemFilterFactory */
+  public IndonesianStemFilterFactory(Map<String,String> args) {
+    super(args);
+    stemDerivational = getBoolean(args, "stemDerivational", true);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekLowerCaseFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekLowerCaseFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekLowerCaseFilterFactory.java	(working copy)
@@ -27,25 +27,23 @@
 
 /** 
  * Factory for {@link GreekLowerCaseFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_glc" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.GreekLowerCaseFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class GreekLowerCaseFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
  
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
+  /** Creates a new GreekLowerCaseFilterFactory */
+  public GreekLowerCaseFilterFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
-    if (args.containsKey("charset"))
-      throw new IllegalArgumentException(
-          "The charset parameter is no longer supported.  "
-          + "Please process your documents as Unicode instead.");
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/el/GreekStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.el.GreekStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link GreekStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_gstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,13 +33,19 @@
  *     &lt;filter class="solr.GreekStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class GreekStemFilterFactory extends TokenFilterFactory {
 
+  /** Creates a new GreekStemFilterFactory */
+  public GreekStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new GreekStemFilter(input);
   }
-
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/en/PorterStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/en/PorterStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/en/PorterStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.en.PorterStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
  * Factory for {@link PorterStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_porterstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.PorterStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class PorterStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new PorterStemFilterFactory */
+  public PorterStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public PorterStemFilter create(TokenStream input) {
     return new PorterStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/en/EnglishPossessiveFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/en/EnglishPossessiveFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/en/EnglishPossessiveFilterFactory.java	(working copy)
@@ -25,22 +25,24 @@
 
 /**
  * Factory for {@link EnglishPossessiveFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_enpossessive" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
  *     &lt;filter class="solr.EnglishPossessiveFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
- * &lt;/fieldType&gt;</pre> 
- *
+ * &lt;/fieldType&gt;</pre>
  */
 public class EnglishPossessiveFilterFactory extends TokenFilterFactory {
   
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
+  /** Creates a new EnglishPossessiveFilterFactory */
+  public EnglishPossessiveFilterFactory(Map<String,String> args) {
+    super(args);
     assureMatchVersion();
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/en/KStemFilterFactory.java	(working copy)
@@ -17,16 +17,34 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.en.KStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /**
- * Factory for {@link KStemFilter}
+ * Factory for {@link KStemFilter}.
+ * <pre class="prettyprint">
+ * &lt;fieldType name="text_kstem" class="solr.TextField" positionIncrementGap="100"&gt;
+ *   &lt;analyzer&gt;
+ *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
+ *     &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
+ *     &lt;filter class="solr.KStemFilterFactory"/&gt;
+ *   &lt;/analyzer&gt;
+ * &lt;/fieldType&gt;</pre>
  */
 public class KStemFilterFactory extends TokenFilterFactory {
 
+  /** Creates a new KStemFilterFactory */
+  public KStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenFilter create(TokenStream input) {
     return new KStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/en/EnglishMinimalStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/en/EnglishMinimalStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/en/EnglishMinimalStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.en.EnglishMinimalStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link EnglishMinimalStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_enminstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.EnglishMinimalStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class EnglishMinimalStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new EnglishMinimalStemFilterFactory */
+  public EnglishMinimalStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new EnglishMinimalStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ArabicStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ArabicStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ArabicStemFilterFactory.java	(working copy)
@@ -17,14 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.ar.ArabicStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
-
 /**
  * Factory for {@link ArabicStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_arstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -32,10 +33,16 @@
  *     &lt;filter class="solr.ArabicStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ArabicStemFilterFactory extends TokenFilterFactory {
 
+  /** Creates a new ArabicStemFilterFactory */
+  public ArabicStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
   @Override
   public ArabicStemFilter create(TokenStream input) {
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ArabicNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ArabicNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/ar/ArabicNormalizationFilterFactory.java	(working copy)
@@ -17,26 +17,34 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.ar.ArabicNormalizationFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
 import org.apache.lucene.analysis.util.MultiTermAwareComponent;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
-
 /**
  * Factory for {@link ArabicNormalizationFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_arnormal" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.ArabicNormalizationFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class ArabicNormalizationFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
 
+  /** Creates a new ArabicNormalizationFilterFactory */
+  public ArabicNormalizationFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+
   @Override
   public ArabicNormalizationFilter create(TokenStream input) {
     return new ArabicNormalizationFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/in/IndicNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/in/IndicNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/in/IndicNormalizationFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.in.IndicNormalizationFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,16 +27,24 @@
 
 /** 
  * Factory for {@link IndicNormalizationFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_innormal" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *     &lt;filter class="solr.IndicNormalizationFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class IndicNormalizationFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
+  
+  /** Creates a new IndicNormalizationFilterFactory */
+  public IndicNormalizationFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new IndicNormalizationFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/es/SpanishLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/es/SpanishLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/es/SpanishLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.es.SpanishLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link SpanishLightStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_eslgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.SpanishLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class SpanishLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new SpanishLightStemFilterFactory */
+  public SpanishLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new SpanishLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/cjk/CJKWidthFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/cjk/CJKWidthFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/cjk/CJKWidthFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.cjk.CJKWidthFilter;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,7 +27,7 @@
 
 /** 
  * Factory for {@link CJKWidthFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_cjk" class="solr.TextField"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -35,9 +37,16 @@
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
  */
-
 public class CJKWidthFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
   
+  /** Creates a new CJKWidthFilterFactory */
+  public CJKWidthFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new CJKWidthFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/cjk/CJKBigramFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/cjk/CJKBigramFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/cjk/CJKBigramFilterFactory.java	(working copy)
@@ -25,7 +25,7 @@
 
 /** 
  * Factory for {@link CJKBigramFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_cjk" class="solr.TextField"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -38,26 +38,30 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class CJKBigramFilterFactory extends TokenFilterFactory {
-  int flags;
-  boolean outputUnigrams;
+  final int flags;
+  final boolean outputUnigrams;
 
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    flags = 0;
-    if (getBoolean("han", true)) {
+  /** Creates a new CJKBigramFilterFactory */
+  public CJKBigramFilterFactory(Map<String,String> args) {
+    super(args);
+    int flags = 0;
+    if (getBoolean(args, "han", true)) {
       flags |= CJKBigramFilter.HAN;
     }
-    if (getBoolean("hiragana", true)) {
+    if (getBoolean(args, "hiragana", true)) {
       flags |= CJKBigramFilter.HIRAGANA;
     }
-    if (getBoolean("katakana", true)) {
+    if (getBoolean(args, "katakana", true)) {
       flags |= CJKBigramFilter.KATAKANA;
     }
-    if (getBoolean("hangul", true)) {
+    if (getBoolean(args, "hangul", true)) {
       flags |= CJKBigramFilter.HANGUL;
     }
-    outputUnigrams = getBoolean("outputUnigrams", false);
+    this.flags = flags;
+    this.outputUnigrams = getBoolean(args, "outputUnigrams", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/it/ItalianLightStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/it/ItalianLightStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/it/ItalianLightStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.it.ItalianLightStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link ItalianLightStemFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_itlgtstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.ItalianLightStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre> 
- *
  */
 public class ItalianLightStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new ItalianLightStemFilterFactory */
+  public ItalianLightStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new ItalianLightStemFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/synonym/SynonymFilterFactory.java	(working copy)
@@ -25,7 +25,9 @@
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CodingErrorAction;
 import java.text.ParseException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.lucene.analysis.Analyzer;
 import org.apache.lucene.analysis.TokenStream;
@@ -41,7 +43,7 @@
 
 /**
  * Factory for {@link SynonymFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_synonym" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -52,9 +54,33 @@
  * &lt;/fieldType&gt;</pre>
  */
 public class SynonymFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
+  private final boolean ignoreCase;
+  private final String tokenizerFactory;
+  private final String synonyms;
+  private final String format;
+  private final boolean expand;
+
   private SynonymMap map;
-  private boolean ignoreCase;
   
+  public SynonymFilterFactory(Map<String,String> args) {
+    super(args);
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    tokenizerFactory = args.remove("tokenizerFactory");
+    if (tokenizerFactory != null) {
+      assureMatchVersion();
+    }
+    synonyms = args.remove("synonyms");
+    if (synonyms == null) {
+      throw new IllegalArgumentException("Missing required argument 'synonyms'.");
+    }
+    format = args.remove("format");
+    expand = getBoolean(args, "expand", true);
+
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     // if the fst is null, it means there's actually no synonyms... just return the original stream
@@ -64,12 +90,7 @@
 
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    final boolean ignoreCase = getBoolean("ignoreCase", false); 
-    this.ignoreCase = ignoreCase;
-
-    String tf = args.get("tokenizerFactory");
-
-    final TokenizerFactory factory = tf == null ? null : loadTokenizerFactory(loader, tf);
+    final TokenizerFactory factory = tokenizerFactory == null ? null : loadTokenizerFactory(loader, tokenizerFactory);
     
     Analyzer analyzer = new Analyzer() {
       @Override
@@ -80,7 +101,6 @@
       }
     };
 
-    String format = args.get("format");
     try {
       if (format == null || format.equals("solr")) {
         // TODO: expose dedup as a parameter?
@@ -99,12 +119,7 @@
   /**
    * Load synonyms from the solr format, "format=solr".
    */
-  private SynonymMap loadSolrSynonyms(ResourceLoader loader, boolean dedup, Analyzer analyzer) throws IOException, ParseException {
-    final boolean expand = getBoolean("expand", true);
-    String synonyms = args.get("synonyms");
-    if (synonyms == null)
-      throw new IllegalArgumentException("Missing required argument 'synonyms'.");
-    
+  private SynonymMap loadSolrSynonyms(ResourceLoader loader, boolean dedup, Analyzer analyzer) throws IOException, ParseException {    
     CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder()
       .onMalformedInput(CodingErrorAction.REPORT)
       .onUnmappableCharacter(CodingErrorAction.REPORT);
@@ -128,11 +143,6 @@
    * Load synonyms from the wordnet format, "format=wordnet".
    */
   private SynonymMap loadWordnetSynonyms(ResourceLoader loader, boolean dedup, Analyzer analyzer) throws IOException, ParseException {
-    final boolean expand = getBoolean("expand", true);
-    String synonyms = args.get("synonyms");
-    if (synonyms == null)
-      throw new IllegalArgumentException("Missing required argument 'synonyms'.");
-    
     CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder()
       .onMalformedInput(CodingErrorAction.REPORT)
       .onUnmappableCharacter(CodingErrorAction.REPORT);
@@ -154,12 +164,17 @@
   
   // (there are no tests for this functionality)
   private TokenizerFactory loadTokenizerFactory(ResourceLoader loader, String cname) throws IOException {
-    TokenizerFactory tokFactory = loader.newInstance(cname, TokenizerFactory.class);
-    tokFactory.setLuceneMatchVersion(luceneMatchVersion);
-    tokFactory.init(args);
-    if (tokFactory instanceof ResourceLoaderAware) {
-      ((ResourceLoaderAware) tokFactory).inform(loader);
+    Map<String,String> args = new HashMap<String,String>();
+    args.put("luceneMatchVersion", getLuceneMatchVersion().toString());
+    Class<? extends TokenizerFactory> clazz = loader.findClass(cname, TokenizerFactory.class);
+    try {
+      TokenizerFactory tokFactory = clazz.newInstance();
+      if (tokFactory instanceof ResourceLoaderAware) {
+        ((ResourceLoaderAware) tokFactory).inform(loader);
+      }
+      return tokFactory;
+    } catch (Exception e) {
+      throw new RuntimeException(e);
     }
-    return tokFactory;
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/commongrams/CommonGramsQueryFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/commongrams/CommonGramsQueryFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/commongrams/CommonGramsQueryFilterFactory.java	(working copy)
@@ -17,77 +17,37 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
 import java.util.Map;
 
+import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.commongrams.CommonGramsFilter;
 import org.apache.lucene.analysis.commongrams.CommonGramsQueryFilter;
-import org.apache.lucene.analysis.core.StopAnalyzer;
-import org.apache.lucene.analysis.core.StopFilterFactory;
-import org.apache.lucene.analysis.util.*;
 
 /**
  * Construct {@link CommonGramsQueryFilter}.
  * 
- * This is pretty close to a straight copy from {@link StopFilterFactory}.
- * 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_cmmngrmsqry" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.CommonGramsQueryFilterFactory" words="commongramsquerystopwords.txt" ignoreCase="false"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
-public class CommonGramsQueryFilterFactory extends TokenFilterFactory
-    implements ResourceLoaderAware {
+public class CommonGramsQueryFilterFactory extends CommonGramsFilterFactory {
 
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    assureMatchVersion();
+  /** Creates a new CommonGramsQueryFilterFactory */
+  public CommonGramsQueryFilterFactory(Map<String,String> args) {
+    super(args);
   }
 
-  @Override
-  public void inform(ResourceLoader loader) throws IOException {
-    String commonWordFiles = args.get("words");
-    ignoreCase = getBoolean("ignoreCase", false);
-
-    if (commonWordFiles != null) {
-      if ("snowball".equalsIgnoreCase(args.get("format"))) {
-        commonWords = getSnowballWordSet(loader, commonWordFiles, ignoreCase);
-      } else {
-        commonWords = getWordSet(loader, commonWordFiles, ignoreCase);
-      }
-    } else {
-      commonWords = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
-    }
-  }
-
-  // Force the use of a char array set, as it is the most performant, although
-  // this may break things if Lucene ever goes away from it. See SOLR-1095
-  private CharArraySet commonWords;
-
-  private boolean ignoreCase;
-
-  public boolean isIgnoreCase() {
-    return ignoreCase;
-  }
-
-  public CharArraySet getCommonWords() {
-    return commonWords;
-  }
-
   /**
    * Create a CommonGramsFilter and wrap it with a CommonGramsQueryFilter
    */
   @Override
-  public CommonGramsQueryFilter create(TokenStream input) {
-    CommonGramsFilter commonGrams = new CommonGramsFilter(luceneMatchVersion, input, commonWords);
-    CommonGramsQueryFilter commonGramsQuery = new CommonGramsQueryFilter(
-        commonGrams);
-    return commonGramsQuery;
+  public TokenFilter create(TokenStream input) {
+    CommonGramsFilter commonGrams = (CommonGramsFilter) super.create(input);
+    return new CommonGramsQueryFilter(commonGrams);
   }
 }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/commongrams/CommonGramsFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/commongrams/CommonGramsFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/commongrams/CommonGramsFilterFactory.java	(working copy)
@@ -18,7 +18,9 @@
  */
 
 import java.io.IOException;
+import java.util.Map;
 
+import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.commongrams.CommonGramsFilter;
 import org.apache.lucene.analysis.core.StopAnalyzer;
@@ -26,29 +28,36 @@
 
 /**
  * Constructs a {@link CommonGramsFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_cmmngrms" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
  *     &lt;filter class="solr.CommonGramsFilterFactory" words="commongramsstopwords.txt" ignoreCase="false"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
+public class CommonGramsFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
+  // TODO: shared base class for Stop/Keep/CommonGrams? 
+  private CharArraySet commonWords;
+  private final String commonWordFiles;
+  private final String format;
+  private final boolean ignoreCase;
+  
+  /** Creates a new CommonGramsFilterFactory */
+  public CommonGramsFilterFactory(Map<String,String> args) {
+    super(args);
+    commonWordFiles = args.remove("words");
+    format = args.remove("format");
+    ignoreCase = getBoolean(args, "ignoreCase", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
-/*
- * This is pretty close to a straight copy from StopFilterFactory
- */
-public class CommonGramsFilterFactory extends TokenFilterFactory implements
-    ResourceLoaderAware {
-
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String commonWordFiles = args.get("words");
-    ignoreCase = getBoolean("ignoreCase", false);
-
     if (commonWordFiles != null) {
-      if ("snowball".equalsIgnoreCase(args.get("format"))) {
+      if ("snowball".equalsIgnoreCase(format)) {
         commonWords = getSnowballWordSet(loader, commonWordFiles, ignoreCase);
       } else {
         commonWords = getWordSet(loader, commonWordFiles, ignoreCase);
@@ -57,10 +66,6 @@
       commonWords = StopAnalyzer.ENGLISH_STOP_WORDS_SET;
     }
   }
-      
-    //Force the use of a char array set, as it is the most performant, although this may break things if Lucene ever goes away from it.  See SOLR-1095
-    private CharArraySet commonWords;
-    private boolean ignoreCase;
 
   public boolean isIgnoreCase() {
     return ignoreCase;
@@ -71,7 +76,7 @@
   }
 
   @Override
-  public CommonGramsFilter create(TokenStream input) {
+  public TokenFilter create(TokenStream input) {
     CommonGramsFilter commonGrams = new CommonGramsFilter(luceneMatchVersion, input, commonWords);
     return commonGrams;
   }
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/DictionaryCompoundWordTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/DictionaryCompoundWordTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/DictionaryCompoundWordTokenFilterFactory.java	(working copy)
@@ -25,7 +25,7 @@
 
 /** 
  * Factory for {@link DictionaryCompoundWordTokenFilter}. 
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_dictcomp" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -33,33 +33,38 @@
  *         minWordSize="5" minSubwordSize="2" maxSubwordSize="15" onlyLongestMatch="true"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class DictionaryCompoundWordTokenFilterFactory extends TokenFilterFactory  implements ResourceLoaderAware {
   private CharArraySet dictionary;
-  private String dictFile;
-  private int minWordSize;
-  private int minSubwordSize;
-  private int maxSubwordSize;
-  private boolean onlyLongestMatch;
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
+  private final String dictFile;
+  private final int minWordSize;
+  private final int minSubwordSize;
+  private final int maxSubwordSize;
+  private final boolean onlyLongestMatch;
+
+  /** Creates a new DictionaryCompoundWordTokenFilterFactory */
+  public DictionaryCompoundWordTokenFilterFactory(Map<String, String> args) {
+    super(args);
     assureMatchVersion();
-    dictFile = args.get("dictionary");
+    dictFile = args.remove("dictionary");
     if (null == dictFile) {
       throw new IllegalArgumentException("Missing required parameter: dictionary");
     }
 
-    minWordSize= getInt("minWordSize",CompoundWordTokenFilterBase.DEFAULT_MIN_WORD_SIZE);
-    minSubwordSize= getInt("minSubwordSize",CompoundWordTokenFilterBase.DEFAULT_MIN_SUBWORD_SIZE);
-    maxSubwordSize= getInt("maxSubwordSize",CompoundWordTokenFilterBase.DEFAULT_MAX_SUBWORD_SIZE);
-    onlyLongestMatch = getBoolean("onlyLongestMatch",true);
+    minWordSize = getInt(args, "minWordSize", CompoundWordTokenFilterBase.DEFAULT_MIN_WORD_SIZE);
+    minSubwordSize = getInt(args, "minSubwordSize", CompoundWordTokenFilterBase.DEFAULT_MIN_SUBWORD_SIZE);
+    maxSubwordSize = getInt(args, "maxSubwordSize", CompoundWordTokenFilterBase.DEFAULT_MAX_SUBWORD_SIZE);
+    onlyLongestMatch = getBoolean(args, "onlyLongestMatch", true);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
+  
   @Override
   public void inform(ResourceLoader loader) throws IOException {
     dictionary = super.getWordSet(loader, dictFile, false);
   }
+  
   @Override
   public TokenStream create(TokenStream input) {
     // if the dictionary is null, it means it was empty
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/HyphenationCompoundWordTokenFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/HyphenationCompoundWordTokenFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/compound/HyphenationCompoundWordTokenFilterFactory.java	(working copy)
@@ -45,7 +45,7 @@
  *    to the stream. defaults to false.
  * </ul>
  * <p>
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_hyphncomp" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
@@ -59,30 +59,32 @@
 public class HyphenationCompoundWordTokenFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
   private CharArraySet dictionary;
   private HyphenationTree hyphenator;
-  private String dictFile;
-  private String hypFile;
-  private String encoding;
-  private int minWordSize;
-  private int minSubwordSize;
-  private int maxSubwordSize;
-  private boolean onlyLongestMatch;
+  private final String dictFile;
+  private final String hypFile;
+  private final String encoding;
+  private final int minWordSize;
+  private final int minSubwordSize;
+  private final int maxSubwordSize;
+  private final boolean onlyLongestMatch;
   
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
+  /** Creates a new HyphenationCompoundWordTokenFilterFactory */
+  public HyphenationCompoundWordTokenFilterFactory(Map<String, String> args) {
+    super(args);
     assureMatchVersion();
-    dictFile = args.get("dictionary");
-    if (args.containsKey("encoding"))
-      encoding = args.get("encoding");
-    hypFile = args.get("hyphenator");
+    dictFile = args.remove("dictionary");
+    encoding = args.remove("encoding");
+    hypFile = args.remove("hyphenator");
     if (null == hypFile) {
       throw new IllegalArgumentException("Missing required parameter: hyphenator");
     }
 
-    minWordSize = getInt("minWordSize", CompoundWordTokenFilterBase.DEFAULT_MIN_WORD_SIZE);
-    minSubwordSize = getInt("minSubwordSize", CompoundWordTokenFilterBase.DEFAULT_MIN_SUBWORD_SIZE);
-    maxSubwordSize = getInt("maxSubwordSize", CompoundWordTokenFilterBase.DEFAULT_MAX_SUBWORD_SIZE);
-    onlyLongestMatch = getBoolean("onlyLongestMatch", false);
+    minWordSize = getInt(args, "minWordSize", CompoundWordTokenFilterBase.DEFAULT_MIN_WORD_SIZE);
+    minSubwordSize = getInt(args, "minSubwordSize", CompoundWordTokenFilterBase.DEFAULT_MIN_SUBWORD_SIZE);
+    maxSubwordSize = getInt(args, "maxSubwordSize", CompoundWordTokenFilterBase.DEFAULT_MAX_SUBWORD_SIZE);
+    onlyLongestMatch = getBoolean(args, "onlyLongestMatch", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
   
   @Override
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/fa/PersianNormalizationFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/fa/PersianNormalizationFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/fa/PersianNormalizationFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.fa.PersianNormalizationFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.util.AbstractAnalysisFactory;
@@ -25,7 +27,7 @@
 
 /** 
  * Factory for {@link PersianNormalizationFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_fanormal" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;charFilter class="solr.PersianCharFilterFactory"/&gt;
@@ -33,9 +35,17 @@
  *     &lt;filter class="solr.PersianNormalizationFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class PersianNormalizationFilterFactory extends TokenFilterFactory implements MultiTermAwareComponent {
+  
+  /** Creates a new PersianNormalizationFilterFactory */
+  public PersianNormalizationFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public PersianNormalizationFilter create(TokenStream input) {
     return new PersianNormalizationFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/fa/PersianCharFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/fa/PersianCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/fa/PersianCharFilterFactory.java	(working copy)
@@ -18,6 +18,7 @@
  */
 
 import java.io.Reader;
+import java.util.Map;
 
 import org.apache.lucene.analysis.CharFilter;
 import org.apache.lucene.analysis.fa.PersianCharFilter;
@@ -27,17 +28,24 @@
 
 /**
  * Factory for {@link PersianCharFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_fa" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;charFilter class="solr.PersianCharFilterFactory"/&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class PersianCharFilterFactory extends CharFilterFactory implements MultiTermAwareComponent {
 
+  /** Creates a new PersianCharFilterFactory */
+  public PersianCharFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public CharFilter create(Reader input) {
     return new PersianCharFilter(input);
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/bg/BulgarianStemFilterFactory.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/bg/BulgarianStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/bg/BulgarianStemFilterFactory.java	(working copy)
@@ -17,13 +17,15 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.bg.BulgarianStemFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
 
 /** 
  * Factory for {@link BulgarianStemFilter}.
- * <pre class="prettyprint" >
+ * <pre class="prettyprint">
  * &lt;fieldType name="text_bgstem" class="solr.TextField" positionIncrementGap="100"&gt;
  *   &lt;analyzer&gt;
  *     &lt;tokenizer class="solr.StandardTokenizerFactory"/&gt;
@@ -31,9 +33,17 @@
  *     &lt;filter class="solr.BulgarianStemFilterFactory"/&gt;
  *   &lt;/analyzer&gt;
  * &lt;/fieldType&gt;</pre>
- *
  */
 public class BulgarianStemFilterFactory extends TokenFilterFactory {
+  
+  /** Creates a new BulgarianStemFilterFactory */
+  public BulgarianStemFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new BulgarianStemFilter(input);
Index: lucene/analysis/uima/src/java/org/apache/lucene/analysis/uima/UIMATypeAwareAnnotationsTokenizerFactory.java
===================================================================
--- lucene/analysis/uima/src/java/org/apache/lucene/analysis/uima/UIMATypeAwareAnnotationsTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/uima/src/java/org/apache/lucene/analysis/uima/UIMATypeAwareAnnotationsTokenizerFactory.java	(working copy)
@@ -32,12 +32,11 @@
   private String descriptorPath;
   private String tokenType;
   private String featurePath;
-  private Map<String, Object> configurationParameters;
+  private final Map<String,Object> configurationParameters = new HashMap<String,Object>();
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    configurationParameters = new HashMap<String, Object>();
+  /** Creates a new UIMATypeAwareAnnotationsTokenizerFactory */
+  public UIMATypeAwareAnnotationsTokenizerFactory(Map<String, String> args) {
+    super(args);
     for (String k : args.keySet()) {
       if (k.equals("featurePath")) {
         featurePath = args.get("featurePath");
Index: lucene/analysis/uima/src/java/org/apache/lucene/analysis/uima/UIMAAnnotationsTokenizerFactory.java
===================================================================
--- lucene/analysis/uima/src/java/org/apache/lucene/analysis/uima/UIMAAnnotationsTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/uima/src/java/org/apache/lucene/analysis/uima/UIMAAnnotationsTokenizerFactory.java	(working copy)
@@ -31,12 +31,11 @@
 
   private String descriptorPath;
   private String tokenType;
-  private Map<String, Object> configurationParameters;
+  private final Map<String,Object> configurationParameters = new HashMap<String,Object>();
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    configurationParameters = new HashMap<String, Object>();
+  /** Creates a new UIMAAnnotationsTokenizerFactory */
+  public UIMAAnnotationsTokenizerFactory(Map<String, String> args) {
+    super(args);
     for (String k : args.keySet()) {
       if (k.equals("tokenType")) {
         tokenType = args.get("tokenType");
@@ -49,7 +48,6 @@
     if (descriptorPath == null || tokenType == null ) {
       throw new IllegalArgumentException("descriptorPath and tokenType are mandatory");
     }
-
   }
 
   @Override
Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseReadingFormFilterFactory.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseReadingFormFilterFactory.java	(revision 1462646)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseReadingFormFilterFactory.java	(working copy)
@@ -37,12 +37,15 @@
  */
 public class JapaneseReadingFormFilterFactory extends TokenFilterFactory {
   private static final String ROMAJI_PARAM = "useRomaji";
-  private boolean useRomaji;
+  private final boolean useRomaji;
   
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    useRomaji = getBoolean(ROMAJI_PARAM, false);
+  /** Creates a new JapaneseReadingFormFilterFactory */
+  public JapaneseReadingFormFilterFactory(Map<String,String> args) {
+    super(args);
+    useRomaji = getBoolean(args, ROMAJI_PARAM, false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseBaseFormFilterFactory.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseBaseFormFilterFactory.java	(revision 1462646)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseBaseFormFilterFactory.java	(working copy)
@@ -17,6 +17,8 @@
  * limitations under the License.
  */
 
+import java.util.Map;
+
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.ja.JapaneseBaseFormFilter;
 import org.apache.lucene.analysis.util.TokenFilterFactory;
@@ -34,6 +36,14 @@
  */
 public class JapaneseBaseFormFilterFactory extends TokenFilterFactory {
 
+  /** Creates a new JapaneseBaseFormFilterFactory */
+  public JapaneseBaseFormFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public TokenStream create(TokenStream input) {
     return new JapaneseBaseFormFilter(input);
Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseTokenizerFactory.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseTokenizerFactory.java	(revision 1462646)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseTokenizerFactory.java	(working copy)
@@ -62,17 +62,28 @@
 
   private UserDictionary userDictionary;
 
-  private Mode mode;
+  private final Mode mode;
+  private final boolean discardPunctuation;  
+  private final String userDictionaryPath;
+  private final String userDictionaryEncoding;
 
-  private boolean discardPunctuation;
-
+  /** Creates a new JapaneseTokenizerFactory */
+  public JapaneseTokenizerFactory(Map<String,String> args) {
+    super(args);
+    mode = getMode(args);
+    userDictionaryPath = args.remove(USER_DICT_PATH);
+    userDictionaryEncoding = args.remove(USER_DICT_ENCODING);
+    discardPunctuation = getBoolean(args, DISCARD_PUNCTUATION, true);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    mode = getMode(args);
-    String userDictionaryPath = args.get(USER_DICT_PATH);
     if (userDictionaryPath != null) {
       InputStream stream = loader.openResource(userDictionaryPath);
-      String encoding = args.get(USER_DICT_ENCODING);
+      String encoding = userDictionaryEncoding;
       if (encoding == null) {
         encoding = IOUtils.UTF_8;
       }
@@ -84,7 +95,6 @@
     } else {
       userDictionary = null;
     }
-    discardPunctuation = getBoolean(DISCARD_PUNCTUATION, true);
   }
   
   @Override
@@ -92,10 +102,10 @@
     return new JapaneseTokenizer(factory, input, userDictionary, discardPunctuation, mode);
   }
   
-  private Mode getMode(Map<String, String> args) {
-    String mode = args.get(MODE);
-    if (mode != null) {
-      return Mode.valueOf(mode.toUpperCase(Locale.ROOT));
+  private Mode getMode(Map<String,String> args) {
+    String modeArg = args.remove(MODE);
+    if (modeArg != null) {
+      return Mode.valueOf(modeArg.toUpperCase(Locale.ROOT));
     } else {
       return JapaneseTokenizer.DEFAULT_MODE;
     }
Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseKatakanaStemFilterFactory.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseKatakanaStemFilterFactory.java	(revision 1462646)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseKatakanaStemFilterFactory.java	(working copy)
@@ -37,15 +37,18 @@
  */
 public class JapaneseKatakanaStemFilterFactory extends TokenFilterFactory {
   private static final String MINIMUM_LENGTH_PARAM = "minimumLength";
-  private int minimumLength;
+  private final int minimumLength;
   
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    minimumLength = getInt(MINIMUM_LENGTH_PARAM, JapaneseKatakanaStemFilter.DEFAULT_MINIMUM_LENGTH);
+  /** Creates a new JapaneseKatakanaStemFilterFactory */
+  public JapaneseKatakanaStemFilterFactory(Map<String,String> args) {
+    super(args);
+    minimumLength = getInt(args, MINIMUM_LENGTH_PARAM, JapaneseKatakanaStemFilter.DEFAULT_MINIMUM_LENGTH);
     if (minimumLength < 2) {
       throw new IllegalArgumentException("Illegal " + MINIMUM_LENGTH_PARAM + " " + minimumLength + " (must be 2 or greater)");
     }
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseIterationMarkCharFilterFactory.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseIterationMarkCharFilterFactory.java	(revision 1462646)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapaneseIterationMarkCharFilterFactory.java	(working copy)
@@ -39,26 +39,27 @@
 public class JapaneseIterationMarkCharFilterFactory extends CharFilterFactory implements MultiTermAwareComponent {
 
   private static final String NORMALIZE_KANJI_PARAM = "normalizeKanji";
-
   private static final String NORMALIZE_KANA_PARAM = "normalizeKana";
 
-  private boolean normalizeKanji = true;
+  private final boolean normalizeKanji;
+  private final boolean normalizeKana;
+  
+  /** Creates a new JapaneseIterationMarkCharFilterFactory */
+  public JapaneseIterationMarkCharFilterFactory(Map<String,String> args) {
+    super(args);
+    normalizeKanji = getBoolean(args, NORMALIZE_KANJI_PARAM, JapaneseIterationMarkCharFilter.NORMALIZE_KANJI_DEFAULT);
+    normalizeKana = getBoolean(args, NORMALIZE_KANA_PARAM, JapaneseIterationMarkCharFilter.NORMALIZE_KANA_DEFAULT);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
 
-  private boolean normalizeKana = true;
-
   @Override
   public CharFilter create(Reader input) {
     return new JapaneseIterationMarkCharFilter(input, normalizeKanji, normalizeKana);
   }
 
   @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    normalizeKanji = getBoolean(NORMALIZE_KANJI_PARAM, JapaneseIterationMarkCharFilter.NORMALIZE_KANJI_DEFAULT);
-    normalizeKana = getBoolean(NORMALIZE_KANA_PARAM, JapaneseIterationMarkCharFilter.NORMALIZE_KANA_DEFAULT);
-  }
-
-  @Override
   public AbstractAnalysisFactory getMultiTermComponent() {
     return this;
   }
Index: lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapanesePartOfSpeechStopFilterFactory.java
===================================================================
--- lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapanesePartOfSpeechStopFilterFactory.java	(revision 1462646)
+++ lucene/analysis/kuromoji/src/java/org/apache/lucene/analysis/ja/JapanesePartOfSpeechStopFilterFactory.java	(working copy)
@@ -19,6 +19,7 @@
 
 import java.io.IOException;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import org.apache.lucene.analysis.TokenStream;
@@ -39,13 +40,22 @@
  * </pre>
  */
 public class JapanesePartOfSpeechStopFilterFactory extends TokenFilterFactory implements ResourceLoaderAware  {
-  private boolean enablePositionIncrements;
+  private final String stopTagFiles;
+  private final boolean enablePositionIncrements;
   private Set<String> stopTags;
 
+  /** Creates a new JapanesePartOfSpeechStopFilterFactory */
+  public JapanesePartOfSpeechStopFilterFactory(Map<String,String> args) {
+    super(args);
+    stopTagFiles = args.remove("tags");
+    enablePositionIncrements = getBoolean(args, "enablePositionIncrements", false);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public void inform(ResourceLoader loader) throws IOException {
-    String stopTagFiles = args.get("tags");
-    enablePositionIncrements = getBoolean("enablePositionIncrements", false);
     stopTags = null;
     CharArraySet cas = getWordSet(loader, stopTagFiles, false);
     if (cas != null) {
Index: solr/test-framework/src/java/org/apache/solr/analysis/MockCharFilterFactory.java
===================================================================
--- solr/test-framework/src/java/org/apache/solr/analysis/MockCharFilterFactory.java	(revision 1462646)
+++ solr/test-framework/src/java/org/apache/solr/analysis/MockCharFilterFactory.java	(working copy)
@@ -27,16 +27,19 @@
  * Factory for {@link MockCharFilter} for testing purposes.
  */
 public class MockCharFilterFactory extends CharFilterFactory {
-  int remainder;
+  final int remainder;
 
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    String sval = args.get("remainder");
+  /** Creates a new MockCharFilterFactory */
+  public MockCharFilterFactory(Map<String,String> args) {
+    super(args);
+    String sval = args.remove("remainder");
     if (sval == null) {
       throw new IllegalArgumentException("remainder is mandatory");
     }
     remainder = Integer.parseInt(sval);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: solr/test-framework/src/java/org/apache/solr/analysis/MockTokenizerFactory.java
===================================================================
--- solr/test-framework/src/java/org/apache/solr/analysis/MockTokenizerFactory.java	(revision 1462646)
+++ solr/test-framework/src/java/org/apache/solr/analysis/MockTokenizerFactory.java	(working copy)
@@ -29,13 +29,13 @@
  * Factory for {@link MockTokenizer} for testing purposes.
  */
 public class MockTokenizerFactory extends TokenizerFactory {
-  CharacterRunAutomaton pattern;
-  boolean enableChecks;
+  final CharacterRunAutomaton pattern;
+  final boolean enableChecks;
   
-  @Override
-  public void init(Map<String,String> args) {
-    super.init(args);
-    String patternArg = args.get("pattern");
+  /** Creates a new MockTokenizerFactory */
+  public MockTokenizerFactory(Map<String,String> args) {
+    super(args);
+    String patternArg = args.remove("pattern");
     if (patternArg == null) {
       patternArg = "whitespace";
     }
@@ -50,7 +50,10 @@
       throw new RuntimeException("invalid pattern!");
     }
     
-    enableChecks = getBoolean("enableChecks", true);
+    enableChecks = getBoolean(args, "enableChecks", true);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
   @Override
Index: solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java
===================================================================
--- solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java	(revision 1462646)
+++ solr/core/src/java/org/apache/solr/schema/FieldTypePluginLoader.java	(working copy)
@@ -183,13 +183,8 @@
   }
 
   private static class MultiTermChainBuilder {
-    static final KeywordTokenizerFactory keyFactory;
+    static final KeywordTokenizerFactory keyFactory = new KeywordTokenizerFactory(new HashMap<String,String>());
 
-    static {
-      keyFactory = new KeywordTokenizerFactory();
-      keyFactory.init(new HashMap<String,String>());
-    }
-
     ArrayList<CharFilterFactory> charFilters = null;
     ArrayList<TokenFilterFactory> filters = new ArrayList<TokenFilterFactory>(2);
     TokenizerFactory tokenizer = keyFactory;
Index: solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java
===================================================================
--- solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java	(revision 1462646)
+++ solr/core/src/java/org/apache/solr/core/SolrResourceLoader.java	(working copy)
@@ -372,7 +372,12 @@
   // Using this pattern, legacy analysis components from previous Solr versions are identified and delegated to SPI loader:
   private static final Pattern legacyAnalysisPattern = 
       Pattern.compile("((\\Q"+base+".analysis.\\E)|(\\Q"+project+".\\E))([\\p{L}_$][\\p{L}\\p{N}_$]+?)(TokenFilter|Filter|Tokenizer|CharFilter)Factory");
-      
+
+  @Override
+  public <T> Class<? extends T> findClass(String cname, Class<T> expectedType) {
+    return findClass(cname, expectedType, empty);
+  }
+  
   /**
    * This method loads a class either with it's FQN or a short-name (solr.class-simplename or class-simplename).
    * It tries to load the class with the name that is given first and if it fails, it tries all the known
Index: solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java
===================================================================
--- solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java	(revision 1462646)
+++ solr/core/src/java/org/apache/solr/handler/admin/LukeRequestHandler.java	(working copy)
@@ -476,7 +476,7 @@
         Map<String, Object> tok = new HashMap<String, Object>();
         String className = cfiltfac.getClass().getName();
         tok.put("className", className);
-        tok.put("args", cfiltfac.getArgs());
+        tok.put("args", cfiltfac.getOriginalArgs());
         cfilters.add(className.substring(className.lastIndexOf('.')+1), tok);
       }
       if (cfilters.size() > 0) {
@@ -486,7 +486,7 @@
       SimpleOrderedMap<Object> tokenizer = new SimpleOrderedMap<Object>();
       TokenizerFactory tfac = tchain.getTokenizerFactory();
       tokenizer.add("className", tfac.getClass().getName());
-      tokenizer.add("args", tfac.getArgs());
+      tokenizer.add("args", tfac.getOriginalArgs());
       aninfo.add("tokenizer", tokenizer);
 
       TokenFilterFactory[] filtfacs = tchain.getTokenFilterFactories();
@@ -495,7 +495,7 @@
         Map<String, Object> tok = new HashMap<String, Object>();
         String className = filtfac.getClass().getName();
         tok.put("className", className);
-        tok.put("args", filtfac.getArgs());
+        tok.put("args", filtfac.getOriginalArgs());
         filters.add(className.substring(className.lastIndexOf('.')+1), tok);
       }
       if (filters.size() > 0) {
Index: solr/core/src/java/org/apache/solr/analysis/TrieTokenizerFactory.java
===================================================================
--- solr/core/src/java/org/apache/solr/analysis/TrieTokenizerFactory.java	(revision 1462646)
+++ solr/core/src/java/org/apache/solr/analysis/TrieTokenizerFactory.java	(working copy)
@@ -31,6 +31,7 @@
 
 import java.io.IOException;
 import java.io.Reader;
+import java.util.HashMap;
 import java.util.Iterator;
 
 /**
@@ -50,6 +51,7 @@
   protected final TrieTypes type;
 
   public TrieTokenizerFactory(TrieTypes type, int precisionStep) {
+    super(new HashMap<String,String>());
     this.type = type;
     this.precisionStep = precisionStep;
   }
Index: solr/core/src/java/org/apache/solr/analysis/ReversedWildcardFilterFactory.java
===================================================================
--- solr/core/src/java/org/apache/solr/analysis/ReversedWildcardFilterFactory.java	(revision 1462646)
+++ solr/core/src/java/org/apache/solr/analysis/ReversedWildcardFilterFactory.java	(working copy)
@@ -71,14 +71,17 @@
   private int minTrailing;
   private float maxFractionAsterisk;
 
-  @Override
-  public void init(Map<String, String> args) {
-    super.init(args);
-    withOriginal = getBoolean("withOriginal", true);
-    maxPosAsterisk = getInt("maxPosAsterisk", 2);
-    maxPosQuestion = getInt("maxPosQuestion", 1);
-    minTrailing = getInt("minTrailing", 2);
-    maxFractionAsterisk = getFloat("maxFractionAsterisk", 0.0f);
+  /** Creates a new ReversedWildcardFilterFactory */
+  public ReversedWildcardFilterFactory(Map<String,String> args) {
+    super(args);
+    withOriginal = getBoolean(args, "withOriginal", true);
+    maxPosAsterisk = getInt(args, "maxPosAsterisk", 2);
+    maxPosQuestion = getInt(args, "maxPosQuestion", 1);
+    minTrailing = getInt(args, "minTrailing", 2);
+    maxFractionAsterisk = getFloat(args, "maxFractionAsterisk", 0.0f);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
   }
 
 
@@ -134,8 +137,8 @@
     return markerChar;
   }
   
-  protected float getFloat(String name, float defValue) {
-    String val = args.get(name);
+  protected final float getFloat(Map<String,String> args, String name, float defValue) {
+    String val = args.remove(name);
     if (val == null) {
       return defValue;
     } else {
Index: solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java
===================================================================
--- solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java	(revision 1462646)
+++ solr/core/src/java/org/apache/solr/analysis/LegacyHTMLStripCharFilterFactory.java	(working copy)
@@ -19,6 +19,7 @@
  */
 
 import java.io.Reader;
+import java.util.Map;
 
 import org.apache.lucene.analysis.charfilter.HTMLStripCharFilterFactory;
 import org.apache.lucene.analysis.util.CharFilterFactory;
@@ -54,6 +55,14 @@
 @Deprecated
 public class LegacyHTMLStripCharFilterFactory extends CharFilterFactory {
 
+  /** Creates a new LegacyHTMLStripCharFilterFactory */
+  public LegacyHTMLStripCharFilterFactory(Map<String,String> args) {
+    super(args);
+    if (!args.isEmpty()) {
+      throw new IllegalArgumentException("Unknown parameters: " + args);
+    }
+  }
+  
   @Override
   public LegacyHTMLStripCharFilter create(Reader input) {
     return new LegacyHTMLStripCharFilter(input);
