bool FnZorbaParseXmlFragmentIterator::nextImpl(
    store::Item_t& result,
    PlanState& planState) const
{
  store::Store& lStore = GENV.getStore();
  zstring docString;
  store::Item_t tempItem;
  bool validated = true;

  FnZorbaParseXmlFragmentIteratorState* state;
  DEFAULT_STACK_INIT(FnZorbaParseXmlFragmentIteratorState, state, planState);

  if (consumeNext(result, theChildren[0].getp(), planState))
  {
    if (result->isStreamable())
    {
      state->theFragmentStream.theStream = &result->getStream();
      state->theFragmentStream.setStreamReleaser(result->getStreamReleaser());
      result->setStreamReleaser(nullptr);
    }
    else
    {
      result->getStringValue2(docString);
      state->theFragmentStream.theIss = new std::istringstream(docString.c_str());
      state->theFragmentStream.theStream = state->theFragmentStream.theIss;
    }

    // read options
    consumeNext(tempItem, theChildren[1].getp(), planState);
    state->theProperties.setBaseUri(theSctx->get_base_uri());
    state->theProperties.setStoreDocument(false);
    state->theProperties.setUseCachedDocument(false);
    processOptions(tempItem, state->theProperties, theSctx, loc);
    state->theProperties.setCreateDocParentLink(false);

    // baseURI serves both as the base URI used by the XML parser
    // to resolve relative entity references within the document,
    // and as the base URI of the document node that is returned.
    state->baseUri = state->theProperties.getBaseUri();
    state->docUri = state->theProperties.getBaseUri();


    ////////////////////////////////////////////////////////////////////////
    // External parsed entity processing
    ////////////////////////////////////////////////////////////////////////
    if (state->theProperties.getParseExternalParsedEntity())
    {
      state->theFragmentStream.root_elements_to_skip =
      state->theProperties.getSkipRootNodes();

      while ( ! state->theFragmentStream.stream_is_consumed())
      {
        try
        {
          result = lStore.loadDocument(state->baseUri,
                                       state->docUri,
                                       state->theFragmentStream,
                                       state->theProperties);
        }
        catch ( ZorbaException const &e )
        {
          if ( !state->theProperties.getNoError() )
          {
            XQueryException xe(
              XQUERY_EXCEPTION(
                err::FODC0006,
                ERROR_PARAMS( "parse-xml:parse()", e.what() ),
                ERROR_LOC( loc )
              )
            );
            set_data( xe, e );
            throw xe;
          }
          result = nullptr;
        }

        if (result == NULL)
          continue;

        // Return the children of document node
        state->theFragmentStream.children = result->getChildren();
        while (state->theFragmentStream.children->next(result) && result != NULL)
        {
          if (state->theProperties.getSkipTopLevelTextNodes() && result->getNodeKind() == store::StoreConsts::textNode)
            continue;

          STACK_PUSH(true, state);
        }
      }
    }
    ////////////////////////////////////////////////////////////////////////
    // XML document processing
    ////////////////////////////////////////////////////////////////////////
    else  // if (!state->theProperties.getEnableExtParsedEntity())
    {
      try 
      {
        result = lStore.loadDocument(state->baseUri, state->docUri, *state->theFragmentStream.theStream, state->theProperties);
      }
      catch ( ZorbaException const &e )
      {
        if ( !state->theProperties.getNoError() )
        {
          XQueryException xe(
            XQUERY_EXCEPTION(
              err::FODC0006,
              ERROR_PARAMS( "parse-xml:parse()", e.what() ),
              ERROR_LOC( loc )
            )
          );
          set_data( xe, e );
          throw xe;
        }
        result = nullptr;
      }

      if (result != NULL)
      {
#ifndef ZORBA_NO_XMLSCHEMA
        if (state->theProperties.getSchemaLaxValidate() ||
            state->theProperties.getSchemaStrictValidate())
        {
          try
          {
            tempItem = NULL; // used as the effectiveValidationValue()'s typeName
            validated = Validator::effectiveValidationValue(
                          result,
                          result,
                          tempItem,
                          theSctx->get_typemanager(),
                          state->theProperties.getSchemaLaxValidate() ? ParseConstants::val_lax : ParseConstants::val_strict,
                          theSctx,
                          this->loc);
          }
          catch (ZorbaException& /*e*/)
          {
            if ( ! state->theProperties.getNoError())
              throw;
            else
            {
              result = NULL;
              validated = false;
            }
          }
        }
#endif
        // Ignore the schema validation options if Zorba is built without schema support

        STACK_PUSH(validated, state);
      } // if (result != NULL)
    } // if (state->theProperties.getEnableExtParsedEntity())
  } // if (consumeNext(result, theChildren[0].getp(), planState))

  STACK_END(state);
}