/*
 * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/AdminPermission.java,v 1.12 2005/05/13 20:32:54 hargrave Exp $
 * 
 * Copyright (c) OSGi Alliance (2000, 2005). All Rights Reserved.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this 
 * distribution, and is available at http://www.eclipse.org/legal/epl-v10.html.
 */

package org.osgi.framework;

import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.util.*;
import org.apache.osgi.framework.FilterImpl;

/**
 * Indicates the caller's authority to perform specific privileged administrative 
 * operations on or to get sensitive information about a bundle.
 * 
 * <ul>
 *   <li>The <code>{@link AdminPermission#METADATA}</code> action allows calls to
 *   	<ul>
 *         <li>{@link Bundle#getHeaders()}
 *         <li>{@link Bundle#getHeaders(String)}
 *         <li>{@link Bundle#getLocation()}
 *         </ul>
 *   <li>The <code>{@link AdminPermission#RESOURCE}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link Bundle#getResource(String)}
 *   		<li>{@link Bundle#getEntry(String)}
 *   		<li>{@link Bundle#getEntryPaths(String)}
 *   		<li>Bundle resource/entry URL creation
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#METADATA}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link Bundle#loadClass(String)}
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#LIFECYCLE}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link BundleContext#installBundle(String)}
 *   		<li>{@link BundleContext#installBundle(String, InputStream)}
 *   		<li>{@link Bundle#update()}
 *   		<li>{@link Bundle#update(InputStream)}
 *   		<li>{@link Bundle#uninstall()}
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#EXECUTE}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link Bundle#start()}
 *   		<li>{@link Bundle#stop()}
 *   		<li>{@link org.osgi.service.startlevel.StartLevel#setBundleStartLevel(Bundle, int)}
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#LISTENER}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link BundleContext#addBundleListener(BundleListener)} for 
 *   				<code>SynchronousBundleListener</code>
 *   		<li>{@link BundleContext#removeBundleListener(BundleListener)} for 
 *   				<code>SynchronousBundleListener</code>
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#PERMISSION}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link org.osgi.service.permissionadmin.PermissionAdmin#setPermissions(String, PermissionInfo[])}
 *   		<li>{@link org.osgi.service.permissionadmin.PermissionAdmin#setDefaultPermissions(PermissionInfo[])}
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#RESOLVE}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link org.osgi.service.packageadmin.PackageAdmin#refreshPackages(Bundle[])}</code>
 *   		<li>{@link org.osgi.service.packageadmin.PackageAdmin#resolveBundles(Bundle[])}</code>
 *   	</ul>
 *   <li>The <code>{@link AdminPermission#STARTLEVEL}</code> action allows calls to
 *   	<ul>
 *   		<li>{@link org.osgi.service.startlevel.StartLevel#setStartLevel(int)}
 *   		<li>{@link org.osgi.service.startlevel.StartLevel#setInitialBundleStartLevel(int)}
 *   	</ul>
 * </ul>
 * 
 * The special action "*" will represent all actions.
 * 
 * @version $Revision: 1.12 $
 */

public final class AdminPermission extends Permission
{
	static final long	serialVersionUID	= 207051004521261705L;

    /**
     * The action string <code>class</code> (Value is "class").
     */
    public final static String CLASS = "class"; //$NON-NLS-1$

    /**
     * The action string <code>execute</code> (Value is "execute").
     */
    public final static String EXECUTE = "execute"; //$NON-NLS-1$
    
    /**
     * The action string <code>lifecycle</code> (Value is "lifecycle").
     */
    public final static String LIFECYCLE = "lifecycle"; //$NON-NLS-1$
    
    /**
     * The action string <code>listener</code> (Value is "listener").
     */
    public final static String LISTENER = "listener"; //$NON-NLS-1$
    
    /**
     * The action string <code>metadata</code> (Value is "metadata").
     */
    public final static String METADATA = "metadata"; //$NON-NLS-1$

    /**
     * The action string <code>permission</code> (Value is "permission").
     */
    public final static String PERMISSION = "permission"; //$NON-NLS-1$
	
