Index: contrib/analyzers/common/src/java/org/apache/lucene/analysis/reverse/ReverseStringFilter.java
===================================================================
--- contrib/analyzers/common/src/java/org/apache/lucene/analysis/reverse/ReverseStringFilter.java	(revision 880722)
+++ contrib/analyzers/common/src/java/org/apache/lucene/analysis/reverse/ReverseStringFilter.java	(working copy)
@@ -20,6 +20,7 @@
 import org.apache.lucene.analysis.TokenFilter;
 import org.apache.lucene.analysis.TokenStream;
 import org.apache.lucene.analysis.tokenattributes.TermAttribute;
+import static java.lang.Character.*;
 
 import java.io.IOException;
 
@@ -105,27 +106,99 @@
     }
   }
 
+  /**
+   * Reverses the given input string
+   * 
+   * @param input the string to reverse
+   * @return the given input string in reversed order
+   */
   public static String reverse( final String input ){
-    char[] charInput = input.toCharArray();
+    final char[] charInput = input.toCharArray();
     reverse( charInput );
     return new String( charInput );
   }
   
-  public static void reverse( char[] buffer ){
+  /**
+   * Reverses the given input buffer in-place
+   * @param buffer the input char array to reverse
+   */
+  public static void reverse( final char[] buffer ){
     reverse( buffer, buffer.length );
   }
   
-  public static void reverse( char[] buffer, int len ){
+  /**
+   * Partially reverses the given input buffer in-place from offset 0
+   * up to the given length.
+   * @param buffer the input char array to reverse
+   * @param len the length in the buffer up to where the
+   *        buffer should be reversed
+   */
+  public static void reverse( final char[] buffer, final int len ){
     reverse( buffer, 0, len );
   }
   
-  public static void reverse( char[] buffer, int start, int len ){
-    if( len <= 1 ) return;
-    int num = len>>1;
-    for( int i = start; i < ( start + num ); i++ ){
-      char c = buffer[i];
-      buffer[i] = buffer[start * 2 + len - i - 1];
-      buffer[start * 2 + len - i - 1] = c;
+  /**
+   * Partially reverses the given input buffer in-place from the given offset
+   * up to the given length.
+   * @param buffer the input char array to reverse
+   * @param start the offset from where to reverse the buffer
+   * @param len the length in the buffer up to where the
+   *        buffer should be reversed
+   */
+  public static void reverse(final char[] buffer, final int start, final int len) {
+    /* modified version of Apache Harmony AbstractStringBuilder reverse0() */
+    if (len < 2)
+      return;
+    int end = (start + len) - 1;
+    char frontHigh = buffer[start];
+    char endLow = buffer[end];
+    boolean allowFrontSur = true, allowEndSur = true;
+    final int mid = start + (len >> 1);
+    for (int i = start; i < mid; ++i, --end) {
+      final char frontLow = buffer[i + 1];
+      final char endHigh = buffer[end - 1];
+      boolean surAtFront = allowFrontSur && isSurrogatePair(frontHigh, frontLow);
+      if (surAtFront && (len < 3)) {
+        // nothing to do since surAtFront is allowed and 1 char left
+        return;
+      }
+      boolean surAtEnd = allowEndSur && isSurrogatePair(endHigh, endLow);
+      allowFrontSur = allowEndSur = true;
+      if (surAtFront == surAtEnd) {
+        if (surAtFront) {
+          // both surrogates
+          buffer[end] = frontLow;
+          buffer[--end] = frontHigh;
+          buffer[i] = endHigh;
+          buffer[++i] = endLow;
+          frontHigh = buffer[i + 1];
+          endLow = buffer[end - 1];
+        } else {
+          // neither surrogates
+          buffer[end] = frontHigh;
+          buffer[i] = endLow;
+          frontHigh = frontLow;
+          endLow = endHigh;
+        }
+      } else {
+        if (surAtFront) {
+          // surrogate only at the front
+          buffer[end] = frontLow;
+          buffer[i] = endLow;
+          endLow = endHigh;
+          allowFrontSur = false;
+        } else {
+          // surrogate only at the end
+          buffer[end] = frontHigh;
+          buffer[i] = endHigh;
+          frontHigh = frontLow;
+          allowEndSur = false;
+        }
+      }
+    }
+    if ((len & 0x01) == 1 && !(allowFrontSur && allowEndSur)) {
+      // only if odd length 
+      buffer[end] = allowFrontSur ? endLow : frontHigh;
     }
   }
 }
Index: contrib/analyzers/common/src/test/org/apache/lucene/analysis/reverse/TestReverseStringFilter.java
===================================================================
--- contrib/analyzers/common/src/test/org/apache/lucene/analysis/reverse/TestReverseStringFilter.java	(revision 880722)
+++ contrib/analyzers/common/src/test/org/apache/lucene/analysis/reverse/TestReverseStringFilter.java	(working copy)
@@ -73,4 +73,40 @@
     ReverseStringFilter.reverse( buffer, 2, 3 );
     assertEquals( "ABEDCF", new String( buffer ) );
   }
+  
+  public void testReverseSupplementary() throws Exception {
+    // supplementary at end
+    assertEquals("𩬅艱鍟䇹愯瀛", ReverseStringFilter.reverse("瀛愯䇹鍟艱𩬅"));
+    // supplementary at end - 1
+    assertEquals("a𩬅艱鍟䇹愯瀛", ReverseStringFilter.reverse("瀛愯䇹鍟艱𩬅a"));
+    // supplementary at start
+    assertEquals("fedcba𩬅", ReverseStringFilter.reverse("𩬅abcdef"));
+    // supplementary at start + 1
+    assertEquals("fedcba𩬅z", ReverseStringFilter.reverse("z𩬅abcdef"));
+    // supplementary medial
+    assertEquals("gfe𩬅dcba", ReverseStringFilter.reverse("abcd𩬅efg"));
+  }
+  
+  public void testReverseSupplementaryChar() throws Exception {
+    // supplementary at end
+    char[] buffer = "abc瀛愯䇹鍟艱𩬅".toCharArray();
+    ReverseStringFilter.reverse(buffer, 3, 7);    
+    assertEquals("abc𩬅艱鍟䇹愯瀛", new String(buffer));
+    // supplementary at end - 1
+    buffer = "abc瀛愯䇹鍟艱𩬅d".toCharArray();
+    ReverseStringFilter.reverse(buffer, 3, 8);    
+    assertEquals("abcd𩬅艱鍟䇹愯瀛", new String(buffer));
+    // supplementary at start
+    buffer = "abc𩬅瀛愯䇹鍟艱".toCharArray();
+    ReverseStringFilter.reverse(buffer, 3, 7);
+    assertEquals("abc艱鍟䇹愯瀛𩬅", new String(buffer));
+    // supplementary at start + 1
+    buffer = "abcd𩬅瀛愯䇹鍟艱".toCharArray();
+    ReverseStringFilter.reverse(buffer, 3, 8);
+    assertEquals("abc艱鍟䇹愯瀛𩬅d", new String(buffer));
+    // supplementary medial
+    buffer = "abc瀛愯𩬅def".toCharArray();
+    ReverseStringFilter.reverse(buffer, 3, 7);
+    assertEquals("abcfed𩬅愯瀛", new String(buffer));
+  }
 }
