diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
index f513b6b..a8ac934 100644
--- a/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFBoxAdapter.java
@@ -24,7 +24,6 @@
 import java.awt.geom.Rectangle2D;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -45,21 +44,15 @@
 
 import org.apache.pdfbox.cos.COSArray;
 import org.apache.pdfbox.cos.COSBase;
-import org.apache.pdfbox.cos.COSBoolean;
 import org.apache.pdfbox.cos.COSDictionary;
-import org.apache.pdfbox.cos.COSFloat;
-import org.apache.pdfbox.cos.COSInteger;
 import org.apache.pdfbox.cos.COSName;
-import org.apache.pdfbox.cos.COSNull;
 import org.apache.pdfbox.cos.COSObject;
 import org.apache.pdfbox.cos.COSStream;
-import org.apache.pdfbox.cos.COSString;
 
 import org.apache.pdfbox.pdmodel.PDDocument;
 import org.apache.pdfbox.pdmodel.PDDocumentCatalog;
 import org.apache.pdfbox.pdmodel.PDPage;
 import org.apache.pdfbox.pdmodel.PDResources;
-import org.apache.pdfbox.pdmodel.common.COSObjectable;
 import org.apache.pdfbox.pdmodel.common.PDRectangle;
 import org.apache.pdfbox.pdmodel.common.PDStream;
 
@@ -71,7 +64,6 @@
 import org.apache.fop.pdf.PDFDictionary;
 import org.apache.fop.pdf.PDFDocument;
 import org.apache.fop.pdf.PDFFormXObject;
-import org.apache.fop.pdf.PDFName;
 import org.apache.fop.pdf.PDFNumber;
 import org.apache.fop.pdf.PDFObject;
 import org.apache.fop.pdf.PDFPage;
@@ -88,14 +80,14 @@
     /** logging instance */
     protected static final Log log = LogFactory.getLog(PDFBoxAdapter.class);
 
-    private static final Set FILTER_FILTER = new HashSet(
-            Arrays.asList(new String[] {"Filter", "DecodeParms"}));
+    protected static final Set<String> FILTER_FILTER = Collections.unmodifiableSet(
+            new HashSet<String>(Arrays.asList("Filter", "DecodeParms")));
 
     private final PDFPage targetPage;
-    private final PDFDocument pdfDoc;
+    protected final PDFDocument pdfDoc;
 
-    private final Map<Object, Object> clonedVersion;
-    private final Map<Object, Object> objectCache;
+    protected final Map<Object, Object> clonedVersion;
+    protected final Map<Object, Object> objectCache;
     private Map<COSName, String> newXObj = new HashMap<COSName, String>();
     private Map<Integer, PDFArray> pageNumbers;
     private Collection<String> parentFonts = new ArrayList<String>();
@@ -134,157 +126,6 @@
         this.currentMCID = currentMCID;
     }
 
