diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/CachingPersistenceManagerProxy.java b/configadmin/src/main/java/org/apache/felix/cm/impl/CachingPersistenceManagerProxy.java
index 7f3225f..997ddd7 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/CachingPersistenceManagerProxy.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/CachingPersistenceManagerProxy.java
@@ -20,12 +20,9 @@
 
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Map;
 import java.util.Vector;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -47,7 +44,7 @@
     private final PersistenceManager pm;
 
     /** cached dictionaries */
-    private final Hashtable cache;
+    private final Hashtable<String, CaseInsensitiveDictionary> cache;
 
     /** protecting lock */
     private final ReadWriteLock globalLock = new ReentrantReadWriteLock();
@@ -67,7 +64,7 @@
     public CachingPersistenceManagerProxy( final PersistenceManager pm )
     {
         this.pm = pm;
-        this.cache = new Hashtable();
+        this.cache = new Hashtable<String, CaseInsensitiveDictionary>();
     }
 
 
@@ -118,6 +115,11 @@
      */
     public Enumeration getDictionaries() throws IOException
     {
+        return getDictionaries( null );
+    }
+
+    public Enumeration getDictionaries( SimpleFilter filter ) throws IOException
+    {
         Lock lock = globalLock.readLock();
         try {
             lock.lock();
@@ -137,7 +139,7 @@
                         String pid = (String) next.get(Constants.SERVICE_PID);
                         if (pid != null)
                         {
-                            cache.put(pid, next);
+                            cache.put(pid, copy( next ) );
                         }
                     }
                     fullyLoaded = true;
@@ -145,10 +147,14 @@
             }
 
             // Deep copy the configuration to avoid any threading issue
-            Vector configs = new Vector();
+            Vector<Dictionary> configs = new Vector<Dictionary>();
             for (Object o : cache.values())
             {
-                configs.add( copy( ( Dictionary ) o ) );
+                Dictionary d = (Dictionary) o;
+                if ( filter == null || filter.matches( d ) )
+                {
+                    configs.add( copy( d ) );
+                }
             }
             return configs.elements();
         } finally {
@@ -172,17 +178,17 @@
         Lock lock = globalLock.readLock();
         try {
             lock.lock();
-            Dictionary loaded = ( Dictionary ) cache.get( pid );
+            Dictionary loaded = cache.get( pid );
             if ( loaded == null && !fullyLoaded )
             {
                 lock.unlock();
                 lock = globalLock.writeLock();
                 lock.lock();
-                loaded = ( Dictionary ) cache.get( pid );
+                loaded = cache.get( pid );
                 if ( loaded == null )
                 {
                     loaded = pm.load(pid);
-                    cache.put(pid, loaded);
+                    cache.put(pid, copy( loaded ) );
                 }
             }
             return copy( loaded );
@@ -219,22 +225,8 @@
      * copies all entries from the source dictionary to the newly created
      * target.
      */
-    Dictionary copy( final Dictionary source )
+    CaseInsensitiveDictionary copy( final Dictionary source )
     {
-        Hashtable copy = new Hashtable();
-        if ( source instanceof Map )
-        {
-            copy.putAll( ( Map ) source );
-        }
-        else
-        {
-            Enumeration keys = source.keys();
-            while ( keys.hasMoreElements() )
-            {
-                Object key = keys.nextElement();
-                copy.put( key, source.get( key ) );
-            }
-        }
-        return copy;
+        return new CaseInsensitiveDictionary( source );
     }
 }
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/CaseInsensitiveDictionary.java b/configadmin/src/main/java/org/apache/felix/cm/impl/CaseInsensitiveDictionary.java
index f05ff44..6c318a5 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/CaseInsensitiveDictionary.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/CaseInsensitiveDictionary.java
@@ -21,14 +21,17 @@
 
 import java.lang.reflect.Array;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.Dictionary;
 import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Locale;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
 import java.util.Vector;
 
 
@@ -38,45 +41,39 @@
  * out by the Configuration Admin Service Specification requiring the property
  * names to keep case but to ignore case when accessing the properties.
  */
-public class CaseInsensitiveDictionary extends Dictionary
+public class CaseInsensitiveDictionary extends Dictionary<String, Object>
 {
 
     /**
      * The backend dictionary with lower case keys.
      */
-    private Hashtable internalMap;
-
-    /**
-     * Mapping of lower case keys to original case keys as last used to set a
-     * property value.
-     */
-    private Hashtable originalKeys;
-
+    private SortedMap<String, Object> internalMap;
 
     public CaseInsensitiveDictionary()
     {
-        internalMap = new Hashtable();
-        originalKeys = new Hashtable();
+        internalMap = new TreeMap<String, Object>( CASE_INSENSITIVE_ORDER );
     }
 
 
     public CaseInsensitiveDictionary( Dictionary props )
     {
-        this();
-
-        if ( props != null )
+        if ( props instanceof CaseInsensitiveDictionary)
         {
+            internalMap = new TreeMap<String, Object>( ((CaseInsensitiveDictionary) props).internalMap );
+        }
+        else if ( props != null )
+        {
+            internalMap = new TreeMap<String, Object>( CASE_INSENSITIVE_ORDER );
             Enumeration keys = props.keys();
             while ( keys.hasMoreElements() )
             {
                 Object key = keys.nextElement();
 
                 // check the correct syntax of the key
-                checkKey( key );
+                String k = checkKey( key );
 
                 // check uniqueness of key
-                String lowerCase = toLowerCase( key );
-                if ( internalMap.containsKey( lowerCase ) )
+                if ( internalMap.containsKey( k ) )
                 {
                     throw new IllegalArgumentException( "Key [" + key + "] already present in different case" );
                 }
@@ -86,22 +83,23 @@
                 value = checkValue( value );
 
                 // add the key/value pair
-                internalMap.put( lowerCase, value );
-                originalKeys.put( lowerCase, key );
+                internalMap.put( k, value );
             }
         }
+        else
+        {
+            internalMap = new TreeMap<String, Object>( CASE_INSENSITIVE_ORDER );
+        }
     }
 
 
     CaseInsensitiveDictionary( CaseInsensitiveDictionary props, boolean deepCopy )
     {
-        Hashtable tmp = new Hashtable( Math.max( 2 * props.internalMap.size(), 11 ), 0.75f );
         if ( deepCopy )
         {
-            Iterator entries = props.internalMap.entrySet().iterator();
-            while ( entries.hasNext() )
+            internalMap = new TreeMap<String, Object>( CASE_INSENSITIVE_ORDER );
+            for( Map.Entry<String, Object> entry : props.internalMap.entrySet() )
             {
-                Map.Entry entry = ( Map.Entry ) entries.next();
                 Object value = entry.getValue();
                 if ( value.getClass().isArray() )
                 {
@@ -119,18 +117,15 @@
                     // Vector. And even though we accept Collection nowadays
                     // there might be clients out there still written against
                     // R4 and R4.1 spec expecting Vector
-                    value = new Vector( ( Collection ) value );
+                    value = new Vector<Object>( ( Collection ) value );
                 }
-                tmp.put( entry.getKey(), value );
+                internalMap.put( entry.getKey(), value );
             }
         }
         else
         {
-            tmp.putAll( props.internalMap );
+            internalMap = new TreeMap<String, Object>( props.internalMap );
         }
-
-        internalMap = tmp;
-        originalKeys = new Hashtable( props.originalKeys );
     }
 
 
@@ -139,7 +134,7 @@
      *
      * @see java.util.Dictionary#elements()
      */
-    public Enumeration elements()
+    public Enumeration<Object> elements()
     {
         return Collections.enumeration( internalMap.values() );
     }
@@ -157,7 +152,7 @@
             throw new NullPointerException( "key" );
         }
 
-        return internalMap.get( toLowerCase( key ) );
+        return internalMap.get( key );
     }
 
 