    /**
     * The action string <code>resolve</code> (Value is "resolve").
     */
    public final static String RESOLVE = "resolve"; //$NON-NLS-1$

    /**
     * The action string <code>resource</code> (Value is "resource").
     */
    public final static String RESOURCE = "resource"; //$NON-NLS-1$
    
    /**
     * The action string <code>startlevel</code> (Value is "startlevel").
     */
    public final static String STARTLEVEL = "startlevel"; //$NON-NLS-1$

    /**
     * The action string <code>extensionLifecycle</code> (Value is "extensionLifecycle").
     */
    public final static String EXTENSIONLIFECYCLE = "extensionLifecycle"; //$NON-NLS-1$

    private final static int ACTION_CLASS				= 0x00000001;
    private final static int ACTION_EXECUTE				= 0x00000002;
    private final static int ACTION_LIFECYCLE			= 0x00000004;
    private final static int ACTION_LISTENER			= 0x00000008;
    private final static int ACTION_METADATA			= 0x00000010;
    private final static int ACTION_PERMISSION			= 0x00000020;
    private final static int ACTION_RESOLVE				= 0x00000040;
    private final static int ACTION_RESOURCE			= 0x00000080;
    private final static int ACTION_STARTLEVEL			= 0x00000100;
	private final static int ACTION_EXTENSIONLIFECYCLE	= 0x00000200;
    private final static int ACTION_ALL = 
		ACTION_CLASS 				|
		ACTION_EXECUTE 				|
		ACTION_LIFECYCLE 			|
		ACTION_LISTENER 			|
    	ACTION_METADATA 			|
		ACTION_PERMISSION			|
		ACTION_RESOLVE 				|
		ACTION_RESOURCE 			|
		ACTION_STARTLEVEL			|
		ACTION_EXTENSIONLIFECYCLE;
    private final static int ACTION_NONE = 0;
	
	/**
	 * Indicates that this AdminPermission refers to all bundles
	 * @serial
	 */
	private boolean wildcard;
	
	/**
	 * An x.500 distinguished name used to match a bundle's signature - only used if
	 * wildcard is false and bundle = null
	 * @serial
	 */
	private String filter;

    /**
     * The actions in canonical form.
     *
     * @serial
     */
    private String actions = null;

    /**
     * The actions mask.
     */
	private transient int action_mask = ACTION_NONE;

	/**
	 * The bundle governed by this AdminPermission - only used if 
	 * wildcard is false and filter == null
	 */
	private transient Bundle bundle;

    /**
     * If this AdminPermission was constructed with a bundle, this dictionary holds
     * the properties of that bundle, used to match a filter in implies.
     * This is not initialized until necessary, and then cached in this object.
     */
    private transient Dictionary bundleProperties;
    
    /**
     * If this AdminPermission was constructed with a filter, this dictionary holds
     * a Filter matching object used to evaluate the filter in implies.
     * This is not initialized until necessary, and then cached in this object
     */
    private transient Filter filterImpl;
    
	/**
     * Creates a new <code>AdminPermission</code> object that matches 
     * all bundles and has all actions.  Equivalent to 
     * AdminPermission("*","*");
     */
    public AdminPermission()
    {
    	this("*",AdminPermission.ACTION_ALL); //$NON-NLS-1$
    }
    
    /**
     * Creates a new <code>AdminPermission</code> object for use by the <code>Policy</code>
     * object to instantiate new <code>Permission</code> objects.
     * 
     * Null arguments are equivalent to "*"
     *
     * @param filter an X.500 Distinguished Name suffix or "*" to match all bundles
     * @param actions <code>class</code>, <code>execute</code>, <code>lifecycle</code>, 
     * <code>listener</code>, <code>metadata</code>, <code>permission</code>, <code>resolve</code>, 
     * <code>resource</code>, <code>startlevel</code>, or "*" to indicate all actions
     */
    public AdminPermission(String filter, String actions)
    {
    	//arguments will be null if called from a PermissionInfo defined with
    	//no args
    	this(
    			(filter == null ? "*" : filter), //$NON-NLS-1$
				getMask((actions == null ? "*" : actions)) //$NON-NLS-1$
				);
    }

