private void initializeArrayField(FieldTreeNode context, ArrayAddExpression expr) {
    for (RValueExpression rvalue : expr.getValues()) {
      Path refPath = null;
      FieldTreeNode refMd = null;
      if (rvalue.getType() == RValueExpression.RValueType._dereference) {
        refPath = rvalue.getPath();
        refMd = context.resolve(refPath);
        if (refMd == null) {
          throw new EvaluationError(CrudConstants.ERR_INVALID_DEREFERENCE + refPath);
        }
      }

      ArrayElement element = fieldMd.getElement();
      validateArrayElement(element, refMd, rvalue, refPath);

      values.add(
          new RValueData(
              refPath,
              refMd == null ? null : refMd.getType(),
              rvalue.getValue(),
              rvalue.getType()));
    }
  }
  @Override
  public boolean update(JsonDoc doc, FieldTreeNode contextMd, Path contextPath) {
    boolean ret = false;
    Path absPath = new Path(contextPath, arrayField);
    JsonNode node = doc.get(absPath);
    int insertTo = insertionIndex;
    if (node == null || node instanceof NullNode) {
      doc.modify(absPath, node = factory.arrayNode(), true);
    }
    if (node instanceof ArrayNode) {
      ArrayNode arrayNode = (ArrayNode) node;
      for (RValueData rvalueData : values) {
        LOGGER.debug("add element to {} rvalue:{}", absPath, rvalueData);
        Object newValue = null;
        Type newValueType = null;
        JsonNode newValueNode = null;
        if (rvalueData.refPath != null) {
          JsonNode refNode = doc.get(new Path(contextPath, rvalueData.refPath));
          if (refNode != null) {
            newValueNode = refNode.deepCopy();
            newValue = rvalueData.refType.fromJson(newValueNode);
            newValueType = rvalueData.refType;
          }
        } else if (rvalueData.value != null) {
          newValue = rvalueData.value.getValue();
          newValueNode =
              newValue instanceof JsonNode
                  ? (JsonNode) newValue
                  : fieldMd.getElement().getType().toJson(factory, newValue);
          newValueType = fieldMd.getElement().getType();
        } else if (rvalueData.rvalueType == RValueExpression.RValueType._null) {
          newValueNode = factory.nullNode();
        }
        LOGGER.debug(
            "newValueType:{}, newValue:{}, newValueNode:{} ", newValueType, newValue, newValueNode);

        if (insertTo >= 0) {
          // If we're inserting, make sure we have that many elements
          while (arrayNode.size() < insertTo) {
            arrayNode.addNull();
          }

          if (arrayNode.size() > insertTo) {
            arrayNode.insert(insertTo, newValueNode);
          } else {
            arrayNode.add(newValueNode);
          }
          insertTo++;
        } else {
          arrayNode.add(newValueNode);
        }
        ret = true;
      }
      if (ret) {
        // We have to rewrite the array indexes in arraySizeField using
        // the context path
        MutablePath p = new MutablePath(arraySizeField);
        p.rewriteIndexes(contextPath);
        LOGGER.debug("Setting {} = {}", p, arrayNode.size());
        doc.modify(p, factory.numberNode(arrayNode.size()), false);
      }
    }
    return ret;
  }