Use OSGi R4.2 implementations of AdminPermission, FrameworkUtil, and
FilterImpl. (FELIX-1404)


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@797130 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/framework/pom.xml b/framework/pom.xml
index dd1b21f..66972dd 100644
--- a/framework/pom.xml
+++ b/framework/pom.xml
@@ -65,7 +65,7 @@
             <Export-Package>org.osgi.framework;-split-package:=merge-first,org.osgi.framework.launch,org.osgi.framework.hooks.service,org.osgi.service.packageadmin,org.osgi.service.url,org.osgi.service.startlevel,org.osgi.util.tracker</Export-Package>
             <Private-Package>org.apache.felix.moduleloader.*,org.apache.felix.framework.*</Private-Package>
             <Import-Package>!*</Import-Package>
-            <Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,{src/main/resources/},org/osgi/framework/=target/classes/org/osgi/framework/</Include-Resource> 
+            <Include-Resource>META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,{src/main/resources/}</Include-Resource> 
           </instructions>
         </configuration>
       </plugin>
diff --git a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
index b596e6d..acdcbda 100644
--- a/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
+++ b/framework/src/main/java/org/apache/felix/framework/BundleContextImpl.java
@@ -99,7 +99,7 @@
     {
         checkValidity();
 
-        return new FilterImpl(m_logger, expr);
+        return FrameworkUtil.createFilter(expr);
     }
 
     public Bundle installBundle(String location)
diff --git a/framework/src/main/java/org/apache/felix/framework/Felix.java b/framework/src/main/java/org/apache/felix/framework/Felix.java
index 6565b58..35e9db5 100644
--- a/framework/src/main/java/org/apache/felix/framework/Felix.java
+++ b/framework/src/main/java/org/apache/felix/framework/Felix.java
@@ -2623,7 +2623,7 @@
         throws InvalidSyntaxException
     {
         m_dispatcher.addListener(
-            bundle, ServiceListener.class, l, (f == null) ? null : new FilterImpl(m_logger, f));
+            bundle, ServiceListener.class, l, (f == null) ? null : FrameworkUtil.createFilter(f));
 
         // Invoke the ListenerHook.added() on all hooks.
         List listenerHooks = m_registry.getListenerHooks();
@@ -2795,7 +2795,7 @@
         Filter filter = null;
         if (expr != null)
         {
-            filter = new FilterImpl(m_logger, expr);
+            filter = FrameworkUtil.createFilter(expr);
         }
 
         // Ask the service registry for all matching service references.