    /**
     * Creates a new <code>AdminPermission</code> object for use by the <code>Policy</code>
     * object to instantiate new <code>Permission</code> objects.
     * 
     * @param bundle A bundle
     * @param actions <code>class</code>, <code>execute</code>, <code>lifecycle</code>, 
     * <code>listener</code>, <code>metadata</code>, <code>permission</code>, <code>resolve</code>, 
     * <code>resource</code>, <code>startlevel</code>, or "*" to indicate all actions
     */
    public AdminPermission(Bundle bundle, String actions) {
    	super(bundle.toString());
    	this.bundle = bundle;
    	this.wildcard = false;
    	this.filter = null;
    	this.action_mask = getMask(actions);
    }
 
    /**
     * Package private constructor used by AdminPermissionCollection.
     *
     * @param filter name filter
     * @param action_mask mask
     */
    AdminPermission(String filter, int action_mask) {
    	super(filter);
    	
    	//name must be either * or a filter
    	if (filter.equals("*")) { //$NON-NLS-1$
    		this.wildcard = true;
    		this.filter = null;
    	} else {
			this.wildcard = false;
			this.filter = filter;
    	}
    	this.bundle = null;
    	this.action_mask = action_mask;
    }

    /**
     * Parse action string into action mask.
     *
     * @param actions Action string.
     * @return action mask.
     */
    private static int getMask(String actions) {
    
    	boolean seencomma = false;

    	int mask = ACTION_NONE;

    	if (actions == null) {
    		return mask;
    	}

    	char[] a = actions.toCharArray();

    	int i = a.length - 1;
    	if (i < 0)
    		return mask;

    	while (i != -1) {
    		char c;

    		// skip whitespace
    		while ((i!=-1) && ((c = a[i]) == ' ' ||
    				c == '\r' ||
					c == '\n' ||
					c == '\f' ||
					c == '\t'))
    			i--;

    		// check for the known strings
    		int matchlen;

    		if (i >= 4 && 
					(a[i-4] == 'c' || a[i-4] == 'C') &&
					(a[i-3] == 'l' || a[i-3] == 'L') &&
					(a[i-2] == 'a' || a[i-2] == 'A') &&
					(a[i-1] == 's' || a[i-1] == 'S') &&
					  (a[i] == 's' ||   a[i] == 'S'))
			{
				matchlen = 5;
				mask |= ACTION_CLASS;
	
    		} else if (i >= 6 && 
					(a[i-6] == 'e' || a[i-6] == 'E') &&
					(a[i-5] == 'x' || a[i-5] == 'X') &&
					(a[i-4] == 'e' || a[i-4] == 'E') &&
					(a[i-3] == 'c' || a[i-3] == 'C') &&
					(a[i-2] == 'u' || a[i-2] == 'U') &&
					(a[i-1] == 't' || a[i-1] == 'T') &&
					  (a[i] == 'e' ||   a[i] == 'E'))
			{
				matchlen = 7;
				mask |= ACTION_EXECUTE;
				
			} else if (i >= 17 && 
					(a[i-17] == 'e' || a[i-17] == 'E') &&
					(a[i-16] == 'x' || a[i-16] == 'X') &&
					(a[i-15] == 't' || a[i-15] == 'T') &&
					(a[i-14] == 'e' || a[i-14] == 'E') &&
					(a[i-13] == 'n' || a[i-13] == 'N') &&
					(a[i-12] == 's' || a[i-12] == 'S') &&
					(a[i-11] == 'i' || a[i-11] == 'I') &&
					(a[i-10] == 'o' || a[i-10] == 'O') &&
					(a[i-9] == 'n' || a[i-9] == 'N') &&
					(a[i-8] == 'l' || a[i-8] == 'L') &&
					(a[i-7] == 'i' || a[i-7] == 'I') &&
					(a[i-6] == 'f' || a[i-6] == 'F') &&
					(a[i-5] == 'e' || a[i-5] == 'E') &&
					(a[i-4] == 'c' || a[i-4] == 'C') &&
					(a[i-3] == 'y' || a[i-3] == 'Y') &&
					(a[i-2] == 'c' || a[i-2] == 'C') &&
					(a[i-1] == 'l' || a[i-1] == 'L') &&
					  (a[i] == 'e' ||   a[i] == 'E'))
    		{
    			matchlen = 18;
    			mask |= ACTION_EXTENSIONLIFECYCLE;

    		} else if (i >= 8 && 
					(a[i-8] == 'l' || a[i-8] == 'L') &&
					(a[i-7] == 'i' || a[i-7] == 'I') &&
					(a[i-6] == 'f' || a[i-6] == 'F') &&
					(a[i-5] == 'e' || a[i-5] == 'E') &&
					(a[i-4] == 'c' || a[i-4] == 'C') &&
					(a[i-3] == 'y' || a[i-3] == 'Y') &&
					(a[i-2] == 'c' || a[i-2] == 'C') &&
					(a[i-1] == 'l' || a[i-1] == 'L') &&
					  (a[i] == 'e' ||   a[i] == 'E'))
			{
				matchlen = 9;
				mask |= ACTION_LIFECYCLE;
				
			} else if (i >= 7 && 
					(a[i-7] == 'l' || a[i-7] == 'L') &&
					(a[i-6] == 'i' || a[i-6] == 'I') &&
					(a[i-5] == 's' || a[i-5] == 'S') &&
					(a[i-4] == 't' || a[i-4] == 'T') &&
					(a[i-3] == 'e' || a[i-3] == 'E') &&
					(a[i-2] == 'n' || a[i-2] == 'N') &&
					(a[i-1] == 'e' || a[i-1] == 'E') &&
					  (a[i] == 'r' ||   a[i] == 'R'))
			{
				matchlen = 8;
				mask |= ACTION_LISTENER;
			
			} else if (i >= 7 && 
    				(a[i-7] == 'm' || a[i-7] == 'M') &&
    	            (a[i-6] == 'e' || a[i-6] == 'E') &&
    	            (a[i-5] == 't' || a[i-5] == 'T') &&
    	            (a[i-4] == 'a' || a[i-4] == 'A') &&
    	            (a[i-3] == 'd' || a[i-3] == 'D') &&
    	            (a[i-2] == 'a' || a[i-2] == 'A') &&
					(a[i-1] == 't' || a[i-1] == 'T') &&
					  (a[i] == 'a' ||   a[i] == 'A'))
    		{
    			matchlen = 8;
    			mask |= ACTION_METADATA;

    		} else if (i >= 9 && 
					(a[i-9] == 'p' || a[i-9] == 'P') &&
					(a[i-8] == 'e' || a[i-8] == 'E') &&
					(a[i-7] == 'r' || a[i-7] == 'R') &&
					(a[i-6] == 'm' || a[i-6] == 'M') &&
					(a[i-5] == 'i' || a[i-5] == 'I') &&
					(a[i-4] == 's' || a[i-4] == 'S') &&
					(a[i-3] == 's' || a[i-3] == 'S') &&
					(a[i-2] == 'i' || a[i-2] == 'I') &&
					(a[i-1] == 'o' || a[i-1] == 'O') &&
					  (a[i] == 'n' ||   a[i] == 'N'))
    		{
    			matchlen = 10;
    			mask |= ACTION_PERMISSION;
			
    		} else if (i >= 6 && 
					(a[i-6] == 'r' || a[i-6] == 'R') &&
					(a[i-5] == 'e' || a[i-5] == 'E') &&
					(a[i-4] == 's' || a[i-4] == 'S') &&
					(a[i-3] == 'o' || a[i-3] == 'O') &&
					(a[i-2] == 'l' || a[i-2] == 'L') &&
					(a[i-1] == 'v' || a[i-1] == 'V') &&
					  (a[i] == 'e' ||   a[i] == 'E'))
    		{
    			matchlen = 7;
    			mask |= ACTION_RESOLVE;
    			
    		} else if (i >= 7 && 
    					(a[i-7] == 'r' || a[i-7] == 'R') &&
						(a[i-6] == 'e' || a[i-6] == 'E') &&
						(a[i-5] == 's' || a[i-5] == 'S') &&
						(a[i-4] == 'o' || a[i-4] == 'O') &&
						(a[i-3] == 'u' || a[i-3] == 'U') &&
						(a[i-2] == 'r' || a[i-2] == 'R') &&
						(a[i-1] == 'c' || a[i-1] == 'C') &&
						  (a[i] == 'e' ||   a[i] == 'E'))
			{
    			matchlen = 8;
    			mask |= ACTION_RESOURCE;

    		} else if (i >= 9 && 
					(a[i-9] == 's' || a[i-9] == 'S') &&
					(a[i-8] == 't' || a[i-8] == 'T') &&
					(a[i-7] == 'a' || a[i-7] == 'A') &&
					(a[i-6] == 'r' || a[i-6] == 'R') &&
					(a[i-5] == 't' || a[i-5] == 'T') &&
					(a[i-4] == 'l' || a[i-4] == 'L') &&
					(a[i-3] == 'e' || a[i-3] == 'E') &&
					(a[i-2] == 'v' || a[i-2] == 'V') &&
					(a[i-1] == 'e' || a[i-1] == 'E') &&
					  (a[i] == 'l' ||   a[i] == 'L'))
    		{
    			matchlen = 10;
    			mask |= ACTION_STARTLEVEL;

    		} else if (i >= 0 && 
					(a[i] == '*'))
    		{
    			matchlen = 1;
    			mask |= ACTION_ALL;

			} else {
				// parse error
				throw new IllegalArgumentException(
						"invalid permission: " + actions);
        }

        // make sure we didn't just match the tail of a word
        // like "ackbarfstartlevel".  Also, skip to the comma.
        seencomma = false;
        while (i >= matchlen && !seencomma) {
        	switch(a[i-matchlen]) {
        		case ',':
        			seencomma = true;
        			/*FALLTHROUGH*/
        		case ' ': case '\r': case '\n':
        		case '\f': case '\t':
        			break;
        		default:
        			throw new IllegalArgumentException(
        					"invalid permission: " + actions);
        	}
        	i--;
        }

        // point i at the location of the comma minus one (or -1).
        i -= matchlen;
    }

    if (seencomma) {
        throw new IllegalArgumentException("invalid permission: " +
                        actions);
    }

    return mask;
    }
     
