/*
 * 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.security.condpermadmin;

import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.net.URL;
import java.security.AccessControlContext;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Permission;
import java.security.Principal;
import java.security.ProtectionDomain;
import java.security.PublicKey;
import java.security.SignatureException;
import java.security.cert.X509Certificate;
import java.util.AbstractSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.Map.Entry;

import org.apache.felix.framework.BundleProtectionDomain;
import org.apache.felix.framework.security.permissionadmin.PermissionAdminImpl;
import org.apache.felix.framework.security.util.Conditions;
import org.apache.felix.framework.security.util.LocalPermissions;
import org.apache.felix.framework.security.util.Permissions;
import org.apache.felix.framework.security.util.PropertiesCache;
import org.apache.felix.framework.util.manifestparser.R4Library;

/*
import org.apache.felix.moduleloader.ICapability;
import org.apache.felix.moduleloader.IContent;
import org.apache.felix.moduleloader.IModule;
import org.apache.felix.moduleloader.IRequirement;
import org.apache.felix.moduleloader.IWire;
*/
import org.apache.felix.framework.capabilityset.Capability;
import org.apache.felix.framework.capabilityset.Requirement;
import org.apache.felix.framework.resolver.Content;
import org.apache.felix.framework.resolver.Module;
import org.apache.felix.framework.resolver.Wire;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.service.condpermadmin.ConditionInfo;
import org.osgi.service.condpermadmin.ConditionalPermissionAdmin;
import org.osgi.service.condpermadmin.ConditionalPermissionInfo;
import org.osgi.service.condpermadmin.ConditionalPermissionUpdate;
import org.osgi.service.permissionadmin.PermissionInfo;

/**
 * An implementation of the ConditionalPermissionAdmin service that doesn't need
 * to have a framework specific security manager set. It use the DomainGripper
 * to know what bundleprotectiondomains are expected.
 */