-    protected Object cloneForNewDocument(Object base) throws IOException {
-        return cloneForNewDocument(base, base);
-    }
-
-    protected Object cloneForNewDocument(Object base, Object keyBase) throws IOException {
-        return cloneForNewDocument(base, keyBase, Collections.EMPTY_LIST);
-    }
-
-    protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
-        if (base == null) {
-            return null;
-        }
-        Object cached = getCachedClone(keyBase);
-        if (cached != null) {
-            // we are done, it has already been converted.
-            return cached;
-        } else if (base instanceof List) {
-            PDFArray array = new PDFArray();
-            cacheClonedObject(keyBase, array);
-            List list = (List)base;
-            for (Object o : list) {
-                array.add(cloneForNewDocument(o, o, exclude));
-            }
-            return array;
-        } else if (base instanceof COSObjectable && !(base instanceof COSBase)) {
-            Object o = ((COSObjectable)base).getCOSObject();
-            Object retval = cloneForNewDocument(o, o, exclude);
-            return cacheClonedObject(keyBase, retval);
-        } else if (base instanceof COSObject) {
-            return readCOSObject((COSObject) base, exclude);
-        } else if (base instanceof COSArray) {
-            PDFArray newArray = new PDFArray();
-            cacheClonedObject(keyBase, newArray);
-            COSArray array = (COSArray)base;
-            for (int i = 0; i < array.size(); i++) {
-                newArray.add(cloneForNewDocument(array.get(i), array.get(i), exclude));
-            }
-            return newArray;
-//        } else if (base instanceof COSStreamArray) {
-//            COSStreamArray array = (COSStreamArray)base;
-//            PDFArray newArray = new PDFArray();
-//            cacheClonedObject(keyBase, newArray);
-//            for (int i = 0, c = array.getStreamCount(); i < c; i++) {
-//                newArray.add(cloneForNewDocument(array.get(i)));
-//            }
-//            return newArray;
-        } else if (base instanceof COSStream) {
-            return readCOSStream((COSStream) base, keyBase);
-        } else if (base instanceof COSDictionary) {
-            return readCOSDictionary((COSDictionary) base, keyBase, exclude);
-        } else if (base instanceof COSName) {
-            byte[] name = ((COSName)base).getName().getBytes("ISO-8859-1");
-            PDFName newName = new PDFName(new String(name, "ISO-8859-1"));
-            return cacheClonedObject(keyBase, newName);
-        } else if (base instanceof COSInteger) {
-            PDFNumber number = new PDFNumber();
-            number.setNumber(((COSInteger)base).longValue());
-            return cacheClonedObject(keyBase, number);
-        } else if (base instanceof COSFloat) {
-            PDFNumber number = new PDFNumber();
-            number.setNumber(((COSFloat)base).floatValue());
-            return cacheClonedObject(keyBase, number);
-        } else if (base instanceof COSBoolean) {
-            //TODO Do we need a PDFBoolean here?
-            Boolean retval = ((COSBoolean)base).getValueAsObject();
-            if (keyBase instanceof COSObject) {
-                return cacheClonedObject(keyBase, new PDFBoolean(retval));
-            } else {
-                return cacheClonedObject(keyBase, retval);
-            }
-        } else if (base instanceof COSString) {
-            return readCOSString((COSString) base, keyBase);
-        } else if (base instanceof COSNull) {
-            return cacheClonedObject(keyBase, null);
-        } else {
-            throw new UnsupportedOperationException("NYI: " + base.getClass().getName());
-        }
-    }
-
-    private PDFDictionary readCOSDictionary(COSDictionary dic, Object keyBase, Collection exclude) throws IOException {
-        PDFDictionary newDict = new PDFDictionary();
-        cacheClonedObject(keyBase, newDict);
-        for (Map.Entry<COSName, COSBase> e : dic.entrySet()) {
-            if (!exclude.contains(e.getKey())) {
-                newDict.put(e.getKey().getName(), cloneForNewDocument(e.getValue(), e.getValue(), exclude));
-            }
-        }
-        return newDict;
-    }
-
-    private Object readCOSObject(COSObject object, Collection exclude) throws IOException {
-        if (log.isTraceEnabled()) {
-            log.trace("Cloning indirect object: "
-                    + object.getObjectNumber()
-                    + " " + object.getGenerationNumber());
-        }
-        Object obj = cloneForNewDocument(object.getObject(), object, exclude);
-        if (obj instanceof PDFObject) {
-            PDFObject pdfobj = (PDFObject)obj;
-            //pdfDoc.registerObject(pdfobj);
-            if (!pdfobj.hasObjectNumber()) {
-                throw new IllegalStateException("PDF object was not registered!");
-            }
-            if (log.isTraceEnabled()) {
-                log.trace("Object registered: "
-                        + pdfobj.getObjectNumber()
-                        + " " + pdfobj.getGeneration()
-                        + " for COSObject: "
-                        + object.getObjectNumber()
-                        + " " + object.getGenerationNumber());
-            }
-        }
-        return obj;
-    }
-
-    private Object readCOSString(COSString string, Object keyBase) throws IOException {
-        //retval = ((COSString)base).getString(); //this is unsafe for binary content
-        byte[] bytes = string.getBytes();
-        //Be on the safe side and use the byte array to avoid encoding problems
-        //as PDFBox doesn't indicate whether the string is just
-        //a string (PDF 1.4, 3.2.3) or a text string (PDF 1.4, 3.8.1).
-        if (keyBase instanceof COSObject) {
-            return cacheClonedObject(keyBase, new PDFString(bytes));
-        } else {
-            if (PDFString.isUSASCII(bytes)) {
-                return cacheClonedObject(keyBase, string.getString());
-            } else {
-                return cacheClonedObject(keyBase, bytes);
-            }
-        }
-    }
-
-    private Object readCOSStream(COSStream originalStream, Object keyBase) throws IOException {
-        InputStream in;
-        Set filter;
-        if (pdfDoc.isEncryptionActive()
-                || (originalStream.containsKey(COSName.DECODE_PARMS) && !originalStream.containsKey(COSName.FILTER))) {
-            in = originalStream.getUnfilteredStream();
-            filter = FILTER_FILTER;
-        } else {
-            //transfer encoded data (don't reencode)
-            in = originalStream.getFilteredStream();
-            filter = Collections.EMPTY_SET;
-        }
-        PDFStream stream = new PDFStream();
-        OutputStream out = stream.getBufferOutputStream();
-        IOUtils.copyLarge(in, out);
-        transferDict(originalStream, stream, filter);
-        return cacheClonedObject(keyBase, stream);
-    }
-
     protected Object getCachedClone(Object base) throws IOException {
         Object key = PDFBoxAdapterUtil.getBaseKey(base);
         Object o = clonedVersion.get(key);
@@ -294,27 +135,19 @@
         return o;
     }
 