    /**
     * Called by <code><@link AdminPermission#implies(Permission)></code> on an AdminPermission
     * which was constructed with a Bundle.  This method loads a dictionary with the
     * filter-matchable properties of this bundle.  The dictionary is cached so this lookup
     * only happens once.
     * 
     * This method should only be called on an AdminPermission which was constructed with a 
     * bundle
     * 
     * @return a dictionary of properties for this bundle
     */
    private Dictionary getProperties() {
    	if (bundleProperties == null) {
    		bundleProperties = new Hashtable();

    		AccessController.doPrivileged(new PrivilegedAction() {
				public Object run() {
		    		//set Id
		    		bundleProperties.put("id",new Long(bundle.getBundleId())); //$NON-NLS-1$
		    		
		    		//set location
		    		bundleProperties.put("location",bundle.getLocation()); //$NON-NLS-1$
		    		
		    		//set name
		    		if (bundle.getSymbolicName() != null)
		    			bundleProperties.put("name",bundle.getSymbolicName()); //$NON-NLS-1$
		    		
		    		//set signers
//		    		bundleProperties.put("signer",new SignerWrapper(bundle)); //$NON-NLS-1$
		    		
		    		return null;
				}
			});
    	}     		
    	return bundleProperties;
    }
/*
    private static class SignerWrapper extends Object {
    	private Bundle bundle;
    	private String pattern;
    	public SignerWrapper(String pattern) {
    		this.pattern = pattern;    			
    	}
    	SignerWrapper(Bundle bundle) {
    		this.bundle = bundle;
    	}
    	
		public boolean equals(Object o) {
			if (!(o instanceof SignerWrapper))
				return false;
			SignerWrapper other = (SignerWrapper) o;
			AbstractBundle matchBundle = (AbstractBundle) (bundle != null ? bundle : other.bundle);
			String matchPattern = bundle != null ? other.pattern : pattern;
			return matchBundle.getBundleData().matchDNChain(matchPattern);
		}
    }
*/    

