private Part buildNewMultiMultiPart(OredParts lp, OredParts rp) {
   ArrayList<Part> newParts = new ArrayList<Part>();
   for (Part lpc : lp.getParts()) {
     for (Part rpc : rp.getParts()) {
       newParts.add(combineParts(lpc.copy(), rpc.copy()));
     }
   }
   FunctionCall orcall =
       new FunctionCall(
           FunctionName.makeOr(), Functional.apply(newParts, Part.castToExpression));
   OredParts op = parent.buildOredParts(orcall, newParts);
   if (op.isComplete()) setComplete(op);
   return op;
 }
 private Part buildNewPartCollection(OredParts lp, Part rp) {
   // rp could be simple or complex, lp has either simple or complex elements.
   // the strategy here is to build a new complex part for each item in the collection, and
   // return a new collection.
   ArrayList<Part> newParts = new ArrayList<Part>();
   for (Part sp : lp.getParts()) {
     newParts.add(buildNewComplexPart(sp, rp.copy()));
   }
   FunctionCall orcall =
       new FunctionCall(
           FunctionName.makeOr(), Functional.apply(newParts, Part.castToExpression));
   OredParts op = parent.buildOredParts(orcall, newParts);
   if (op.isComplete()) setComplete(op);
   return op;
 }
    @Override
    public Part copy() {
      List<Part> newparts = new ArrayList<Part>();
      for (Part p : parts) newparts.add(p.copy());
      FunctionCall newp =
          new FunctionCall(
              FunctionName.makeAnd(),
              Functional.apply(
                  newparts,
                  new UnaryFunction<ExpressionNode, Part>() {

                    @Override
                    public ExpressionNode evaluate(Part object) {
                      return (ExpressionNode) object.getParent();
                    }
                  }));
      return new AndedParts(newp, getTableKey(), newparts, complete);
    }