@@ -177,18 +172,18 @@
      *
      * @see java.util.Dictionary#keys()
      */
-    public Enumeration keys()
+    public Enumeration<String> keys()
     {
-        return Collections.enumeration( originalKeys.values() );
+        return Collections.enumeration( internalMap.keySet() );
     }
 
 
     /*
      * (non-Javadoc)
      *
-     * @see java.util.Dictionary#put(java.lang.Object, java.lang.Object)
+     * @see java.util.Dictionary#put(java.lang.String, java.lang.Object)
      */
-    public Object put( Object key, Object value )
+    public Object put( String key, Object value )
     {
         if ( key == null || value == null )
         {
@@ -198,9 +193,7 @@
         checkKey( key );
         value = checkValue( value );
 
-        String lowerCase = toLowerCase( key );
-        originalKeys.put( lowerCase, key );
-        return internalMap.put( lowerCase, value );
+        return internalMap.put( key, value );
     }
 
 
@@ -216,9 +209,7 @@
             throw new NullPointerException( "key" );
         }
 
-        String lowerCase = toLowerCase( key );
-        originalKeys.remove( lowerCase );
-        return internalMap.remove( lowerCase );
+        return internalMap.remove( key );
     }
 
 
@@ -250,12 +241,12 @@
      * If the key does not comply an <code>IllegalArgumentException</code> is
      * thrown.
      *
-     * @param key
+     * @param keyObject
      *            The configuration property key to check.
      * @throws IllegalArgumentException
      *             if the key does not comply with the symbolic-name production.
      */
-    static void checkKey( Object keyObject )
+    static String checkKey( Object keyObject )
     {
         // check for wrong type or null key
         if ( !( keyObject instanceof String ) )
@@ -270,26 +261,32 @@
         {
             throw new IllegalArgumentException( "Key [" + key + "] must not be an empty string" );
         }
+
+        return key;
     }
 
 