-    protected Object cacheClonedObject(Object base, Object cloned) throws IOException {
-        Object key = PDFBoxAdapterUtil.getBaseKey(base);
-        if (key == null) {
-            return cloned;
-        }
-        PDFObject pdfobj = (PDFObject) cloned;
-        if (pdfobj != null && !pdfobj.hasObjectNumber() && !(base instanceof COSDictionary)) {
-            pdfDoc.registerObject(pdfobj);
-            if (log.isTraceEnabled()) {
-                log.trace(key + ": " + pdfobj.getClass().getName() + " registered as "
-                        + pdfobj.getObjectNumber() + " " + pdfobj.getGeneration());
-            }
-        }
-        clonedVersion.put(key, cloned);
-        if (key instanceof Integer) {
-            objectCache.put(key, cloned);
-        }
-        return cloned;
+    protected Object cloneForNewDocument(Object base) throws IOException {
+        return new PDFCloner(this).cloneForNewDocument(base);
     }
 
-    private void transferDict(COSDictionary orgDict, PDFStream targetDict, Set filter) throws IOException {
+    protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
+        return new PDFCloner(this).cloneForNewDocument(base, keyBase, exclude);
+    }
+
+    protected void cacheClonedObject(Object base, Object cloned) throws IOException {
+        new PDFCloner(this).cacheClonedObject(base, cloned);
+    }
+
+    protected void transferDict(COSDictionary orgDict, PDFStream targetDict, Set filter) throws IOException {
         transferDict(orgDict, targetDict, filter, false);
     }
 
diff --git a/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java b/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
new file mode 100644
index 0000000..dae4738
--- /dev/null
+++ b/src/java/org/apache/fop/render/pdf/pdfbox/PDFCloner.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+package org.apache.fop.render.pdf.pdfbox;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.io.IOUtils;
+
+import org.apache.pdfbox.cos.COSArray;
+import org.apache.pdfbox.cos.COSBase;
+import org.apache.pdfbox.cos.COSBoolean;
+import org.apache.pdfbox.cos.COSDictionary;
+import org.apache.pdfbox.cos.COSFloat;
+import org.apache.pdfbox.cos.COSInteger;
+import org.apache.pdfbox.cos.COSName;
+import org.apache.pdfbox.cos.COSNull;
+import org.apache.pdfbox.cos.COSObject;
+import org.apache.pdfbox.cos.COSStream;
+import org.apache.pdfbox.cos.COSString;
+import org.apache.pdfbox.pdmodel.common.COSObjectable;
+
+import org.apache.fop.pdf.PDFArray;
+import org.apache.fop.pdf.PDFDictionary;
+import org.apache.fop.pdf.PDFName;
+import org.apache.fop.pdf.PDFNumber;
+import org.apache.fop.pdf.PDFObject;
+import org.apache.fop.pdf.PDFStream;
+
+public class PDFCloner {
+    private PDFBoxAdapter adapter;
+
+    PDFCloner(PDFBoxAdapter adapter) {
+        this.adapter = adapter;
+    }
+
+    protected Object cloneForNewDocument(Object base) throws IOException {
+        return cloneForNewDocument(base, base);
+    }
+
+    protected Object cloneForNewDocument(Object base, Object keyBase) throws IOException {
+        return cloneForNewDocument(base, keyBase, Collections.EMPTY_LIST);
+    }
+
+    protected Object cloneForNewDocument(Object base, Object keyBase, Collection exclude) throws IOException {
+        if (base == null) {
+            return null;
+        }
+        Object cached = adapter.getCachedClone(keyBase);
+        if (cached != null) {
+            // we are done, it has already been converted.
+            return cached;
+        } else if (base instanceof COSObjectable && !(base instanceof COSBase)) {
+            Object o = ((COSObjectable)base).getCOSObject();
+            Object retval = cloneForNewDocument(o, o, exclude);
+            return cacheClonedObject(keyBase, retval);
+        } else if (base instanceof COSObject) {
+            return readCOSObject((COSObject) base, exclude);
+        } else if (base instanceof COSArray) {
+            PDFArray newArray = new PDFArray();
+            cacheClonedObject(keyBase, newArray);
+            COSArray array = (COSArray)base;
+            for (int i = 0; i < array.size(); i++) {
+                newArray.add(cloneForNewDocument(array.get(i), array.get(i), exclude));
+            }
+            return newArray;
+//        } else if (base instanceof COSStreamArray) {
+//            COSStreamArray array = (COSStreamArray)base;
+//            PDFArray newArray = new PDFArray();
+//            cacheClonedObject(keyBase, newArray);
+//            for (int i = 0, c = array.getStreamCount(); i < c; i++) {
+//                newArray.add(cloneForNewDocument(array.get(i)));
+//            }
+//            return newArray;
+        } else if (base instanceof COSStream) {
+            return readCOSStream((COSStream) base, keyBase);
+        } else if (base instanceof COSDictionary) {
+            return readCOSDictionary((COSDictionary) base, keyBase, exclude);
+        } else if (base instanceof COSName) {
+            PDFName newName = new PDFName(((COSName)base).getName());
+            return cacheClonedObject(keyBase, newName);
+        } else if (base instanceof COSInteger) {
+            PDFNumber number = new PDFNumber();
+            number.setNumber(((COSInteger)base).longValue());
+            return cacheClonedObject(keyBase, number);
+        } else if (base instanceof COSFloat) {
+            PDFNumber number = new PDFNumber();
+            number.setNumber(((COSFloat)base).floatValue());
+            return cacheClonedObject(keyBase, number);
+        } else if (base instanceof COSBoolean) {
+            //TODO Do we need a PDFBoolean here?
+            Boolean retval = ((COSBoolean)base).getValueAsObject();
+            if (keyBase instanceof COSObject) {
+                return cacheClonedObject(keyBase, new PDFBoolean(retval));
+            } else {
+                return cacheClonedObject(keyBase, retval);
+            }
+        } else if (base instanceof COSString) {
+            return readCOSString((COSString) base, keyBase);
+        } else if (base instanceof COSNull) {
+            return cacheClonedObject(keyBase, null);
+        } else {
+            throw new UnsupportedOperationException("NYI: " + base.getClass().getName());
+        }
+    }
+
+    protected Object readCOSObject(COSObject object, Collection exclude) throws IOException {
+        Object obj = cloneForNewDocument(object.getObject(), object, exclude);
+        if (obj instanceof PDFObject) {
+            PDFObject pdfobj = (PDFObject)obj;
+            //pdfDoc.registerObject(pdfobj);
+            if (!pdfobj.hasObjectNumber()) {
+                throw new IllegalStateException("PDF object was not registered!");
+            }
+        }
+        return obj;
+    }
+
+    private PDFDictionary readCOSDictionary(COSDictionary dic, Object keyBase, Collection exclude) throws IOException {
+        PDFDictionary newDict = new PDFDictionary();
+        cacheClonedObject(keyBase, newDict);
+        for (Map.Entry<COSName, COSBase> e : dic.entrySet()) {
+            if (!exclude.contains(e.getKey())) {
+                newDict.put(e.getKey().getName(), cloneForNewDocument(e.getValue(), e.getValue(), exclude));
+            }
+        }
+        return newDict;
+    }
+
+    private Object readCOSString(COSString string, Object keyBase) throws IOException {
+        //retval = ((COSString)base).getString(); //this is unsafe for binary content
+        byte[] bytes = string.getBytes();
+        //Be on the safe side and use the byte array to avoid encoding problems
+        //as PDFBox doesn't indicate whether the string is just
+        //a string (PDF 1.4, 3.2.3) or a text string (PDF 1.4, 3.8.1).
+        if (keyBase instanceof COSObject) {
+            return cacheClonedObject(keyBase, new PDFString(bytes));
+        } else {
+            if (PDFString.isUSASCII(bytes)) {
+                return cacheClonedObject(keyBase, string.getString());
+            } else {
+                return cacheClonedObject(keyBase, bytes);
+            }
+        }
+    }
+
+    private Object readCOSStream(COSStream originalStream, Object keyBase) throws IOException {
+        InputStream in;
+        Set filter;
+        if (adapter.pdfDoc.isEncryptionActive()
+                || (originalStream.containsKey(COSName.DECODE_PARMS) && !originalStream.containsKey(COSName.FILTER))) {
+            in = originalStream.getUnfilteredStream();
+            filter = adapter.FILTER_FILTER;
+        } else {
+            //transfer encoded data (don't reencode)
+            in = originalStream.getFilteredStream();
+            filter = Collections.EMPTY_SET;
+        }
+        PDFStream stream = new PDFStream();
+        OutputStream out = stream.getBufferOutputStream();
+        IOUtils.copyLarge(in, out);
+        adapter.transferDict(originalStream, stream, filter);
+        return cacheClonedObject(keyBase, stream);
+    }
+
+    protected Object cacheClonedObject(Object base, Object cloned) throws IOException {
+        Object key = PDFBoxAdapterUtil.getBaseKey(base);
+        if (key == null) {
+            return cloned;
+        }
+        PDFObject pdfobj = (PDFObject) cloned;
+        if (pdfobj != null && !pdfobj.hasObjectNumber() && !(base instanceof COSDictionary)) {
+            adapter.pdfDoc.registerObject(pdfobj);
+        }
+        adapter.clonedVersion.put(key, cloned);
+        if (key instanceof Integer) {
+            adapter.objectCache.put(key, cloned);
+        }
+        return cloned;
+    }
+}