    /**
     * Called by <tt><@link AdminPermission#implies(Permission)></tt> on an AdminPermission
     * which was constructed with a filter.  This method loads a FilterImpl with the
     * filter specification of this AdminPermission.  The filter is cached so this work
     * only happens once.
     * 
     * This method should only be called on an AdminPermission which was constructed with a 
     * filter
     * 
     * @return a filterImpl for this bundle
     */
    private Filter getFilterImpl() {
        if (filterImpl == null) {
            try {
                int pos = filter.indexOf("signer"); //$NON-NLS-1$
                if (pos != -1){ 
                
                    //there may be a signer attribute 
                    StringBuffer filterBuf = new StringBuffer(filter);
                    int numAsteriskFound = 0; //use as offset to replace in buffer
                    
                    int walkbackPos; //temp pos

                    //find occurences of (signer= and escape out *'s
                    while (pos != -1) {

                        //walk back and look for '(' to see if this is an attr
                        walkbackPos = pos-1; 
                        
                        //consume whitespace
                        while(walkbackPos >= 0 && Character.isWhitespace(filter.charAt(walkbackPos))) {
                            walkbackPos--;
                        }
                        if (walkbackPos <0) {
                            //filter is invalid - FilterImpl will throw error
                            break;
                        }
                        
                        //check to see if we have unescaped '('
                        if (filter.charAt(walkbackPos) != '(' || (walkbackPos > 0 && filter.charAt(walkbackPos-1) == '\\')) {
                            //'(' was escaped or not there
                            pos = filter.indexOf("signer",pos+6); //$NON-NLS-1$
                            continue;
                        }                   
                        pos+=6; //skip over 'signer'

                        //found signer - consume whitespace before '='
                        while (Character.isWhitespace(filter.charAt(pos))) {
                            pos++;
                        }

                        //look for '='
                        if (filter.charAt(pos) != '=') {
                            //attr was signerx - keep looking
                            pos = filter.indexOf("signer",pos); //$NON-NLS-1$
                            continue;
                        }
                        pos++; //skip over '='
                        
                        //found signer value - escape '*'s
                        while (!(filter.charAt(pos) == ')' && filter.charAt(pos-1) != '\\')) {
                            if (filter.charAt(pos) == '*') {
                                filterBuf.insert(pos+numAsteriskFound,'\\');
                                numAsteriskFound++;
                            }
                            pos++;
                        }

                        //end of signer value - look for more?
                        pos = filter.indexOf("signer",pos); //$NON-NLS-1$
                    } //end while (pos != -1)
                    filter = filterBuf.toString();
                } //end if (pos != -1)

                filterImpl = new FilterImpl(filter);
            } catch (InvalidSyntaxException e) {
                //we will return null
            }
        }           
        return filterImpl;
    }