-    static final String toLowerCase( Object keyObject )
-    {
-        final String key = ( String ) keyObject;
-        return key.toLowerCase( Locale.ENGLISH );
-    }
-
+    private static final Set<Class> KNOWN = new HashSet<Class>(Arrays.<Class>asList(
+            String.class, Integer.class, Long.class, Float.class,
+            Double.class, Byte.class, Short.class, Character.class,
+            Boolean.class));
 
     static Object checkValue( Object value )
     {
-        Class type;
         if ( value == null )
         {
             // null is illegal
             throw new IllegalArgumentException( "Value must not be null" );
 
         }
-        else if ( value.getClass().isArray() )
+
+        Class type = value.getClass();
+        // Fast check for simple types
+        if ( KNOWN.contains( type ) )
+        {
+            return value;
+        }
+        else if ( type.isArray() )
         {
             // check simple or primitive
             type = value.getClass().getComponentType();
@@ -312,11 +309,10 @@
             }
 
             // ensure all elements have the same type and to internal list
-            Collection internalValue = new ArrayList( collection.size() );
+            Collection<Object> internalValue = new ArrayList<Object>( collection.size() );
             type = null;
-            for ( Iterator ci = collection.iterator(); ci.hasNext(); )
+            for ( Object el : collection )
             {
-                Object el = ci.next();
                 if ( el == null )
                 {
                     throw new IllegalArgumentException( "Collection must not contain null elements" );
@@ -341,9 +337,7 @@
         }
 
         // check for simple type
-        if ( type == String.class || type == Integer.class || type == Long.class || type == Float.class
-            || type == Double.class || type == Byte.class || type == Short.class || type == Character.class
-            || type == Boolean.class )
+        if ( KNOWN.contains( type ) )
         {
             return value;
         }
@@ -360,4 +354,56 @@
         return internalMap.toString();
     }
 
+    public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator();
+
+    private static class CaseInsensitiveComparator implements Comparator<String>
+    {
+
+        public int compare(String s1, String s2)
+        {
+            int n1 = s1.length();
+            int n2 = s2.length();
+            int min = n1 < n2 ? n1 : n2;
+            for ( int i = 0; i < min; i++ )
+            {
+                char c1 = s1.charAt( i );
+                char c2 = s2.charAt( i );
+                if ( c1 != c2 )
+                {
+                    // Fast check for simple ascii codes
+                    if ( c1 <= 128 && c2 <= 128 )
+                    {
+                        c1 = toLowerCaseFast(c1);
+                        c2 = toLowerCaseFast(c2);
+                        if ( c1 != c2 )
+                        {
+                            return c1 - c2;
+                        }
+                    }
+                    else
+                    {
+                        c1 = Character.toUpperCase( c1 );
+                        c2 = Character.toUpperCase( c2 );
+                        if ( c1 != c2 )
+                        {
+                            c1 = Character.toLowerCase( c1 );
+                            c2 = Character.toLowerCase( c2 );
+                            if ( c1 != c2 )
+                            {
+                                // No overflow because of numeric promotion
+                                return c1 - c2;
+                            }
+                        }
+                    }
+                }
+            }
+            return n1 - n2;
+        }
+    }
+
+    private static char toLowerCaseFast( char ch )
+    {
+        return ( ch >= 'A' && ch <= 'Z' ) ? ( char ) ( ch + 'a' - 'A' ) : ch;
+    }
+
 }
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
index 12dd0de..c1b80a5 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/ConfigurationManager.java
@@ -46,7 +46,6 @@
 import org.osgi.framework.BundleEvent;
 import org.osgi.framework.BundleListener;
 import org.osgi.framework.Constants;
