/**
   * @param action is the action on the assignment (null means default action)
   * @param attributeDefName
   * @param checkSecurity
   * @return if removed or already not assigned
   */
  private AttributeAssignResult removeAttributeHelper(
      String action, AttributeDefName attributeDefName, boolean checkSecurity) {
    if (checkSecurity) {
      this.assertCanUpdateAttributeDefName(attributeDefName);
    }

    AttributeAssignResult attributeAssignResult = new AttributeAssignResult();
    attributeAssignResult.setChanged(false);
    // see if it exists
    if (!this.hasAttributeHelper(action, attributeDefName, false)) {
      return attributeAssignResult;
    }
    action = StringUtils.defaultIfEmpty(action, AttributeDef.ACTION_DEFAULT);
    Set<AttributeAssign> attributeAssigns =
        retrieveAttributeAssignsByOwnerAndAttributeDefNameId(attributeDefName.getId());
    Set<AttributeAssign> attributeAssignsToReturn = new LinkedHashSet<AttributeAssign>();
    for (AttributeAssign attributeAssign : attributeAssigns) {
      String currentAttributeAction = attributeAssign.getAttributeAssignAction().getName();
      if (StringUtils.equals(action, currentAttributeAction)) {
        attributeAssignResult.setChanged(true);
        attributeAssignsToReturn.add(attributeAssign);
        attributeAssign.delete();
      }
    }
    attributeAssignResult.setAttributeAssigns(attributeAssignsToReturn);
    return attributeAssignResult;
  }
  /**
   * @param checkSecurity
   * @param assignId
   * @return if removed or already gone
   */
  public AttributeAssignResult removeAttributeByAssignId(String assignId, boolean checkSecurity) {

    AttributeAssign attributeAssign = AttributeAssignFinder.findById(assignId, false);

    AttributeAssignResult attributeAssignResult = new AttributeAssignResult();

    attributeAssignResult.setChanged(false);

    if (attributeAssign == null) {
      return attributeAssignResult;
    }

    AttributeDefName attributeDefName =
        GrouperDAOFactory.getFactory()
            .getAttributeDefName()
            .findByIdSecure(attributeAssign.getAttributeDefNameId(), true);

    if (checkSecurity) {
      this.assertCanUpdateAttributeDefName(attributeDefName);
    }

    attributeAssignResult.setChanged(true);
    attributeAssignResult.setAttributeAssign(attributeAssign);
    attributeAssign.delete();

    return attributeAssignResult;
  }
  /**
   * add a multi assignable attribute
   *
   * @param action is the action on the assignment (null means default action)
   * @param attributeDefName
   * @param checkSecurity
   * @param uuid uuid of the assignment
   * @return the result including if added or already there
   */
  public AttributeAssignResult internal_addAttributeHelper(
      String action, AttributeDefName attributeDefName, boolean checkSecurity, String uuid) {

    AttributeDef attributeDef = attributeDefName.getAttributeDef();
    if (!attributeDef.isMultiAssignable()) {
      throw new RuntimeException(
          "This attribute must be multi-assignable to call this method, use the non multi-assign method: "
              + attributeDefName.getName());
    }

    if (checkSecurity) {
      this.assertCanUpdateAttributeDefName(attributeDefName);
    }

    this.assertScopeOk(attributeDef);

    AttributeAssign attributeAssign = newAttributeAssign(action, attributeDefName, uuid);

    if (StringUtils.isBlank(attributeAssign.getAttributeAssignActionId())) {
      attributeAssign.setAttributeAssignActionId(
          attributeDef.getAttributeDefActionDelegate().allowedAction(action, true).getId());
    }

    attributeAssign.saveOrUpdate(checkSecurity);

    return new AttributeAssignResult(true, attributeAssign);
  }
  /**
   * see if the group
   *
   * @param action is the action on the assignment (null means default action)
   * @param attributeDefNameName
   * @return true if has attribute, false if not
   */
  public boolean hasAttributeByName(String action, String attributeDefNameName) {
    AttributeDefName attributeDefName =
        GrouperDAOFactory.getFactory()
            .getAttributeDefName()
            .findByNameSecure(attributeDefNameName, true);

    Set<AttributeAssign> attributeAssigns = retrieveAssignments(attributeDefName);
    action = StringUtils.defaultIfEmpty(action, AttributeDef.ACTION_DEFAULT);
    for (AttributeAssign attributeAssign : attributeAssigns) {
      String currentAttributeAction = attributeAssign.getAttributeAssignAction().getName();
      if (StringUtils.equals(action, currentAttributeAction)) {
        return true;
      }
    }
    return false;
  }
  /**
   * @param action on the assignment
   * @param attributeDefName
   * @param checkSecurity
   * @return true if has attribute, false if not
   */
  boolean hasAttributeHelper(
      String action, AttributeDefName attributeDefName, boolean checkSecurity) {
    if (checkSecurity) {
      this.assertCanReadAttributeDefName(attributeDefName);
    }
    Set<AttributeAssign> attributeAssigns =
        retrieveAttributeAssignsByOwnerAndAttributeDefNameId(attributeDefName.getId());

    action = StringUtils.defaultIfEmpty(action, AttributeDef.ACTION_DEFAULT);
    for (AttributeAssign attributeAssign : attributeAssigns) {
      String currentAttributeAction = attributeAssign.getAttributeAssignAction().getName();
      if (StringUtils.equals(action, currentAttributeAction)) {
        return true;
      }
    }

    return false;
  }
 /**
  * @param action
  * @param attributeDefName
  * @param exceptionIfNull
  * @param attributeAssigns
  * @return assignment
  */
 private AttributeAssign retrieveAssignmentHelper(
     String action,
     AttributeDefName attributeDefName,
     boolean exceptionIfNull,
     Set<AttributeAssign> attributeAssigns) {
   AttributeAssign attributeAssignResult = null;
   action = StringUtils.defaultIfEmpty(action, AttributeDef.ACTION_DEFAULT);
   for (AttributeAssign attributeAssign : attributeAssigns) {
     String currentAttributeAction = attributeAssign.getAttributeAssignAction().getName();
     if (StringUtils.equals(action, currentAttributeAction)) {
       if (attributeAssignResult != null) {
         throw new RuntimeException(
             "Multiple assignments exist: " + attributeDefName + ", " + action + ", " + this);
       }
       attributeAssignResult = attributeAssign;
     }
   }
   if (exceptionIfNull && attributeAssignResult == null) {
     throw new RuntimeException(
         "Cant find assignment: " + action + ", " + attributeDefName + ", " + this);
   }
   return attributeAssignResult;
 }
  /**
   * @param action is the action on the assignment (null means default action)
   * @param attributeDefName
   * @param checkSecurity
   * @param uuid uuid of the assignment
   * @param permissionAllowed if permission this is the allowed flag
   * @return the result including if added or already there
   */
  public AttributeAssignResult internal_assignAttributeHelper(
      String action,
      AttributeDefName attributeDefName,
      boolean checkSecurity,
      String uuid,
      PermissionAllowed permissionAllowed) {

    if (permissionAllowed == null) {
      permissionAllowed = PermissionAllowed.ALLOWED;
    }

    AttributeDef attributeDef = attributeDefName.getAttributeDef();

    if (checkSecurity) {
      this.assertCanUpdateAttributeDefName(attributeDefName);
    }

    boolean isPermission =
        AttributeDefType.perm.equals(attributeDefName.getAttributeDef().getAttributeDefType());
    if (permissionAllowed != null && permissionAllowed.isDisallowed() && !isPermission) {
      throw new RuntimeException(
          "Can only assign a permissionAllowed with attributeDefName as perm (permission) type: "
              + attributeDefName.getName()
              + ", "
              + attributeDefName.getAttributeDef().getAttributeDefType());
    }

    AttributeAssign attributeAssign = retrieveAssignment(action, attributeDefName, false, false);

    if (attributeAssign != null) {
      if (permissionAllowed != null
          && permissionAllowed.isDisallowed() != attributeAssign.isDisallowed()) {
        throw new RuntimeException(
            "Assigning disallowed: "
                + permissionAllowed.isDisallowed()
                + ", but the existing assignment "
                + attributeAssign.getId()
                + " has: "
                + attributeAssign.isDisallowed()
                + ", you need to delete assignment and reassign.");
      }
      return new AttributeAssignResult(false, attributeAssign);
    }

    attributeAssign = newAttributeAssign(action, attributeDefName, uuid);

    attributeAssign.setDisallowed(
        permissionAllowed == null ? false : permissionAllowed.isDisallowed());

    if (StringUtils.isBlank(attributeAssign.getAttributeAssignActionId())) {
      attributeAssign.setAttributeAssignActionId(
          attributeDef.getAttributeDefActionDelegate().allowedAction(action, true).getId());
    }

    this.assertScopeOk(attributeDef);

    attributeAssign.internalSetAttributeDef(attributeDef);
    attributeAssign.internalSetAttributeDefName(attributeDefName);
    attributeAssign.saveOrUpdate(checkSecurity);
    return new AttributeAssignResult(true, attributeAssign);
  }