    /**
     * Determines if the specified permission is implied by this object.
     * This method throws an exception if the specified permission was not
     * constructed with a bundle.
     * 
     * <p>This method returns <code>true</code> if
     * The specified permission is an AdminPermission AND
     * <ul>
     * 	<li>this object's filter is an X.500 Distinguished name suffix that 
     * matches the specified permission's bundle OR
     * 	<li>this object's filter is "*" OR
     * 	<li>this object's bundle is a equal to the specified permission's
     * bundle
     * </ul>
     * AND this object's actions include all of the specified permission's actions 	 
     *
     * Special case: if the specified permission was constructed with "*", then this method
     * returns <code>true</code> if this object's filter is "*" and this object's actions include
     * all of the specified permission's actions
     * 
     * @param p The permission to interrogate.
     *
     * @return <code>true</code> if the specified permission is implied by
     * this object; <code>false</code> otherwise.
     * @throws RuntimeException if specified permission was not constructed with
     * a bundle or "*"
     */
    public boolean implies(Permission p)
    {
    	if (!(p instanceof AdminPermission))
    		return false;
    	AdminPermission target = (AdminPermission)p;
    	//check actions first - much faster
    	if ((action_mask & target.action_mask)!=target.action_mask)
    		return false;
    	//if passed in a filter, puke
    	if (target.filter != null)
    		throw new RuntimeException("Cannot imply a filter");
    	//special case - only wildcard implies wildcard
    	if (target.wildcard)
    		return wildcard;

    	//check our name 
    	if (filter != null) {
    		//it's a filter
    		Filter filterImpl = getFilterImpl();
			return filterImpl != null && filterImpl.match(target.getProperties());
    	} else if (wildcard) {
    		//it's "*"
    		return true;
    	} else {
    		//it's a bundle id
    		return bundle.equals(target.bundle);
    	}
    	    	
    }
    