-import org.osgi.framework.Filter;
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
@@ -163,7 +162,7 @@
      * {@link #persistenceManagerMap}, which is ordered according to the
      * {@link RankingComparator}.
      */
-    private PersistenceManager[] persistenceManagers;
+    private CachingPersistenceManagerProxy[] persistenceManagers;
 
     // the persistenceManagerTracker.getTrackingCount when the
     // persistenceManagers were last got
@@ -642,10 +641,10 @@
     ConfigurationImpl[] listConfigurations( ConfigurationAdminImpl configurationAdmin, String filterString )
         throws IOException, InvalidSyntaxException
     {
-        Filter filter = null;
+        SimpleFilter filter = null;
         if ( filterString != null )
         {
-            filter = bundleContext.createFilter( filterString );
+            filter = SimpleFilter.parse( filterString );
         }
 
         log( LogService.LOG_DEBUG, "Listing configurations matching {0}", new Object[]
@@ -653,10 +652,10 @@
 
         List configList = new ArrayList();
 
-        PersistenceManager[] pmList = getPersistenceManagers();
+        CachingPersistenceManagerProxy[] pmList = getPersistenceManagers();
         for ( int i = 0; i < pmList.length; i++ )
         {
-            Enumeration configs = pmList[i].getDictionaries();
+            Enumeration configs = pmList[i].getDictionaries( filter );
             while ( configs.hasMoreElements() )
             {
                 final Dictionary config = ( Dictionary ) configs.nextElement();
@@ -681,30 +680,23 @@
                     continue;
                 }
 
-                // check filter
-                if ( filter == null || filter.match( config ) )
+                // ensure the service.pid and returned a cached config if available
+                ConfigurationImpl cfg = getCachedConfiguration( pid );
+                if ( cfg == null )
                 {
-                    // ensure the service.pid and returned a cached config if available
-                    ConfigurationImpl cfg = getCachedConfiguration( pid );
-                    if ( cfg == null )
-                    {
-                        cfg = new ConfigurationImpl( this, pmList[i], config );
-                    }
+                    cfg = new ConfigurationImpl( this, pmList[i], config );
+                }
 
-                    // FELIX-611: Ignore configuration objects without props
-                    if ( !cfg.isNew() )
-                    {
-                        log( LogService.LOG_DEBUG, "Adding configuration {0}", new Object[]
-                            { pid } );
-                        configList.add( cfg );
-                    }
-                    else
-                    {
-                        log( LogService.LOG_DEBUG, "Omitting configuration {0}: Is new", new Object[]
-                            { pid } );
-                    }
-                } else {
-                    log( LogService.LOG_DEBUG, "Omitting configuration {0}: Does not match filter", new Object[]
+                // FELIX-611: Ignore configuration objects without props
+                if ( !cfg.isNew() )
+                {
+                    log( LogService.LOG_DEBUG, "Adding configuration {0}", new Object[]
+                        { pid } );
+                    configList.add( cfg );
+                }
+                else
+                {
+                    log( LogService.LOG_DEBUG, "Omitting configuration {0}: Is new", new Object[]
                         { pid } );
                 }
             }
@@ -813,19 +805,19 @@
 
     // ---------- internal -----------------------------------------------------
 
-    private PersistenceManager[] getPersistenceManagers()
+    private CachingPersistenceManagerProxy[] getPersistenceManagers()
     {
         int currentPmtCount = persistenceManagerTracker.getTrackingCount();
         if ( persistenceManagers == null || currentPmtCount > pmtCount )
         {
 
             List pmList = new ArrayList();
-            PersistenceManager[] pm;
+            CachingPersistenceManagerProxy[] pm;
 
             ServiceReference[] refs = persistenceManagerTracker.getServiceReferences();
             if ( refs == null || refs.length == 0 )
             {
-                pm = new PersistenceManager[0];
+                pm = new CachingPersistenceManagerProxy[0];
             }
             else
             {
@@ -845,7 +837,7 @@
                     }
                 }
 
-                pm = ( PersistenceManager[] ) pmList.toArray( new PersistenceManager[pmList.size()] );
+                pm = ( CachingPersistenceManagerProxy[] ) pmList.toArray( new CachingPersistenceManagerProxy[pmList.size()] );
             }
 
             pmtCount = currentPmtCount;
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java b/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
index b3564ac..77b3c99 100644
--- a/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/Factory.java
@@ -133,7 +133,7 @@
         }
         else
         {
-            props.put( FACTORY_PID, this.getFactoryPid() );
+            props.put( FACTORY_PID, this.getFactoryPid().toString() );
             getPersistenceManager().store( id, props );
         }
     }
diff --git a/configadmin/src/main/java/org/apache/felix/cm/impl/SimpleFilter.java b/configadmin/src/main/java/org/apache/felix/cm/impl/SimpleFilter.java
new file mode 100644
index 0000000..0305e08
--- /dev/null
+++ b/configadmin/src/main/java/org/apache/felix/cm/impl/SimpleFilter.java
@@ -0,0 +1,863 @@
+/*
+ * 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.
+ */
+package org.apache.felix.cm.impl;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.Iterator;
+import java.util.List;
+
+public class SimpleFilter
+{
+    public static final int MATCH_ALL = 0;
+    public static final int AND = 1;
+    public static final int OR = 2;
+    public static final int NOT = 3;
+    public static final int EQ = 4;
+    public static final int LTE = 5;
+    public static final int GTE = 6;
+    public static final int SUBSTRING = 7;
+    public static final int PRESENT = 8;
+    public static final int APPROX = 9;
+
+    private final String m_name;
+    private final Object m_value;
+    private final int m_op;
+
+    public SimpleFilter(String attr, Object value, int op)
+    {
+        m_name = attr;
+        m_value = value;
+        m_op = op;
+    }
+
+    public String getName()
+    {
+        return m_name;
+    }
+
+    public Object getValue()
+    {
+        return m_value;
+    }
+
+    public int getOperation()
+    {
+        return m_op;
+    }
+
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder();
+        toString(sb);
+        return sb.toString();
+    }
+
+    private void toString(StringBuilder sb)
+    {
+        switch (m_op)
+        {
+            case AND:
+                sb.append("(&");
+                toString(sb, (List) m_value);
+                sb.append(")");
+                break;
+            case OR:
+                sb.append("(|");
+                toString(sb, (List) m_value);
+                sb.append(")");
+                break;
+            case NOT:
+                sb.append("(!");
+                toString(sb, (List) m_value);
+                sb.append(")");
+                break;
+            case EQ:
+                sb.append("(")
+                        .append(m_name)
+                        .append("=");
+                toEncodedString(sb, m_value);
+                sb.append(")");
+                break;
+            case LTE:
+                sb.append("(")
+                        .append(m_name)
+                        .append("<=");
+                toEncodedString(sb, m_value);
+                sb.append(")");
+                break;
+            case GTE:
+                sb.append("(")
+                        .append(m_name)
+                        .append(">=");
+                toEncodedString(sb, m_value);
+                sb.append(")");
+                break;
+            case SUBSTRING:
+                sb.append("(").append(m_name).append("=");
+                unparseSubstring(sb, (List) m_value);
+                sb.append(")");
+                break;
+            case PRESENT:
+                sb.append("(").append(m_name).append("=*)");
+                break;
+            case APPROX:
+                sb.append("(").append(m_name).append("~=");
+                toEncodedString(sb, m_value);
+                sb.append(")");
+                break;
+            case MATCH_ALL:
+                sb.append("(*)");
+                break;
+        }
+    }
+
+    private static void toString(StringBuilder sb, List list)
+    {
+        for (Object o : list)
+        {
+            SimpleFilter sf = (SimpleFilter) o;
+            sf.toString(sb);
+        }
+    }
+
+    private static String toDecodedString(String s, int startIdx, int endIdx)
+    {
+        StringBuilder sb = new StringBuilder(endIdx - startIdx);
+        boolean escaped = false;
+        for (int i = 0; i < (endIdx - startIdx); i++)
+        {
+            char c = s.charAt(startIdx + i);
+            if (!escaped && (c == '\\'))
+            {
+                escaped = true;
+            }
+            else
+            {
+                escaped = false;
+                sb.append(c);
+            }
+        }
+
+        return sb.toString();
+    }
+
+    private static void toEncodedString(StringBuilder sb, Object o)
+    {
+        if (o instanceof String)
+        {
+            String s = (String) o;
+            for (int i = 0; i < s.length(); i++)
+            {
+                char c = s.charAt(i);
+                if ((c == '\\') || (c == '(') || (c == ')') || (c == '*'))
+                {
+                    sb.append('\\');
+                }
+                sb.append(c);
+            }
+        }
+        else
+        {
+            sb.append(o);
+        }
+    }
+
+    public static SimpleFilter parse(String filter)
+    {
+        int idx = skipWhitespace(filter, 0);
+
+        if ((filter == null) || (filter.length() == 0) || (idx >= filter.length()))
+        {
+            throw new IllegalArgumentException("Null or empty filter.");
+        }
+        else if (filter.charAt(idx) != '(')
+        {
+            throw new IllegalArgumentException("Missing opening parenthesis: " + filter);
+        }
+
+        SimpleFilter sf = null;
+        List<Object> stack = new ArrayList<Object>();
+        boolean isEscaped = false;
+        while (idx < filter.length())
+        {
+            if (sf != null)
+            {
+                throw new IllegalArgumentException(
+                        "Only one top-level operation allowed: " + filter);
+            }
+
+            if (!isEscaped && (filter.charAt(idx) == '('))
+            {
+                // Skip paren and following whitespace.
+                idx = skipWhitespace(filter, idx + 1);
+
+                if (filter.charAt(idx) == '&')
+                {
+                    int peek = skipWhitespace(filter, idx + 1);
+                    if (filter.charAt(peek) == '(')
+                    {
+                        idx = peek - 1;
+                        stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.AND));
+                    }
+                    else
+                    {
+                        stack.add(0, idx);
+                    }
+                }
+                else if (filter.charAt(idx) == '|')
+                {
+                    int peek = skipWhitespace(filter, idx + 1);
+                    if (filter.charAt(peek) == '(')
+                    {
+                        idx = peek - 1;
+                        stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.OR));
+                    }
+                    else
+                    {
+                        stack.add(0, idx);
+                    }
+                }
+                else if (filter.charAt(idx) == '!')
+                {
+                    int peek = skipWhitespace(filter, idx + 1);
+                    if (filter.charAt(peek) == '(')
+                    {
+                        idx = peek - 1;
+                        stack.add(0, new SimpleFilter(null, new ArrayList(), SimpleFilter.NOT));
+                    }
+                    else
+                    {
+                        stack.add(0, idx);
+                    }
+                }
+                else
+                {
+                    stack.add(0, idx);
+                }
+            }
+            else if (!isEscaped && (filter.charAt(idx) == ')'))
+            {
+                Object top = stack.remove(0);
+                if (top instanceof SimpleFilter)
+                {
+                    if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
+                    {
+                        ((List) ((SimpleFilter) stack.get(0)).m_value).add(top);
+                    }
+                    else
+                    {
+                        sf = (SimpleFilter) top;
+                    }
+                }
+                else if (!stack.isEmpty() && (stack.get(0) instanceof SimpleFilter))
+                {
+                    ((List) ((SimpleFilter) stack.get(0)).m_value).add(
+                            SimpleFilter.subfilter(filter, (Integer) top, idx));
+                }
+                else
+                {
+                    sf = SimpleFilter.subfilter(filter, (Integer) top, idx);
+                }
+            }
+            else if (!isEscaped && (filter.charAt(idx) == '\\'))
+            {
+                isEscaped = true;
+            }
+            else
+            {
+                isEscaped = false;
+            }
+
+            idx = skipWhitespace(filter, idx + 1);
+        }
+
+        if (sf == null)
+        {
+            throw new IllegalArgumentException("Missing closing parenthesis: " + filter);
+        }
+
+        return sf;
+    }
+
+    private static SimpleFilter subfilter(String filter, int startIdx, int endIdx)
+    {
+        final String opChars = "=<>~";
+
+        // Determine the ending index of the attribute name.
+        int attrEndIdx = startIdx;
+        for (int i = 0; i < (endIdx - startIdx); i++)
+        {
+            char c = filter.charAt(startIdx + i);
+            if (opChars.indexOf(c) >= 0)
+            {
+                break;
+            }
+            else if (!Character.isWhitespace(c))
+            {
+                attrEndIdx = startIdx + i + 1;
+            }
+        }
+        if (attrEndIdx == startIdx)
+        {
+            throw new IllegalArgumentException(
+                    "Missing attribute name: " + filter.substring(startIdx, endIdx));
+        }
+        String attr = filter.substring(startIdx, attrEndIdx);
+
+        // Skip the attribute name and any following whitespace.
+        startIdx = skipWhitespace(filter, attrEndIdx);
+
+        // Determine the operator type.
+        int op;
+        switch (filter.charAt(startIdx))
+        {
+            case '=':
+                op = EQ;
+                startIdx++;
+                break;
+            case '<':
+                if (filter.charAt(startIdx + 1) != '=')
+                {
+                    throw new IllegalArgumentException(
+                            "Unknown operator: " + filter.substring(startIdx, endIdx));
+                }
+                op = LTE;
+                startIdx += 2;
+                break;
+            case '>':
+                if (filter.charAt(startIdx + 1) != '=')
+                {
+                    throw new IllegalArgumentException(
+                            "Unknown operator: " + filter.substring(startIdx, endIdx));
+                }
+                op = GTE;
+                startIdx += 2;
+                break;
+            case '~':
+                if (filter.charAt(startIdx + 1) != '=')
+                {
+                    throw new IllegalArgumentException(
+                            "Unknown operator: " + filter.substring(startIdx, endIdx));
+                }
+                op = APPROX;
+                startIdx += 2;
+                break;
+            default:
+                throw new IllegalArgumentException(
+                        "Unknown operator: " + filter.substring(startIdx, endIdx));
+        }
+
+        // Parse value.
+        Object value = toDecodedString(filter, startIdx, endIdx);
+
+        // Check if the equality comparison is actually a substring
+        // or present operation.
+        if (op == EQ)
+        {
+            String valueStr = filter.substring(startIdx, endIdx);
+            List<String> values = parseSubstring(valueStr);
+            if ((values.size() == 2)
+                    && (values.get(0).length() == 0)
+                    && (values.get(1).length() == 0))
+            {
+                op = PRESENT;
+            }
+            else if (values.size() > 1)
+            {
+                op = SUBSTRING;
+                value = values;
+            }
+        }
+
+        return new SimpleFilter(attr, value, op);
+    }
+
+    public static List<String> parseSubstring(String value)
+    {
+        List<String> pieces = new ArrayList<String>();
+        StringBuilder ss = new StringBuilder();
+        // int kind = SIMPLE; // assume until proven otherwise
+        boolean wasStar = false; // indicates last piece was a star
+        boolean leftstar = false; // track if the initial piece is a star
+        boolean rightstar = false; // track if the final piece is a star
+
+        int idx = 0;
+
+        // We assume (sub)strings can contain leading and trailing blanks
+        boolean escaped = false;
+        loop:   for (;;)
+        {
+            if (idx >= value.length())
+            {
+                if (wasStar)
+                {
+                    // insert last piece as "" to handle trailing star
+                    rightstar = true;
+                }
+                else
+                {
+                    pieces.add(ss.toString());
+                    // accumulate the last piece
+                    // note that in the case of
+                    // (cn=); this might be
+                    // the string "" (!=null)
+                }
+                ss.setLength(0);
+                break loop;
+            }
+
+            // Read the next character and account for escapes.
+            char c = value.charAt(idx++);
+            if (!escaped && (c == '*'))
+            {
+                // If we have successive '*' characters, then we can
+                // effectively collapse them by ignoring succeeding ones.
+                if (!wasStar)
+                {
+                    if (ss.length() > 0)
+                    {
+                        pieces.add(ss.toString()); // accumulate the pieces
+                        // between '*' occurrences
+                    }
+                    ss.setLength(0);
+                    // if this is a leading star, then track it
+                    if (pieces.isEmpty())
+                    {
+                        leftstar = true;
+                    }
+                    wasStar = true;
+                }
+            }
+            else if (!escaped && (c == '\\'))
+            {
+                escaped = true;
+            }
+            else
+            {
+                escaped = false;
+                wasStar = false;
+                ss.append(c);
+            }
+        }
+        if (leftstar || rightstar || pieces.size() > 1)
+        {
+            // insert leading and/or trailing "" to anchor ends
+            if (rightstar)
+            {
+                pieces.add("");
+            }
+            if (leftstar)
+            {
+                pieces.add(0, "");
+            }
+        }
+        return pieces;
+    }
+
+    public static void unparseSubstring(StringBuilder sb, List<String> pieces)
+    {
+        for (int i = 0; i < pieces.size(); i++)
+        {
+            if (i > 0)
+            {
+                sb.append("*");
+            }
+            toEncodedString(sb, pieces.get(i));
+        }
+    }
+
+    public static boolean compareSubstring(List<String> pieces, String s)
+    {
+        // Walk the pieces to match the string
+        // There are implicit stars between each piece,
+        // and the first and last pieces might be "" to anchor the match.
+        // assert (pieces.length > 1)
+        // minimal case is <string>*<string>
+
+        boolean result = true;
+        int len = pieces.size();
+
+        // Special case, if there is only one piece, then
+        // we must perform an equality test.
+        if (len == 1)
+        {
+            return s.equals(pieces.get(0));
+        }
+
+        // Otherwise, check whether the pieces match
+        // the specified string.
+
+        int index = 0;
+
+        loop:   for (int i = 0; i < len; i++)
+        {
+            String piece = pieces.get(i);
+
+            // If this is the first piece, then make sure the
+            // string starts with it.
+            if (i == 0)
+            {
+                if (!s.startsWith(piece))
+                {
+                    result = false;
+                    break loop;
+                }
+            }
+
+            // If this is the last piece, then make sure the
+            // string ends with it.
+            if (i == (len - 1))
+            {
+                if (s.endsWith(piece) && (s.length() >= (index + piece.length())))
+                {
+                    result = true;
+                }
+                else
+                {
+                    result = false;
+                }
+                break loop;
+            }
+
+            // If this is neither the first or last piece, then
+            // make sure the string contains it.
+            if ((i > 0) && (i < (len - 1)))
+            {
+                index = s.indexOf(piece, index);
+                if (index < 0)
+                {
+                    result = false;
+                    break loop;
+                }
+            }
+
+            // Move string index beyond the matching piece.
+            index += piece.length();
+        }
+
+        return result;
+    }
+
+    private static int skipWhitespace(String s, int startIdx)
+    {
+        int len = s.length();
+        while ((startIdx < len) && Character.isWhitespace(s.charAt(startIdx)))
+        {
+            startIdx++;
+        }
+        return startIdx;
+    }
+
+    public boolean matches(Dictionary dict)
+    {
+        boolean matched = true;
+
+        if (getOperation() == SimpleFilter.MATCH_ALL)
+        {
+            matched = true;
+        }
+        else if (getOperation() == SimpleFilter.AND)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For AND we calculate the intersection of each subfilter.
+            // We can short-circuit the AND operation if there are no
+            // remaining capabilities.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) getValue();
+            for (int i = 0; matched && (i < sfs.size()); i++)
+            {
+                matched = sfs.get(i).matches(dict);
+            }
+        }
+        else if (getOperation() == SimpleFilter.OR)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            matched = false;
+            List<SimpleFilter> sfs = (List<SimpleFilter>) getValue();
+            for (int i = 0; !matched && (i < sfs.size()); i++)
+            {
+                matched = sfs.get(i).matches(dict);
+            }
+        }
+        else if (getOperation() == SimpleFilter.NOT)
+        {
+            // Evaluate each subfilter against the remaining capabilities.
+            // For OR we calculate the union of each subfilter.
+            List<SimpleFilter> sfs = (List<SimpleFilter>) getValue();
+            for (int i = 0; i < sfs.size(); i++)
+            {
+                matched = !sfs.get(i).matches(dict);
+            }
+        }
+        else
+        {
+            matched = false;
+            Object lhs = dict.get( getName() );
+            if (lhs != null)
+            {
+                matched = compare(lhs, getValue(), getOperation());
+            }
+        }
+
+        return matched;
+    }
+
+    private static final Class<?>[] STRING_CLASS = new Class[] { String.class };
+
+    private static boolean compare(Object lhs, Object rhsUnknown, int op)
+    {
+        if (lhs == null)
+        {
+            return false;
+        }
+
+        // If this is a PRESENT operation, then just return true immediately
+        // since we wouldn't be here if the attribute wasn't present.
+        if (op == SimpleFilter.PRESENT)
+        {
+            return true;
+        }
+
+        // If the type is comparable, then we can just return the
+        // result immediately.
+        if (lhs instanceof Comparable)
+        {
+            // Spec says SUBSTRING is false for all types other than string.
+            if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+            {
+                return false;
+            }
+
+            Object rhs;
+            if (op == SimpleFilter.SUBSTRING)
+            {
+                rhs = rhsUnknown;
+            }
+            else
+            {
+                try
+                {
+                    rhs = coerceType(lhs, (String) rhsUnknown);
+                }
+                catch (Exception ex)
+                {
+                    return false;
+                }
+            }
+
+            switch (op)
+            {
+            case SimpleFilter.EQ :
+                try
+                {
+                    return (((Comparable) lhs).compareTo(rhs) == 0);
+                }
+                catch (Exception ex)
+                {
+                    return false;
+                }
+            case SimpleFilter.GTE :
+                try
+                {
+                    return (((Comparable) lhs).compareTo(rhs) >= 0);
+                }
+                catch (Exception ex)
+                {
+                    return false;
+                }
+            case SimpleFilter.LTE :
+                try
+                {
+                    return (((Comparable) lhs).compareTo(rhs) <= 0);
+                }
+                catch (Exception ex)
+                {
+                    return false;
+                }
+            case SimpleFilter.APPROX :
+                return compareApproximate(((Comparable) lhs), rhs);
+            case SimpleFilter.SUBSTRING :
+                return SimpleFilter.compareSubstring((List<String>) rhs, (String) lhs);
+            default:
+                throw new RuntimeException(
+                        "Unknown comparison operator: " + op);
+            }
+        }
+        // Booleans do not implement comparable, so special case them.
+        else if (lhs instanceof Boolean)
+        {
+            Object rhs;
+            try
+            {
+                rhs = coerceType(lhs, (String) rhsUnknown);
+            }
+            catch (Exception ex)
+            {
+                return false;
+            }
+
+            switch (op)
+            {
+            case SimpleFilter.EQ :
+            case SimpleFilter.GTE :
+            case SimpleFilter.LTE :
+            case SimpleFilter.APPROX :
+                return (lhs.equals(rhs));
+            default:
+                throw new RuntimeException(
+                        "Unknown comparison operator: " + op);
+            }
+        }
+
+        // If the LHS is not a comparable or boolean, check if it is an
+        // array. If so, convert it to a list so we can treat it as a
+        // collection.
+        if (lhs.getClass().isArray())
+        {
+            lhs = convertArrayToList(lhs);
+        }
+
+        // If LHS is a collection, then call compare() on each element
+        // of the collection until a match is found.
+        if (lhs instanceof Collection)
+        {
+            for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext(); )
+            {
+                if (compare(iter.next(), rhsUnknown, op))
+                {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        // Spec says SUBSTRING is false for all types other than string.
+        if ((op == SimpleFilter.SUBSTRING) && !(lhs instanceof String))
+        {
+            return false;
+        }
+
+        // Since we cannot identify the LHS type, then we can only perform
+        // equality comparison.
+        try
+        {
+            return lhs.equals(coerceType(lhs, (String) rhsUnknown));
+        }
+        catch (Exception ex)
+        {
+            return false;
+        }
+    }
+
+    private static boolean compareApproximate(Object lhs, Object rhs)
+    {
+        if (rhs instanceof String)
+        {
+            return removeWhitespace((String) lhs)
+                    .equalsIgnoreCase(removeWhitespace((String) rhs));
+        }
+        else if (rhs instanceof Character)
+        {
+            return Character.toLowerCase(((Character) lhs))
+                    == Character.toLowerCase(((Character) rhs));
+        }
+        return lhs.equals(rhs);
+    }
+
+    private static String removeWhitespace(String s)
+    {
+        StringBuilder sb = new StringBuilder(s.length());
+        for (int i = 0; i < s.length(); i++)
+        {
+            if (!Character.isWhitespace(s.charAt(i)))
+            {
+                sb.append(s.charAt(i));
+            }
+        }
+        return sb.toString();
+    }
+
+    private static Object coerceType(Object lhs, String rhsString) throws Exception
+    {
+        // If the LHS expects a string, then we can just return
+        // the RHS since it is a string.
+        if (lhs.getClass() == rhsString.getClass())
+        {
+            return rhsString;
+        }
+
+        // Try to convert the RHS type to the LHS type by using
+        // the string constructor of the LHS class, if it has one.
+        Object rhs = null;
+        try
+        {
+            // The Character class is a special case, since its constructor
+            // does not take a string, so handle it separately.
+            if (lhs instanceof Character)
+            {
+                rhs = rhsString.charAt(0);
+            }
+            else
+            {
+                // Spec says we should trim number types.
+                if ((lhs instanceof Number) || (lhs instanceof Boolean))
+                {
+                    rhsString = rhsString.trim();
+                }
+                Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS);
+                ctor.setAccessible(true);
+                rhs = ctor.newInstance(rhsString);
+            }
+        }
+        catch (Exception ex)
+        {
+            throw new Exception(
+                    "Could not instantiate class "
+                            + lhs.getClass().getName()
+                            + " from string constructor with argument '"
+                            + rhsString + "' because " + ex);
+        }
+
+        return rhs;
+    }
+
+    /**
+     * This is an ugly utility method to convert an array of primitives
+     * to an array of primitive wrapper objects. This method simplifies
+     * processing LDAP filters since the special case of primitive arrays
+     * can be ignored.
+     * @param array An array of primitive types.
+     * @return An corresponding array using pritive wrapper objects.
+     **/
+    private static List convertArrayToList(Object array)
+    {
+        int len = Array.getLength(array);
+        List<Object> list = new ArrayList<Object>(len);
+        for (int i = 0; i < len; i++)
+        {
+            list.add(Array.get(array, i));
+        }
+        return list;
+    }
+}