diff --git a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java b/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
deleted file mode 100644
index 840901f..0000000
--- a/framework/src/main/java/org/apache/felix/framework/FilterImpl.java
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * 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.framework;
-
-import java.io.CharArrayReader;
-import java.io.IOException;
-import java.lang.ref.SoftReference;
-import java.util.*;
-
-import org.apache.felix.framework.util.StringMap;
-import org.apache.felix.framework.util.ldap.*;
-import org.osgi.framework.*;
-
-/**
- * This class implements an RFC 1960-based filter. The syntax of the
- * filter string is the string representation of LDAP search filters
- * as defined in RFC 1960. These filters are used to search for services
- * and to track services using <tt>ServiceTracker</tt> objects.
-**/
-public class FilterImpl implements Filter
-{
-    private static final WeakHashMap m_programCache = new WeakHashMap();
-    private final ThreadLocal m_cache = new ThreadLocal();
-    private final Logger m_logger;
-    private final Object[] m_program;
-    private volatile String m_toString;
-
-// TODO: FilterImpl needs a logger, this is a hack for FrameworkUtil.
-    public FilterImpl(String expr) throws InvalidSyntaxException
-    {
-        this(null, expr);
-    }
-
-    /**
-     * Construct a filter for a given filter expression string.
-     * @param expr the filter expression string for the filter.
-    **/
-    public FilterImpl(Logger logger, String expr) throws InvalidSyntaxException
-    {
-        m_logger = logger;
-        if (expr == null)
-        {
-            throw new NullPointerException("Filter cannot be null");
-        }
-        Object[] program = null;
-        synchronized (m_programCache)
-        {
-            program = (Object[]) m_programCache.get(expr);
-        }
-        if (program == null)
-        {
-            CharArrayReader car = new CharArrayReader(expr.toCharArray());
-            LdapLexer lexer = new LdapLexer(car);
-            Parser parser = new Parser(lexer);
-            try
-            {
-                if (!parser.start())
-                {
-                    throw new InvalidSyntaxException(
-                        "Failed to parse LDAP query.", expr);
-                }
-            }
-            catch (ParseException ex)
-            {
-                throw new InvalidSyntaxException(
-                   ex.getMessage(), expr);
-            }
-            catch (IOException ex)
-            {
-                throw new InvalidSyntaxException(
-                    ex.getMessage(), expr);
-            }
-            program = parser.getProgram();
-            synchronized (m_programCache)
-            {
-                if (!m_programCache.containsKey(expr))
-                {
-                    m_programCache.put(expr, program);
-                }
-            }
-        }
-        m_program = program;
-    }
-
-    /**
-     * Compares the <tt>Filter</tt> object to another.
-     * @param o the object to compare this <tt>Filter</tt> against.
-     * @return If the other object is a <tt>Filter</tt> object, it
-     *         returns <tt>this.toString().equals(obj.toString())</tt>;
-     *         <tt>false</tt> otherwise.
-    **/
-    public boolean equals(Object o)
-    {
-        if (o == null)
-        {
-            return false;
-        }
-        else if (o instanceof Filter)
-        {
-            return toString().equals(o.toString());
-        }
-        return false;
-    }
-
-    /**
-     * Returns the hash code for the <tt>Filter</tt> object.
-     * @return The value <tt>this.toString().hashCode()</tt>.
-    **/
-    public int hashCode()
-    {
-        return toString().hashCode();
-    }
-
-    private boolean match(Dictionary dict, ServiceReference ref, boolean caseSensitive)
-        throws IllegalArgumentException
-    {
-        SoftReference tupleRef = (SoftReference) m_cache.get();
-        Evaluator evaluator = null;
-        SimpleMapper mapper = null;
-        Object[] tuple = null;
-
-        if (tupleRef != null)
-        {
-            tuple = (Object[]) tupleRef.get();
-        }
-
-        if (tuple == null)
-        {
-            evaluator = new Evaluator(m_program);
-            mapper = new SimpleMapper();
-        }
-        else
-        {
-            evaluator = (Evaluator) tuple[0];
-            mapper = (SimpleMapper) tuple[1];
-            m_cache.set(null);
-        }
-
-        try
-        {
-            if (dict != null)
-            {
-                mapper.setSource(dict, caseSensitive);
-            }
-            else
-            {
-                mapper.setSource(ref);
-            }
-
-            return evaluator.evaluate(mapper);
-        }
-        catch (AttributeNotFoundException ex)
-        {
-            log(Logger.LOG_DEBUG, "FilterImpl: Attribute not found.", ex);
-        }
-        catch (EvaluationException ex)
-        {
-            log(Logger.LOG_ERROR, "FilterImpl: " + toString(), ex);
-        }
-        finally
-        {
-            if (dict != null)
-            {
-                mapper.setSource(null, caseSensitive);
-            }
-            else
-            {
-                mapper.setSource(null);
-            }
-
-            if (tuple == null)
-            {
-                m_cache.set(new SoftReference(new Object[] {evaluator, mapper}));
-            }
-            else
-            {
-                m_cache.set(tupleRef);
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Filter using a <tt>Dictionary</tt> object. The <tt>Filter</tt>
-     * is executed using the <tt>Dictionary</tt> object's keys and values.
-     * @param dict the <tt>Dictionary</tt> object whose keys and values
-     *             are used to determine a match.
-     * @return <tt>true</tt> if the <tt>Dictionary</tt> object's keys
-     *         and values match this filter; <tt>false</tt> otherwise.
-     * @throws IllegalArgumentException if the dictionary contains case
-     *         variants of the same key name.
-    **/
-    public boolean match(Dictionary dict)
-        throws IllegalArgumentException
-    {
-        return match(dict, null, false);
-    }
-
-    /**
-     * Filter using a service's properties. The <tt>Filter</tt>
-     * is executed using the properties of the referenced service.
-     * @param ref A reference to the service whose properties
-     *             are used to determine a match.
-     * @return <tt>true</tt> if the service's properties match this
-     *         filter; <tt>false</tt> otherwise.
-    **/
-    public boolean match(ServiceReference ref)
-    {
-        return match(null, ref, false);
-    }
-
-    public boolean matchCase(Dictionary dict)
-    {
-        return match(dict, null, true);
-    }
-
-    /**
-     * Returns the <tt>Filter</tt> object's filter string.
-     * @return Filter string.
-    **/
-    public String toString()
-    {
-        if (m_toString == null)
-        {
-            m_toString = new Evaluator(m_program).toStringInfix();
-        }
-        return m_toString;
-    }
-
-    private void log(int flag, String msg, Throwable th)
-    {
-        if (m_logger == null)
-        {
-            System.out.println(msg + ": " + th);
-        }
-        else
-        {
-            m_logger.log(flag, msg, th);
-        }
-    }
-
-    static class SimpleMapper implements Mapper
-    {
-        private ServiceReference m_ref = null;
-        private StringMap m_map = null;
-
-        public void setSource(ServiceReference ref)
-        {
-            m_ref = ref;
-            m_map = null;
-        }
-
-        public void setSource(Dictionary dict, boolean caseSensitive)
-        {
-            // Create a map if we don't have one.
-
-            if (m_map == null)
-            {
-                m_map = new StringMap();
-            }
-            else
-            {
-                m_map.clear();
-            }
-
-            // Set case comparison accordingly.
-            m_map.setCaseSensitive(caseSensitive);
-
-            // Put all dictionary entries into the map.
-            if (dict != null)
-            {
-                Enumeration keys = dict.keys();
-                while (keys.hasMoreElements())
-                {
-                    Object key = keys.nextElement();
-                    if (m_map.get(key) == null)
-                    {
-                        m_map.put(key, dict.get(key));
-                    }
-                    else
-                    {
-                        throw new IllegalArgumentException(
-                            "Duplicate attribute: " + key.toString());
-                    }
-                }
-            }
-            m_ref = null;
-        }
-
-        public Object lookup(String name)
-        {
-            if (m_ref != null)
-            {
-                return m_ref.getProperty(name);
-            }
-            return (m_map != null) ? m_map.get(name) : null;
-        }
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/AttributeNotFoundException.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/AttributeNotFoundException.java
deleted file mode 100644
index 3be535a..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/AttributeNotFoundException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-public class AttributeNotFoundException extends EvaluationException
-{
-    public AttributeNotFoundException(String msg)
-    {
-        super(msg);
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Driver.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Driver.java
deleted file mode 100644
index 906c2c6..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Driver.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-import java.io.*;
-import java.util.*;
-
-public class Driver {
-
-    public static void main(String[] argv)
-    {
-    Mapper mapper = new DriverMapper();
-
-    if(argv== null || argv.length == 0) {
-        System.err.println("usage: Driver <ldap spec file>");
-        return;
-    }
-    LdapLexer lexer = new LdapLexer();
-    FileReader fr = null;
-    char[] line = null;
-    Evaluator engine = new Evaluator();
-
-    Parser parser = new Parser();
-//	parser.setDebug(System.out);
-
-    try {
-        File spec = new File(argv[0]);
-        fr = new FileReader(spec);
-
-        // The basic operation of the driver is:
-        // 1. read a line from the file
-        // 2. parse that line
-        // 3. print the resulting program
-        // 4. repeat 1 until eof
-
-        for(;;) {
-        line = getLine(fr);
-        if(line == null) break;
-        System.out.println("Driver: filter: "+new String(line));
-        CharArrayReader car = new CharArrayReader(line);
-        lexer.setReader(car);
-        parser.reset(lexer);
-        boolean status = false;
-        try {
-            status = parser.start();
-            if(!status) {
-            System.err.println("parse failed");
-            printErrorLocation(line,lexer.charno());
-            }
-        } catch (ParseException pe) {
-            System.err.println(pe.toString());
-            printErrorLocation(line,lexer.charno());
-        }
-        if(status) {
-            try {
-            engine.reset(parser.getProgram());
-//            System.out.println("Driver: program: "+engine.toString());
-            System.out.println("Driver: program: "+engine.toStringInfix());
-            System.out.println("Eval = " + engine.evaluate(mapper));
-            } catch (EvaluationException ee) {
-            System.err.print("Driver: ");
-            printEvaluationStack(engine.getOperands());
-            System.err.println(ee.toString());
-            }
-        }
-        }
-    } catch (Exception e) {
-        System.err.println(e.toString());
-        printErrorLocation(line,lexer.charno());
-        e.printStackTrace();
-    }
-    }
-
-    // Get a line of input at a time and return a char[] buffer
-    // containing the line
-
-    static char[] getLine(Reader reader) throws IOException
-    {
-    StringBuffer buf = new StringBuffer();
-    for(;;) {
-        int c = reader.read();
-        if(c == '\r') continue;
-        if(c < 0) {
-        if(buf.length() == 0) return null; // no more lines
-        break;
-        }
-        if(c == '\n') break;
-        buf.append((char)c);
-    }
-
-    char[] cbuf = new char[buf.length()];
-    buf.getChars(0,buf.length(),cbuf,0);
-    return cbuf;
-    }
-
-
-    static void printErrorLocation(char[] line, int charno)
-    {
-    System.err.print("|");
-    if(line != null) System.err.print(new String(line));
-    System.err.println("|");
-    for(int i=0;i<charno;i++) System.err.print(" ");
-    System.err.println("^");
-    }
-
-    // Report the final contents of the evaluation stack
-    static void printEvaluationStack(Stack stack)
-    {
-    System.err.print("Stack:");
-    // recast operands as Vector to make interior access easier
-    Vector operands = stack;
-    int len = operands.size();
-    for(int i=0;i<len;i++) System.err.print(" "+operands.elementAt(i));
-    System.err.println();
-    }
-
-}
-
-class DriverMapper implements Mapper {
-
-    Hashtable hash = new Hashtable();
-
-    public DriverMapper()
-    {
-        hash.put("cn","Babs Jensen");
-        hash.put("objectClass","Person");
-        hash.put("sn","Jensen");
-        hash.put("o","university of michigan");
-        hash.put("foo","bar");
-    }
-
-    public Object lookup(String key)
-    {
-        return hash.get(key);
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/EvaluationException.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/EvaluationException.java
deleted file mode 100644
index aa25997..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/EvaluationException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-public class EvaluationException extends Exception
-{
-    private Class m_unsupportedType = null;
-
-    public EvaluationException(String msg)
-    {
-        super(msg);
-    }
-    
-    public EvaluationException(String msg, Class clazz)
-    {
-        super(msg);
-        m_unsupportedType = clazz;
-    }
-    
-    public boolean isUnsupportedType()
-    {
-        return (m_unsupportedType != null);
-    }
-    
-    public Class getUnsupportedType()
-    {
-        return m_unsupportedType;
-    }
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Evaluator.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Evaluator.java
deleted file mode 100644
index ff881e0..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Evaluator.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-import java.util.Stack;
-import java.util.Vector;
-
-public class Evaluator {
-
-    Object[] program = null;
-    Stack operands = new Stack();
-    Mapper mapper = null;
-
-    public Evaluator()
-    {
-        reset();
-    }
-
-    public Evaluator(Object[] prog)
-    {
-        reset(prog);
-    }
-
-    public void reset()
-    {
-        program = null;
-        mapper = null;
-        operands.clear();
-    }
-
-    public void reset(Object[] prog)
-    {
-        reset();
-        setProgram(prog);
-    }
-
-    public void setProgram(Object[] prog)
-    {
-        program = prog;
-    }
-
-    public void setMapper(Mapper mapper)
-    {
-        this.mapper = mapper;
-    }
-
-    public Stack getOperands()
-    {
-        return operands;
-    }
-
-    public boolean evaluate(Mapper mapper) throws EvaluationException
-    {
-        try
-        {
-            // The following code is a little complicated because it
-            // is trying to deal with evaluating a given filter expression
-            // when it contains an attribute that does not exist in the
-            // supplied mapper. In such a situation the code below
-            // catches the "attribute not found" exception and inserts
-            // an instance of Unknown, which is used as a marker for
-            // non-existent attributes. The Unknown instance forces the
-            // operator to throw an "unsupported type" exception, which
-            // the code below converts into a FALSE and this has the effect
-            // of evaluating the subexpression that contained the
-            // non-existent attribute to FALSE. The rest of the filter
-            // expression evaluates normally. Any other exceptions are
-            // rethrown.
-            setMapper(mapper);
-            for (int i = 0; i < program.length; i++)
-            {
-                try
-                {
-                    Operator op = (Operator) program[i];
-                    op.execute(operands, mapper);
-//                    printAction(op); // for debug output
-                }
-                catch (AttributeNotFoundException ex)
-                {
-                    operands.push(new Unknown());
-                }
-                catch (EvaluationException ex)
-                {
-                    // If the exception is for an unsupported type of
-                    // type Unknown, then just push FALSE onto the
-                    // operand stack because this type will only appear
-                    // if an attribute was not found.
-                    if (ex.isUnsupportedType() &&
-                        (ex.getUnsupportedType() == Unknown.class))
-                    {
-                        operands.push(Boolean.FALSE);
-                    }
-                    // Otherwise, rethrow the exception.
-                    else
-                    {
-                        throw ex;
-                    }
-                }
-            }
-
-            if (operands.empty())
-            {
-                throw new EvaluationException(
-                    "Evaluation.evalute: final stack is empty");
-            }
-
-            Object result = operands.pop();
-
-            if (!operands.empty())
-            {
-                throw new EvaluationException(
-                    "Evaluation.evalute: final stack has more than one result");
-            }
-
-            if (!(result instanceof Boolean))
-            {
-                throw new EvaluationException(
-                    "Evaluation.evalute: final result is not Boolean");
-            }
-
-            return ((Boolean) result).booleanValue();
-        }
-        finally
-        {
-            // Clear the operands just in case an exception was thrown,
-            // otherwise stuff will be left in the stack.
-            operands.clear();
-        }
-    }
-
-    // For debugging; Dump the operator and stack
-    void printAction(Operator op)
-    {
-        System.err.println("Operator:"+op.toString());
-        System.err.print("Stack After:");
-        // recast operands as Vector to make interior access easier
-        Vector v = operands;
-        int len = v.size();
-        for (int i = 0; i < len; i++)
-            System.err.print(" " + v.elementAt(i));
-        System.err.println();
-    }
-
-    public String toString()
-    {
-        StringBuffer buf = new StringBuffer();
-        for (int i = 0; i < program.length; i++)
-        {
-            buf.append((i==0) ? "{" : ";");
-                buf.append(((Operator) program[i]).toString());
-        }
-        buf.append("}");
-        return buf.toString();
-    }
-
-    public String toStringInfix()
-    {
-        // First, we "evaluate" the program
-        // but for the purpose of re-constructing
-        // a parsetree.
-        operands.clear();
-        for (int i = 0; i < program.length; i++)
-        {
-            ((Operator) program[i]).buildTree(operands);
-        }
-        StringBuffer b = new StringBuffer();
-        Object result = operands.pop();
-        ((Operator)result).toStringInfix(b);
-        operands.clear();
-        return b.toString();
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/LdapLexer.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/LdapLexer.java
deleted file mode 100644
index 68c1e08..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/LdapLexer.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-import java.io.IOException;
-import java.io.Reader;
-
-public class LdapLexer {
-
-    static final int EOF = -1;
-    static final int NOCHAR = 0; // signal no peeked char; different from EOF
-
-    Reader reader = null;
-
-    int nextChar = NOCHAR; // last peeked character
-
-    public LdapLexer() {}
-
-    public LdapLexer(Reader r)
-    {
-    setReader(r);
-    charno = 1;
-    }
-
-    public void setReader(Reader r)
-    {
-    reader = r;
-    }
-
-    /*
-    The procedures get(),peek(),skipwhitespace(),getnw(), and peeknw()
-    provide the essential LdapLexer interface.
-    */
-
-    public int get() throws IOException // any next char
-    {
-    if(nextChar == NOCHAR) return readChar();
-    int c = nextChar;
-    nextChar = NOCHAR;
-    return c;
-    }
-
-    public int peek() throws IOException
-    {
-    if(nextChar == NOCHAR) {
-        nextChar = readChar();
-    }
-    return nextChar;
-    }
-
-    void skipwhitespace() throws IOException
-    {
-        while (Character.isWhitespace((char) peek())) get();
-    }
-
-    public int getnw() throws IOException // next non-whitespace char
-    {					   // (note: not essential but useful)
-    skipwhitespace();
-    return get();
-    }
-
-    public int peeknw() throws IOException // next non-whitespace char
-    {					   // (note: not essential but useful)
-    skipwhitespace();
-    return peek();
-    }
-
-    // Following is for error reporting
-
-    // Pass all character reads thru this so we can track char count
-
-    int charno; // 1-based
-
-    public int charno() {return charno;}
-
-    int readChar() throws IOException
-    {
-    charno++;
-    return reader.read();
-    }
-
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Mapper.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Mapper.java
deleted file mode 100644
index 351a8d6..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Mapper.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-public interface Mapper
-{
-    public Object lookup(String key);
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java
deleted file mode 100644
index aa10391..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Operator.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-import java.util.Stack;
-
-public abstract class Operator
-{
-    public abstract void execute(Stack operands, Mapper mapper)
-        throws EvaluationException;
-
-    public abstract String toString();
-
-    public abstract void buildTree(Stack operands); // re-build the parsetree
-    public abstract void toStringInfix(StringBuffer b); // convert to canonical string
-
-    // Place to store the reconstructed parsetree
-    // Vector -> ArrayList is using jdk1.2 or later
-    public volatile Operator[] children = null;
-}
\ No newline at end of file
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/ParseException.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/ParseException.java
deleted file mode 100644
index 9260d62..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/ParseException.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-public class ParseException extends Exception {
-    public ParseException() {super();}
-    public ParseException(String msg) {super(msg);}
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
deleted file mode 100644
index f823404..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Parser.java
+++ /dev/null
@@ -1,1851 +0,0 @@
-/*
- * 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.framework.util.ldap;
-
-import java.io.IOException;
-import java.io.PrintStream;
-import java.lang.reflect.Constructor;
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.*;
-
-public class Parser
-{
-    //
-    // Parser contants.
-    //
-
-    // End of file.
-    public static final int EOF = -1;
-
-    // Special characters in parse
-    public static final char LPAREN = '(';
-    public static final char RPAREN = ')';
-    public static final char STAR = '*';
-
-    // Define an enum for substring procedure
-    public static final int SIMPLE = 0;
-    public static final int PRESENT = 1;
-    public static final int SUBSTRING = 2;
-
-    // different from =|>|<|~
-    public static final int NOOP = 0;
-
-    // Comparison operators.
-    public static final int EQUAL = 0;
-    public static final int GREATER_EQUAL = 1;
-    public static final int LESS_EQUAL = 2;
-    public static final int APPROX = 3;
-
-    // Criteria in % to accept something as approximate.
-    public static final int APPROX_CRITERIA = 10;
-
-    // Flag indicating presense of BigDecimal.
-    private static boolean m_hasBigDecimal = false;
-
-    private static final Class[] STRING_CLASS = new Class[] { String.class };
-
-    static
-    {
-        try
-        {
-            Class.forName("java.math.BigDecimal");
-            m_hasBigDecimal = true;
-        }
-        catch (Exception ex)
-        {
-            // Ignore.
-        }
-    }
-    //
-    // Instance variables.
-    //
-
-    private LdapLexer lexer = null;
-    private List program;
-
-    public Parser()
-    {
-        reset();
-    }
-
-    public Parser(LdapLexer l)
-    {
-        reset(l);
-    }
-
-    public void reset()
-    {
-        lexer = null;
-        if (program == null)
-        {
-            program = new ArrayList();
-        }
-        program.clear();
-    }
-
-    public void reset(LdapLexer l)
-    {
-        reset();
-        lexer = l;
-    }
-
-    public Object[] getProgram()
-    {
-        return program.toArray(new Object[program.size()]);
-    }
-
-    // Define the recursive descent procedures
-
-    /*
-    <start>::= <filter> <EOF>
-    */
-    public boolean start() throws ParseException, IOException
-    {
-        boolean ok = filter();
-        if (!ok)
-        {
-            return ok;
-        }
-        // Ignore trailing whitespace.
-        for (int ch = lexer.get(); ch != EOF; ch = lexer.get())
-        {
-            if (!Character.isWhitespace(ch))
-            {
-                throw new ParseException(
-                    "expected <EOF>; found '" + ((char) ch) + "'");
-            }
-        }
-        return ok;
-    }
-
-    /*
-    <filter> ::= '(' <filtercomp> ')'
-     */
-    boolean filter() throws ParseException, IOException
-    {
-        debug("filter");
-        if (lexer.peeknw() != LPAREN)
-        {
-            return false;
-        }
-        lexer.get();
-        if (!filtercomp())
-        {
-            throw new ParseException("expected filtercomp");
-        }
-        if (lexer.getnw() != RPAREN)
-        {
-            throw new ParseException("expected )");
-        }
-        return true;
-    }
-
-    /*
-    <filtercomp> ::= <and> | <or> | <not> | <item>
-    <and> ::= '&' <filterlist>
-    <or> ::= '|' <filterlist>
-    <not> ::= '!' <filter>
-    */
-    boolean filtercomp() throws ParseException, IOException
-    {
-        debug("filtercomp");
-        int c = lexer.peeknw();
-        switch (c)
-        {
-            case '&' :
-            case '|' :
-                lexer.get();
-                int cnt = filterlist();
-                if (cnt == 0)
-                {
-                    return item((c == '&') ? "&" : "|");
-                }
-                // Code: [And|Or](cnt)
-                program.add(
-                    c == '&'
-                        ? (Operator) new AndOperator(cnt)
-                        : (Operator) new OrOperator(cnt));
-                return true;
-            case '!' :
-                lexer.get();
-                if (!filter())
-                {
-                    return item("!");
-                }
-                // Code: Not()
-                program.add(new NotOperator());
-                return true;
-            case '=':
-            case '>':
-            case '<':
-            case '~':
-            case '(':
-            case ')':
-            case EOF :
-                return false;
-            default :
-                return item("");
-        }
-    }
-
-    /*
-    <filterlist> ::= <filter> | <filter> <filterlist>
-    */
-    int filterlist() throws ParseException, IOException
-    {
-        debug("filterlist");
-        int cnt = 0;
-        if (filter())
-        {
-            do
-            {
-                cnt++;
-            }
-            while (filter());
-        }
-        return (cnt);
-    }
-
-    /*
-    <item> ::= <simple> | <present> | <substring>
-    <simple> ::= <attr> <filtertype> <value>
-    <filtertype> ::= <equal> | <approx> | <greater> | <less>
-    <present> ::= <attr> '=*'
-    <substring> ::= <attr> '=' <initial> <any> <final>
-    */
-    boolean item(String start) throws ParseException, IOException
-    {
-        debug("item");
-
-        StringBuffer attr = new StringBuffer(start);
-        if (!attribute(attr))
-        {
-            return false;
-        }
-        lexer.skipwhitespace(); // assume allowable before equal operator
-        // note: I treat the =* case as = followed by a special substring
-        int op = equalop();
-        if (op == NOOP)
-        {
-            String oplist = "=|~=|>=|<=";
-            throw new ParseException("expected " + oplist);
-        }
-        ArrayList pieces = new ArrayList();
-        int kind = substring(pieces);
-        // Get some of the illegal cases out of the way
-        if (op != '=' && kind != SIMPLE)
-        {
-            // We assume that only the = operator can work
-            // with right sides containing stars.  If not correct
-            // then this code must change.
-            throw new ParseException("expected value|substring|*");
-        }
-
-        switch (kind)
-        {
-            case SIMPLE :
-                if ((op == '=') && "objectClass".equalsIgnoreCase(attr.toString()))
-                {
-                    program.add(new ObjectClassOperator((String) pieces.get(0)));
-                    return true;
-                }
-                // Code: Push(attr); Constant(pieces.get(0)); <operator>();
-                program.add(new PushOperator(attr.toString()));
-                program.add(new ConstOperator(pieces.get(0)));
-                switch (op)
-                {
-                    case '<' :
-                        program.add(new LessEqualOperator());
-                        break;
-                    case '>' :
-                        program.add(new GreaterEqualOperator());
-                        break;
-                    case '~' :
-                        program.add(new ApproxOperator());
-                        break;
-                    case '=' :
-                    default :
-                        program.add(new EqualOperator());
-                }
-                break;
-            case PRESENT :
-                // Code: Present(attr);
-                program.add(new PresentOperator(attr.toString()));
-                break;
-            case SUBSTRING :
-                generateSubStringCode(attr.toString(), pieces);
-                break;
-            default :
-                throw new ParseException("expected value|substring|*");
-        }
-        return true;
-    }
-
-    // Generating code for substring right side is mildly
-    // complicated.
-
-    void generateSubStringCode(String attr, ArrayList pieces)
-    {
-        // Code: Push(attr)
-        program.add(new PushOperator(attr.toString()));
-
-        // Convert the pieces arraylist to a String[]
-        String[] list =
-            (String[]) pieces.toArray(new String[pieces.size()]);
-
-        // Code: SubString(list)
-        program.add(new SubStringOperator(list));
-    }
-
-    /*
-    <attr> is a string representing an attributte,
-    or key, in the properties
-    objects of the registered services. Attribute names are not case
-    sensitive; that is cn and CN both refer to the same attribute.
-    Attribute names may have embedded spaces, but not leading or
-    trailing spaces.
-    */
-    boolean attribute(StringBuffer buf) throws ParseException, IOException
-    {
-        debug("attribute");
-        lexer.skipwhitespace();
-        int c = lexer.peek();
-        // need to make sure there
-        // is at least one KEYCHAR
-        switch (c)
-        {
-            case '=':
-            case '>':
-            case '<':
-            case '~':
-            case '(':
-            case ')':
-            case EOF:
-                return false;
-            default:
-                break;
-        }
-
-        boolean parsing = true;
-        while (parsing)
-        {
-            buf.append((char) lexer.get());
-            c = lexer.peek();
-            switch (c)
-            {
-                case '=':
-                case '>':
-                case '<':
-                case '~':
-                case '(':
-                case ')':
-                case EOF:
-                    parsing = false;
-                default:
-                    break;
-            }
-        }
-
-        // The above may have accumulated trailing blanks that must be removed
-        int i = buf.length() - 1;
-        while (i > 0 && Character.isWhitespace(buf.charAt(i)))
-        {
-            i--;
-        }
-        buf.setLength(i + 1);
-        return true;
-    }
-
-    /*
-       <equal> ::= '='
-       <approx> ::= '~='
-       <greater> ::= '>='
-       <less> ::= '<='
-       <present> ::= <attr> '=*'
-    */
-    int equalop() throws ParseException, IOException
-    {
-        debug("equalop");
-        lexer.skipwhitespace();
-        int op = lexer.peek();
-        switch (op)
-        {
-            case '=' :
-                lexer.get();
-                break;
-            case '~' :
-            case '<' :
-            case '>' :
-                // skip main operator char
-                int c = lexer.get();
-                // make sure that the next char is '='
-                c = lexer.get();
-                if (c != '=')
-                {
-                    throw new ParseException("expected ~=|>=|<=");
-                }
-                break;
-            default :
-                op = NOOP;
-        }
-        return op;
-    }
-
-    /*
-    <substring> ::= <attr> '=' <initial> <any> <final>
-    <initial> ::= NULL | <value>
-    <any> ::= '*' <starval>
-    <starval> ::= NULL | <value> '*' <starval>
-    <final> ::= NULL | <value>
-    <value> ::= ...
-    */
-    /*
-    This procedure handles all cases on right side of an item
-    */
-    int substring(ArrayList pieces) throws ParseException, IOException
-    {
-        debug("substring");
-
-        pieces.clear();
-        StringBuffer ss = new StringBuffer();
-        //        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
-
-        // We assume (sub)strings can contain leading and trailing blanks
-loop:   for (;;)
-        {
-            int c = lexer.peek();
-            switch (c)
-            {
-                case RPAREN :
-                    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;
-                case '\\' :
-                    wasStar = false;
-                    lexer.get();
-                    c = lexer.get();
-                    if (c == EOF)
-                    {
-                        throw new ParseException("unexpected EOF");
-                    }
-                    ss.append((char) c);
-                    break;
-                case LPAREN:
-                case EOF :
-                    if (pieces.size() > 0)
-                    {
-                        throw new ParseException("expected ')'");
-                    }
-                    else
-                    {
-                        throw new ParseException("expected value|substring");
-                    }
-                case '*' :
-                    if (wasStar)
-                    {
-                        // encountered two successive stars;
-                        // I assume this is illegal
-                        throw new ParseException("unexpected '**'");
-                    }
-                    lexer.get();
-                    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.size() == 0)
-                    {
-                        leftstar = true;
-                    }
-                    ss.setLength(0);
-                    wasStar = true;
-                    break;
-                default :
-                    wasStar = false;
-                    ss.append((char) lexer.get());
-            }
-        }
-        if (pieces.size() == 0)
-        {
-            return PRESENT;
-        }
-        if (leftstar || rightstar || pieces.size() > 1)
-        {
-            // insert leading and/or trailing "" to anchor ends
-            if (rightstar)
-            {
-                pieces.add("");
-            }
-            if (leftstar)
-            {
-                pieces.add(0, "");
-            }
-            return SUBSTRING;
-        }
-        // assert !leftstar && !rightstar && pieces.size == 1
-        return SIMPLE;
-    }
-
-    // Debug stuff
-
-    static boolean debug = false;
-
-    PrintStream dbgout = null;
-
-    public void setDebug(PrintStream out)
-    {
-        debug = true;
-        dbgout = out;
-    }
-
-    void debug(String proc)
-    {
-        if (!debug || dbgout == null)
-        {
-            return;
-        }
-        dbgout.println("parsing " + proc + ":" + lexer.charno());
-        dbgout.flush();
-    }
-
-    // Exclusive inner classes
-    private static final class AndOperator extends Operator
-    {
-        private final int operandCount;
-
-        public AndOperator(int opcnt)
-        {
-            operandCount = opcnt;
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            // Determine result using short-circuit evaluation.
-            boolean result = true;
-            for (int i = 0; i < operandCount; i++)
-            {
-                if (operands.empty())
-                {
-                    fewOperands("AND");
-                }
-
-                // For short-circuited evaluation, once the AND
-                // becomes false, we can ignore the remaining
-                // expressions, but we must still pop them off.
-                if (!result)
-                {
-                    operands.pop();
-                }
-                else
-                {
-                    result = ((Boolean) operands.pop()).booleanValue();
-                }
-            }
-            operands.push((result ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return "&(" + operandCount + ")";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                Operator[] tmp = new Operator[operandCount];
-                // need to preserve stack order
-                for (int i = 0; i < operandCount; i++)
-                {
-                    tmp[(operandCount - 1) - i] =
-                        (Operator) operands.pop();
-                }
-                children = tmp;
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(&");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class OrOperator extends Operator
-    {
-        private final int operandCount;
-
-        public OrOperator(int opcnt)
-        {
-            operandCount = opcnt;
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            // Determine result using short-circuit evaluation.
-            boolean result = false;
-            for (int i = 0; i < operandCount; i++)
-            {
-                if (operands.empty())
-                {
-                    fewOperands("OR");
-                }
-
-                // For short-circuited evaluation, once the OR
-                // becomes true, we can ignore the remaining
-                // expressions, but we must still pop them off.
-                if (result)
-                {
-                    operands.pop();
-                }
-                else
-                {
-                    result = ((Boolean) operands.pop()).booleanValue();
-                }
-            }
-            operands.push((result ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return "|(" + operandCount + ")";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                Operator[] tmp = new Operator[operandCount];
-
-                // need to preserve stack order
-                for (int i = 0; i < operandCount; i++)
-                {
-                    tmp[(operandCount - 1) - i] =
-                        (Operator) operands.pop();
-                }
-                children = tmp;
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(|");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class NotOperator extends Operator
-    {
-        public NotOperator()
-        {
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            if (operands.empty())
-            {
-                fewOperands("NOT");
-            }
-            boolean result = !((Boolean) operands.pop()).booleanValue();
-            operands.push((result ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return "!()";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                children = new Operator[]{
-                    (Operator) operands.pop()};
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(!");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class ObjectClassOperator extends Operator
-    {
-        public final String m_target;
-
-        public ObjectClassOperator(String target)
-        {
-            m_target = target;
-        }
-
-        public void buildTree(Stack operands)
-        {
-            operands.push(this);
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            String[] objectClass = (String[]) mapper.lookup("objectClass");
-            if (objectClass != null)
-            {
-                for (int i = 0; i < objectClass.length; i++)
-                {
-                    if (m_target.equals(objectClass[i]))
-                    {
-                        operands.push(Boolean.TRUE);
-                        return;
-                    }
-                }
-            }
-            operands.push(Boolean.FALSE);
-        }
-
-        public String toString()
-        {
-            return "=()";
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append('(').append("objectClass=").append(m_target).append(')');
-        }
-    }
-
-    private static final class EqualOperator extends Operator
-    {
-        public EqualOperator()
-        {
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            if (operands.empty())
-            {
-                fewOperands("=");
-            }
-
-            // We cheat and use the knowledge that top (right) operand
-            // will always be a string because of the way code was generated
-            String rhs = (String) operands.pop();
-            if (operands.empty())
-            {
-                fewOperands("=");
-            }
-
-            Object lhs = operands.pop();
-
-            operands.push((compare(lhs, rhs, EQUAL) ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return "=()";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                Operator[] tmp = new Operator[2];
-
-                // need to preserve stack order
-                for (int i = 0; i < 2; i++)
-                {
-                    Operator o = (Operator) operands.pop();
-                    tmp[1 - i] = o;
-                }
-                children = tmp;
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                if (i > 0)
-                {
-                    b.append("=");
-                }
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class GreaterEqualOperator extends Operator
-    {
-        public GreaterEqualOperator()
-        {
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            if (operands.empty())
-            {
-                fewOperands(">=");
-            }
-            // We cheat and use the knowledge that top (right) operand
-            // will always be a string because of the way code was generated
-            String rhs = (String) operands.pop();
-            if (operands.empty())
-            {
-                fewOperands(">=");
-            }
-            Object lhs = operands.pop();
-
-            operands.push((compare(lhs, rhs, GREATER_EQUAL) ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return ">=()";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                Operator[] tmp = new Operator[2];
-
-                // need to preserve stack order
-                for (int i = 0; i < 2; i++)
-                {
-                    tmp[1 - i] = (Operator) operands.pop();
-                }
-                children = tmp;
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                if (i > 0)
-                {
-                    b.append(">=");
-                }
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class LessEqualOperator extends Operator
-    {
-        public LessEqualOperator()
-        {
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            if (operands.empty())
-            {
-                fewOperands("<=");
-            }
-            // We cheat and use the knowledge that top (right) operand
-            // will always be a string because of the way code was generated
-            String rhs = (String) operands.pop();
-            if (operands.empty())
-            {
-                fewOperands("<=");
-            }
-            Object lhs = (Object) operands.pop();
-            operands.push((compare(lhs, rhs, LESS_EQUAL) ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return "<=()";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                Operator[] tmp = new Operator[2];
-
-                // need to preserve stack order
-                for (int i = 0; i < 2; i++)
-                {
-                    tmp[1 - i] = (Operator) operands.pop();
-                }
-                children = tmp;
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                if (i > 0)
-                {
-                    b.append("<=");
-                }
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class ApproxOperator extends Operator
-    {
-        public ApproxOperator()
-        {
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            if (operands.empty())
-            {
-                fewOperands("~=");
-            }
-            // We cheat and use the knowledge that top (right) operand
-            // will always be a string because of the way code was generated
-            String rhs = (String) operands.pop();
-            if (operands.empty())
-            {
-                fewOperands("~=");
-            }
-            Object lhs = operands.pop();
-            operands.push((compare(lhs, rhs, APPROX) ? Boolean.TRUE : Boolean.FALSE));
-        }
-
-        public String toString()
-        {
-            return "~=()";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                Operator[] tmp = new Operator[2];
-
-                // need to preserve stack order
-                for (int i = 0; i < 2; i++)
-                {
-                    tmp[1 - i] = (Operator) operands.pop();
-                }
-                children = tmp;
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(");
-            for (int i = 0; i < children.length; i++)
-            {
-                Operator o = (Operator) children[i];
-                if (i > 0)
-                {
-                    b.append("~=");
-                }
-                o.toStringInfix(b);
-            }
-            b.append(")");
-        }
-    }
-
-    private static final class PresentOperator extends Operator
-    {
-        final String attribute;
-
-        public PresentOperator(String attribute)
-        {
-            this.attribute = attribute;
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            Object value = mapper.lookup(attribute);
-            operands.push((value != null) ? Boolean.TRUE : Boolean.FALSE);
-        }
-
-        public String toString()
-        {
-            return attribute + "=*";
-        }
-
-        public void buildTree(Stack operands)
-        {
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(");
-            b.append(attribute + "=*");
-            b.append(")");
-        }
-    }
-
-    private static final class PushOperator extends Operator
-    {
-        final String attribute;
-
-        public PushOperator(String attribute)
-        {
-            this.attribute = attribute;
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            // find and push the value of a given attribute
-            Object value = mapper.lookup(attribute);
-            if (value == null)
-            {
-                throw new AttributeNotFoundException(
-                    "attribute " + attribute + " not found");
-            }
-            operands.push(value);
-        }
-
-        public String toString()
-        {
-            return "push(" + attribute + ")";
-        }
-
-        public String toStringInfix()
-        {
-            return attribute;
-        }
-
-        public void buildTree(Stack operands)
-        {
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append(attribute);
-        }
-    }
-
-    private static final class ConstOperator extends Operator
-    {
-        final Object val;
-
-        public ConstOperator(Object val)
-        {
-            this.val = val;
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            operands.push(val);
-        }
-
-        public String toString()
-        {
-            return "const(" + val + ")";
-        }
-
-        public String toStringInfix()
-        {
-            return val.toString();
-        }
-
-        public void buildTree(Stack operands)
-        {
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            appendEscaped(b, val.toString());
-        }
-    }
-
-    private static final class SubStringOperator extends Operator
-        implements OperatorConstants
-    {
-        final String[] pieces;
-
-        public SubStringOperator(String[] pieces)
-        {
-            this.pieces = pieces;
-        }
-
-        public void execute(Stack operands, Mapper mapper)
-            throws EvaluationException
-        {
-            if (operands.empty())
-            {
-                fewOperands("SUBSTRING");
-            }
-
-            Object op = operands.pop();
-
-            // The operand can either be a string or an array of strings.
-            if (op instanceof String)
-            {
-                operands.push(check((String) op));
-            }
-            else if (op instanceof String[])
-            {
-                // If one element of the array matches, then push true.
-                String[] ops = (String[]) op;
-                boolean result = false;
-                for (int i = 0; !result && (i < ops.length); i++)
-                {
-                    if (check(ops[i]) == Boolean.TRUE)
-                    {
-                        result = true;
-                    }
-                }
-
-                operands.push(result ? Boolean.TRUE : Boolean.FALSE);
-            }
-            else
-            {
-                unsupportedType("SUBSTRING", op.getClass());
-            }
-        }
-
-        private Boolean check(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 = Boolean.FALSE;
-            int len = pieces.length;
-
-            int index = 0;
-            for (int i = 0; i < len; i++)
-            {
-                String piece = (String) pieces[i];
-
-                if (i == len - 1)
-                {
-                    // this is the last piece
-                    if (s.endsWith(piece))
-                    {
-                        result = Boolean.TRUE;
-                    }
-                    else
-                    {
-                        result = Boolean.FALSE;
-                    }
-                    break;
-                }
-                // initial non-star; assert index == 0
-                else if (i == 0)
-                {
-                    if (!s.startsWith(piece))
-                    {
-                        result = Boolean.FALSE;
-                        break;
-                    }
-                }
-                // assert i > 0 && i < len-1
-                else
-                {
-                    // Sure wish stringbuffer supported e.g. indexOf
-                    index = s.indexOf(piece, index);
-                    if (index < 0)
-                    {
-                        result = Boolean.FALSE;
-                        break;
-                    }
-                }
-                // start beyond the matching piece
-                index += piece.length();
-            }
-
-            return result;
-        }
-
-        public String toString()
-        {
-            StringBuffer b = new StringBuffer();
-            b.append("substring(");
-            for (int i = 0; i < pieces.length; i++)
-            {
-                String piece = pieces[i];
-                if (i > 0)
-                {
-                    b.append("*");
-                }
-                b.append(escape(piece));
-            }
-            b.append(")");
-            return b.toString();
-        }
-
-        public String escape(String s)
-        {
-            int len = s.length();
-            StringBuffer buf = new StringBuffer(len);
-            for (int i = 0; i < len; i++)
-            {
-                char c = s.charAt(i);
-                if (c == ')' || c == '*')
-                    buf.append('\\');
-                buf.append(c);
-            }
-            return buf.toString();
-        }
-
-        public void buildTree(Stack operands)
-        {
-            if (children == null)
-            {
-                children = new Operator[]{
-                    (Operator) operands.pop()};
-            }
-            operands.push(this);
-        }
-
-        public void toStringInfix(StringBuffer b)
-        {
-            b.append("(");
-            children[0].toStringInfix(b); // dump attribute
-            b.append("=");
-            for (int i = 0; i < pieces.length; i++)
-            {
-                String piece = pieces[i];
-                if (i > 0)
-                {
-                    b.append("*");
-                }
-                appendEscaped(b, piece);
-            }
-            b.append(")");
-        }
-    }
-
-    // Utility classes and Interfaces
-
-    private interface OperatorConstants
-    {
-        static final int SSINIT = 0;
-        static final int SSFINAL = 1;
-        static final int SSMIDDLE = 2;
-        static final int SSANY = 3;
-    }
-
-    /**
-     * Compare two operands in an expression with respect
-     * to the following operators =, <=, >= and ~=
-     *
-     * Example: value=100
-     *
-     * @param lhs an object that implements comparable or an array of
-     *            objects that implement comparable.
-     * @param rhs a string representing the right operand.
-     * @param operator an integer that represents the operator.
-     * @return <tt>true</tt> or <tt>false</tt> according to the evaluation.
-     * @throws EvaluationException if it is not possible to do the comparison.
-    **/
-    public static boolean compare(Object lhs, String rhs, int operator)
-        throws EvaluationException
-    {
-        // Try to optimize the common case of strings by just
-        // checking for them directly.
-        if (lhs instanceof String)
-        {
-            switch (operator)
-            {
-                case EQUAL :
-                    return (((String) lhs).compareTo(rhs) == 0);
-                case GREATER_EQUAL :
-                    return (((String) lhs).compareTo(rhs) >= 0);
-                case LESS_EQUAL :
-                    return (((String) lhs).compareTo(rhs) <= 0);
-                case APPROX:
-                    return compareToApprox(((String) lhs), rhs);
-                default:
-                    throw new EvaluationException("Unknown comparison operator..."
-                        + operator);
-            }
-        }
-        else if (lhs instanceof Comparable)
-        {
-            // Here we know that the LHS is a comparable object, so
-            // try to create an object for the RHS by using a constructor
-            // that will take the RHS string as a parameter.
-            Comparable rhsComparable = null;
-            try
-            {
-                // We are expecting to be able to construct a comparable
-                // instance from the RHS string by passing it into the
-                // constructor of the corresponing comparable class. The
-                // Character class is a special case, since its constructor
-                // does not take a string, so handle it separately.
-                if (lhs instanceof Character)
-                {
-                    rhsComparable = new Character(rhs.charAt(0));
-                }
-                else
-                {
-                    Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS);
-                    // We don't invoke the constructor in a privileged block,
-                    // since we don't want to elevate the caller's privileges.
-                    // If the object needs to, it should be doing a privileged
-                    // block internally.
-                    rhsComparable = (Comparable) ctor.newInstance(new Object[] { rhs });
-                }
-            }
-            catch (Exception ex)
-            {
-                throw new EvaluationException(
-                    "Could not instantiate class "
-                        + lhs.getClass().getName()
-                        + " with constructor String parameter "
-                        + rhs + " " + ex);
-            }
-
-            Comparable lhsComparable = (Comparable) lhs;
-
-            switch (operator)
-            {
-                case EQUAL :
-                    return (lhsComparable.compareTo(rhsComparable) == 0);
-                case GREATER_EQUAL :
-                    return (lhsComparable.compareTo(rhsComparable) >= 0);
-                case LESS_EQUAL :
-                    return (lhsComparable.compareTo(rhsComparable) <= 0);
-                case APPROX:
-                    return compareToApprox(lhsComparable, rhsComparable);
-                default:
-                    throw new EvaluationException("Unknown comparison operator..."
-                        + operator);
-            }
-        }
-
-        // Determine class of LHS.
-        Class lhsClass = lhs.getClass();
-
-        // If LHS is an array, then call compare() on each element
-        // of the array until a match is found.
-        if (lhsClass.isArray())
-        {
-            // First, if this is an array of primitives, then convert
-            // the entire array to an array of the associated
-            // primitive wrapper class instances.
-            if (lhsClass.getComponentType().isPrimitive())
-            {
-                lhs = convertPrimitiveArray(lhs);
-            }
-
-            // Now call compare on each element of array.
-            Object[] array = (Object[]) lhs;
-            for (int i = 0; i < array.length; i++)
-            {
-                if (compare(array[i], rhs, operator))
-                {
-                    return true;
-                }
-            }
-        }
-        // If LHS is a vector, then call compare() on each element
-        // of the vector until a match is found.
-        else if (lhs instanceof Collection)
-        {
-            for (Iterator iter = ((Collection) lhs).iterator(); iter.hasNext();)
-            {
-                if (compare(iter.next(), rhs, operator))
-                {
-                    return true;
-                }
-            }
-        }
-        else
-        {
-            // At this point we are expecting the LHS to be a comparable,
-            // but Boolean is a special case since it is the only primitive
-            // wrapper class that does not implement comparable; deal with
-            // Boolean separately.
-            if (lhsClass == Boolean.class)
-            {
-                return compareBoolean(lhs, rhs, operator);
-            }
-
-            // If the LHS is not a comparable, then try to use simple
-            // equals() comparison. If that fails, return false.
-            if (!(Comparable.class.isAssignableFrom(lhsClass)))
-            {
-                try
-                {
-                    Constructor ctor = lhs.getClass().getConstructor(STRING_CLASS);
-                    // We don't invoke the constructor in a privileged block,
-                    // since we don't want to elevate the caller's privileges.
-                    // If the object needs to, it should be doing a privileged
-                    // block internally.
-                    Object rhsObject = ctor.newInstance(new Object[] { rhs });
-                    return lhs.equals(rhsObject);
-                }
-                catch (Exception ex)
-                {
-                    // Always return false.
-                }
-
-                return false;
-            }
-
-        }
-
-        return false;
-    }
-
-    private static void appendEscaped(StringBuffer buf, String value)
-    {
-        for (int i = 0; i < value.length(); i++)
-        {
-            char c = value.charAt(i);
-            if (c == '(' || c == ')' || c == '*' || c == '\\')
-            {
-                buf.append('\\');
-            }
-            buf.append(c);
-        }
-    }
-
-    /**
-     * 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
-     * @return
-    **/
-    private static Object[] convertPrimitiveArray(Object array)
-    {
-        Class clazz = array.getClass().getComponentType();
-
-        if (clazz == Boolean.TYPE)
-        {
-            boolean[] src = (boolean[]) array;
-            array = new Boolean[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = (src[i] ? Boolean.TRUE : Boolean.FALSE);
-            }
-        }
-        else if (clazz == Character.TYPE)
-        {
-            char[] src = (char[]) array;
-            array = new Character[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Character(src[i]);
-            }
-        }
-        else if (clazz == Byte.TYPE)
-        {
-            byte[] src = (byte[]) array;
-            array = new Byte[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Byte(src[i]);
-            }
-        }
-        else if (clazz == Short.TYPE)
-        {
-            short[] src = (short[]) array;
-            array = new Short[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Short(src[i]);
-            }
-        }
-        else if (clazz == Integer.TYPE)
-        {
-            int[] src = (int[]) array;
-            array = new Integer[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Integer(src[i]);
-            }
-        }
-        else if (clazz == Long.TYPE)
-        {
-            long[] src = (long[]) array;
-            array = new Long[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Long(src[i]);
-            }
-        }
-        else if (clazz == Float.TYPE)
-        {
-            float[] src = (float[]) array;
-            array = new Float[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Float(src[i]);
-            }
-        }
-        else if (clazz == Double.TYPE)
-        {
-            double[] src = (double[]) array;
-            array = new Double[src.length];
-            for (int i = 0; i < src.length; i++)
-            {
-                ((Object[]) array)[i] = new Double(src[i]);
-            }
-        }
-
-        return (Object[]) array;
-    }
-
-    private static boolean compareBoolean(Object lhs, String rhs, int operator)
-        throws EvaluationException
-    {
-        Boolean rhsBoolean = new Boolean(rhs);
-        if (lhs.getClass().isArray())
-        {
-            Object[] objs = (Object[]) lhs;
-            for (int i = 0; i < objs.length; i++)
-            {
-                switch (operator)
-                {
-                    case EQUAL :
-                    case GREATER_EQUAL :
-                    case LESS_EQUAL :
-                    case APPROX:
-                        if (objs[i].equals(rhsBoolean))
-                        {
-                            return true;
-                        }
-                        break;
-                    default:
-                        throw new EvaluationException(
-                            "Unknown comparison operator: " + operator);
-                }
-            }
-            return false;
-        }
-        else
-        {
-            switch (operator)
-            {
-                case EQUAL :
-                case GREATER_EQUAL :
-                case LESS_EQUAL :
-                case APPROX:
-                    return (lhs.equals(rhsBoolean));
-                default:
-                    throw new EvaluationException("Unknown comparison operator..."
-                        + operator);
-            }
-        }
-    }
-
-    /**
-     * Test if two objects are approximate. The two objects that are passed must
-     * have the same type.
-     *
-     * Approximate for numerical values involves a difference of less than APPROX_CRITERIA
-     * Approximate for string values is calculated by using the Levenshtein distance
-     * between strings and is case insensitive. Less than APPROX_CRITERIA of
-     * difference is considered as approximate.
-     *
-     * Supported types only include the following subclasses of Number:
-     * - Byte
-     * - Double
-     * - Float
-     * - Int
-     * - Long
-     * - Short
-     * - BigInteger
-     * - BigDecimal
-     * As subclasses of Number must provide methods to convert the represented numeric value
-     * to byte, double, float, int, long, and short. (see API)
-     *
-     * @param obj1
-     * @param obj2
-     * @return true if they are approximate
-     * @throws EvaluationException if it the two objects cannot be approximated
-    **/
-    private static boolean compareToApprox(Object obj1, Object obj2) throws EvaluationException
-    {
-        if (obj1 instanceof Byte)
-        {
-            byte value1 = ((Byte)obj1).byteValue();
-            byte value2 = ((Byte)obj2).byteValue();
-            return (value2 >= (value1-((Math.abs(value1)*(byte)APPROX_CRITERIA)/(byte)100))
-                && value2 <= (value1+((Math.abs(value1)*(byte)APPROX_CRITERIA)/(byte)100)));
-        }
-        else if (obj1 instanceof Character)
-        {
-            // We should ignore case.
-            char value1 = Character.toLowerCase(((Character) obj1).charValue());
-            char value2 = Character.toLowerCase(((Character) obj2).charValue());
-            return (value2 >= (value1-((Math.abs(value1)*(char)APPROX_CRITERIA)/(char)100))
-                && value2 <= (value1+((Math.abs(value1)*(char)APPROX_CRITERIA)/(char)100)));
-        }
-        else if (obj1 instanceof Double)
-        {
-            double value1 = ((Double)obj1).doubleValue();
-            double value2 = ((Double)obj2).doubleValue();
-            return (value2 >= (value1-((Math.abs(value1)*(double)APPROX_CRITERIA)/(double)100))
-                && value2 <= (value1+((Math.abs(value1)*(double)APPROX_CRITERIA)/(double)100)));
-        }
-        else if (obj1 instanceof Float)
-        {
-            float value1 = ((Float)obj1).floatValue();
-            float value2 = ((Float)obj2).floatValue();
-            return (value2 >= (value1-((Math.abs(value1)*(float)APPROX_CRITERIA)/(float)100))
-                && value2 <= (value1+((Math.abs(value1)*(float)APPROX_CRITERIA)/(float)100)));
-        }
-        else if (obj1 instanceof Integer)
-        {
-            int value1 = ((Integer)obj1).intValue();
-            int value2 = ((Integer)obj2).intValue();
-            return (value2 >= (value1-((Math.abs(value1)*(int)APPROX_CRITERIA)/(int)100))
-                && value2 <= (value1+((Math.abs(value1)*(int)APPROX_CRITERIA)/(int)100)));
-        }
-        else if (obj1 instanceof Long)
-        {
-            long value1 = ((Long)obj1).longValue();
-            long value2 = ((Long)obj2).longValue();
-            return (value2 >= (value1-((Math.abs(value1)*(long)APPROX_CRITERIA)/(long)100))
-                && value2 <= (value1+((Math.abs(value1)*(long)APPROX_CRITERIA)/(long)100)));
-        }
-        else if (obj1 instanceof Short)
-        {
-            short value1 = ((Short)obj1).shortValue();
-            short value2 = ((Short)obj2).shortValue();
-            return (value2 >= (value1-((Math.abs(value1)*(short)APPROX_CRITERIA)/(short)100))
-                && value2 <= (value1+((Math.abs(value1)*(short)APPROX_CRITERIA)/(short)100)));
-        }
-        else if (obj1 instanceof String)
-        {
-            // Spec says to ignore case and whitespace, to let's convert
-            // to lower case and remove whitespace.
-            int distance = getDistance(
-                removeWhitespace(obj1.toString()), removeWhitespace(obj2.toString()));
-             int size = ((String)obj1).length();
-             return (distance <= ((size*APPROX_CRITERIA)/100));
-        }
-        else if (obj1 instanceof BigInteger)
-        {
-            BigInteger value1 = (BigInteger)obj1;
-            BigInteger value2 = (BigInteger)obj2;
-            BigInteger delta = value1.abs().multiply(
-                BigInteger.valueOf(APPROX_CRITERIA)
-                    .divide(BigInteger.valueOf(100)));
-            BigInteger low = value1.subtract(delta);
-            BigInteger high = value1.add(delta);
-            return (value2.compareTo(low) >= 0) && (value2.compareTo(high) <= 0);
-        }
-        else if (m_hasBigDecimal && (obj1 instanceof BigDecimal))
-        {
-            BigDecimal value1 = (BigDecimal)obj1;
-            BigDecimal value2 = (BigDecimal)obj2;
-            BigDecimal delta = value1.abs().multiply(
-                BigDecimal.valueOf(APPROX_CRITERIA)
-                    .divide(BigDecimal.valueOf(100), BigDecimal.ROUND_HALF_DOWN));
-            BigDecimal low = value1.subtract(delta);
-            BigDecimal high = value1.add(delta);
-            return (value2.compareTo(low) >= 0) && (value2.compareTo(high) <= 0);
-        }
-        throw new EvaluationException(
-            "Approximate operator not supported for type "
-            + obj1.getClass().getName());
-    }
-
-    private static String removeWhitespace(String s)
-    {
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < s.length(); i++)
-        {
-            if (!Character.isWhitespace(s.charAt(i)))
-            {
-                sb.append(Character.toLowerCase(s.charAt(i)));
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Calculate the Levenshtein distance (LD) between two strings.
-     * The Levenshteing distance is a measure of the similarity between
-     * two strings, which we will refer to as the source string (s) and
-     * the target string (t). The distance is the number of deletions,
-     * insertions, or substitutions required to transform s into t.
-     *
-     * Algorithm from: http://www.merriampark.com/ld.htm
-     *
-     * @param s the first string
-     * @param t the second string
-     * @return
-     */
-    private static int getDistance(String s, String t)
-    {
-        int d[][]; // matrix
-        int n; // length of s
-        int m; // length of t
-        int i; // iterates through s
-        int j; // iterates through t
-        char s_i; // ith character of s
-        char t_j; // jth character of t
-        int cost; // cost
-
-        // Step 1
-        n = s.length();
-        m = t.length();
-        if (n == 0)
-        {
-            return m;
-        }
-        if (m == 0)
-        {
-            return n;
-        }
-        d = new int[n + 1][m + 1];
-
-        // Step 2
-        for (i = 0; i <= n; i++)
-        {
-            d[i][0] = i;
-        }
-
-        for (j = 0; j <= m; j++)
-        {
-            d[0][j] = j;
-        }
-
-        // Step 3
-        for (i = 1; i <= n; i++)
-        {
-            s_i = s.charAt(i - 1);
-            // Step 4
-            for (j = 1; j <= m; j++)
-            {
-                t_j = t.charAt(j - 1);
-                // Step 5
-                if (s_i == t_j)
-                {
-                    cost = 0;
-                }
-                else
-                {
-                    cost = 1;
-                }
-                // Step 6
-                d[i][j] =
-                    Minimum(
-                        d[i - 1][j] + 1,
-                        d[i][j - 1] + 1,
-                        d[i - 1][j - 1] + cost);
-            }
-        }
-        // Step 7
-        return d[n][m];
-    }
-
-    /**
-     * Calculate the minimum between three values
-     *
-     * @param a
-     * @param b
-     * @param c
-     * @return
-     */
-    private static int Minimum(int a, int b, int c)
-    {
-        int mi;
-        mi = a;
-        if (b < mi)
-        {
-            mi = b;
-        }
-        if (c < mi)
-        {
-            mi = c;
-        }
-        return mi;
-    }
-
-    private static void fewOperands(String op) throws EvaluationException
-    {
-        throw new EvaluationException(op + ": too few operands");
-    }
-
-    private static void unsupportedType(String opStr, Class clazz)
-        throws EvaluationException
-    {
-        throw new EvaluationException(
-            opStr + ": unsupported type " + clazz.getName(), clazz);
-    }
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/ldap/Unknown.java b/framework/src/main/java/org/apache/felix/framework/util/ldap/Unknown.java
deleted file mode 100644
index 58f8dd5..0000000
--- a/framework/src/main/java/org/apache/felix/framework/util/ldap/Unknown.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/* 
- * 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.framework.util.ldap;
-
-/**
- * This class is used to create simple marker instances that are inserted
- * into the evaluation stack of a LDAP filter expression when an attribute
- * is referenced that has no defined value. These invalid marker instances
- * force the operators to throw an "unsupported type" exception, which the
- * evaluator catches and then converts the entire subexpression containing
- * the non-existent attribute to <tt>false</tt>.
-**/
-class Unknown
-{
-}
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
index 91cb625..cbd7d73 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/R4LibraryClause.java
@@ -20,7 +20,6 @@
 
 import java.util.*;
 
-import org.apache.felix.framework.FilterImpl;
 import org.apache.felix.framework.Logger;
 import org.apache.felix.framework.util.FelixConstants;
 import org.apache.felix.framework.util.VersionRange;
@@ -214,7 +213,7 @@
         // Compute expression
         try
         {
-            FilterImpl filter = new FilterImpl(expr);
+            Filter filter = FrameworkUtil.createFilter(expr);
             return filter.match(dict);
         }
         catch (Exception ex)
diff --git a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java
index f70f3ca..42cb756 100644
--- a/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java
+++ b/framework/src/main/java/org/apache/felix/framework/util/manifestparser/Requirement.java
@@ -18,7 +18,6 @@
  */
 package org.apache.felix.framework.util.manifestparser;
 
-import org.apache.felix.framework.FilterImpl;
 import org.apache.felix.framework.util.MapToDictionary;
 import org.apache.felix.framework.util.VersionRange;
 import org.apache.felix.moduleloader.ICapability;
@@ -39,7 +38,7 @@
     public Requirement(String namespace, String filterStr) throws InvalidSyntaxException
     {
         m_namespace = namespace;
-        m_filter = new FilterImpl(filterStr);
+        m_filter = FrameworkUtil.createFilter(filterStr);
         m_directives = null;
         m_attributes = null;
         m_isOptional = false;
@@ -362,7 +361,7 @@
 
         try
         {
-            return new FilterImpl(sb.toString());
+            return FrameworkUtil.createFilter(sb.toString());
         }
         catch (InvalidSyntaxException ex)
         {
diff --git a/framework/src/main/java/org/osgi/framework/AdminPermission.java b/framework/src/main/java/org/osgi/framework/AdminPermission.java
deleted file mode 100644
index dc798ff..0000000
--- a/framework/src/main/java/org/osgi/framework/AdminPermission.java
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * 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.osgi.framework;
-
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.BasicPermission;
-import java.security.Permission;
-import java.security.PermissionCollection;
-import java.security.PrivilegedAction;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.StringTokenizer;
-
-import org.apache.felix.framework.FilterImpl;
-
-/**
- * <p>
- * This class is a replacement for the version that ships with the
- * standard OSGi JAR file.
- * </p>
-**/
-public final class AdminPermission extends BasicPermission
-{
-    static final long serialVersionUID = 307051004521261705L;
-
-    public static final String CLASS = "class";
-    public static final String EXECUTE = "execute";
-    public static final String EXTENSIONLIFECYCLE = "extensionLifecycle";
-    public static final String LIFECYCLE = "lifecycle";
-    public static final String LISTENER = "listener";
-    public static final String METADATA = "metadata";
-    public static final String RESOLVE = "resolve";
-    public static final String RESOURCE = "resource";
-    public static final String STARTLEVEL = "startlevel";
-
-    private static final int CLASS_MASK = 1;
-    private static final int EXECUTE_MASK = 2;
-    private static final int EXTENSIONLIFECYCLE_MASK = 4;
-    private static final int LIFECYCLE_MASK = 8;
-    private static final int LISTENER_MASK = 16;
-    private static final int METADATA_MASK = 32;
-    private static final int RESOLVE_MASK = 64;
-    private static final int RESOURCE_MASK = 128;
-    private static final int STARTLEVEL_MASK = 256;
-    private static final int ALL_MASK =
-        CLASS_MASK | EXECUTE_MASK | EXTENSIONLIFECYCLE_MASK |
-        LIFECYCLE_MASK | LISTENER_MASK | METADATA_MASK |
-        RESOLVE_MASK | RESOURCE_MASK | STARTLEVEL_MASK;
-
-    private String m_actions = null;
-    int m_actionMask = 0;
-
-    // Cached filter for permissions created with a filter when
-    // granting admin permissions.
-    private FilterImpl m_filterImpl = null;
-
-    // Bundle associated with the permission when checking
-    // admin permissions.
-    private Bundle m_bundle = null;
-    // Cached bundle property dictionary when checking
-    // admin permissions.
-    private Dictionary m_bundleDict = null;
-
-    // This constructor is only used when granting an admin permission.
-	public AdminPermission()
-    {
-		this("*", ALL_MASK);
-    }
-
-    // This constructor is only used when checking a granted admin permission.
-    public AdminPermission(Bundle bundle, String actions)
-    {
-        this(createName(bundle), actions);
-        m_bundle = bundle;
-    }
-
-    // This constructor is only used when granting an admin permission.
-	public AdminPermission(String filter, String actions)
-    {
-		super((filter == null) || (filter.equals("*")) ? "(id=*)" : filter);
-        m_actionMask = parseActions(actions);
-    }
-
-    // This constructor is only used by the admin permission collection
-    // when combining admin permissions or by the default constructor when granting
-    // an admin permission
-    AdminPermission(String filter, int actionMask)
-    {
-        super((filter == null) || (filter.equals("*")) ? "(id=*)" : filter);
-        m_actionMask = actionMask;
-    }
-
-    public boolean equals(Object obj)
-    {
-	if (obj == this)
-        {
-	    return true;
-	}
-
-	if (!(obj instanceof AdminPermission))
-        {
-	    return false;
-	}
-
-	AdminPermission p = (AdminPermission) obj;
-
-	return getName().equals(p.getName()) && (m_actionMask == p.m_actionMask);
-    }
-
-    public int hashCode()
-    {
-	return getName().hashCode() ^ getActions().hashCode();
-    }
-
-    public String getActions()
-    {
-        if (m_actions == null)
-        {
-            m_actions = createActionString(m_actionMask);
-        }
-	return m_actions;
-    }
-
-    public boolean implies(Permission p)
-    {
-	if (!(p instanceof AdminPermission))
-        {
-	    return false;
-	}
-
-        AdminPermission admin = (AdminPermission) p;
-
-        // Make sure that the permission was create with a bundle or a "*".
-        // Otherwise, throw an Exception - as per spec.
-        if ((admin.m_bundle == null) && !(admin.getName().equals("(id=*)")))
-        {
-            throw new RuntimeException(
-                "The specified permission was not constructed with a bundle or *!");
-        }
-
-        // Make sure the action mask is a subset.
-        if ((m_actionMask & admin.m_actionMask) != admin.m_actionMask)
-        {
-            return false;
-        }
-
-        // Special case: if the specified permission was constructed with "*"
-        // filter, then this method returns <code>true</code> if this object's
-        // filter is "*".
-        if (admin.getName().equals("(id=*)"))
-        {
-            return getName().equals("(id=*)");
-        }
-
-        // Next, if this object was create with a "*" we can return true
-        // (This way we avoid creating and matching a filter).
-        if (getName().equals("(id=*)"))
-        {
-            return true;
-        }
-
-        // Otherwise, see if this permission's filter matches the
-        // dictionary of the passed in permission.
-        if (m_filterImpl == null)
-        {
-            try
-            {
-                m_filterImpl = new FilterImpl(getName());
-            }
-            catch (InvalidSyntaxException ex)
-            {
-                return false;
-            }
-        }
-
-        return m_filterImpl.match(admin.getBundleDictionary());
-    }
-
-    public PermissionCollection newPermissionCollection()
-    {
-	return new AdminPermissionCollection();
-    }
-
-    private Dictionary getBundleDictionary()
-    {
-        if (m_bundleDict == null)
-        {
-            // Add bundle properties to dictionary.
-            m_bundleDict = new Hashtable();
-            m_bundleDict.put("id", new Long(m_bundle.getBundleId()));
-
-            String symbolicName = m_bundle.getSymbolicName();
-            if (symbolicName != null)
-            {
-                m_bundleDict.put("name", symbolicName);
-            }
-            // Add location in privileged block since it performs a security check.
-            if (System.getSecurityManager() != null)
-            {
-                AccessController.doPrivileged(new PrivilegedAction()
-                {
-                    public Object run()
-                    {
-                        m_bundleDict.put("location", m_bundle.getLocation());
-
-                        createSigner(m_bundle, m_bundleDict);
-                        return null;
-                    }
-                });
-            }
-            else
-            {
-                m_bundleDict.put("location", m_bundle.getLocation());
-                createSigner(m_bundle, m_bundleDict);
-            }
-        }
-        return m_bundleDict;
-    }
-
-    private static void createSigner(Bundle bundle, Dictionary dict)
-    {
-        try
-        {
-            Method method = bundle.getClass().getDeclaredMethod(
-                "getSignerMatcher", null);
-            method.setAccessible(true);
-
-            Object signer = method.invoke(bundle, null);
-
-            if (signer != null)
-            {
-                dict.put("signer", signer);
-            }
-        }
-        catch (Exception ex)
-        {
-// TODO: log this or something
-            ex.printStackTrace();
-        }
-    }
-
-    private static int parseActions(String actions)
-    {
-        if (actions == null)
-        {
-            return ALL_MASK;
-        }
-
-        int mask = 0;
-
-        StringTokenizer st = new StringTokenizer(actions, ", ");
-        while (st.hasMoreTokens())
-        {
-            String s = st.nextToken();
-            if (s.equals("*"))
-            {
-                mask = ALL_MASK;
-                break;
-            }
-            else if (s.equalsIgnoreCase(CLASS))
-            {
-                mask |= CLASS_MASK;
-            }
-            else if (s.equalsIgnoreCase(EXECUTE))
-            {
-                mask |= EXECUTE_MASK;
-            }
-            else if (s.equalsIgnoreCase(EXTENSIONLIFECYCLE))
-            {
-                mask |= EXTENSIONLIFECYCLE_MASK;
-            }
-            else if (s.equalsIgnoreCase(LIFECYCLE))
-            {
-                mask |= LIFECYCLE_MASK;
-            }
-            else if (s.equalsIgnoreCase(LISTENER))
-            {
-                mask |= LISTENER_MASK;
-            }
-            else if (s.equalsIgnoreCase(METADATA))
-            {
-                mask |= METADATA_MASK;
-            }
-            else if (s.equalsIgnoreCase(RESOLVE))
-            {
-                mask |= RESOLVE_MASK;
-            }
-            else if (s.equalsIgnoreCase(RESOURCE))
-            {
-                mask |= RESOURCE_MASK;
-            }
-            else if (s.equalsIgnoreCase(STARTLEVEL))
-            {
-                mask |= STARTLEVEL_MASK;
-            }
-        }
-
-        return mask;
-    }
-
-    private static String createActionString(int mask)
-    {
-        StringBuffer sb = new StringBuffer();
-
-        if ((mask & CLASS_MASK) > 0)
-        {
-            sb.append(CLASS);
-            sb.append(",");
-        }
-
-        if ((mask & EXECUTE_MASK) > 0)
-        {
-            sb.append(EXECUTE);
-            sb.append(",");
-        }
-
-        if ((mask & EXTENSIONLIFECYCLE_MASK) > 0)
-        {
-            sb.append(EXTENSIONLIFECYCLE);
-            sb.append(",");
-        }
-
-        if ((mask & LIFECYCLE_MASK) > 0)
-        {
-            sb.append(LIFECYCLE);
-            sb.append(",");
-        }
-
-        if ((mask & LISTENER_MASK) > 0)
-        {
-            sb.append(LISTENER);
-            sb.append(",");
-        }
-
-        if ((mask & METADATA_MASK) > 0)
-        {
-            sb.append(METADATA);
-            sb.append(",");
-        }
-
-        if ((mask & RESOLVE_MASK) > 0)
-        {
-            sb.append(RESOLVE);
-            sb.append(",");
-        }
-
-        if ((mask & RESOURCE_MASK) > 0)
-        {
-            sb.append(RESOURCE);
-            sb.append(",");
-        }
-
-        if ((mask & STARTLEVEL_MASK) > 0)
-        {
-            sb.append(STARTLEVEL);
-            sb.append(",");
-        }
-
-        // Remove trailing comma.
-        if (sb.length() > 0)
-        {
-            sb.setLength(sb.length() - 1);
-        }
-
-        return sb.toString();
-    }
-
-    private static String createName(Bundle bundle)
-    {
-        StringBuffer sb = new StringBuffer();
-        sb.append("(id=");
-        sb.append(bundle.getBundleId());
-        sb.append(")");
-        return sb.toString();
-    }
-}
-
-final class AdminPermissionCollection extends PermissionCollection
-{
-    private static final long serialVersionUID = 3747361397420496672L;
-    private HashMap m_map = new HashMap();
-
-    public void add(Permission permission)
-    {
-        if (!(permission instanceof AdminPermission))
-        {
-            throw new IllegalArgumentException("Invalid permission: " + permission);
-        }
-        else if (isReadOnly())
-        {
-            throw new SecurityException(
-                "Cannot add to read-only permission collection.");
-        }
-
-        AdminPermission admin = (AdminPermission) permission;
-        AdminPermission current = (AdminPermission) m_map.get(admin.getName());
-        if (current != null)
-        {
-            if (admin.m_actionMask != current.m_actionMask)
-            {
-                m_map.put(admin.getName(),
-                    new AdminPermission(admin.getName(),
-                        admin.m_actionMask | current.m_actionMask));
-            }
-        }
-        else
-        {
-            m_map.put(admin.getName(), admin);
-        }
-    }
-
-    public boolean implies(Permission permission)
-    {
-        if (!(permission instanceof AdminPermission))
-        {
-            return false;
-        }
-
-        for (Iterator iter = m_map.values().iterator(); iter.hasNext(); )
-        {
-            if (((AdminPermission) iter.next()).implies(permission))
-            {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    public Enumeration elements()
-    {
-        return Collections.enumeration(m_map.values());
-    }
-}
diff --git a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java b/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
deleted file mode 100644
index 022dfa1..0000000
--- a/framework/src/main/java/org/osgi/framework/FrameworkUtil.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/* 
- * 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.osgi.framework;
-
-import org.apache.felix.framework.FilterImpl;
-
-/**
- * <p>
- * Framework utility class that currently only provides public access to
- * <tt>Filter</tt> instance creation. This class is a replacement for the
- * version that ships with the standard OSGi JAR file.
- * </p>
-**/
-public class FrameworkUtil
-{
-    private FrameworkUtil()
-    {
-    }
-
-    public static Filter createFilter(String filter)
-        throws InvalidSyntaxException
-    {
-        return new FilterImpl(null, filter);
-    }
-}
\ No newline at end of file
diff --git a/main/pom.xml b/main/pom.xml
index 7eb0d86..43d4f83 100644
--- a/main/pom.xml
+++ b/main/pom.xml
@@ -146,23 +146,6 @@
         <artifactId>maven-dependency-plugin</artifactId>
         <executions>
           <execution>
-            <id>unpack</id>
-            <phase>validate</phase>
-            <goals>
-              <goal>unpack</goal>
-            </goals>
-            <configuration>
-               <outputDirectory>${project.build.outputDirectory}</outputDirectory>
-              <artifactItems>
-                <artifactItem>
-                  <groupId>${pom.groupId}</groupId>
-                  <artifactId>org.apache.felix.framework</artifactId>
-                  <version>1.9.0-SNAPSHOT</version>
-                </artifactItem>
-              </artifactItems>
-            </configuration>
-          </execution>
-          <execution>
             <id>copy</id>
             <phase>install</phase>
             <goals>