gt:             Serializer serializer = broker.getSerializer();
context: package org.exist.xquery;
  
  import java.io.IOException;
  import java.nio.file.Path;
  import java.nio.file.Paths;
  import java.util.Optional;
  
  import org.exist.EXistException;
  import org.exist.collections.Collection;
  import org.exist.collections.IndexInfo;
  import org.exist.dom.persistent.DocumentImpl;
  import org.exist.security.PermissionDeniedException;
  import org.exist.storage.BrokerPool;
  import org.exist.storage.DBBroker;
  import org.exist.storage.serializers.Serializer;
  import org.exist.storage.txn.TransactionManager;
  import org.exist.storage.txn.Txn;
  import org.exist.util.Configuration;
  import org.exist.util.DatabaseConfigurationException;
  import org.exist.util.LockException;
  import org.exist.xmldb.XmldbURI;
  import org.exist.xquery.value.NodeValue;
  import org.exist.xquery.value.Sequence;
  import org.junit.After;
  import org.junit.Before;
  import org.junit.Ignore;
  import org.junit.Test;
  import org.xml.sax.SAXException;
  
  import static org.junit.Assert.assertEquals;
  
  public class XQueryUpdateTest {
  
      protected static XmldbURI TEST_COLLECTION = XmldbURI.create(XmldbURI.ROOT_COLLECTION + "/test");
  
      protected static String TEST_XML =
              "<?xml version=\"1.0\"?>" +
                      "<products/>";
  
      protected static String UPDATE_XML =
              "<progress total=\"100\" done=\"0\" failed=\"0\" passed=\"0\"/>";
  
      protected final static int ITEMS_TO_APPEND = 1000;
  
      private BrokerPool pool;
  
      @Test
      public void append() throws EXistException, PermissionDeniedException, XPathException, SAXException {
          try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
  
              XQuery xquery = pool.getXQueryService();
              String query =
              	"   declare variable $i external;\n" +
              	"	update insert\n" +
              	"		<product id='id{$i}' num='{$i}'>\n" +
              	"			<description>Description {$i}</description>\n" +
              	"			<price>{$i + 1.0}</price>\n" +
              	"			<stock>{$i * 10}</stock>\n" +
              	"		</product>\n" +
              	"	into /products";
              XQueryContext context = new XQueryContext(pool);
              CompiledXQuery compiled = xquery.compile(broker, context, query);
              for (int i = 0; i < ITEMS_TO_APPEND; i++) {
                  context.declareVariable("i", Integer.valueOf(i));
                  xquery.execute(broker, compiled, null);
              }
  
              Sequence seq = xquery.execute(broker, "/products", null);
              assertEquals(seq.getItemCount(), 1);
  
              Serializer serializer = broker.getSerializer();
              serializer.serialize((NodeValue) seq.itemAt(0));
  
              seq = xquery.execute(broker, "//product", null);
              assertEquals(ITEMS_TO_APPEND, seq.getItemCount());
  
              seq = xquery.execute(broker, "//product[price > 0.0]", null);
              assertEquals(ITEMS_TO_APPEND, seq.getItemCount());
          }
      }
  
      @Test
      public void appendAttributes() throws EXistException, PermissionDeniedException, XPathException, SAXException, LockException, IOException {
  
          append();
  
          try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
  
              XQuery xquery = pool.getXQueryService();
              String query =
              	"   declare variable $i external;\n" +
              	"	update insert\n" +
              	"		attribute name { concat('n', $i) }\n" +
              	"	into //product[@num = $i]";
              XQueryContext context = new XQueryContext(pool);
              CompiledXQuery compiled = xquery.compile(broker, context, query);
              for (int i = 0; i < ITEMS_TO_APPEND; i++) {
                  context.declareVariable("i", Integer.valueOf(i));
                  xquery.execute(broker, compiled, null);
              }
  
              Sequence seq = xquery.execute(broker, "/products", null);
              assertEquals(seq.getItemCount(), 1);
  
              Serializer serializer = broker.getSerializer();
              serializer.serialize((NodeValue) seq.itemAt(0));
  
              seq = xquery.execute(broker, "//product", null);
              assertEquals(ITEMS_TO_APPEND, seq.getItemCount());
  
              seq = xquery.execute(broker, "//product[@name = 'n20']", null);
              assertEquals(1, seq.getItemCount());
  
              store(broker, "attribs.xml", "<test attr1='aaa' attr2='bbb'>ccc</test>");
              query = "update insert attribute attr1 { 'eee' } into /test";
  
              //testing duplicate attribute ...
              xquery.execute(broker, query, null);
  
              seq = xquery.execute(broker, "xmldb:document('" + TEST_COLLECTION + "/attribs.xml')/test[@attr1 = 'eee']", null);
              assertEquals(1, seq.getItemCount());
              serializer.serialize((NodeValue) seq.itemAt(0));
          }
      }
  
      @Test
      public void insertBefore() throws EXistException, PermissionDeniedException, XPathException, SAXException {
          try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
  
              String query =
                      "   update insert\n" +
                              "       <product id='original'>\n" +
                              "           <description>Description</description>\n" +
                              "           <price>0</price>\n" +
                              "           <stock>10</stock>\n" +
                              "       </product>\n" +
                              "   into /products";
  
              XQuery xquery = pool.getXQueryService();
              xquery.execute(broker, query, null);
  
              query =
                  "   declare variable $i external;\n" +
                  "   update insert\n" +
                  "       <product id='id{$i}'>\n" +
                  "           <description>Description {$i}</description>\n" +
                  "           <price>{$i + 1.0}</price>\n" +
                  "           <stock>{$i * 10}</stock>\n" +
                  "       </product>\n" +
                  "   preceding /products/product[1]";
              XQueryContext context = new XQueryContext(pool);
              CompiledXQuery compiled = xquery.compile(broker, context, query);
              for (int i = 0; i < ITEMS_TO_APPEND; i++) {
                  context.declareVariable("i", Integer.valueOf(i));
                  xquery.execute(broker, compiled, null);
              }
  
              Sequence seq = xquery.execute(broker, "/products", null);
              assertEquals(seq.getItemCount(), 1);
  
              Serializer serializer = broker.getSerializer();
              serializer.serialize((NodeValue) seq.itemAt(0));
  
              seq = xquery.execute(broker, "//product", null);
              assertEquals(ITEMS_TO_APPEND + 1, seq.getItemCount());
  
              seq = xquery.execute(broker, "//product[price > 0.0]", null);
              assertEquals(ITEMS_TO_APPEND, seq.getItemCount());
          }
      }
  
      @Test
      public void insertAfter() throws EXistException, PermissionDeniedException, XPathException, SAXException {
          try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
  
              String query =
                      "   update insert\n" +
                              "       <product id='original'>\n" +
                              "           <description>Description</description>\n" +
                              "           <price>0</price>\n" +
                              "           <stock>10</stock>\n" +
                              "       </product>\n" +
                              "   into /products";
  
              XQuery xquery = pool.getXQueryService();
              xquery.execute(broker, query, null);
  
              query =
                  "   declare variable $i external;\n" +
                  "   update insert\n" +
                  "       <product id='id{$i}'>\n" +
                  "           <description>Description {$i}</description>\n" +
                  "           <price>{$i + 1.0}</price>\n" +
                  "           <stock>{$i * 10}</stock>\n" +
                  "       </product>\n" +
                  "   following /products/product[1]";
              XQueryContext context = new XQueryContext(pool);
              CompiledXQuery compiled = xquery.compile(broker, context, query);
              for (int i = 0; i < ITEMS_TO_APPEND; i++) {
                  context.declareVariable("i", Integer.valueOf(i));
                  xquery.execute(broker, compiled, null);
              }
  
              Sequence seq = xquery.execute(broker, "/products", null);
              assertEquals(seq.getItemCount(), 1);
  
              Serializer serializer = broker.getSerializer();
              serializer.serialize((NodeValue) seq.itemAt(0));
  
              seq = xquery.execute(broker, "//product", null);
              assertEquals(ITEMS_TO_APPEND + 1, seq.getItemCount());
  
              seq = xquery.execute(broker, "//product[price > 0.0]", null);
              assertEquals(ITEMS_TO_APPEND, seq.getItemCount());
          }
      }
  
      @Test
      public void update() throws EXistException, PermissionDeniedException, XPathException, SAXException {
  
          append();
  
          try(final DBBroker broker = pool.get(Optional.of(pool.getSecurityManager().getSystemSubject()))) {
  
              XQuery xquery = pool.getXQueryService();
  
              String query =
              	"declare option exist:output-size-limit '-1';\n" +
              	"for $prod at $i in //product return\n" +
                  "	update value $prod/description\n" +
                  "	with concat('Updated Description', $i)";
              Sequence seq = xquery.execute(broker, query, null);
  
              seq = xquery.execute(broker, "//product[starts-with(description, 'Updated')]", null);
              assertEquals(seq.getItemCount(), ITEMS_TO_APPEND);
  
  