    /**
     * Returns the canonical string representation of the <code>AdminPermission</code> actions.
     *
     * <p>Always returns present <code>AdminPermission</code> actions in the following order:
     * <code>CLASS</code>, <code>EXECUTE</code>, <code>LIFECYCLE</code>, <code>LISTENER</code>, 
     * <code>METADATA</code>, <code>PERMISSION</code>, <code>RESOLVE</code>, <code>RESOURCE</code>, 
     * <code>STARTLEVEL</code>.
     * @return Canonical string representation of the <code>AdminPermission</code> actions.
     */
	public String getActions() {
		if (actions == null) {
			if (action_mask == ACTION_ALL) {
				actions = "*"; //$NON-NLS-1$
			} else {
				StringBuffer sb = new StringBuffer();
				
				if ((action_mask & ACTION_CLASS) == ACTION_CLASS) {
					sb.append(CLASS);
					sb.append(',');
				}

				if ((action_mask & ACTION_EXECUTE) == ACTION_EXECUTE) {
					sb.append(EXECUTE);
					sb.append(',');
				}
	
				if ((action_mask & ACTION_LIFECYCLE) == ACTION_LIFECYCLE) {
					sb.append(LIFECYCLE);
					sb.append(',');
				}
	
				if ((action_mask & ACTION_LISTENER) == ACTION_LISTENER) {
					sb.append(LISTENER);
					sb.append(',');
				}
				
				if ((action_mask & ACTION_METADATA) == ACTION_METADATA) {
					sb.append(METADATA);
					sb.append(',');
				}
	
				if ((action_mask & ACTION_PERMISSION) == ACTION_PERMISSION) {
					sb.append(PERMISSION);
					sb.append(',');
				}
	
				if ((action_mask & ACTION_RESOLVE) == ACTION_RESOLVE) {
					sb.append(RESOLVE);
					sb.append(',');
				}
	
				if ((action_mask & ACTION_RESOURCE) == ACTION_RESOURCE) {
					sb.append(RESOURCE);
					sb.append(',');
				}
	
				if ((action_mask & ACTION_STARTLEVEL) == ACTION_STARTLEVEL) {
					sb.append(STARTLEVEL);
					sb.append(',');
				}

				if ((action_mask & ACTION_EXTENSIONLIFECYCLE) == ACTION_EXTENSIONLIFECYCLE) {
					sb.append(EXTENSIONLIFECYCLE);
					sb.append(',');
				}

				//remove trailing comma
				if (sb.length() > 0) {
					sb.deleteCharAt(sb.length()-1);
				}
				
				actions = sb.toString();
			}
		}
		return actions;
	}
	
    /**
     * Determines the equality of two <code>AdminPermission</code> objects. <p>Two 
     * <code>AdminPermission</code> objects are equal.
     *
     * @param obj The object being compared for equality with this object.
     * @return <code>true</code> if <code>obj</code> is equivalent to this 
     * <code>AdminPermission</code>; <code>false</code> otherwise.
     */
    public boolean equals(Object obj)
    {
        if (obj == this) {
        	return true;
        }
        
        if (!(obj instanceof AdminPermission))
        {
            return false;
        }
        
        AdminPermission a = (AdminPermission) obj;

        return (action_mask == a.action_mask) &&
        		(wildcard == a.wildcard) &&
        		(bundle == null ? a.bundle == null : (a.bundle == null ? false : bundle.getBundleId() == a.bundle.getBundleId())) &&
				(filter == null ? a.filter == null : filter.equals(a.filter));
    }

