/// <summary>
        /// package private to allow calls from ProtectionDomain without performing
        /// the security check for <seealso cref="SecurityConstants.CREATE_ACC_PERMISSION"/>
        /// permission
        /// </summary>
        internal AccessControlContext(AccessControlContext acc, DomainCombiner combiner, bool preauthorized)
        {
            if (!preauthorized)
            {
                SecurityManager sm = System.SecurityManager;
                if (sm != null)
                {
                    sm.CheckPermission(SecurityConstants.CREATE_ACC_PERMISSION);
                    this.IsAuthorized = true;
                }
            }
            else
            {
                this.IsAuthorized = true;
            }

            this.Context_Renamed = acc.Context_Renamed;

            // we do not need to run the combine method on the
            // provided ACC.  it was already "combined" when the
            // context was originally retrieved.
            //
            // at this point in time, we simply throw away the old
            // combiner and use the newly provided one.
            this.Combiner_Renamed = combiner;
        }
        /// <summary>
        /// Performs the specified {@code PrivilegedExceptionAction} with
        /// privileges enabled.  The action is performed with <i>all</i> of the
        /// permissions possessed by the caller's protection domain.
        ///
        /// <para> If the action's {@code run} method throws an <i>unchecked</i>
        /// exception, it will propagate through this method.
        ///
        /// </para>
        /// <para> This method preserves the current AccessControlContext's
        /// DomainCombiner (which may be null) while the action is performed.
        ///
        /// </para>
        /// </summary>
        /// @param <T> the type of the value returned by the
        ///                  PrivilegedExceptionAction's {@code run} method.
        /// </param>
        /// <param name="action"> the action to be performed.
        /// </param>
        /// <returns> the value returned by the action's {@code run} method
        /// </returns>
        /// <exception cref="PrivilegedActionException"> if the specified action's
        ///         {@code run} method threw a <i>checked</i> exception </exception>
        /// <exception cref="NullPointerException"> if the action is {@code null}
        /// </exception>
        /// <seealso cref= #doPrivileged(PrivilegedAction) </seealso>
        /// <seealso cref= #doPrivileged(PrivilegedExceptionAction,AccessControlContext) </seealso>
        /// <seealso cref= java.security.DomainCombiner
        ///
        /// @since 1.6 </seealso>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @CallerSensitive public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action) throws PrivilegedActionException
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        public static T doPrivilegedWithCombiner <T>(PrivilegedExceptionAction <T> action)
        {
            AccessControlContext acc = StackAccessControlContext;

            if (acc == null)
            {
                return(AccessController.doPrivileged(action));
            }
            DomainCombiner dc = acc.AssignedCombiner;

            return(AccessController.doPrivileged(action, PreserveCombiner(dc, Reflection.CallerClass)));
        }
        /// <summary>
        /// Create a wrapper to contain the limited privilege scope data.
        /// </summary>
        private static AccessControlContext CreateWrapper(DomainCombiner combiner, Class caller, AccessControlContext parent, AccessControlContext context, Permission[] perms)
        {
            ProtectionDomain callerPD = GetCallerPD(caller);

            // check if caller is authorized to create context
            if (context != null && !context.Authorized && System.SecurityManager != null && !callerPD.ImpliesCreateAccessControlContext())
            {
                ProtectionDomain nullPD = new ProtectionDomain(null, null);
                return(new AccessControlContext(new ProtectionDomain[] { nullPD }));
            }
            else
            {
                return(new AccessControlContext(callerPD, combiner, parent, context, perms));
            }
        }
        /// <summary>
        /// Performs the specified {@code PrivilegedExceptionAction} with
        /// privileges enabled and restricted by the specified
        /// {@code AccessControlContext} and with a privilege scope limited by
        /// specified {@code Permission} arguments.
        ///
        /// The action is performed with the intersection of the permissions
        /// possessed by the caller's protection domain, and those possessed
        /// by the domains represented by the specified
        /// {@code AccessControlContext}.
        /// <para>
        /// If the action's {@code run} method throws an (unchecked) exception,
        /// it will propagate through this method.
        ///
        /// </para>
        /// <para> This method preserves the current AccessControlContext's
        /// DomainCombiner (which may be null) while the action is performed.
        /// </para>
        /// <para>
        /// If a security manager is installed and the specified
        /// {@code AccessControlContext} was not created by system code and the
        /// caller's {@code ProtectionDomain} has not been granted the
        /// {@literal "createAccessControlContext"}
        /// <seealso cref="java.security.SecurityPermission"/>, then the action is performed
        /// with no permissions.
        ///
        /// </para>
        /// </summary>
        /// @param <T> the type of the value returned by the
        ///                  PrivilegedExceptionAction's {@code run} method. </param>
        /// <param name="action"> the action to be performed. </param>
        /// <param name="context"> an <i>access control context</i>
        ///                representing the restriction to be applied to the
        ///                caller's domain's privileges before performing
        ///                the specified action.  If the context is
        ///                {@code null},
        ///                then no additional restriction is applied. </param>
        /// <param name="perms"> the {@code Permission} arguments which limit the
        ///              scope of the caller's privileges. The number of arguments
        ///              is variable.
        /// </param>
        /// <returns> the value returned by the action's {@code run} method.
        /// </returns>
        /// <exception cref="PrivilegedActionException"> if the specified action's
        ///         {@code run} method threw a <i>checked</i> exception </exception>
        /// <exception cref="NullPointerException"> if action or perms or any element of
        ///         perms is {@code null}
        /// </exception>
        /// <seealso cref= #doPrivileged(PrivilegedAction) </seealso>
        /// <seealso cref= #doPrivileged(PrivilegedAction,AccessControlContext) </seealso>
        /// <seealso cref= java.security.DomainCombiner
        ///
        /// @since 1.8 </seealso>
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @CallerSensitive public static <T> T doPrivilegedWithCombiner(PrivilegedExceptionAction<T> action, AccessControlContext context, Permission... perms) throws PrivilegedActionException
//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in .NET:
        public static T doPrivilegedWithCombiner <T>(PrivilegedExceptionAction <T> action, AccessControlContext context, params Permission[] perms)
        {
            AccessControlContext parent = Context;
            DomainCombiner       dc     = parent.Combiner;

            if (dc == null && context != null)
            {
                dc = context.Combiner;
            }
            if (perms == null)
            {
                throw new NullPointerException("null permissions parameter");
            }
            Class caller = Reflection.CallerClass;

            return(AccessController.doPrivileged(action, CreateWrapper(dc, caller, parent, context, perms)));
        }
        /// <summary>
        /// Take the stack-based context (this) and combine it with the
        /// privileged or inherited context, if need be. Any limited
        /// privilege scope is flagged regardless of whether the assigned
        /// context comes from an immediately enclosing limited doPrivileged().
        /// The limited privilege scope can indirectly flow from the inherited
        /// parent thread or an assigned context previously captured by getContext().
        /// </summary>
        internal AccessControlContext Optimize()
        {
            // the assigned (privileged or inherited) context
            AccessControlContext acc;
            DomainCombiner       combiner = null;
            AccessControlContext parent   = null;

            Permission[] permissions = null;

            if (IsPrivileged)
            {
                acc = PrivilegedContext;
                if (acc != null)
                {
                    /*
                     * If the context is from a limited scope doPrivileged() then
                     * copy the permissions and parent fields out of the wrapper
                     * context that was created to hold them.
                     */
                    if (acc.IsWrapped)
                    {
                        permissions = acc.Permissions;
                        parent      = acc.Parent;
                    }
                }
            }
            else
            {
                acc = AccessController.InheritedAccessControlContext;
                if (acc != null)
                {
                    /*
                     * If the inherited context is constrained by a limited scope
                     * doPrivileged() then set it as our parent so we will process
                     * the non-domain-related state.
                     */
                    if (acc.IsLimited)
                    {
                        parent = acc;
                    }
                }
            }

            // this.context could be null if only system code is on the stack;
            // in that case, ignore the stack context
            bool skipStack = (Context_Renamed == null);

            // acc.context could be null if only system code was involved;
            // in that case, ignore the assigned context
            bool skipAssigned = (acc == null || acc.Context_Renamed == null);

            ProtectionDomain[] assigned = (skipAssigned) ? null : acc.Context_Renamed;
            ProtectionDomain[] pd;

            // if there is no enclosing limited privilege scope on the stack or
            // inherited from a parent thread
            bool skipLimited = ((acc == null || !acc.IsWrapped) && parent == null);

            if (acc != null && acc.Combiner_Renamed != null)
            {
                // let the assigned acc's combiner do its thing
                if (Debug != null)
                {
                    Debug_Renamed.println("AccessControlContext invoking the Combiner");
                }

                // No need to clone current and assigned.context
                // combine() will not update them
                combiner = acc.Combiner_Renamed;
                pd       = combiner.Combine(Context_Renamed, assigned);
            }
            else
            {
                if (skipStack)
                {
                    if (skipAssigned)
                    {
                        CalculateFields(acc, parent, permissions);
                        return(this);
                    }
                    else if (skipLimited)
                    {
                        return(acc);
                    }
                }
                else if (assigned != null)
                {
                    if (skipLimited)
                    {
                        // optimization: if there is a single stack domain and
                        // that domain is already in the assigned context; no
                        // need to combine
                        if (Context_Renamed.Length == 1 && Context_Renamed[0] == assigned[0])
                        {
                            return(acc);
                        }
                    }
                }

                pd = Combine(Context_Renamed, assigned);
                if (skipLimited && !skipAssigned && pd == assigned)
                {
                    return(acc);
                }
                else if (skipAssigned && pd == Context_Renamed)
                {
                    CalculateFields(acc, parent, permissions);
                    return(this);
                }
            }

            // Reuse existing ACC
            this.Context_Renamed  = pd;
            this.Combiner_Renamed = combiner;
            this.IsPrivileged     = false;

            CalculateFields(acc, parent, permissions);
            return(this);
        }
        /// <summary>
        /// package private for AccessController
        ///
        /// This "argument wrapper" context will be passed as the actual context
        /// parameter on an internal doPrivileged() call used in the implementation.
        /// </summary>
        internal AccessControlContext(ProtectionDomain caller, DomainCombiner combiner, AccessControlContext parent, AccessControlContext context, Permission[] perms)
        {
            /*
             * Combine the domains from the doPrivileged() context into our
             * wrapper context, if necessary.
             */
            ProtectionDomain[] callerPDs = null;
            if (caller != null)
            {
                callerPDs = new ProtectionDomain[] { caller };
            }
            if (context != null)
            {
                if (combiner != null)
                {
                    this.Context_Renamed = combiner.Combine(callerPDs, context.Context_Renamed);
                }
                else
                {
                    this.Context_Renamed = Combine(callerPDs, context.Context_Renamed);
                }
            }
            else
            {
                /*
                 * Call combiner even if there is seemingly nothing to combine.
                 */
                if (combiner != null)
                {
                    this.Context_Renamed = combiner.Combine(callerPDs, null);
                }
                else
                {
                    this.Context_Renamed = Combine(callerPDs, null);
                }
            }
            this.Combiner_Renamed = combiner;

            Permission[] tmp = null;
            if (perms != null)
            {
                tmp = new Permission[perms.Length];
                for (int i = 0; i < perms.Length; i++)
                {
                    if (perms[i] == null)
                    {
                        throw new NullPointerException("permission can't be null");
                    }

                    /*
                     * An AllPermission argument is equivalent to calling
                     * doPrivileged() without any limit permissions.
                     */
                    if (perms[i].GetType() == typeof(AllPermission))
                    {
                        parent = null;
                    }
                    tmp[i] = perms[i];
                }
            }

            /*
             * For a doPrivileged() with limited privilege scope, initialize
             * the relevant fields.
             *
             * The limitedContext field contains the union of all domains which
             * are enclosed by this limited privilege scope. In other words,
             * it contains all of the domains which could potentially be checked
             * if none of the limiting permissions implied a requested permission.
             */
            if (parent != null)
            {
                this.LimitedContext    = Combine(parent.Context_Renamed, parent.LimitedContext);
                this.IsLimited         = true;
                this.IsWrapped         = true;
                this.Permissions       = tmp;
                this.Parent            = parent;
                this.PrivilegedContext = context;                 // used in checkPermission2()
            }
            this.IsAuthorized = true;
        }
 /// <summary>
 /// Create a new {@code AccessControlContext} with the given
 /// {@code AccessControlContext} and {@code DomainCombiner}.
 /// This constructor associates the provided
 /// {@code DomainCombiner} with the provided
 /// {@code AccessControlContext}.
 ///
 /// <para>
 ///
 /// </para>
 /// </summary>
 /// <param name="acc"> the {@code AccessControlContext} associated
 ///          with the provided {@code DomainCombiner}.
 /// </param>
 /// <param name="combiner"> the {@code DomainCombiner} to be associated
 ///          with the provided {@code AccessControlContext}.
 /// </param>
 /// <exception cref="NullPointerException"> if the provided
 ///          {@code context} is {@code null}.
 /// </exception>
 /// <exception cref="SecurityException"> if a security manager is installed and the
 ///          caller does not have the "createAccessControlContext"
 ///          <seealso cref="SecurityPermission"/>
 /// @since 1.3 </exception>
 public AccessControlContext(AccessControlContext acc, DomainCombiner combiner) : this(acc, combiner, false)
 {
 }
 /// <summary>
 /// preserve the combiner across the doPrivileged call
 /// </summary>
 private static AccessControlContext PreserveCombiner(DomainCombiner combiner, Class caller)
 {
     return(CreateWrapper(combiner, caller, null, null, null));
 }