public void execute(
      XFormsActionInterpreter actionInterpreter,
      Element actionElement,
      Scope actionScope,
      boolean hasOverriddenContext,
      Item overriddenContext) {

    final IndentedLogger indentedLogger = actionInterpreter.indentedLogger();
    final XFormsContainingDocument containingDocument = actionInterpreter.containingDocument();
    final XFormsContextStack contextStack = actionInterpreter.actionXPathContext();

    final String atAttribute = actionElement.attributeValue("at");
    final String originAttribute = actionElement.attributeValue("origin");
    final String contextAttribute = actionElement.attributeValue(XFormsConstants.CONTEXT_QNAME);

    // Extension: allow position to be an AVT
    final String resolvedPositionAttribute =
        actionInterpreter.resolveAVT(actionElement, "position");

    // Extension: xxf:default="true" AVT requires that recalculate apply default values on the
    // inserted nodes.
    final boolean setRequireDefaultValues =
        "true"
            .equals(
                actionInterpreter.resolveAVT(
                    actionElement, XFormsConstants.XXFORMS_DEFAULTS_QNAME));

    // "2. The Node Set Binding node-set is determined."
    final List<Item> collectionToBeUpdated;
    {
      final BindingContext currentBindingContext = contextStack.getCurrentBindingContext();
      collectionToBeUpdated =
          currentBindingContext.newBind()
              ? currentBindingContext.nodeset()
              : XFormsConstants.EMPTY_ITEM_LIST;
    }
    final boolean isEmptyNodesetBinding =
        collectionToBeUpdated == null || collectionToBeUpdated.size() == 0;

    // "1. The insert context is determined."

    // "The insert action is terminated with no effect if [...] a. The context attribute is not
    // given and the Node
    // Set Binding node-set is the empty node-set."
    if (contextAttribute == null && isEmptyNodesetBinding) {
      if (indentedLogger.isDebugEnabled())
        indentedLogger.logDebug("xf:insert", "context is empty, terminating");
      return;
    }

    // Handle insert context (with @context attribute)
    final Item insertContextItem;
    if (hasOverriddenContext) {
      // "If the result is an empty nodeset or not a nodeset, then the insert action is terminated
      // with no effect. "
      if (overriddenContext == null || !(overriddenContext instanceof NodeInfo)) {
        if (indentedLogger.isDebugEnabled())
          indentedLogger.logDebug(
              "xf:insert", "overridden context is an empty nodeset or not a nodeset, terminating");
        return;
      } else {
        insertContextItem = overriddenContext;
      }
    } else {
      insertContextItem = contextStack.getCurrentBindingContext().getSingleItem();
    }

    // "The insert action is terminated with no effect if [...] b. The context attribute is given,
    // the insert
    // context does not evaluate to an element node and the Node Set Binding node-set is the empty
    // node-set."
    // NOTE: In addition we support inserting into a context which is a document node
    if (contextAttribute != null
        && isEmptyNodesetBinding
        && !DataModel.isElement(insertContextItem)
        && !DataModel.isDocument(insertContextItem)) {
      if (indentedLogger.isDebugEnabled())
        indentedLogger.logDebug(
            "xf:insert",
            "insert context is not an element node and binding node-set is empty, terminating");
      return;
    }

    // "3. The origin node-set is determined."
    final List<Item> originObjects;
    {
      if (originAttribute == null) {
        originObjects = null;
      } else {
        // There is an @origin attribute

        // "If the origin attribute is given, the origin node-set is the result of the evaluation of
        // the
        // origin attribute in the insert context."

        originObjects =
            actionInterpreter.evaluateKeepItems(
                actionElement, Collections.singletonList(insertContextItem), 1, originAttribute);

        // "The insert action is terminated with no effect if the origin node-set is the empty
        // node-set."
        if (originObjects.size() == 0) {
          if (indentedLogger.isDebugEnabled())
            indentedLogger.logDebug("xf:insert", "origin node-set is empty, terminating");
          return;
        }
      }
    }

    // "4. The insert location node is determined."
    int insertionIndex;
    {
      if (isEmptyNodesetBinding) {
        // "If the Node Set Binding node-set empty, then this attribute is ignored"
        insertionIndex = 0;
      } else if (atAttribute == null) {
        // "If the attribute is not given, then the default is the size of the Node Set Binding
        // node-set"
        insertionIndex = collectionToBeUpdated.size();
      } else {
        // "a. The evaluation context node is the first node in document order from the Node Set
        // Binding
        // node-set, the context size is the size of the Node Set Binding node-set, and the context
        // position is 1."

        // "b. The return value is processed according to the rules of the XPath function round()"
        final String insertionIndexString =
            actionInterpreter.evaluateAsString(
                actionElement, collectionToBeUpdated, 1, "round(" + atAttribute + ")");

        // "c. If the result is in the range 1 to the Node Set Binding node-set size, then the
        // insert
        // location is equal to the result. If the result is non-positive, then the insert location
        // is
        // 1. Otherwise, the result is NaN or exceeds the Node Set Binding node-set size, so the
        // insert
        // location is the Node Set Binding node-set size."

        // Don't think we will get NaN with XPath 2.0...
        insertionIndex =
            "NaN".equals(insertionIndexString)
                ? collectionToBeUpdated.size()
                : Integer.parseInt(insertionIndexString);

        // Adjust index to be in range
        if (insertionIndex > collectionToBeUpdated.size())
          insertionIndex = collectionToBeUpdated.size();

        if (insertionIndex < 1) insertionIndex = 1;
      }
    }

    final String normalizedPosition;
    {
      if (resolvedPositionAttribute == null) {
        // Default value
        normalizedPosition = "after";
      } else if ("after".equals(resolvedPositionAttribute)
          || "before".equals(resolvedPositionAttribute)) {
        // Specified value
        normalizedPosition = resolvedPositionAttribute;
      } else {
        // Invalid value
        if (indentedLogger.isInfoEnabled())
          indentedLogger.logWarning(
              "xf:insert",
              "invalid position attribute, defaulting to \"after\"",
              "value",
              resolvedPositionAttribute);

        normalizedPosition = "after";
      }
    }

    doInsert(
        containingDocument,
        indentedLogger,
        normalizedPosition,
        collectionToBeUpdated,
        (NodeInfo) insertContextItem,
        originObjects,
        insertionIndex,
        true,
        true,
        setRequireDefaultValues);
  }