    /**
     * Returns the hash code value for this object.
     *
     * @return Hash code value for this object.
     */
	public int hashCode() {
		return getName().hashCode() ^ getActions().hashCode();
	}

	private synchronized void writeObject(java.io.ObjectOutputStream s) throws IOException {
		// Write out the actions. The superclass takes care of the name
		// call getActions to make sure actions field is initialized
		if (actions == null)
			getActions();
		if (filter == null && !wildcard)
			throw new UnsupportedOperationException("cannot serialize");
		s.defaultWriteObject();
	}

	/**
	 * readObject is called to restore the state of this permission from a
	 * stream.
	 */
	private synchronized void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
		// Read in the action, then initialize the rest
		s.defaultReadObject();
		action_mask = getMask(actions);
	}

    /**
     * Returns a new <code>PermissionCollection</code> object suitable for storing
     * <code>AdminPermission</code>s.
     * 
     * @return A new <code>PermissionCollection</code> object.
     */
    public PermissionCollection newPermissionCollection()
    {
        return(new AdminPermissionCollection());
    }

	/**
	 * Stores a collection of <code>AdminPermission</code>s.
	 */
	private final class AdminPermissionCollection extends PermissionCollection
	{
		private static final long serialVersionUID = 3906372644575328048L;
		/**
	     * Collection of permissions.
	     *
	     * @serial
	     */
		private Hashtable permissions;
	
	    /**
	     * Create an empty AdminPermissions object.
	     *
	     */
	
	    public AdminPermissionCollection()
	    {
	        permissions = new Hashtable();        
	    }

	    /**
	     * Adds a permission to the <code>AdminPermission</code> objects. The key for 
	     * the hashtable is the name
	     *
	     * @param permission The <code>AdminPermission</code> object to add.
	     *
	     * @exception IllegalArgumentException If the permission is not an
	     * <code>AdminPermission</code> instance.
	     *
	     * @exception SecurityException If this <code>AdminPermissionCollection</code>
	     * object has been marked read-only.
	     */
	    public void add(Permission permission)
	    {
	        if (! (permission instanceof AdminPermission))
	            throw new IllegalArgumentException("invalid permission: "+
	                                               permission);
	        if (isReadOnly())
	            throw new SecurityException("attempt to add a Permission to a " +
	                                        "readonly AdminCollection");
	        AdminPermission ap = (AdminPermission) permission;
	    	AdminPermission existing = (AdminPermission) permissions.get(ap.getName());
	    	if (existing != null){
	    		int oldMask = existing.action_mask;
	    		int newMask = ap.action_mask;
	        
	    		if (oldMask != newMask) {
	    			permissions.put(existing.getName(),
	    					new AdminPermission(existing.getName(), oldMask | newMask));
	    		}
	    	} else {
	    		permissions.put(ap.getName(), ap);
	    	}
	    }
	
	
	    /**
	     * Determines if the specified permissions implies the permissions
	     * expressed in <code>permission</code>.
	     *
	     * @param permission The Permission object to compare with the <code>AdminPermission</code>
	     *  objects in this collection.
	     *
	     * @return <code>true</code> if <code>permission</code> is implied by an 
	     * <code>AdminPermission</code> in this collection, <code>false</code> otherwise.
	     */
	    public boolean implies(Permission permission)
	    {
	        if (!(permission instanceof AdminPermission))
	            return(false);
	
	        AdminPermission target = (AdminPermission) permission;
	        
	        //just iterate one by one
	        Iterator permItr = permissions.values().iterator();
	        
	        while(permItr.hasNext())
	        	if (((AdminPermission)permItr.next()).implies(target))
	        		return true;
	        return false;
	    }
	 
	
	    /**
	     * Returns an enumeration of all <code>AdminPermission</code> objects in the
	     * container.
	     *
	     * @return Enumeration of all <code>AdminPermission</code> objects.
	     */
	
	    public Enumeration elements()
	    {
	        return(Collections.enumeration(permissions.values()));
	    }
	}
}