Index: src/test/org/apache/lucene/analysis/TestCharArraySet.java
===================================================================
--- src/test/org/apache/lucene/analysis/TestCharArraySet.java	(revision 899985)
+++ src/test/org/apache/lucene/analysis/TestCharArraySet.java	(working copy)
@@ -26,7 +26,9 @@
 import org.apache.lucene.util.LuceneTestCase;
 import org.apache.lucene.util.Version;
 
-
+/**
+ * TestCase for {@link CharArraySet} 
+ */
 public class TestCharArraySet extends LuceneTestCase {
   
   static final String[] TEST_STOP_WORDS = {
@@ -97,6 +99,13 @@
     final int size = set.size();
     set = CharArraySet.unmodifiableSet(set);
     assertEquals("Set size changed due to unmodifiableSet call" , size, set.size());
+    tryModifyUnmodifiableSet(set, size);
+    for (int i = 0; i < TEST_STOP_WORDS.length; i++) {
+      assertTrue(set.contains(TEST_STOP_WORDS[i]));  
+    }
+  }
+  
+  private void tryModifyUnmodifiableSet(CharArraySet set, int size) { 
     String NOT_IN_SET = "SirGallahad";
     assertFalse("Test String already exists in set", set.contains(NOT_IN_SET));
     
@@ -167,9 +176,6 @@
       assertFalse("Test String has been added to unmodifiable set", set.contains(NOT_IN_SET));
     }
     
-    for (int i = 0; i < TEST_STOP_WORDS.length; i++) {
-      assertTrue(set.contains(TEST_STOP_WORDS[i]));  
-    }
   }
   
   public void testUnmodifiableSet(){
@@ -364,7 +370,6 @@
     for (String string : newWords) {
       assertFalse(setIngoreCase.contains(string));  
       assertFalse(setCaseSensitive.contains(string));  
-
     }
   }
   
@@ -404,4 +409,53 @@
       assertFalse(set.contains(string));  
     }
   }
+  
+  /**
+   * Tests a special case of {@link CharArraySet#copy(Version, Set)} where the
+   * set to copy is the {@link CharArraySet#EMPTY_SET}
+   */
+  public void testCopyEmptySet() {
+    assertSame(CharArraySet.EMPTY_SET, 
+        CharArraySet.copy(Version.LUCENE_CURRENT, CharArraySet.EMPTY_SET));
+  }
+  
+  /**
+   * Smoketests the static empty set
+   */
+  public void testEmptySet() {
+    assertEquals(0, CharArraySet.EMPTY_SET.size());
+    
+    assertTrue(CharArraySet.EMPTY_SET.isEmpty());
+    for (String stopword : TEST_STOP_WORDS) {
+      assertFalse(CharArraySet.EMPTY_SET.contains(stopword));
+    }
+    assertFalse(CharArraySet.EMPTY_SET.contains((Object)"foo"));
+    assertFalse(CharArraySet.EMPTY_SET.contains((Object)"foo".toCharArray()));
+    assertFalse(CharArraySet.EMPTY_SET.contains("foo".toCharArray(),0,3));
+  }
+  
+  /**
+   * Test for NPE 
+   */
+  public void testContainsWithNull() {
+    CharArraySet set = new CharArraySet(Version.LUCENE_CURRENT, 1, true);
+    try{
+      set.contains((char[]) null, 0, 10);
+      fail("null value must raise NPE");
+    }catch (NullPointerException e) {
+      //
+    }
+    try{
+      set.contains((CharSequence) null);
+      fail("null value must raise NPE");
+    }catch (NullPointerException e) {
+      //
+    }
+    try{
+      set.contains((Object) null);
+      fail("null value must raise NPE");
+    }catch (NullPointerException e) {
+      //
+    }
+  }
 }
Index: src/java/org/apache/lucene/analysis/CharArraySet.java
===================================================================
--- src/java/org/apache/lucene/analysis/CharArraySet.java	(revision 899985)
+++ src/java/org/apache/lucene/analysis/CharArraySet.java	(working copy)
@@ -62,8 +62,7 @@
   private char[][] entries;
   private int count;
   private final boolean ignoreCase;
-  public static final CharArraySet EMPTY_SET = CharArraySet.unmodifiableSet(
-      new CharArraySet(Version.LUCENE_CURRENT, 0, false));
+  public static final CharArraySet EMPTY_SET = new EmptyCharArraySet();
   
   private final CharacterUtils charUtils;
   private final Version matchVersion;
@@ -482,7 +481,7 @@
    * the internal representation of a {@link CharArraySet} to a super
    * constructor and overrides all mutators. 
    */
-  private static final class UnmodifiableCharArraySet extends CharArraySet {
+  private static class UnmodifiableCharArraySet extends CharArraySet {
 
     private UnmodifiableCharArraySet(Version matchVersion, char[][] entries, boolean ignoreCase,
         int count) {
@@ -519,5 +518,38 @@
       throw new UnsupportedOperationException();
     }
   }
+  
+  /**
+   * Empty {@link UnmodifiableCharArraySet} optimized for speed.
+   * Contains checks will always return <code>false</code> or throw
+   * NPE if necessary.
+   */
+  private static final class EmptyCharArraySet extends UnmodifiableCharArraySet {
 
+    private EmptyCharArraySet() {
+      super(Version.LUCENE_CURRENT, new char[0][], false, 0);
+    }
+    
+    @Override
+    public boolean contains(char[] text, int off, int len) {
+      if(text == null)
+        throw new NullPointerException();
+      return false;
+    }
+
+    @Override
+    public boolean contains(CharSequence cs) {
+      if(cs == null)
+        throw new NullPointerException();
+      return false;
+    }
+
+    @Override
+    public boolean contains(Object o) {
+      if(o == null)
+        throw new NullPointerException();
+      return false;
+    }
+  }
+
 }
