Index: examples/src/main/java/org/apache/pdfbox/examples/pdmodel/CreateBookmarks.java
===================================================================
--- examples/src/main/java/org/apache/pdfbox/examples/pdmodel/CreateBookmarks.java	(revisione 1658902)
+++ examples/src/main/java/org/apache/pdfbox/examples/pdmodel/CreateBookmarks.java	(copia locale)
@@ -25,8 +25,7 @@
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
 
 /**
- * This is an example on how to add bookmarks to a PDF document.  It simply
- * adds 1 bookmark for every page.
+ * This is an example on how to add bookmarks to a PDF document. It simply adds 1 bookmark for every page.
  *
  * Usage: java org.apache.pdfbox.examples.pdmodel.CreateBookmarks &lt;input-pdf&gt; &lt;output-pdf&gt;
  *
@@ -36,7 +35,7 @@
 {
     private CreateBookmarks()
     {
-        //utility class
+        // utility class
     }
 
     /**
@@ -46,9 +45,9 @@
      *
      * @throws Exception If there is an error parsing the document.
      */
-    public static void main( String[] args ) throws Exception
+    public static void main(String[] args) throws Exception
     {
-        if( args.length != 2 )
+        if (args.length != 2)
         {
             usage();
         }
@@ -57,36 +56,35 @@
             PDDocument document = null;
             try
             {
-                document = PDDocument.load( new File(args[0]) );
-                if( document.isEncrypted() )
+                document = PDDocument.load(new File(args[0]));
+                if (document.isEncrypted())
                 {
-                    System.err.println( "Error: Cannot add bookmarks to encrypted document." );
-                    System.exit( 1 );
+                    System.err.println("Error: Cannot add bookmarks to encrypted document.");
+                    System.exit(1);
                 }
-                PDDocumentOutline outline =  new PDDocumentOutline();
-                document.getDocumentCatalog().setDocumentOutline( outline );
+                PDDocumentOutline outline = new PDDocumentOutline();
+                document.getDocumentCatalog().setDocumentOutline(outline);
                 PDOutlineItem pagesOutline = new PDOutlineItem();
-                pagesOutline.setTitle( "All Pages" );
-                outline.appendChild( pagesOutline );
+                pagesOutline.setTitle("All Pages");
+                outline.addLast(pagesOutline);
                 int pageNum = 0;
-                for( PDPage page : document.getPages() )
+                for (PDPage page : document.getPages())
                 {
                     pageNum++;
                     PDPageFitWidthDestination dest = new PDPageFitWidthDestination();
-                    dest.setPage( page );
+                    dest.setPage(page);
                     PDOutlineItem bookmark = new PDOutlineItem();
-                    bookmark.setDestination( dest );
-                    bookmark.setTitle( "Page " + pageNum );
-                    pagesOutline.appendChild( bookmark );
+                    bookmark.setDestination(dest);
+                    bookmark.setTitle("Page " + pageNum);
+                    pagesOutline.addLast(bookmark);
                 }
                 pagesOutline.openNode();
-                outline.openNode();
 
-                document.save( args[1] );
+                document.save(args[1]);
             }
             finally
             {
-                if( document != null )
+                if (document != null)
                 {
                     document.close();
                 }
@@ -99,6 +97,7 @@
      */
     private static void usage()
     {
-        System.err.println( "Usage: java org.apache.pdfbox.examples.pdmodel.CreateBookmarks <input-pdf> <output-pdf>" );
+        System.err
+                .println("Usage: java org.apache.pdfbox.examples.pdmodel.CreateBookmarks <input-pdf> <output-pdf>");
     }
 }
Index: examples/src/main/java/org/apache/pdfbox/examples/pdmodel/PrintBookmarks.java
===================================================================
--- examples/src/main/java/org/apache/pdfbox/examples/pdmodel/PrintBookmarks.java	(revisione 1658902)
+++ examples/src/main/java/org/apache/pdfbox/examples/pdmodel/PrintBookmarks.java	(copia locale)
@@ -16,14 +16,14 @@
  */
 package org.apache.pdfbox.examples.pdmodel;
 
+import java.io.File;
+import java.io.IOException;
+
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineNode;
 
-import java.io.File;
-import java.io.IOException;
-
 /**
  * This is an example on how to access the bookmarks that are part of a pdf document.
  *
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDDictionaryWrapper.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDDictionaryWrapper.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDDictionaryWrapper.java	(copia locale)
@@ -16,7 +16,6 @@
  */
 package org.apache.pdfbox.pdmodel.common;
 
-import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
 
 /**
@@ -50,26 +49,12 @@
     }
 
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
-    public COSBase getCOSObject()
+    public COSDictionary getCOSObject()
     {
         return this.dictionary;
     }
 
-    /**
-     * Gets the COS dictionary.
-     * 
-     * @return the COS dictionary
-     */
-    protected COSDictionary getCOSDictionary()
-    {
-        return this.dictionary;
-    }
-
-
     @Override
     public boolean equals(Object obj)
     {
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDTypedDictionaryWrapper.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDTypedDictionaryWrapper.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/common/PDTypedDictionaryWrapper.java	(copia locale)
@@ -37,7 +37,7 @@
     public PDTypedDictionaryWrapper(String type)
     {
         super();
-        this.getCOSDictionary().setName(COSName.TYPE, type);
+        this.getCOSObject().setName(COSName.TYPE, type);
     }
 
     /**
@@ -58,7 +58,7 @@
      */
     public String getType()
     {
-        return this.getCOSDictionary().getNameAsString(COSName.TYPE);
+        return this.getCOSObject().getNameAsString(COSName.TYPE);
     }
 
     // There is no setType(String) method because changing the Type would most
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDAttributeObject.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDAttributeObject.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDAttributeObject.java	(copia locale)
@@ -126,7 +126,7 @@
      */
     public String getOwner()
     {
-        return this.getCOSDictionary().getNameAsString(COSName.O);
+        return this.getCOSObject().getNameAsString(COSName.O);
     }
 
     /**
@@ -136,7 +136,7 @@
      */
     protected void setOwner(String owner)
     {
-        this.getCOSDictionary().setName(COSName.O, owner);
+        this.getCOSObject().setName(COSName.O, owner);
     }
 
     /**
@@ -148,7 +148,7 @@
     public boolean isEmpty()
     {
         // only entry is the owner?
-        return (this.getCOSDictionary().size() == 1) && (this.getOwner() != null);
+        return (this.getCOSObject().size() == 1) && (this.getOwner() != null);
     }
 
 
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDDefaultAttributeObject.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDDefaultAttributeObject.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDDefaultAttributeObject.java	(copia locale)
@@ -60,7 +60,7 @@
     public List<String> getAttributeNames()
     {
         List<String> attrNames = new ArrayList<String>();
-        for (Entry<COSName, COSBase> entry : this.getCOSDictionary().entrySet())
+        for (Entry<COSName, COSBase> entry : this.getCOSObject().entrySet())
         {
             COSName key = entry.getKey();
             if (!COSName.O.equals(key))
@@ -79,7 +79,7 @@
      */
     public COSBase getAttributeValue(String attrName)
     {
-        return this.getCOSDictionary().getDictionaryObject(attrName);
+        return this.getCOSObject().getDictionaryObject(attrName);
     }
 
     /**
@@ -91,7 +91,7 @@
      */
     protected COSBase getAttributeValue(String attrName, COSBase defaultValue)
     {
-        COSBase value = this.getCOSDictionary().getDictionaryObject(attrName);
+        COSBase value = this.getCOSObject().getDictionaryObject(attrName);
         if (value == null)
         {
             return defaultValue;
@@ -108,7 +108,7 @@
     public void setAttribute(String attrName, COSBase attrValue)
     {
         COSBase old = this.getAttributeValue(attrName);
-        this.getCOSDictionary().setItem(COSName.getPDFName(attrName), attrValue);
+        this.getCOSObject().setItem(COSName.getPDFName(attrName), attrValue);
         this.potentiallyNotifyChanged(old, attrValue);
     }
 
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDUserAttributeObject.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDUserAttributeObject.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDUserAttributeObject.java	(copia locale)
@@ -63,7 +63,7 @@
      */
     public List<PDUserProperty> getOwnerUserProperties()
     {
-        COSArray p = (COSArray) this.getCOSDictionary()
+        COSArray p = (COSArray) this.getCOSObject()
             .getDictionaryObject(COSName.P);
         List<PDUserProperty> properties = new ArrayList<PDUserProperty>(p.size());
         for (int i = 0; i < p.size(); i++)
@@ -86,7 +86,7 @@
         {
             p.add(userProperty);
         }
-        this.getCOSDictionary().setItem(COSName.P, p);
+        this.getCOSObject().setItem(COSName.P, p);
     }
 
     /**
@@ -96,7 +96,7 @@
      */
     public void addUserProperty(PDUserProperty userProperty)
     {
-        COSArray p = (COSArray) this.getCOSDictionary()
+        COSArray p = (COSArray) this.getCOSObject()
             .getDictionaryObject(COSName.P);
         p.add(userProperty);
         this.notifyChanged();
@@ -113,7 +113,7 @@
         {
             return;
         }
-        COSArray p = (COSArray) this.getCOSDictionary()
+        COSArray p = (COSArray) this.getCOSObject()
             .getDictionaryObject(COSName.P);
         p.remove(userProperty.getCOSObject());
         this.notifyChanged();
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDUserProperty.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDUserProperty.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/logicalstructure/PDUserProperty.java	(copia locale)
@@ -63,7 +63,7 @@
      */
     public String getName()
     {
-        return this.getCOSDictionary().getNameAsString(COSName.N);
+        return this.getCOSObject().getNameAsString(COSName.N);
     }
 
     /**
@@ -74,7 +74,7 @@
     public void setName(String name)
     {
         this.potentiallyNotifyChanged(this.getName(), name);
-        this.getCOSDictionary().setName(COSName.N, name);
+        this.getCOSObject().setName(COSName.N, name);
     }
 
     /**
@@ -84,7 +84,7 @@
      */
     public COSBase getValue()
     {
-        return this.getCOSDictionary().getDictionaryObject(COSName.V);
+        return this.getCOSObject().getDictionaryObject(COSName.V);
     }
 
     /**
@@ -95,7 +95,7 @@
     public void setValue(COSBase value)
     {
         this.potentiallyNotifyChanged(this.getValue(), value);
-        this.getCOSDictionary().setItem(COSName.V, value);
+        this.getCOSObject().setItem(COSName.V, value);
     }
 
     /**
@@ -105,7 +105,7 @@
      */
     public String getFormattedValue()
     {
-        return this.getCOSDictionary().getString(COSName.F);
+        return this.getCOSObject().getString(COSName.F);
     }
 
     /**
@@ -116,7 +116,7 @@
     public void setFormattedValue(String formattedValue)
     {
         this.potentiallyNotifyChanged(this.getFormattedValue(), formattedValue);
-        this.getCOSDictionary().setString(COSName.F, formattedValue);
+        this.getCOSObject().setString(COSName.F, formattedValue);
     }
 
     /**
@@ -127,7 +127,7 @@
      */
     public boolean isHidden()
     {
-        return this.getCOSDictionary().getBoolean(COSName.H, false);
+        return this.getCOSObject().getBoolean(COSName.H, false);
     }
 
     /**
@@ -139,7 +139,7 @@
     public void setHidden(boolean hidden)
     {
         this.potentiallyNotifyChanged(this.isHidden(), hidden);
-        this.getCOSDictionary().setBoolean(COSName.H, hidden);
+        this.getCOSObject().setBoolean(COSName.H, hidden);
     }
 
 
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/taggedpdf/PDLayoutAttributeObject.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/taggedpdf/PDLayoutAttributeObject.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/taggedpdf/PDLayoutAttributeObject.java	(copia locale)
@@ -842,7 +842,7 @@
     public PDRectangle getBBox()
     {
         COSArray array =
-            (COSArray) this.getCOSDictionary().getDictionaryObject(BBOX);
+ (COSArray) this.getCOSObject().getDictionaryObject(BBOX);
         if (array != null)
         {
             return new PDRectangle(array);
@@ -858,8 +858,8 @@
     public void setBBox(PDRectangle bbox)
     {
         String name = BBOX;
-        COSBase oldValue = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setItem(name, bbox);
+        COSBase oldValue = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setItem(name, bbox);
         COSBase newValue = bbox == null ? null : bbox.getCOSObject();
         this.potentiallyNotifyChanged(oldValue, newValue);
     }
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/taggedpdf/PDStandardAttributeObject.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/taggedpdf/PDStandardAttributeObject.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/documentinterchange/taggedpdf/PDStandardAttributeObject.java	(copia locale)
@@ -62,7 +62,7 @@
      */
     public boolean isSpecified(String name)
     {
-        return this.getCOSDictionary().getDictionaryObject(name) != null;
+        return this.getCOSObject().getDictionaryObject(name) != null;
     }
 
 
@@ -74,7 +74,7 @@
      */
     protected String getString(String name)
     {
-        return this.getCOSDictionary().getString(name);
+        return this.getCOSObject().getString(name);
     }
 
     /**
@@ -85,9 +85,9 @@
      */
     protected void setString(String name, String value)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setString(name, value);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setString(name, value);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -99,7 +99,7 @@
      */
     protected String[] getArrayOfString(String name)
     {
-        COSBase v = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase v = this.getCOSObject().getDictionaryObject(name);
         if (v instanceof COSArray)
         {
             COSArray array = (COSArray) v;
@@ -121,14 +121,14 @@
      */
     protected void setArrayOfString(String name, String[] values)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
         COSArray array = new COSArray();
         for (String value : values)
         {
             array.add(new COSString(value));
         }
-        this.getCOSDictionary().setItem(name, array);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        this.getCOSObject().setItem(name, array);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -140,7 +140,7 @@
      */
     protected String getName(String name)
     {
-        return this.getCOSDictionary().getNameAsString(name);
+        return this.getCOSObject().getNameAsString(name);
     }
 
     /**
@@ -152,7 +152,7 @@
      */
     protected String getName(String name, String defaultValue)
     {
-        return this.getCOSDictionary().getNameAsString(name, defaultValue);
+        return this.getCOSObject().getNameAsString(name, defaultValue);
     }
 
     /**
@@ -164,7 +164,7 @@
      */
     protected Object getNameOrArrayOfName(String name, String defaultValue)
     {
-        COSBase v = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase v = this.getCOSObject().getDictionaryObject(name);
         if (v instanceof COSArray)
         {
             COSArray array = (COSArray) v;
@@ -194,9 +194,9 @@
      */
     protected void setName(String name, String value)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setName(name, value);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setName(name, value);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -208,14 +208,14 @@
      */
     protected void setArrayOfName(String name, String[] values)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
         COSArray array = new COSArray();
         for (String value : values)
         {
             array.add(COSName.getPDFName(value));
         }
-        this.getCOSDictionary().setItem(name, array);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        this.getCOSObject().setItem(name, array);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -228,7 +228,7 @@
      */
     protected Object getNumberOrName(String name, String defaultValue)
     {
-        COSBase value = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase value = this.getCOSObject().getDictionaryObject(name);
         if (value instanceof COSNumber)
         {
             return ((COSNumber) value).floatValue();
@@ -249,7 +249,7 @@
      */
     protected int getInteger(String name, int defaultValue)
     {
-        return this.getCOSDictionary().getInt(name, defaultValue);
+        return this.getCOSObject().getInt(name, defaultValue);
     }
 
     /**
@@ -260,9 +260,9 @@
      */
     protected void setInteger(String name, int value)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setInt(name, value);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setInt(name, value);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -275,7 +275,7 @@
      */
     protected float getNumber(String name, float defaultValue)
     {
-        return this.getCOSDictionary().getFloat(name, defaultValue);
+        return this.getCOSObject().getFloat(name, defaultValue);
     }
 
     /**
@@ -286,7 +286,7 @@
      */
     protected float getNumber(String name)
     {
-        return this.getCOSDictionary().getFloat(name);
+        return this.getCOSObject().getFloat(name);
     }
 
     /**
@@ -303,7 +303,7 @@
      */
     protected Object getNumberOrArrayOfNumber(String name, float defaultValue)
     {
-        COSBase v = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase v = this.getCOSObject().getDictionaryObject(name);
         if (v instanceof COSArray)
         {
             COSArray array = (COSArray) v;
@@ -337,9 +337,9 @@
      */
     protected void setNumber(String name, float value)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setFloat(name, value);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setFloat(name, value);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -351,9 +351,9 @@
      */
     protected void setNumber(String name, int value)
     {
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setInt(name, value);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setInt(name, value);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -370,9 +370,9 @@
         {
             array.add(new COSFloat(values[i]));
         }
-        COSBase oldBase = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setItem(name, array);
-        COSBase newBase = this.getCOSDictionary().getDictionaryObject(name);
+        COSBase oldBase = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setItem(name, array);
+        COSBase newBase = this.getCOSObject().getDictionaryObject(name);
         this.potentiallyNotifyChanged(oldBase, newBase);
     }
 
@@ -384,7 +384,7 @@
      */
     protected PDGamma getColor(String name)
     {
-        COSArray c = (COSArray) this.getCOSDictionary().getDictionaryObject(name);
+        COSArray c = (COSArray) this.getCOSObject().getDictionaryObject(name);
         if (c != null)
         {
             return new PDGamma(c);
@@ -401,7 +401,7 @@
     protected Object getColorOrFourColors(String name)
     {
         COSArray array =
-            (COSArray) this.getCOSDictionary().getDictionaryObject(name);
+ (COSArray) this.getCOSObject().getDictionaryObject(name);
         if (array == null)
         {
             return null;
@@ -426,8 +426,8 @@
      */
     protected void setColor(String name, PDGamma value)
     {
-        COSBase oldValue = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setItem(name, value);
+        COSBase oldValue = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setItem(name, value);
         COSBase newValue = value == null ? null : value.getCOSObject();
         this.potentiallyNotifyChanged(oldValue, newValue);
     }
@@ -440,8 +440,8 @@
      */
     protected void setFourColors(String name, PDFourColours value)
     {
-        COSBase oldValue = this.getCOSDictionary().getDictionaryObject(name);
-        this.getCOSDictionary().setItem(name, value);
+        COSBase oldValue = this.getCOSObject().getDictionaryObject(name);
+        this.getCOSObject().setItem(name, value);
         COSBase newValue = value == null ? null : value.getCOSObject();
         this.potentiallyNotifyChanged(oldValue, newValue);
     }
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDDocumentOutline.java	(copia locale)
@@ -25,25 +25,38 @@
  * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
  * @version $Revision: 1.2 $
  */
-public class PDDocumentOutline extends PDOutlineNode
+public final class PDDocumentOutline extends PDOutlineNode
 {
 
-    /**
-     * Default Constructor.
-     */
     public PDDocumentOutline()
     {
-        super();
-        node.setName( COSName.TYPE, "Outlines" );
+        getCOSObject().setName(COSName.TYPE, COSName.OUTLINES.getName());
     }
 
     /**
-     * Constructor for an existing document outline.
-     *
      * @param dic The storage dictionary.
      */
-    public PDDocumentOutline( COSDictionary dic )
+    public PDDocumentOutline(COSDictionary dic)
     {
-        super( dic );
+        super(dic);
+        getCOSObject().setName(COSName.TYPE, COSName.OUTLINES.getName());
     }
+
+    @Override
+    public boolean isNodeOpen()
+    {
+        return true;
+    }
+
+    @Override
+    public void openNode()
+    {
+        // The root of the outline hierarchy is not an OutlineItem and cannot be opened or closed
+    }
+
+    @Override
+    public void closeNode()
+    {
+        // The root of the outline hierarchy is not an OutlineItem and cannot be opened or closed
+    }
 }
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineItem.java	(copia locale)
@@ -30,8 +30,8 @@
 import org.apache.pdfbox.pdmodel.documentinterchange.logicalstructure.PDStructureElement;
 import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
 import org.apache.pdfbox.pdmodel.graphics.color.PDDeviceRGB;
+import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
 import org.apache.pdfbox.pdmodel.interactive.action.PDActionFactory;
-import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
 import org.apache.pdfbox.pdmodel.interactive.action.PDActionGoTo;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDDestination;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDNamedDestination;
@@ -39,18 +39,15 @@
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageXYZDestination;
 
 /**
- * This represents an outline in a pdf document.
+ * This represents an outline item in a pdf document.
  *
  * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
  */
-public class PDOutlineItem extends PDOutlineNode
+public final class PDOutlineItem extends PDOutlineNode
 {
     private static final int ITALIC_FLAG = 1;
     private static final int BOLD_FLAG = 2;
 
-    /**
-     * Default Constructor.
-     */
     public PDOutlineItem()
     {
         super();
@@ -57,57 +54,73 @@
     }
 
     /**
-     * Constructor for an existing outline item.
-     *
      * @param dic The storage dictionary.
      */
-    public PDOutlineItem( COSDictionary dic )
+    public PDOutlineItem(COSDictionary dic)
     {
-        super( dic );
+        super(dic);
     }
 
     /**
-     * Insert a sibling after this node.
+     * Insert a single sibling after this node.
      *
-     * @param item The item to insert.
+     * @param newSibling The item to insert.
+     * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+     * sibling)
      */
-    public void insertSiblingAfter( PDOutlineItem item )
+    public void insertSiblingAfter(PDOutlineItem newSibling)
     {
-        item.setParent( getParent() );
+        requireSingleNode(newSibling);
+        PDOutlineNode parent = getParent();
+        newSibling.setParent(parent);
         PDOutlineItem next = getNextSibling();
-        setNextSibling( item );
-        item.setPreviousSibling( this );
-        if( next != null )
+        setNextSibling(newSibling);
+        newSibling.setPreviousSibling(this);
+        if (next != null)
         {
-            item.setNextSibling( next );
-            next.setPreviousSibling( item );
+            newSibling.setNextSibling(next);
+            next.setPreviousSibling(newSibling);
         }
-        updateParentOpenCount( 1 );
+        else if (parent != null)
+        {
+            getParent().setLastChild(newSibling);
+        }
+        updateParentOpenCountForAddedChild(newSibling);
     }
 
     /**
-     * {@inheritDoc}
+     * Insert a single sibling before this node.
+     *
+     * @param newSibling The item to insert.
+     * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+     * sibling)
      */
-    @Override
-    public PDOutlineNode getParent()
+    public void insertSiblingBefore(PDOutlineItem newSibling)
     {
-        return super.getParent();
+        requireSingleNode(newSibling);
+        PDOutlineNode parent = getParent();
+        newSibling.setParent(parent);
+        PDOutlineItem previous = getPreviousSibling();
+        setPreviousSibling(newSibling);
+        newSibling.setNextSibling(this);
+        if (previous != null)
+        {
+            previous.setNextSibling(newSibling);
+            newSibling.setPreviousSibling(previous);
+        }
+        else if (parent != null)
+        {
+            getParent().setFirstChild(newSibling);
+        }
+        updateParentOpenCountForAddedChild(newSibling);
     }
 
     /**
-     * Return the previous sibling or null if there is no sibling.
-     *
-     * @return The previous sibling.
+     * @return The previous sibling or null if there is no sibling.
      */
     public PDOutlineItem getPreviousSibling()
     {
-        PDOutlineItem last = null;
-        COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( COSName.PREV );
-        if( lastDic != null )
-        {
-            last = new PDOutlineItem( lastDic );
-        }
-        return last;
+        return getItem(COSName.PREV);
     }
 
     /**
@@ -115,25 +128,17 @@
      *
      * @param outlineNode The new previous sibling.
      */
-    protected void setPreviousSibling( PDOutlineNode outlineNode )
+    void setPreviousSibling(PDOutlineNode outlineNode)
     {
-        node.setItem( COSName.PREV, outlineNode );
+        getCOSObject().setItem(COSName.PREV, outlineNode);
     }
 
     /**
-     * Return the next sibling or null if there is no next sibling.
-     *
-     * @return The next sibling.
+     * @return The next sibling or null if there is no next sibling.
      */
     public PDOutlineItem getNextSibling()
     {
-        PDOutlineItem last = null;
-        COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( COSName.NEXT );
-        if( lastDic != null )
-        {
-            last = new PDOutlineItem( lastDic );
-        }
-        return last;
+        return getItem(COSName.NEXT);
     }
 
     /**
@@ -141,19 +146,17 @@
      *
      * @param outlineNode The new next sibling.
      */
-    protected void setNextSibling( PDOutlineNode outlineNode )
+    void setNextSibling(PDOutlineNode outlineNode)
     {
-        node.setItem( COSName.NEXT, outlineNode );
+        getCOSObject().setItem(COSName.NEXT, outlineNode);
     }
 
     /**
-     * Get the title of this node.
-     *
      * @return The title of this node.
      */
     public String getTitle()
     {
-        return node.getString( COSName.TITLE );
+        return getCOSObject().getString(COSName.TITLE);
     }
 
     /**
@@ -161,20 +164,18 @@
      *
      * @param title The new title for this node.
      */
-    public void setTitle( String title )
+    public void setTitle(String title)
     {
-        node.setString( COSName.TITLE, title );
+        getCOSObject().setString(COSName.TITLE, title);
     }
 
     /**
-     * Get the page destination of this node.
-     *
      * @return The page destination of this node.
      * @throws IOException If there is an error creating the destination.
      */
     public PDDestination getDestination() throws IOException
     {
-        return PDDestination.create( node.getDictionaryObject( COSName.DEST ) );
+        return PDDestination.create(getCOSObject().getDictionaryObject(COSName.DEST));
     }
 
     /**
@@ -182,9 +183,9 @@
      *
      * @param dest The new page destination for this node.
      */
-    public void setDestination( PDDestination dest )
+    public void setDestination(PDDestination dest)
     {
-        node.setItem( COSName.DEST, dest );
+        getCOSObject().setItem(COSName.DEST, dest);
     }
 
     /**
@@ -192,21 +193,21 @@
      *
      * @param page The page to refer to.
      */
-    public void setDestination( PDPage page )
+    public void setDestination(PDPage page)
     {
         PDPageXYZDestination dest = null;
-        if( page != null )
+        if (page != null)
         {
             dest = new PDPageXYZDestination();
-            dest.setPage( page );
+            dest.setPage(page);
         }
-        setDestination( dest );
+        setDestination(dest);
     }
 
     /**
-     * This method will attempt to find the page in this PDF document that this outline points to.
-     * If the outline does not point to anything then this method will return null.  If the outline
-     * is an action that is not a GoTo action then this methods will throw the OutlineNotLocationException
+     * This method will attempt to find the page in this PDF document that this outline points to. If the outline does
+     * not point to anything then this method will return null. If the outline is an action that is not a GoTo action
+     * then this methods will throw the OutlineNotLocationException
      *
      * @param doc The document to get the page from.
      *
@@ -213,15 +214,15 @@
      * @return The page that this outline will go to when activated or null if it does not point to anything.
      * @throws IOException If there is an error when trying to find the page.
      */
-    public PDPage findDestinationPage( PDDocument doc ) throws IOException
+    public PDPage findDestinationPage(PDDocument doc) throws IOException
     {
         PDDestination dest = getDestination();
-        if( dest == null )
+        if (dest == null)
         {
             PDAction outlineAction = getAction();
-            if( outlineAction instanceof PDActionGoTo )
+            if (outlineAction instanceof PDActionGoTo)
             {
-                dest = ((PDActionGoTo)outlineAction).getDestination();
+                dest = ((PDActionGoTo) outlineAction).getDestination();
             }
             else
             {
@@ -230,17 +231,18 @@
         }
 
         PDPageDestination pageDestination;
-        if( dest instanceof PDNamedDestination )
+        if (dest instanceof PDNamedDestination)
         {
-            //if we have a named destination we need to lookup the PDPageDestination
-            PDNamedDestination namedDest = (PDNamedDestination)dest;
+            // if we have a named destination we need to lookup the PDPageDestination
+            PDNamedDestination namedDest = (PDNamedDestination) dest;
             PDDocumentNameDictionary namesDict = doc.getDocumentCatalog().getNames();
-            if( namesDict != null )
+            if (namesDict != null)
             {
                 PDDestinationNameTreeNode destsTree = namesDict.getDests();
-                if( destsTree != null )
+                if (destsTree != null)
                 {
-                    pageDestination = (PDPageDestination)destsTree.getValue( namedDest.getNamedDestination() );
+                    pageDestination = (PDPageDestination) destsTree.getValue(namedDest
+                            .getNamedDestination());
                 }
                 else
                 {
@@ -252,26 +254,26 @@
                 return null;
             }
         }
-        else if( dest instanceof PDPageDestination)
+        else if (dest instanceof PDPageDestination)
         {
             pageDestination = (PDPageDestination) dest;
         }
-        else if( dest == null )
+        else if (dest == null)
         {
             return null;
         }
         else
         {
-            throw new IOException( "Error: Unknown destination type " + dest );
+            throw new IOException("Error: Unknown destination type " + dest);
         }
 
         PDPage page = pageDestination.getPage();
-        if( page == null )
+        if (page == null)
         {
             int pageNumber = pageDestination.getPageNumber();
-            if( pageNumber != -1 )
+            if (pageNumber != -1)
             {
-                page = doc.getPage( pageNumber - 1 );
+                page = doc.getPage(pageNumber - 1);
             }
         }
 
@@ -285,7 +287,8 @@
      */
     public PDAction getAction()
     {
-        return PDActionFactory.createAction( (COSDictionary)node.getDictionaryObject( COSName.A ) );
+        return PDActionFactory.createAction((COSDictionary) getCOSObject().getDictionaryObject(
+                COSName.A));
     }
 
     /**
@@ -293,9 +296,9 @@
      *
      * @param action The new action for this node.
      */
-    public void setAction( PDAction action )
+    public void setAction(PDAction action)
     {
-        node.setItem( COSName.A, action );
+        getCOSObject().setItem(COSName.A, action);
     }
 
     /**
@@ -306,10 +309,10 @@
     public PDStructureElement getStructureElement()
     {
         PDStructureElement se = null;
-        COSDictionary dic = (COSDictionary)node.getDictionaryObject( COSName.SE );
-        if( dic != null )
+        COSDictionary dic = (COSDictionary) getCOSObject().getDictionaryObject(COSName.SE);
+        if (dic != null)
         {
-            se = new PDStructureElement( dic );
+            se = new PDStructureElement(dic);
         }
         return se;
     }
@@ -319,14 +322,13 @@
      *
      * @param structureElement The new structure element for this node.
      */
-    public void setStructuredElement( PDStructureElement structureElement )
+    public void setStructuredElement(PDStructureElement structureElement)
     {
-        node.setItem( COSName.SE, structureElement );
+        getCOSObject().setItem(COSName.SE, structureElement);
     }
 
     /**
-     * Get the RGB text color of this node.  Default is black and this method
-     * will never return null.
+     * Get the RGB text color of this node. Default is black and this method will never return null.
      *
      * @return The structure element of this node.
      */
@@ -333,12 +335,12 @@
     public PDColor getTextColor()
     {
         PDColor retval = null;
-        COSArray csValues = (COSArray)node.getDictionaryObject( COSName.C );
-        if( csValues == null )
+        COSArray csValues = (COSArray) getCOSObject().getDictionaryObject(COSName.C);
+        if (csValues == null)
         {
             csValues = new COSArray();
-            csValues.growToSize( 3, new COSFloat( 0 ) );
-            node.setItem( COSName.C, csValues );
+            csValues.growToSize(3, new COSFloat(0));
+            getCOSObject().setItem(COSName.C, csValues);
         }
         retval = new PDColor(csValues.toFloatArray(), PDDeviceRGB.INSTANCE);
         return retval;
@@ -349,9 +351,9 @@
      *
      * @param textColor The text color for this node.
      */
-    public void setTextColor( PDColor textColor )
+    public void setTextColor(PDColor textColor)
     {
-        node.setItem( COSName.C, textColor.toCOSArray() );
+        getCOSObject().setItem(COSName.C, textColor.toCOSArray());
     }
 
     /**
@@ -359,13 +361,13 @@
      *
      * @param textColor The text color for this node.
      */
-    public void setTextColor( Color textColor )
+    public void setTextColor(Color textColor)
     {
         COSArray array = new COSArray();
-        array.add( new COSFloat( textColor.getRed()/255f));
-        array.add( new COSFloat( textColor.getGreen()/255f));
-        array.add( new COSFloat( textColor.getBlue()/255f));
-        node.setItem( COSName.C, array );
+        array.add(new COSFloat(textColor.getRed() / 255f));
+        array.add(new COSFloat(textColor.getGreen() / 255f));
+        array.add(new COSFloat(textColor.getBlue() / 255f));
+        getCOSObject().setItem(COSName.C, array);
     }
 
     /**
@@ -375,7 +377,7 @@
      */
     public boolean isItalic()
     {
-        return node.getFlag( COSName.F, ITALIC_FLAG );
+        return getCOSObject().getFlag(COSName.F, ITALIC_FLAG);
     }
 
     /**
@@ -383,9 +385,9 @@
      *
      * @param italic The new italic flag.
      */
-    public void setItalic( boolean italic )
+    public void setItalic(boolean italic)
     {
-        node.setFlag( COSName.F, ITALIC_FLAG, italic );
+        getCOSObject().setFlag(COSName.F, ITALIC_FLAG, italic);
     }
 
     /**
@@ -395,7 +397,7 @@
      */
     public boolean isBold()
     {
-        return node.getFlag( COSName.F, BOLD_FLAG );
+        return getCOSObject().getFlag(COSName.F, BOLD_FLAG);
     }
 
     /**
@@ -403,9 +405,9 @@
      *
      * @param bold The new bold flag.
      */
-    public void setBold( boolean bold )
+    public void setBold(boolean bold)
     {
-        node.setFlag( COSName.F, BOLD_FLAG, bold );
+        getCOSObject().setFlag(COSName.F, BOLD_FLAG, bold);
     }
 
 }
Index: pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/pdmodel/interactive/documentnavigation/outline/PDOutlineNode.java	(copia locale)
@@ -16,182 +16,192 @@
  */
 package org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline;
 
-import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.pdmodel.common.PDDictionaryWrapper;
 
-import org.apache.pdfbox.pdmodel.common.COSObjectable;
-
 /**
- * This represents an node in an outline in a pdf document.
+ * Base class for a node in the outline of a PDF document.
  *
  * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
  * @version $Revision: 1.3 $
  */
-public class PDOutlineNode implements COSObjectable
+public abstract class PDOutlineNode extends PDDictionaryWrapper
 {
-    /**
-     * The dictionary for this node.
-     */
-    protected COSDictionary node;
 
-    /**
-     * Default Constructor.
-     */
     public PDOutlineNode()
     {
-        node = new COSDictionary();
+        super();
     }
 
     /**
-     * Default Constructor.
-     *
      * @param dict The dictionary storage.
      */
-    public PDOutlineNode( COSDictionary dict)
+    public PDOutlineNode(COSDictionary dict)
     {
-        node = dict;
+        super(dict);
     }
 
     /**
-     * Convert this standard java object to a COS object.
-     *
-     * @return The cos object that matches this Java object.
+     * @return The parent of this node or null if there is no parent.
      */
-    @Override
-    public COSBase getCOSObject()
+    PDOutlineNode getParent()
     {
-        return node;
+        COSDictionary item = (COSDictionary) getCOSObject().getDictionaryObject(COSName.PARENT);
+        if (item != null)
+        {
+            if (COSName.OUTLINES.equals(item.getCOSName(COSName.TYPE)))
+            {
+                return new PDDocumentOutline(item);
+            }
+            return new PDOutlineItem(item);
+        }
+        return null;
     }
 
+    void setParent(PDOutlineNode parent)
+    {
+        getCOSObject().setItem(COSName.PARENT, parent);
+    }
+
     /**
-     * Convert this standard java object to a COS object.
+     * Adds the given node to the bottom of the children list.
      *
-     * @return The cos object that matches this Java object.
+     * @param newChild The node to add.
+     * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+     * sibling)
      */
-    public COSDictionary getCOSDictionary()
+    public void addLast(PDOutlineItem newChild)
     {
-        return node;
+        requireSingleNode(newChild);
+        append(newChild);
+        updateParentOpenCountForAddedChild(newChild);
     }
 
     /**
-     * Get the parent of this object.  This will either be a DocumentOutline or an OutlineItem.
-     *
-     * @return The parent of this object, or null if this is the document outline and there
-     * is no parent.
+     * Adds the given node to the top of the children list.
+     * 
+     * @param newChild
+     * @return the newly added child
+     * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+     * sibling)
      */
-    protected PDOutlineNode getParent()
+    public void addFirst(PDOutlineItem newChild)
     {
-        PDOutlineNode retval = null;
-        COSDictionary parent = (COSDictionary) node.getDictionaryObject(COSName.PARENT);
-        if (parent != null)
+        requireSingleNode(newChild);
+        prepend(newChild);
+        updateParentOpenCountForAddedChild(newChild);
+    }
+
+    /**
+     * @param node
+     * @throws IllegalArgumentException if the given node is part of a list (i.e. if it has a previous or a next
+     * sibling)
+     */
+    void requireSingleNode(PDOutlineItem node)
+    {
+        if (node.getNextSibling() != null || node.getPreviousSibling() != null)
         {
-            if (parent.getDictionaryObject(COSName.PARENT) == null)
-            {
-                retval = new PDDocumentOutline(parent);
-            }
-            else
-            {
-                retval = new PDOutlineItem(parent);
-            }
+            throw new IllegalArgumentException("A single node with no siblings is required");
         }
-
-        return retval;
     }
 
     /**
-     * Set the parent of this object, this is maintained by these objects and should not
-     * be called by any clients of PDFBox code.
-     *
-     * @param parent The parent of this object.
+     * Appends the child to the linked list of children. This method only adjust pointers but doesn't take care of the
+     * Count key in the parent hierarchy.
+     * 
+     * @param newChild
      */
-    protected void setParent( PDOutlineNode parent )
+    private void append(PDOutlineItem newChild)
     {
-        node.setItem(COSName.PARENT, parent );
+        newChild.setParent(this);
+        if (!hasChildren())
+        {
+            setFirstChild(newChild);
+        }
+        else
+        {
+            PDOutlineItem previousLastChild = getLastChild();
+            previousLastChild.setNextSibling(newChild);
+            newChild.setPreviousSibling(previousLastChild);
+        }
+        setLastChild(newChild);
     }
 
     /**
-     * append a child node to this node.
-     *
-     * @param outlineNode The node to add.
+     * Prepends the child to the linked list of children. This method only adjust pointers but doesn't take care of the
+     * Count key in the parent hierarchy.
+     * 
+     * @param newChild
      */
-    public void appendChild( PDOutlineItem outlineNode )
+    private void prepend(PDOutlineItem newChild)
     {
-        outlineNode.setParent( this );
-        if( getFirstChild() == null )
+        newChild.setParent(this);
+        if (!hasChildren())
         {
-            int currentOpenCount = getOpenCount();
-            setFirstChild( outlineNode );
-            //1 for the the item we are adding;
-            int numberOfOpenNodesWeAreAdding = 1;
-            if( outlineNode.isNodeOpen() )
-            {
-                numberOfOpenNodesWeAreAdding += outlineNode.getOpenCount();
-            }
-            if( isNodeOpen() )
-            {
-                setOpenCount( currentOpenCount + numberOfOpenNodesWeAreAdding );
-            }
-            else
-            {
-                setOpenCount( currentOpenCount - numberOfOpenNodesWeAreAdding );
-            }
-            updateParentOpenCount( numberOfOpenNodesWeAreAdding );
+            setLastChild(newChild);
         }
         else
         {
-            PDOutlineItem previousLastChild = getLastChild();
-            previousLastChild.insertSiblingAfter( outlineNode );
+            PDOutlineItem previousFirstChild = getFirstChild();
+            newChild.setNextSibling(previousFirstChild);
+            previousFirstChild.setPreviousSibling(newChild);
         }
-        
-        PDOutlineItem lastNode = outlineNode;
-        while(lastNode.getNextSibling() != null)
+        setFirstChild(newChild);
+    }
+
+    void updateParentOpenCountForAddedChild(PDOutlineItem newChild)
+    {
+        int delta = 1;
+        if (newChild.isNodeOpen())
         {
-            lastNode = lastNode.getNextSibling();
+            delta += newChild.getOpenCount();
         }
-        setLastChild( lastNode );
+        newChild.updateParentOpenCount(delta);
     }
 
     /**
-     * Return the first child or null if there is no child.
-     *
-     * @return The first child.
+     * @return true if the node has at least one child
      */
-    public PDOutlineItem getFirstChild()
+    public boolean hasChildren()
     {
-        PDOutlineItem first = null;
-        COSDictionary firstDic = (COSDictionary)node.getDictionaryObject( "First" );
-        if( firstDic != null )
+        return getFirstChild() != null;
+    }
+
+    PDOutlineItem getItem(COSName name)
+    {
+        COSDictionary item = (COSDictionary) getCOSObject().getDictionaryObject(name);
+        if (item != null)
         {
-            first = new PDOutlineItem( firstDic );
+            return new PDOutlineItem(item);
         }
-        return first;
+        return null;
     }
 
     /**
+     * @return The first child or null if there is no child.
+     */
+    public PDOutlineItem getFirstChild()
+    {
+        return getItem(COSName.FIRST);
+    }
+
+    /**
      * Set the first child, this will be maintained by this class.
      *
      * @param outlineNode The new first child.
      */
-    protected void setFirstChild( PDOutlineNode outlineNode )
+    void setFirstChild(PDOutlineNode outlineNode)
     {
-        node.setItem(COSName.FIRST, outlineNode);
+        getCOSObject().setItem(COSName.FIRST, outlineNode);
     }
 
     /**
-     * Return the last child or null if there is no child.
-     *
-     * @return The last child.
+     * @return The last child or null if there is no child.
      */
     public PDOutlineItem getLastChild()
     {
-        PDOutlineItem last = null;
-        COSDictionary lastDic = (COSDictionary)node.getDictionaryObject( "Last" );
-        if( lastDic != null )
-        {
-            last = new PDOutlineItem( lastDic );
-        }
-        return last;
+        return getItem(COSName.LAST);
     }
 
     /**
@@ -199,80 +209,64 @@
      *
      * @param outlineNode The new last child.
      */
-    protected void setLastChild( PDOutlineNode outlineNode )
+    void setLastChild(PDOutlineNode outlineNode)
     {
-        node.setItem( "Last", outlineNode );
+        getCOSObject().setItem(COSName.LAST, outlineNode);
     }
 
     /**
-     * Get the number of open nodes.  Or a negative number if this node
-     * is closed.  See PDF Reference for more details.  This value
-     * is updated as you append children and siblings.
+     * Get the number of open nodes or a negative number if this node is closed. See PDF Reference 32000-1:2008 table
+     * 152 and 153 for more details. This value is updated as you append children and siblings.
      *
      * @return The Count attribute of the outline dictionary.
      */
     public int getOpenCount()
     {
-        return node.getInt( "Count", 0 );
+        return getCOSObject().getInt(COSName.COUNT, 0);
     }
 
     /**
-     * Set the open count.  This number is automatically managed for you
-     * when you add items to the outline.
+     * Set the open count. This number is automatically managed for you when you add items to the outline.
      *
-     * @param openCount The new open cound.
+     * @param openCount The new open count.
      */
-    protected void setOpenCount( int openCount )
+    void setOpenCount(int openCount)
     {
-        node.setInt( "Count", openCount );
+        getCOSObject().setInt(COSName.COUNT, openCount);
     }
 
     /**
-     * This will set this node to be open when it is shown in the viewer.  By default, when
-     * a new node is created it will be closed.
-     * This will do nothing if the node is already open.
+     * This will set this node to be open when it is shown in the viewer. By default, when a new node is created it will
+     * be closed. This will do nothing if the node is already open.
      */
     public void openNode()
     {
-        //if the node is already open then do nothing.
-        if( !isNodeOpen() )
+        if (!isNodeOpen())
         {
-            int openChildrenCount = 0;
-            PDOutlineItem currentChild = getFirstChild();
-            while( currentChild != null )
-            {
-                //first increase by one for the current child
-                openChildrenCount++;
-                //then increase by the number of open nodes the child has
-                if( currentChild.isNodeOpen() )
-                {
-                    openChildrenCount += currentChild.getOpenCount();
-                }
-                currentChild = currentChild.getNextSibling();
-            }
-            setOpenCount( openChildrenCount );
-            updateParentOpenCount( openChildrenCount );
+            switchNodeCount();
         }
     }
 
     /**
      * Close this node.
-     *
      */
     public void closeNode()
     {
-        //if the node is already closed then do nothing.
-        if( isNodeOpen() )
+        if (isNodeOpen())
         {
-            int openCount = getOpenCount();
-            updateParentOpenCount( -openCount );
-            setOpenCount( -openCount );
+            switchNodeCount();
         }
     }
 
+    private void switchNodeCount()
+    {
+        int openCount = getOpenCount();
+        setOpenCount(-openCount);
+        updateParentOpenCount(-openCount);
+    }
+
     /**
-     * Node is open if the open count is greater than zero.
-     * @return true if this node is open.
+     * @return true if this node count is greater than zero, false otherwise.
      */
     public boolean isNodeOpen()
     {
@@ -280,34 +274,23 @@
     }
 
     /**
-     * The count parameter needs to be updated when you add or remove elements to
-     * the outline.  When you add an element at a lower level then you need to
-     * increase all of the parents.
+     * The count parameter needs to be updated when you add, remove, open or close outline items.
      *
-     * @param amount The amount to update by.
+     * @param delta The amount to update by.
      */
-    protected void updateParentOpenCount( int amount )
+    void updateParentOpenCount(int delta)
     {
         PDOutlineNode parent = getParent();
-        if( parent != null )
+        if (parent != null)
         {
-            int currentCount = parent.getOpenCount();
-            //if the currentCount is negative or it is absent then
-            //we will treat it as negative.  The default is to be negative.
-            boolean negative = currentCount < 0 ||
-                parent.getCOSDictionary().getDictionaryObject( "Count" ) == null;
-            currentCount = Math.abs( currentCount );
-            currentCount += amount;
-            if( negative )
+            if (parent.isNodeOpen())
             {
-                currentCount = -currentCount;
+                parent.setOpenCount(parent.getOpenCount() + delta);
+                parent.updateParentOpenCount(delta);
             }
-            parent.setOpenCount( currentCount );
-            //recursively call parent to update count, but the parents count is only
-            //updated if this is an open node
-            if( !negative )
+            else
             {
-                parent.updateParentOpenCount( amount );
+                parent.setOpenCount(parent.getOpenCount() - delta);
             }
         }
     }
Index: pdfbox/src/main/java/org/apache/pdfbox/util/PDFMergerUtility.java
===================================================================
--- pdfbox/src/main/java/org/apache/pdfbox/util/PDFMergerUtility.java	(revisione 1658902)
+++ pdfbox/src/main/java/org/apache/pdfbox/util/PDFMergerUtility.java	(copia locale)
@@ -328,7 +328,7 @@
                 if (first != null)
                 {
                     PDOutlineItem clonedFirst = new PDOutlineItem((COSDictionary) cloner.cloneForNewDocument(first));
-                    destOutline.appendChild(clonedFirst);
+                    destOutline.addLast(clonedFirst);
                 }
             }
         }
Index: preflight/src/main/java/org/apache/pdfbox/preflight/process/BookmarkValidationProcess.java
===================================================================
--- preflight/src/main/java/org/apache/pdfbox/preflight/process/BookmarkValidationProcess.java	(revisione 1658902)
+++ preflight/src/main/java/org/apache/pdfbox/preflight/process/BookmarkValidationProcess.java	(copia locale)
@@ -21,13 +21,14 @@
 
 package org.apache.pdfbox.preflight.process;
 
-import java.util.HashSet;
-import java.util.Set;
-
 import static org.apache.pdfbox.preflight.PreflightConfiguration.ACTIONS_PROCESS;
+import static org.apache.pdfbox.preflight.PreflightConfiguration.DESTINATION_PROCESS;
 import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_SYNTAX_NOCATALOG;
 import static org.apache.pdfbox.preflight.PreflightConstants.ERROR_SYNTAX_TRAILER_OUTLINES_INVALID;
 
+import java.util.HashSet;
+import java.util.Set;
+
 import org.apache.pdfbox.cos.COSBase;
 import org.apache.pdfbox.cos.COSDictionary;
 import org.apache.pdfbox.cos.COSDocument;
@@ -37,7 +38,6 @@
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
 import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
-import static org.apache.pdfbox.preflight.PreflightConfiguration.DESTINATION_PROCESS;
 import org.apache.pdfbox.preflight.PreflightContext;
 import org.apache.pdfbox.preflight.ValidationResult.ValidationError;
 import org.apache.pdfbox.preflight.exception.ValidationException;
@@ -56,7 +56,7 @@
             PDDocumentOutline outlineHierarchy = catalog.getDocumentOutline();
             if (outlineHierarchy != null)
             {
-                COSDictionary dict = outlineHierarchy.getCOSDictionary();
+                COSDictionary dict = outlineHierarchy.getCOSObject();
                 if (!checkIndirectObjects(ctx, dict))
                 {
                     return;
@@ -138,7 +138,7 @@
         {
             addValidationError(ctx, new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
                     "The value of /Prev of first object " + firstObj + " on a level is " 
-                            + inputItem.getCOSDictionary().getItem(COSName.PREV) 
+                            + inputItem.getCOSObject().getItem(COSName.PREV)
                             + ", but shouldn't exist"));
             result = false;
         }
@@ -150,7 +150,7 @@
             {
                 result = false;
             }
-            currentObj = toCOSObject(currentItem.getCOSDictionary().getItem(COSName.NEXT));
+            currentObj = toCOSObject(currentItem.getCOSObject().getItem(COSName.NEXT));
             if (levelObjects.contains(currentObj))
             {
                 addValidationError(ctx, new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
@@ -171,7 +171,7 @@
             }
             else 
             {
-                COSObject prevObject = toCOSObject(currentItem.getCOSDictionary().getItem(COSName.PREV));
+                COSObject prevObject = toCOSObject(currentItem.getCOSObject().getItem(COSName.PREV));
                 if (!realPrevObject.equals(prevObject))
                 {
                     addValidationError(ctx, new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
@@ -200,7 +200,7 @@
         // Dest entry isn't permitted if the A entry is present
         // A entry isn't permitted if the Dest entry is present
         // If the A entry is present, the referenced actions is validated
-        COSDictionary dictionary = inputItem.getCOSDictionary();
+        COSDictionary dictionary = inputItem.getCOSObject();
         COSBase dest = dictionary.getItem(COSName.DEST);
         COSBase action = dictionary.getItem(COSName.A);
         
@@ -228,7 +228,7 @@
         PDOutlineItem fChild = inputItem.getFirstChild();
         if (fChild != null)
         {
-            if (!isCountEntryPresent(inputItem.getCOSDictionary()))
+            if (!isCountEntryPresent(inputItem.getCOSObject()))
             {
                 addValidationError(ctx, new ValidationError(ERROR_SYNTAX_TRAILER_OUTLINES_INVALID,
                         "Outline item doesn't have Count entry but has at least one descendant"));
