@Test
    public void testModifyDocument() {
        Document doc = new Document(testDocType, new DocumentId("id:ns:testdoc::"));
        doc.setFieldValue("primitive1", 1);

        Struct l1s1 = new Struct(doc.getField("l1s1").getDataType());
        l1s1.setFieldValue("primitive1", 2);

        Struct l2s1 = new Struct(doc.getField("struct2").getDataType());
        l2s1.setFieldValue("primitive1", 3);
        l2s1.setFieldValue("primitive2", 4);

        Array<IntegerFieldValue> iarr1 = new Array<>(l2s1.getField("iarray").getDataType());
        iarr1.add(new IntegerFieldValue(11));
        iarr1.add(new IntegerFieldValue(12));
        iarr1.add(new IntegerFieldValue(13));
        l2s1.setFieldValue("iarray", iarr1);

        ArrayDataType dt = (ArrayDataType)l2s1.getField("sarray").getDataType();
        Array<Struct> sarr1 = new Array<>(dt);
        {
            Struct l3s1 = new Struct(dt.getNestedType());
            l3s1.setFieldValue("primitive1", 1);
            l3s1.setFieldValue("primitive2", 2);
            sarr1.add(l3s1);
        }
        {
            Struct l3s1 = new Struct(dt.getNestedType());
            l3s1.setFieldValue("primitive1", 1);
            l3s1.setFieldValue("primitive2", 2);
            sarr1.add(l3s1);
        }
        l2s1.setFieldValue("sarray", sarr1);

        MapFieldValue<StringFieldValue, StringFieldValue> smap1 = new MapFieldValue<>((MapDataType)l2s1.getField("smap").getDataType());
        smap1.put(new StringFieldValue("leonardo"), new StringFieldValue("dicaprio"));
        smap1.put(new StringFieldValue("ellen"), new StringFieldValue("page"));
        smap1.put(new StringFieldValue("joseph"), new StringFieldValue("gordon-levitt"));
        l2s1.setFieldValue("smap", smap1);

        l1s1.setFieldValue("ss", l2s1.clone());

        MapFieldValue<StringFieldValue, Struct> structmap1 = new MapFieldValue<>((MapDataType)l1s1.getField("structmap").getDataType());
        structmap1.put(new StringFieldValue("test"), l2s1.clone());
        l1s1.setFieldValue("structmap", structmap1);

        WeightedSet<StringFieldValue> wset1 = new WeightedSet<>(l1s1.getField("wset").getDataType());
        wset1.add(new StringFieldValue("foo"));
        wset1.add(new StringFieldValue("bar"));
        wset1.add(new StringFieldValue("zoo"));
        l1s1.setFieldValue("wset", wset1);

        Struct l2s2 = new Struct(doc.getField("struct2").getDataType());
        l2s2.setFieldValue("primitive1", 5);
        l2s2.setFieldValue("primitive2", 6);

        WeightedSet<Struct> wset2 = new WeightedSet<>(l1s1.getField("structwset").getDataType());
        wset2.add(l2s1.clone());
        wset2.add(l2s2.clone());
        l1s1.setFieldValue("structwset", wset2);

        doc.setFieldValue("l1s1", l1s1.clone());

        {
            ModifyIteratorHandler handler = new ModifyIteratorHandler();

            FieldPath path = doc.getDataType().buildFieldPath("l1s1.structmap.value.smap{leonardo}");
            doc.iterateNested(path, 0, handler);

            FieldValue fv = doc.getRecursiveValue("l1s1.structmap.value.smap{leonardo}");
            assertEquals(new StringFieldValue("newvalue"), fv);
        }

        {
            AddIteratorHandler handler = new AddIteratorHandler();
            FieldPath path = doc.getDataType().buildFieldPath("l1s1.ss.iarray");
            doc.iterateNested(path, 0, handler);

            FieldValue fv = doc.getRecursiveValue("l1s1.ss.iarray");
            assertTrue(((Array<?>)fv).contains(new IntegerFieldValue(32)));
            assertEquals(4, ((Array<?>)fv).size());
        }

        {
            RemoveIteratorHandler handler = new RemoveIteratorHandler();
            FieldPath path = doc.getDataType().buildFieldPath("l1s1.ss.iarray[1]");
            doc.iterateNested(path, 0, handler);

            FieldValue fv = doc.getRecursiveValue("l1s1.ss.iarray");

            assertFalse(((Array<?>)fv).contains(12));
            assertEquals(3, ((Array<?>)fv).size());
        }

        {
            RemoveIteratorHandler handler = new RemoveIteratorHandler();
            FieldPath path = doc.getDataType().buildFieldPath("l1s1.ss.iarray[$x]");
            doc.iterateNested(path, 0, handler);

            FieldValue fv = doc.getRecursiveValue("l1s1.ss.iarray");
            assertEquals(0, ((Array<?>)fv).size());
        }

        {
            RemoveIteratorHandler handler = new RemoveIteratorHandler();
            FieldPath path = doc.getDataType().buildFieldPath("l1s1.structmap.value.smap{leonardo}");
            doc.iterateNested(path, 0, handler);

            FieldValue fv = doc.getRecursiveValue("l1s1.structmap.value.smap");
            assertFalse(((MapFieldValue<?, ?>)fv).contains(new StringFieldValue("leonardo")));
        }

        {
            RemoveIteratorHandler handler = new RemoveIteratorHandler();
            FieldPath path = doc.getDataType().buildFieldPath("l1s1.wset{foo}");
            doc.iterateNested(path, 0, handler);

            FieldValue fv = doc.getRecursiveValue("l1s1.wset");
            assertFalse(((WeightedSet<?>)fv).contains(new StringFieldValue("foo")));
        }
    }
Test for Document and all its features, including (de)serialization.

@author Thomas Gundersen
@author bratseth
document/src/test/java/com/yahoo/document/DocumentTestCase.java