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 1511372)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballPorterFilterFactory.java	(working copy)
@@ -47,6 +47,7 @@
 
   private final String language;
   private final String wordFiles;
+  private final int minTokenLength;
   private Class<? extends SnowballProgram> stemClass;
   private CharArraySet protectedWords = null;
   
@@ -55,6 +56,7 @@
     super(args);
     language = get(args, "language", "English");
     wordFiles = get(args, PROTECTED_TOKENS);
+    minTokenLength = getInt(args, "minTokenLength", -1);
     if (!args.isEmpty()) {
       throw new IllegalArgumentException("Unknown parameters: " + args);
     }
@@ -81,7 +83,7 @@
 
     if (protectedWords != null)
       input = new SetKeywordMarkerFilter(input, protectedWords);
-    return new SnowballFilter(input, program);
+    return new SnowballFilter(input, program, minTokenLength);
   }
 }
 
Index: lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java
===================================================================
--- lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java	(revision 1511372)
+++ lucene/analysis/common/src/java/org/apache/lucene/analysis/snowball/SnowballFilter.java	(working copy)
@@ -53,15 +53,25 @@
 public final class SnowballFilter extends TokenFilter {
 
   private final SnowballProgram stemmer;
+  private final int minTokenLength;
 
   private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
   private final KeywordAttribute keywordAttr = addAttribute(KeywordAttribute.class);
 
   public SnowballFilter(TokenStream input, SnowballProgram stemmer) {
+    this(input, stemmer, -1);
+  }
+  
+  public SnowballFilter(TokenStream input, SnowballProgram stemmer, int minTokenLength) {
     super(input);
     this.stemmer = stemmer;
+    this.minTokenLength = minTokenLength;
   }
 
+  public SnowballFilter(TokenStream in, String name) {
+    this(in, name, -1);
+  }
+  
   /**
    * Construct the named stemming filter.
    *
@@ -72,8 +82,9 @@
    * @param in the input tokens to stem
    * @param name the name of a stemmer
    */
-  public SnowballFilter(TokenStream in, String name) {
+  public SnowballFilter(TokenStream in, String name, int minTokenLength) {
     super(in);
+    this.minTokenLength = minTokenLength;
     //Class.forName is frowned upon in place of the ResourceLoader but in this case,
     // the factory will use the other constructor so that the program is already loaded.
     try {
@@ -92,14 +103,16 @@
       if (!keywordAttr.isKeyword()) {
         char termBuffer[] = termAtt.buffer();
         final int length = termAtt.length();
-        stemmer.setCurrent(termBuffer, length);
-        stemmer.stem();
-        final char finalTerm[] = stemmer.getCurrentBuffer();
-        final int newLength = stemmer.getCurrentBufferLength();
-        if (finalTerm != termBuffer)
-          termAtt.copyBuffer(finalTerm, 0, newLength);
-        else
-          termAtt.setLength(newLength);
+        if (minTokenLength == -1 || length >= minTokenLength) {
+          stemmer.setCurrent(termBuffer, length);
+          stemmer.stem();
+          final char finalTerm[] = stemmer.getCurrentBuffer();
+          final int newLength = stemmer.getCurrentBufferLength();
+          if (finalTerm != termBuffer)
+            termAtt.copyBuffer(finalTerm, 0, newLength);
+          else
+            termAtt.setLength(newLength);
+        }
       }
       return true;
     } else {
