/**
   * Check and see if this collection of permissions implies the permissions expressed in
   * "permission".
   *
   * @param p the Permission object to compare
   * @return true if "permission" is a proper subset of a permission in the collection, false if
   *     not.
   */
  public boolean implies(Permission permission) {
    if (!(permission instanceof ServicePermission)) return false;

    ServicePermission np = (ServicePermission) permission;
    int desired = np.getMask();
    int effective = 0;
    int needed = desired;

    synchronized (this) {
      int len = perms.size();

      // need to deal with the case where the needed permission has
      // more than one action and the collection has individual permissions
      // that sum up to the needed.

      for (int i = 0; i < len; i++) {
        ServicePermission x = (ServicePermission) perms.get(i);

        // System.out.println("  trying "+x);
        if (((needed & x.getMask()) != 0) && x.impliesIgnoreMask(np)) {
          effective |= x.getMask();
          if ((effective & desired) == desired) return true;
          needed = (desired ^ effective);
        }
      }
    }
    return false;
  }
  /**
   * Checks two ServicePermission objects for equality.
   *
   * <p>
   *
   * @param obj the object to test for equality with this object.
   * @return true if <i>obj</i> is a ServicePermission, and has the same service principal, and
   *     actions as this ServicePermission object.
   */
  public boolean equals(Object obj) {
    if (obj == this) return true;

    if (!(obj instanceof ServicePermission)) return false;

    ServicePermission that = (ServicePermission) obj;
    return ((this.mask & that.mask) == that.mask) && this.getName().equals(that.getName());
  }
 boolean impliesIgnoreMask(ServicePermission p) {
   return ((this.getName().equals("*")) || this.getName().equals(p.getName()));
 }