/**
  * Perform a SubSet function against two defined Bags.
  *
  * @param firstBag
  * @param secondBag
  * @param pip
  * @return
  * @throws XACML3EntitlementException
  */
 private boolean SubSet(DataBag firstBag, DataBag secondBag, XACMLEvalContext pip)
     throws XACML3EntitlementException {
   int subSetCount = 0;
   // Iterate over the First Bag.
   for (int b = 0; b < firstBag.size(); b++) {
     DataValue dataValue1 = (DataValue) firstBag.get(b).doEvaluate(pip);
     for (int z = 0; z < secondBag.size(); z++) {
       DataValue dataValue2 = (DataValue) secondBag.get(z).doEvaluate(pip);
       // Check Equality by using this Types Equality Function.
       AnyuriEqual fEquals = new AnyuriEqual();
       fEquals.addArgument(dataValue2);
       fEquals.addArgument(dataValue1);
       FunctionArgument result = fEquals.doEvaluate(pip);
       if (result.isTrue()) {
         subSetCount++;
         break;
       }
     } // End of Inner Loop.
   } // End of Outer For Loop.
   // Determine if we have in-fact a subSet.
   return (subSetCount == firstBag.size());
 }
  public FunctionArgument evaluate(XACMLEvalContext pip) throws XACML3EntitlementException {

    int args = getArgCount();
    if (args != 2) {
      throw new IndeterminateException(
          "Function Requires 2 arguments, " + "however " + args + " in stack.");
    }
    // Iterate Over the 2 DataBag's in Stack, Evaluate and determine if First Bag is a Subset of the
    // Second Bag and
    // in reverse and then And against each result.
    boolean firstSubSet = false;
    boolean secondSubSet = false;

    DataBag firstBag = null;
    DataBag secondBag = null;
    try {
      firstBag = (DataBag) getArg(0).doEvaluate(pip);
      secondBag = (DataBag) getArg(1).doEvaluate(pip);

      // Verify our Data Type with First Data Bag's Data Type.
      if (firstBag.getType().getIndex() != secondBag.getType().getIndex()) {
        throw new IndeterminateException(
            "First Bag Type: "
                + firstBag.getType().getTypeName()
                + ", however the subsequent Bag Type was "
                + secondBag.getType().getTypeName());
      }
      // Is the First Bag a SubSet of the Second?
      firstSubSet = this.SubSet(firstBag, secondBag, pip);
      // Is the Second Bag a SubSet of the First?
      secondSubSet = this.SubSet(secondBag, firstBag, pip);
    } catch (Exception e) {
      throw new IndeterminateException("Iterating over Arguments Exception: " + e.getMessage());
    }
    // And our Conditions.
    return (firstSubSet & secondSubSet)
        ? FunctionArgument.trueObject
        : FunctionArgument.falseObject;
  }
  public FunctionArgument evaluate(XACMLEvalContext pip) throws XACML3EntitlementException {

    int args = getArgCount();
    if (args < 2) {
      throw new IndeterminateException(
          "Function Requires at least 2 arguments, " + "however " + getArgCount() + " in stack.");
    }
    // Create our union DataBag from other Bags.
    DataBag unionBag = new DataBag();
    // Iterate Over All DataBag's in Stack, Evaluate and create a Union of all Bags with Unique
    // Objects.
    try {
      for (int i = 0; i < args; i++) {
        DataBag bag = (DataBag) getArg(i).doEvaluate(pip);
        if (bag == null) {
          continue;
        }
        // Set our Union Data Bag with First Bag's Data Type and check subsequent Bags.
        if (i == 0) {
          unionBag.setType(bag.getType());
        } else {
          // Verify our Data Type with First Data Bag's Data Type.
          if (bag.getType().getIndex() != unionBag.getType().getIndex()) {
            throw new IndeterminateException(
                "First Bag Type: "
                    + unionBag.getType().getTypeName()
                    + ", however a subsequent Bag Type was "
                    + bag.getType().getTypeName());
          }
        }
        // Iterate over the current Bag.
        for (int b = 0; b < bag.size(); b++) {
          DataValue dataValue = (DataValue) bag.get(b).doEvaluate(pip);
          boolean contained = false;
          for (int z = 0; z < unionBag.size(); z++) {
            // Apply the Typed Equal Function to determine if
            // the object already exists in the Union Bag.
            TimeEqual fEquals = new TimeEqual();
            fEquals.addArgument(unionBag.get(z));
            fEquals.addArgument(dataValue);
            FunctionArgument result = fEquals.doEvaluate(pip);
            if (result.isTrue()) {
              contained = true;
              break;
            }
          }
          // Add the Object if not contained.
          if (!contained) {
            // Add the Unique DataValue Element into the Union Bag.
            unionBag.add(dataValue);
          }
        } // End of Inner For Loop.
      } // End of Outer For Loop.
    } catch (Exception e) {
      throw new IndeterminateException("Iterating over Arguments Exception: " + e.getMessage());
    }
    // Return our UnionBag Value.
    return unionBag;
  }