public final class ConditionalPermissionAdminImpl implements
    ConditionalPermissionAdmin
{
    private static class OrderedHashMap extends HashMap
    {
        private final List m_order = new ArrayList();

        public Object put(Object key, Object value)
        {
            Object result = super.put(key, value);
            if (result != value)
            {
                m_order.remove(key);
                m_order.add(key);
            }
            return result;
        };

        public void putAll(Map map)
        {
            for (Iterator iter = map.entrySet().iterator(); iter.hasNext();)
            {
                Entry entry = (Entry) iter.next();
                put(entry.getKey(), entry.getValue());
            }
        };

        public Set keySet()
        {
            return new AbstractSet()
            {
                public Iterator iterator()
                {
                    return m_order.iterator();
                }

                public int size()
                {
                    return m_order.size();
                }

            };
        };

        public Set entrySet()
        {
            return new AbstractSet()
            {

                public Iterator iterator()
                {
                    return new Iterator()
                    {
                        Iterator m_iter = m_order.iterator();

                        public boolean hasNext()
                        {
                            return m_iter.hasNext();
                        }

                        public Object next()
                        {
                            final Object key = m_iter.next();
                            return new Entry()
                            {

                                public Object getKey()
                                {
                                    return key;
                                }

                                public Object getValue()
                                {
                                    return get(key);
                                }

                                public Object setValue(Object arg0)
                                {
                                    throw new IllegalStateException(
                                        "Not Implemented");
                                }
                            };
                        }

                        public void remove()
                        {
                            throw new IllegalStateException("Not Implemented");
                        }

                    };
                }

                public int size()
                {
                    return m_order.size();
                }

            };
        };

        public Collection values()
        {
            List result = new ArrayList();
            for (Iterator iter = m_order.iterator(); iter.hasNext();)
            {
                result.add(super.get(iter.next()));
            }
            return result;
        };

        public Object remove(Object key)
        {
            Object result = super.remove(key);
            if (result != null)
            {
                m_order.remove(key);
            }
            return result;
        };

        public void clear()
        {
            super.clear();
            m_order.clear();
        };
    };

    private static final ConditionInfo[] EMPTY_CONDITION_INFO = new ConditionInfo[0];
    private static final PermissionInfo[] EMPTY_PERMISSION_INFO = new PermissionInfo[0];
    private final Map m_condPermInfos = new OrderedHashMap();
    private final PropertiesCache m_propertiesCache;
    private final Permissions m_permissions;
    private final Conditions m_conditions;
    private final LocalPermissions m_localPermissions;
    private final PermissionAdminImpl m_pai;

    public ConditionalPermissionAdminImpl(Permissions permissions,
        Conditions condtions, LocalPermissions localPermissions,
        PropertiesCache cache, PermissionAdminImpl pai) throws IOException
    {
        m_propertiesCache = cache;
        m_permissions = permissions;
        m_conditions = condtions;
        m_localPermissions = localPermissions;
        Map old = new OrderedHashMap();
        // Now try to restore the cache.
        m_propertiesCache.read(ConditionalPermissionInfoImpl.class, old);
        for (Iterator iter = old.entrySet().iterator(); iter.hasNext();)
        {
            Entry entry = (Entry) iter.next();
            String name = (String) entry.getKey();
            ConditionalPermissionInfoImpl cpi = ((ConditionalPermissionInfoImpl) entry
                .getValue());
            m_condPermInfos.put(name, new ConditionalPermissionInfoImpl(name,
                cpi._getConditionInfos(), cpi._getPermissionInfos(), this, cpi
                    .isAllow()));
        }
        m_pai = pai;
    }

    public ConditionalPermissionInfo addConditionalPermissionInfo(
        ConditionInfo[] conditions, PermissionInfo[] permissions)
    {
        Object sm = System.getSecurityManager();
        if (sm != null)
        {
            ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
        }
        ConditionalPermissionInfoImpl result = new ConditionalPermissionInfoImpl(
            notNull(conditions), notNull(permissions), this, true);

        return write(result.getName(), result);
    }

    ConditionalPermissionInfoImpl write(String name,
        ConditionalPermissionInfoImpl cpi)
    {
        synchronized (m_propertiesCache)
        {
            Map tmp = null;

            synchronized (m_condPermInfos)
            {
                tmp = new OrderedHashMap();
                tmp.putAll(m_condPermInfos);

                if ((name != null) && (cpi != null))
                {
                    m_condPermInfos.put(name, cpi);
                }
                else if (name != null)
                {
                    m_condPermInfos.remove(name);
                }
                else
                {
                    tmp = null;
                }
            }

            try
            {
                m_propertiesCache.write(m_condPermInfos);
            }
            catch (IOException ex)
            {
                synchronized (m_condPermInfos)
                {
                    if (tmp != null)
                    {
                        m_condPermInfos.clear();
                        m_condPermInfos.putAll(tmp);
                    }
                }
                ex.printStackTrace();
                throw new IllegalStateException(ex.getMessage());
            }
        }
        synchronized (m_condPermInfos)
        {
            return (ConditionalPermissionInfoImpl) m_condPermInfos.get(name);
        }
    }

    private static class FakeBundle implements Bundle
    {
        private final Map m_certs;

        public FakeBundle(Map certs)
        {
            m_certs = Collections.unmodifiableMap(certs);
        }

        public Enumeration findEntries(String arg0, String arg1, boolean arg2)
        {
            return null;
        }

        public BundleContext getBundleContext()
        {
            return null;
        }

        public long getBundleId()
        {
            return -1;
        }

        public URL getEntry(String arg0)
        {
            return null;
        }

        public Enumeration getEntryPaths(String arg0)
        {
            return null;
        }

        public Dictionary getHeaders()
        {
            return new Hashtable();
        }

        public Dictionary getHeaders(String arg0)
        {
            return new Hashtable();
        }

        public long getLastModified()
        {
            return 0;
        }

        public String getLocation()
        {
            return "";
        }

        public ServiceReference[] getRegisteredServices()
        {
            return null;
        }

        public URL getResource(String arg0)
        {
            return null;
        }

        public Enumeration getResources(String arg0) throws IOException
        {
            return null;
        }

        public ServiceReference[] getServicesInUse()
        {
            return null;
        }

        public Map getSignerCertificates(int arg0)
        {
            return m_certs;
        }

        public int getState()
        {
            return Bundle.UNINSTALLED;
        }

        public String getSymbolicName()
        {
            return null;
        }

        public Version getVersion()
        {
            return Version.emptyVersion;
        }

        public boolean hasPermission(Object arg0)
        {
            return false;
        }

        public Class loadClass(String arg0) throws ClassNotFoundException
        {
            return null;
        }

        public void start() throws BundleException
        {
            throw new IllegalStateException();
        }

        public void start(int arg0) throws BundleException
        {
            throw new IllegalStateException();
        }

        public void stop() throws BundleException
        {
            throw new IllegalStateException();
        }

        public void stop(int arg0) throws BundleException
        {
            throw new IllegalStateException();
        }

        public void uninstall() throws BundleException
        {
            throw new IllegalStateException();
        }

        public void update() throws BundleException
        {
            throw new IllegalStateException();
        }

        public void update(InputStream arg0) throws BundleException
        {
            throw new IllegalStateException();
        }

        public boolean equals(Object o)
        {
            return this == o;
        }

        public int hashCode()
        {
            return System.identityHashCode(this);
        }
    }

    private static class FakeCert extends X509Certificate
    {
        private final Principal m_principal;

        public FakeCert(final String principal)
        {
            m_principal = new Principal()
            {
                public String getName()
                {
                    return principal;
                }
            };
        }

        public void checkValidity()
            throws java.security.cert.CertificateExpiredException,
            java.security.cert.CertificateNotYetValidException
        {

        }

        public void checkValidity(Date date)
            throws java.security.cert.CertificateExpiredException,
            java.security.cert.CertificateNotYetValidException
        {
        }

        public int getBasicConstraints()
        {
            return 0;
        }

        public Principal getIssuerDN()
        {
            return null;
        }

        public boolean[] getIssuerUniqueID()
        {
            return null;
        }

        public boolean[] getKeyUsage()
        {
            return null;
        }

        public Date getNotAfter()
        {
            return null;
        }

        public Date getNotBefore()
        {
            return null;
        }

        public BigInteger getSerialNumber()
        {
            return null;
        }

        public String getSigAlgName()
        {
            return null;
        }

        public String getSigAlgOID()
        {
            return null;
        }

        public byte[] getSigAlgParams()
        {
            return null;
        }

        public byte[] getSignature()
        {
            return null;
        }

        public Principal getSubjectDN()
        {
            return m_principal;
        }

        public boolean[] getSubjectUniqueID()
        {
            return null;
        }

        public byte[] getTBSCertificate()
            throws java.security.cert.CertificateEncodingException
        {
            return null;
        }

        public int getVersion()
        {
            return 0;
        }

        public byte[] getEncoded()
            throws java.security.cert.CertificateEncodingException
        {
            return null;
        }

        public PublicKey getPublicKey()
        {
            return null;
        }

        public String toString()
        {
            return m_principal.getName();
        }

        public void verify(PublicKey key)
            throws java.security.cert.CertificateException,
            NoSuchAlgorithmException, InvalidKeyException,
            NoSuchProviderException, SignatureException
        {

        }

        public void verify(PublicKey key, String sigProvider)
            throws java.security.cert.CertificateException,
            NoSuchAlgorithmException, InvalidKeyException,
            NoSuchProviderException, SignatureException
        {

        }

        public Set getCriticalExtensionOIDs()
        {
            return null;
        }

        public byte[] getExtensionValue(String arg0)
        {
            return null;
        }

        public Set getNonCriticalExtensionOIDs()
        {
            return null;
        }

        public boolean hasUnsupportedCriticalExtension()
        {
            return false;
        }

        public boolean equals(Object o)
        {
            return this == o;
        }

        public int hashCode()
        {
            return System.identityHashCode(this);
        }

    }

    public AccessControlContext getAccessControlContext(final String[] signers)
    {
        Map certificates = new HashMap();
        for (int i = 0; i < signers.length; i++)
        {
            StringTokenizer tok = new StringTokenizer(signers[i], ";");
            List certsList = new ArrayList();
            while (tok.hasMoreTokens())
            {
                certsList.add(tok.nextToken());
            }
            String[] certs = (String[]) certsList.toArray(new String[certsList
                .size()]);

            X509Certificate key = new FakeCert(certs[0]);
            List certList = new ArrayList();
            certificates.put(key, certList);
            certList.add(key);
            for (int j = 1; j < certs.length; j++)
            {
                certList.add(new FakeCert(certs[j]));
            }
        }
        final Bundle fake = new FakeBundle(certificates);
        ProtectionDomain domain = new ProtectionDomain(null, null)
        {
            public boolean implies(Permission permission)
            {
                List posts = new ArrayList();
                Boolean result = m_pai.hasPermission("", fake, permission,
                    ConditionalPermissionAdminImpl.this, this, null);
                if (result != null)
                {
                    return result.booleanValue();
                }
                if (eval(posts, new Module()
                {

                    public Bundle getBundle()
                    {
                        return fake;
                    }

                    public List<Capability> getCapabilities()
                    {
                        return null;
                    }

                    public Class getClassByDelegation(String arg0)
                        throws ClassNotFoundException
                    {
                        return null;
                    }

                    public Content getContent()
                    {
                        return null;
                    }

                    public int getDeclaredActivationPolicy()
                    {
                        return 0;
                    }

                    public List<Requirement> getDynamicRequirements()
                    {
                        return null;
                    }

                    public URL getEntry(String arg0)
                    {
                        return null;
                    }

                    public Map getHeaders()
                    {
                        return null;
                    }

                    public String getId()
                    {
                        return null;
                    }

                    public InputStream getInputStream(int arg0, String arg1)
                        throws IOException
                    {
                        return null;
                    }

                    public List<R4Library> getNativeLibraries()
                    {
                        return null;
                    }

                    public List<Requirement> getRequirements()
                    {
                        return null;
                    }

                    public URL getResourceByDelegation(String arg0)
                    {
                        return null;
                    }

                    public Enumeration getResourcesByDelegation(String arg0)
                    {
                        return null;
                    }

                    public Object getSecurityContext()
                    {
                        return null;
                    }

                    public String getSymbolicName()
                    {
                        return null;
                    }

                    public Version getVersion()
                    {
                        return null;
                    }

                    public List<Wire> getWires()
                    {
                        return null;
                    }

                    public boolean hasInputStream(int arg0, String arg1)
                        throws IOException
                    {
                        return false;
                    }

                    public boolean isExtension()
                    {
                        return false;
                    }

                    public boolean isResolved()
                    {
                        return false;
                    }

                    public void setSecurityContext(Object arg0)
                    {
                    }

                    public URL getLocalURL(int arg0, String arg1)
                    {
                        // TODO Auto-generated method stub
                        return null;
                    }

                    public boolean isRemovalPending()
                    {
                        return false;
                    }
                }, permission, m_pai))
                {
                    if (!posts.isEmpty())
                    {
                        return m_conditions.evalRecursive(posts);
                    }
                    return true;
                }
                return false;
            }
        };
        return new AccessControlContext(new ProtectionDomain[] { domain });
    }

    public ConditionalPermissionInfo getConditionalPermissionInfo(String name)
    {
        if (name == null)
        {
            throw new IllegalArgumentException("Name may not be null");
        }
        ConditionalPermissionInfoImpl result = null;

        synchronized (m_condPermInfos)
        {
            result = (ConditionalPermissionInfoImpl) m_condPermInfos.get(name);
        }

        if (result == null)
        {
            result = new ConditionalPermissionInfoImpl(this, name, true);

            result = write(result.getName(), result);
        }

        return result;
    }

    public Enumeration getConditionalPermissionInfos()
    {
        synchronized (m_condPermInfos)
        {
            return Collections.enumeration(new ArrayList(m_condPermInfos
                .values()));
        }
    }

    public ConditionalPermissionInfo setConditionalPermissionInfo(String name,
        ConditionInfo[] conditions, PermissionInfo[] permissions)
    {
        Object sm = System.getSecurityManager();
        if (sm != null)
        {
            ((SecurityManager) sm).checkPermission(Permissions.ALL_PERMISSION);
        }

        ConditionalPermissionInfoImpl result = null;
        conditions = notNull(conditions);
        permissions = notNull(permissions);

        if (name != null)
        {
            synchronized (m_condPermInfos)
            {
                result = (ConditionalPermissionInfoImpl) m_condPermInfos
                    .get(name);

                if (result == null)
                {
                    result = new ConditionalPermissionInfoImpl(name,
                        conditions, permissions, this, true);
                }
                else
                {
                    result.setConditionsAndPermissions(conditions, permissions);
                }
            }
        }
        else
        {
            result = new ConditionalPermissionInfoImpl(conditions, permissions,
                this, true);
        }

        return write(result.getName(), result);
    }

    private PermissionInfo[] notNull(PermissionInfo[] permissions)
    {
        if (permissions == null)
        {
            return ConditionalPermissionInfoImpl.PERMISSION_INFO;
        }
        return (PermissionInfo[]) notNull((Object[]) permissions).toArray(
            EMPTY_PERMISSION_INFO);
    }

    private ConditionInfo[] notNull(ConditionInfo[] conditions)
    {
        if (conditions == null)
        {
            return ConditionalPermissionInfoImpl.CONDITION_INFO;
        }
        return (ConditionInfo[]) notNull((Object[]) conditions).toArray(
            EMPTY_CONDITION_INFO);
    }

    private List notNull(Object[] elements)
    {
        List result = new ArrayList();

        for (int i = 0; i < elements.length; i++)
        {
            if (elements[i] != null)
            {
                result.add(elements[i]);
            }
        }

        return result;
    }

    // The thread local stack used to keep track of bundle protection domains we
    // still expect to see.
    private final ThreadLocal m_stack = new ThreadLocal();

    /**
     * This method does the actual permission check. If it is not a direct check
     * it will try to determine the other bundle domains that will follow
     * automatically in case this is the first check in one permission check. If
     * not then it will keep track of which domains we have already see. While
     * it keeps track it builds up a list of postponed tuples which it will
     * evaluate at the last domain. See the core spec 9.5.1 and following for a
     * general description.
     * 
     * @param felixBundle
     *            the bundle in question.
     * @param loader
     *            the content loader of the bundle to get access to the jar to
     *            check for local permissions.
     * @param root
     *            the bundle id.
     * @param signers
     *            the signers (this is to support the ACC based on signers)
     * @param pd
     *            the bundle protection domain
     * @param permission
     *            the permission currently checked
     * @param direct
     *            whether this is a direct check or not. direct check will not
     *            expect any further bundle domains on the stack
     * @return true in case the permission is granted or there are postponed
     *         tuples false if not. Again, see the spec for more explanations.
     */
    public boolean hasPermission(Module module, Content content,
        ProtectionDomain pd, Permission permission, boolean direct, Object admin)
    {
        // System.out.println(felixBundle + "-" + permission);
        List domains = null;
        List tuples = null;
        Object[] entry = null;
        // first see whether this is the normal case (the special case is for
        // the ACC based on signers).
        // In case of a direct call we don't need to look for other pds
        if (direct)
        {
            domains = new ArrayList();
            tuples = new ArrayList();
            domains.add(pd);
        }
        else
        {
            // Get the other pds from the stck
            entry = (Object[]) m_stack.get();

            // if there are none then get them from the gripper
            if (entry == null)
            {
                entry = new Object[] { new ArrayList(DomainGripper.grab()),
                    new ArrayList() };
            }
            else
            {
                m_stack.set(null);
            }

            domains = (List) entry[0];
            tuples = (List) entry[1];
            if (!domains.contains(pd))
            {
                // We have been called directly without the direct flag
                domains.clear();
                domains.add(pd);
            }
        }

        // check the local permissions. they need to all the permission if there
        // are any
        if (!impliesLocal(module.getBundle(), content, permission))
        {
            return false;
        }

        List posts = new ArrayList();

        boolean result = eval(posts, module, permission, admin);

        domains.remove(pd);

        // We postponed tuples
        if (!posts.isEmpty())
        {
            tuples.add(posts);
        }

        // Are we at the end or this was a direct call?
        if (domains.isEmpty())
        {
            m_stack.set(null);
            // Now eval the postponed tupels. if the previous eval did return
            // false
            // tuples will be empty so we don't return from here.
            if (!tuples.isEmpty())
            {
                return m_conditions.evalRecursive(tuples);
            }
        }
        else
        {
            // this is to support recursive permission checks. In case we
            // trigger
            // a permission check while eval the stack is null until this point
            m_stack.set(entry);
        }

        return result;
    }

    public boolean impliesLocal(Bundle felixBundle, Content content,
        Permission permission)
    {
        return m_localPermissions.implies(content, felixBundle, permission);
    }

    public boolean isEmpty()
    {
        synchronized (m_condPermInfos)
        {
            return m_condPermInfos.isEmpty();
        }
    }

    // we need to find all conditions that apply and then check whether they
    // de note the permission in question unless the conditions are postponed
    // then we make sure their permissions imply the permission and add them
    // to the list of posts. Return true in case we pass or have posts
    // else falls and clear the posts first.
    private boolean eval(List posts, Module module, Permission permission,
        Object admin)
    {
        List condPermInfos = null;

        synchronized (m_condPermInfos)
        {
            if (isEmpty() && (admin == null))
            {
                return true;
            }
            condPermInfos = new ArrayList(m_condPermInfos.values());
        }

        // Check for implicit permissions like access to file area
        if (m_permissions.getPermissions(
            m_permissions.getImplicit(module.getBundle())).implies(permission,
            module.getBundle()))
        {
            return true;
        }
        List pls = new ArrayList();
        // now do the real thing
        for (Iterator iter = condPermInfos.iterator(); iter.hasNext();)
        {
            ConditionalPermissionInfoImpl cpi = (ConditionalPermissionInfoImpl) iter
                .next();

            ConditionInfo[] conditions = cpi._getConditionInfos();

            List currentPosts = new ArrayList();

            Conditions conds = m_conditions.getConditions(module, conditions);
            if (!conds.isSatisfied(currentPosts, m_permissions
                .getPermissions(cpi._getPermissionInfos()), permission))
            {
                continue;
            }

            if (!m_permissions.getPermissions(cpi._getPermissionInfos())
                .implies(permission, null))
            {
                continue;
            }

            if (currentPosts.isEmpty())
            {
                pls.add(new Object[] { cpi, null });
                break;
            }
            pls.add(new Object[] { cpi, currentPosts, conds });
        }
        while (pls.size() > 1)
        {
            if (!((ConditionalPermissionInfoImpl) ((Object[]) pls.get(pls
                .size() - 1))[0]).isAllow())
            {
                pls.remove(pls.size() - 1);
            }
            else
            {
                break;
            }
        }
        if (pls.size() == 1)
        {
            if (((Object[]) pls.get(0))[1] != null)
            {
                posts.add(pls.get(0));
            }
            return ((ConditionalPermissionInfoImpl) ((Object[]) pls.get(0))[0])
                .isAllow();
        }
        for (Iterator iter = pls.iterator(); iter.hasNext();)
        {
            posts.add(iter.next());
        }
        return !posts.isEmpty();
    }

    public ConditionalPermissionInfo newConditionalPermissionInfo(
        String encodedConditionalPermissionInfo)
    {
        return new ConditionalPermissionInfoImpl(
            encodedConditionalPermissionInfo);
    }

    public ConditionalPermissionInfo newConditionalPermissionInfo(String name,
        ConditionInfo[] conditions, PermissionInfo[] permissions, String access)
    {
        return new ConditionalPermissionInfoImpl(name, conditions, permissions,
            ConditionalPermissionAdminImpl.this, access
                .equals(ConditionalPermissionInfo.ALLOW));
    }

    public ConditionalPermissionUpdate newConditionalPermissionUpdate()
    {
        return new ConditionalPermissionUpdate()
        {
            List current = null;
            List out = null;
            {
                synchronized (m_condPermInfos)
                {
                    current = new ArrayList(m_condPermInfos.values());
                    out = new ArrayList(m_condPermInfos.values());
                }
            }

            public boolean commit()
            {
                synchronized (m_condPermInfos)
                {
                    if (current.equals(new ArrayList(m_condPermInfos.values())))
                    {
                        m_condPermInfos.clear();
                        write(null, null);
                        for (Iterator iter = out.iterator(); iter.hasNext();)
                        {
                            ConditionalPermissionInfoImpl cpii = (ConditionalPermissionInfoImpl) iter
                                .next();
                            write(cpii.getName(), cpii);
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                return true;
            }

            public List getConditionalPermissionInfos()
            {
                return out;
            }
        };
    }

    public boolean handlePAHandle(BundleProtectionDomain pd)
    {
        Object[] entry = (Object[]) m_stack.get();

        if (entry == null)
        {
            entry = new Object[] { new ArrayList(DomainGripper.grab()),
                new ArrayList() };
        }

        ((List) entry[0]).remove(pd);
        if (((List) entry[0]).isEmpty())
        {
            m_stack.set(null);
            if (!((List) entry[1]).isEmpty())
            {
                return m_conditions.evalRecursive(((List) entry[1]));
            }
        }
        else
        {
            m_stack.set(entry);
        }

        return true;
    }

    public void clearPD()
    {
        m_stack.set(null);
    }
}
