Index: contrib/analyzers/src/java/org/apache/lucene/analysis/ngram/NGramTokenFilter.java
===================================================================
--- contrib/analyzers/src/java/org/apache/lucene/analysis/ngram/NGramTokenFilter.java	(revision 636712)
+++ contrib/analyzers/src/java/org/apache/lucene/analysis/ngram/NGramTokenFilter.java	(working copy)
@@ -34,6 +34,12 @@
 
   private int minGram, maxGram;
   private LinkedList ngrams;
+  
+  private int optimize=0;
+  /** generates all avaulable tokens */
+  public static int NO_OPTIMIZE = 0;
+  /** skip some tokens that is nessessary in query phase */
+  public static int QUERY_OPTIMIZE = 1;
 
   /**
    * Creates NGramTokenFilter with given min and max n-grams.
@@ -80,20 +86,56 @@
       return null;
   }
 
+  /**
+   * Set optimization criteria
+   *
+   * <li><i>NO_OPTIMIZE</i> generates all avaulable tokens
+   * <li><i>QUERY_OPTIMIZE</i> skip some tokens that is nessessary in query phase
+   */
+  public final void setOptimize(int flag){
+    this.optimize=flag;
+  }
+
   private void ngram(Token token) { 
     String inStr = token.termText();
     int inLen = inStr.length();
-    int gramSize = minGram;
-    while (gramSize <= maxGram) {
-      int pos = 0;                        // reset to beginning of string
-      while (pos+gramSize <= inLen) {     // while there is input
-        String gram = inStr.substring(pos, pos+gramSize);
-        Token tok = new Token(gram, pos, pos+gramSize);
-//        tok.setPositionIncrement(pos);
+    
+    int start=token.startOffset();
+    int end  =token.endOffset();
+    
+    if(this.optimize == QUERY_OPTIMIZE){
+      if(inStr.length() < minGram) return;
+      
+      int pos=0;
+      while(pos<inLen){
+        String gram = "";
+        if(pos+maxGram < inLen){
+          gram = inStr.substring(pos, pos+maxGram);
+        }else{
+          gram = inStr.substring(inLen-maxGram);
+        }
+        Token tok = new Token(gram, token.startOffset(), token.endOffset());
+        if(ngrams.size()!=0){
+          tok.setPositionIncrement(maxGram);
+        }
         ngrams.add(tok);
+        pos+=maxGram;
+      }
+    }else{
+      int pos=0;
+      while(pos<inLen){
+        int increment=1;
+        int gramSize=minGram;
+        while(gramSize<=maxGram && pos+gramSize<=inLen){
+          String gram = inStr.substring(pos, pos+gramSize);
+          Token tok = new Token(gram, start, end);
+          tok.setPositionIncrement(increment);
+          ngrams.add(tok);
+          increment=0;
+          gramSize++;
+        }
         pos++;
       }
-      gramSize++;                         // increase n-gram size
     }
   }
 }
