Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java	(revision 628156)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/GarbageCollectorTest.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.data;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.SessionImpl;
 import org.apache.jackrabbit.core.state.ItemStateException;
@@ -138,14 +139,7 @@
 
         InputStream in = n.getProperty("test").getStream();
         InputStream in2 = new RandomInputStream(10, 10000);
-        while (true) {
-            int a = in.read();
-            int b = in2.read();
-            assertEquals(a, b);
-            if (a < 0) {
-                break;
-            }
-        }
+        assertTrue(IOUtils.contentEquals(in, in2));
 
         deleteMyNodes();
     }
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java	(revision 628156)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ExportImportTest.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.data;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.test.AbstractJCRTest;
 
 import java.io.ByteArrayInputStream;
@@ -84,15 +85,11 @@
     }
 
     private byte[] readFromStream(InputStream in) throws IOException {
-        ByteArrayOutputStream out2 = new ByteArrayOutputStream();
-        while (true) {
-            int x = in.read();
-            if (x < 0) {
-                break;
-            }
-            out2.write(x);
+        try {
+            return IOUtils.toByteArray(in);
+        } finally {
+            in.close();
         }
-        return out2.toByteArray();
     }
 
     private void clean(Node root) throws RepositoryException {
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/RandomInputStream.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/RandomInputStream.java	(revision 628156)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/RandomInputStream.java	(working copy)
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.core.data;
 
-import java.io.BufferedInputStream;
-import java.io.IOException;
 import java.io.InputStream;
 
 public class RandomInputStream extends InputStream {
@@ -43,24 +41,6 @@
         this(seed, len, DEFAULT_MAX_READ_BLOCK_SIZE);
     }
 
-    public static void compareStreams(InputStream a, InputStream b) throws IOException {
-        a = new BufferedInputStream(a);
-        b = new BufferedInputStream(b);
-        long pos = 0;
-        while (true) {
-            int x = a.read();
-            int y = b.read();
-            if (x == -1 || y == -1) {
-                if (x == y) {
-                    break;
-                }
-            }
-            if (x != y) {
-                throw new IOException("Incorrect byte at position " + pos + ": x=" + x + " y=" + y);
-            }
-        }
-    }
-
     public RandomInputStream(long seed, long len, int maxReadBlockSize) {
         this.initialSeed = seed;
         this.len = len;
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/config/RepositoryConfigTest.java
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/config/RepositoryConfigTest.java	(revision 628156)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/config/RepositoryConfigTest.java	(working copy)
@@ -17,6 +17,8 @@
 package org.apache.jackrabbit.core.config;
 
 import junit.framework.TestCase;
+
+import org.apache.commons.io.IOUtils;
 import org.xml.sax.InputSource;
 
 import java.io.File;
@@ -65,11 +67,7 @@
         try {
             OutputStream output = new FileOutputStream(REPOSITORY_XML);
             try {
-                int n;
-                byte[] buffer = new byte[1024];
-                while ((n = input.read(buffer)) != -1) {
-                    output.write(buffer, 0, n);
-                }
+                IOUtils.copy(input, output);
             } finally {
                 output.close();
             }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/xml/XMLPersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/xml/XMLPersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/xml/XMLPersistenceManager.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.persistence.xml;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.fs.BasedFileSystem;
@@ -361,11 +362,7 @@
                                 try {
                                     values.add(InternalValue.create(in));
                                 } finally {
-                                    try {
-                                        in.close();
-                                    } catch (IOException e) {
-                                        // ignore
-                                    }
+                                    IOUtils.closeQuietly(in);
                                 }
                             }
                         } catch (Exception e) {
@@ -680,11 +677,7 @@
                                 try {
                                     blobStore.put(blobId, in, blobVal.getLength());
                                 } finally {
-                                    try {
-                                        in.close();
-                                    } catch (IOException e) {
-                                        // ignore
-                                    }
+                                    IOUtils.closeQuietly(in);
                                 }
                                 // store id of BLOB as property value
                                 writer.write(blobId);
@@ -702,11 +695,7 @@
                                     try {
                                         values[i] = InternalValue.create(in);
                                     } finally {
-                                        try {
-                                            in.close();
-                                        } catch (IOException e) {
-                                            // ignore
-                                        }
+                                        IOUtils.closeQuietly(in);
                                     }
                                 }
                                 blobVal.discard();
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/DatabasePersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/DatabasePersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/DatabasePersistenceManager.java	(working copy)
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core.persistence.db;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.CountingInputStream;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.fs.FileSystem;
@@ -367,7 +369,7 @@
                 log.error(msg, e);
                 throw new ItemStateException(msg, e);
             } finally {
-                closeStream(in);
+                IOUtils.closeQuietly(in);
                 closeResultSet(rs);
             }
         }
@@ -405,7 +407,7 @@
                 log.error(msg, e);
                 throw new ItemStateException(msg, e);
             } finally {
-                closeStream(in);
+                IOUtils.closeQuietly(in);
                 closeResultSet(rs);
             }
         }
@@ -583,7 +585,7 @@
                 log.error(msg, e);
                 throw new ItemStateException(msg, e);
             } finally {
-                closeStream(in);
+                IOUtils.closeQuietly(in);
                 closeResultSet(rs);
             }
         }
@@ -924,15 +926,6 @@
         }
     }
 
-    protected void closeStream(InputStream in) {
-        if (in != null) {
-            try {
-                in.close();
-            } catch (IOException ignore) {
-            }
-        }
-    }
-
     protected void closeStatement(Statement stmt) {
         if (stmt != null) {
             try {
@@ -1030,7 +1023,7 @@
                 // commit the changes
                 con.commit();
             } finally {
-                closeStream(in);
+                IOUtils.closeQuietly(in);
                 closeStatement(stmt);
             }
         }
@@ -1150,9 +1143,8 @@
 
     //--------------------------------------------------------< inner classes >
 
-    class SizedInputStream extends FilterInputStream {
+    class SizedInputStream extends CountingInputStream {
         private final long size;
-        private boolean consumed = false;
 
         SizedInputStream(InputStream in, long size) {
             super(in);
@@ -1164,28 +1156,9 @@
         }
 
         boolean isConsumed() {
-            return consumed;
+            return this.getByteCount() > 0;
         }
 
-        public int read() throws IOException {
-            consumed = true;
-            return super.read();
-        }
-
-        public long skip(long n) throws IOException {
-            consumed = true;
-            return super.skip(n);
-        }
-
-        public int read(byte[] b) throws IOException {
-            consumed = true;
-            return super.read(b);
-        }
-
-        public int read(byte[] b, int off, int len) throws IOException {
-            consumed = true;
-            return super.read(b, off, len);
-        }
     }
 
     class DbBLOBStore implements BLOBStore {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/OraclePersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/OraclePersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/db/OraclePersistenceManager.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.persistence.db;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.persistence.PMContext;
 import org.apache.jackrabbit.core.persistence.util.Serializer;
 import org.apache.jackrabbit.core.state.NodeReferences;
@@ -345,7 +346,7 @@
                 // commit the changes
                 con.commit();
             } finally {
-                closeStream(in);
+                IOUtils.closeQuietly(in);
                 closeStatement(stmt);
             }
         }
@@ -377,11 +378,7 @@
                 blobClass.getMethod("getBinaryOutputStream", new Class[0]);
         OutputStream out = (OutputStream) getBinaryOutputStream.invoke(blob, null);
         try {
-            int read;
-            byte[] buf = new byte[8192];
-            while ((read = in.read(buf, 0, buf.length)) > -1) {
-                out.write(buf, 0, read);
-            }
+            IOUtils.copy(in, out);
         } finally {
             try {
                 out.flush();
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java	(working copy)
@@ -18,6 +18,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.core.state.ChangeLog;
 import org.apache.jackrabbit.core.state.ItemStateException;
@@ -762,7 +763,7 @@
         } catch (Exception e) {
             log.error("Error in bundle", e);
         } finally {
-            closeStream(din);
+            IOUtils.closeQuietly(din);
             closeResultSet(rs);
         }
 
@@ -978,13 +979,9 @@
             Blob b = rs.getBlob(1);
             // JCR-1039: pre-fetch/buffer blob data
             long length = b.length();
-            byte[] bytes = new byte[(int) length];
             in = b.getBinaryStream();
-            int read, pos = 0;
-            while ((read = in.read(bytes, pos, bytes.length - pos)) > 0) {
-                pos += read;
-            }
-            DataInputStream din = new DataInputStream(new ByteArrayInputStream(bytes));
+            DataInputStream din = new DataInputStream(
+                    new ByteArrayInputStream(IOUtils.toByteArray(in)));
             NodePropBundle bundle = binding.readBundle(din, id);
             bundle.setSize(length);
             return bundle;
@@ -993,7 +990,7 @@
             log.error(msg);
             throw new ItemStateException(msg, e);
         } finally {
-            closeStream(in);
+            IOUtils.closeQuietly(in);
             closeResultSet(rs);
         }
     }
@@ -1085,7 +1082,7 @@
             log.error(msg, e);
             throw new ItemStateException(msg, e);
         } finally {
-            closeStream(in);
+            IOUtils.closeQuietly(in);
             closeResultSet(rs);
         }
     }
@@ -1206,20 +1203,6 @@
     }
 
     /**
-     * closes the input stream
-     * @param ins the input stream
-     */
-    protected void closeStream(InputStream ins) {
-        if (ins != null) {
-            try {
-                ins.close();
-            } catch (IOException ignore) {
-                // ignore
-            }
-        }
-    }
-
-    /**
      * closes the statement
      * @param stmt the statement
      */
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleFsPersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleFsPersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleFsPersistenceManager.java	(working copy)
@@ -18,6 +18,8 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.CountingInputStream;
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.fs.BasedFileSystem;
 import org.apache.jackrabbit.core.fs.FileSystemException;
@@ -26,7 +28,6 @@
 import org.apache.jackrabbit.core.persistence.bundle.util.NodePropBundle;
 import org.apache.jackrabbit.core.persistence.bundle.util.ErrorHandling;
 import org.apache.jackrabbit.core.persistence.bundle.util.BundleBinding;
-import org.apache.jackrabbit.core.persistence.bundle.util.TrackingInputStream;
 import org.apache.jackrabbit.core.persistence.util.Serializer;
 import org.apache.jackrabbit.core.persistence.util.BLOBStore;
 import org.apache.jackrabbit.core.persistence.util.FileSystemBLOBStore;
@@ -42,7 +43,6 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.File;
-import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.sql.SQLException;
@@ -244,17 +244,17 @@
                 return null;
             }
             InputStream in = itemFs.getInputStream(path);
-            TrackingInputStream cin = new TrackingInputStream(in);
+            CountingInputStream cin = new CountingInputStream(in);
             din = new DataInputStream(cin);
             NodePropBundle bundle = binding.readBundle(din, id);
-            bundle.setSize(cin.getPosition());
+            bundle.setSize(cin.getByteCount());
             return bundle;
         } catch (Exception e) {
             String msg = "failed to read bundle: " + id + ": " + e;
             log.error(msg);
             throw new ItemStateException(msg, e);
         } finally {
-            closeStream(din);
+            IOUtils.closeQuietly(din);
         }
     }
 
@@ -376,7 +376,7 @@
             BundleFsPersistenceManager.log.error(msg, e);
             throw new ItemStateException(msg, e);
         } finally {
-            closeStream(in);
+            IOUtils.closeQuietly(in);
         }
     }
 
@@ -445,20 +445,6 @@
     }
 
     /**
-     * closes the input stream
-     * @param ins
-     */
-    protected void closeStream(InputStream ins) {
-        if (ins != null) {
-            try {
-                ins.close();
-            } catch (IOException ignore) {
-                // ignore
-            }
-        }
-    }
-
-    /**
      * logs an sql exception
      * @param message
      * @param se
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/PostgreSQLPersistenceManager.java	(working copy)
@@ -16,12 +16,12 @@
  */
 package org.apache.jackrabbit.core.persistence.bundle;
 
+import org.apache.commons.io.input.CountingInputStream;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.persistence.PMContext;
 import org.apache.jackrabbit.core.persistence.bundle.util.DbNameIndex;
 import org.apache.jackrabbit.core.persistence.bundle.util.NodePropBundle;
 import org.apache.jackrabbit.core.persistence.bundle.util.PostgreSQLNameIndex;
-import org.apache.jackrabbit.core.persistence.bundle.util.TrackingInputStream;
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -97,10 +97,10 @@
                 if (rs.next()) {
                     InputStream input = rs.getBinaryStream(1);
                     try {
-                        TrackingInputStream cin = new TrackingInputStream(input);
+                        CountingInputStream cin = new CountingInputStream(input);
                         DataInputStream din = new DataInputStream(cin);
                         NodePropBundle bundle = binding.readBundle(din, id);
-                        bundle.setSize(cin.getPosition());
+                        bundle.setSize(cin.getByteCount());
                         return bundle;
                     } finally {
                         input.close();
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java	(working copy)
@@ -18,6 +18,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.persistence.util.BLOBStore;
 import org.apache.jackrabbit.core.persistence.util.ResourceBasedBLOBStore;
 import org.apache.jackrabbit.core.NodeId;
@@ -33,7 +34,6 @@
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
-import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.HashSet;
@@ -592,11 +592,7 @@
                                     blobStore.put(blobId, in, size);
                                     state.setBlobId(blobId, i);
                                 } finally {
-                                    try {
-                                        in.close();
-                                    } catch (IOException e) {
-                                        // ignore
-                                    }
+                                    IOUtils.closeQuietly(in);
                                 }
                             } catch (Exception e) {
                                 String msg = "Error while storing blob. id="
@@ -624,24 +620,16 @@
                     } else {
                         // delete evt. blob
                         out.writeInt((int) size);
-                        byte[] data = new byte[(int) size];
                         try {
                             InputStream in = blobVal.getStream();
                             try {
-                                int pos = 0;
-                                while (pos < size) {
-                                    int n = in.read(data, pos, (int) size - pos);
-                                    if (n < 0) {
-                                        throw new EOFException();
-                                    }
-                                    pos += n;
-                                }
+                                byte[] data = IOUtils.toByteArray(in);
+                                out.write(data, 0, data.length);
+                                // replace value instance with value
+                                // backed by resource in blob store and delete temp file
+                                values[i] = InternalValue.create(data);
                             } finally {
-                                try {
-                                    in.close();
-                                } catch (IOException e) {
-                                    // ignore
-                                }
+                                IOUtils.closeQuietly(in);
                             }
                         } catch (Exception e) {
                             String msg = "Error while storing blob. id="
@@ -649,10 +637,6 @@
                             log.error(msg, e);
                             throw new IOException(msg);
                         }
-                        out.write(data, 0, data.length);
-                        // replace value instance with value
-                        // backed by resource in blob store and delete temp file
-                        values[i] = InternalValue.create(data);
                         blobVal.discard();
                     }
                     break;
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ItemStateBinding.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ItemStateBinding.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/ItemStateBinding.java	(working copy)
@@ -272,10 +272,7 @@
     public UUID readUUID(DataInputStream in) throws IOException {
         if (in.readBoolean()) {
             byte[] bytes = new byte[16];
-            int pos = 0;
-            while (pos < 16) {
-                pos += in.read(bytes, pos, 16 - pos);
-            }
+            in.readFully(bytes);
             return new UUID(bytes);
         } else {
             return null;
@@ -304,13 +301,9 @@
      * @throws IOException in an I/O error occurs.
      */
     public NodeId readID(DataInputStream in) throws IOException {
-        if (in.readBoolean()) {
-            byte[] bytes = new byte[16];
-            int pos = 0;
-            while (pos < 16) {
-                pos += in.read(bytes, pos, 16 - pos);
-            }
-            return new NodeId(new UUID(bytes));
+        UUID uuid = readUUID(in);
+        if (uuid != null) {
+            return new NodeId(uuid);
         } else {
             return null;
         }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/TrackingInputStream.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/TrackingInputStream.java	(revision 628076)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/TrackingInputStream.java	(working copy)
@@ -1,139 +0,0 @@
-/*
- * 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.
- */
-package org.apache.jackrabbit.core.persistence.bundle.util;
-
-import java.io.InputStream;
-import java.io.IOException;
-
-/**
- * Implements a input stream that keeps track of the number of bytes read.
- */
-public class TrackingInputStream extends InputStream {
-
-    /**
-     * The underlying input stream
-     */
-    private final InputStream in;
-
-    /**
-     * the current position
-     */
-    private long position;
-
-    /**
-     * the mark position
-     */
-    private long markPos;
-
-    /**
-     * Creates a new tracking input stream
-     * @param in the underlying input stream
-     */
-    public TrackingInputStream(InputStream in) {
-        this.in = in;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int available() throws IOException {
-        return in.available();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public void close() throws IOException {
-        in.close();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public synchronized void reset() throws IOException {
-        in.reset();
-        position = markPos;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public boolean markSupported() {
-        return in.markSupported();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public synchronized void mark(int readlimit) {
-        in.mark(readlimit);
-        markPos = position;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public long skip(long n) throws IOException {
-        long read = in.skip(n);
-        if (read > 0) {
-            position += read;
-        }
-        return read;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int read(byte[] b) throws IOException {
-        int read = in.read(b);
-        if (read > 0) {
-            position += read;
-        }
-        return read;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int read(byte[] b, int off, int len) throws IOException {
-        int read = in.read(b, off, len);
-        if (read > 0) {
-            position += read;
-        }
-        return read;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    public int read() throws IOException {
-        int read = in.read();
-        if (read >= 0) {
-            position++;
-        }
-        return read;
-    }
-
-    /**
-     * Returns the number of bytes read so far.
-     * @return the number of bytes.
-     */
-    public long getPosition() {
-        return position;
-    }
-
-}
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/Oracle9PersistenceManager.java	(working copy)
@@ -18,6 +18,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.persistence.PMContext;
 import org.apache.jackrabbit.core.persistence.bundle.util.NodePropBundle;
 import org.apache.jackrabbit.core.persistence.util.Serializer;
@@ -198,11 +199,7 @@
         Method getBinaryOutputStream = blobClass.getMethod("getBinaryOutputStream", new Class[0]);
         OutputStream out = (OutputStream) getBinaryOutputStream.invoke(blob, null);
         try {
-            int read;
-            byte[] buf = new byte[8192];
-            while ((read = in.read(buf, 0, buf.length)) > -1) {
-                out.write(buf, 0, read);
-            }
+            IOUtils.copy(in, out);
         } finally {
             try {
                 out.flush();
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/FileSystemBLOBStore.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/FileSystemBLOBStore.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/FileSystemBLOBStore.java	(working copy)
@@ -16,12 +16,12 @@
  */
 package org.apache.jackrabbit.core.persistence.util;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.fs.FileSystem;
 import org.apache.jackrabbit.core.fs.FileSystemPathUtil;
 import org.apache.jackrabbit.core.fs.FileSystemResource;
 
-import java.io.BufferedOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 
@@ -85,21 +85,14 @@
      * {@inheritDoc}
      */
     public void put(String blobId, InputStream in, long size) throws Exception {
-        OutputStream out = null;
         // the blobId is an absolute file system path
         FileSystemResource internalBlobFile = new FileSystemResource(fs, blobId);
         internalBlobFile.makeParentDirs();
+        OutputStream out = internalBlobFile.getOutputStream();
         try {
-            out = new BufferedOutputStream(internalBlobFile.getOutputStream());
-            byte[] buffer = new byte[8192];
-            int read;
-            while ((read = in.read(buffer)) > 0) {
-                out.write(buffer, 0, read);
-            }
+            IOUtils.copy(in, out);
         } finally {
-            if (out != null) {
-                out.close();
-            }
+            out.close();
         }
     }
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/Serializer.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/Serializer.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/Serializer.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.persistence.util;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.fs.FileSystemResource;
@@ -200,11 +201,7 @@
                 try {
                     blobStore.put(blobId, in, blobVal.getLength());
                 } finally {
-                    try {
-                        in.close();
-                    } catch (IOException e) {
-                        // ignore
-                    }
+                    IOUtils.closeQuietly(in);
                 }
                 // store id of BLOB as property value
                 out.writeUTF(blobId);   // value
@@ -295,11 +292,7 @@
                     try {
                         val = InternalValue.create(is);
                     } finally {
-                        try {
-                            is.close();
-                        } catch (IOException e) {
-                            // ignore
-                        }
+                        IOUtils.closeQuietly(in);
                     }
                 }
             } else {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/TransientRepository.java	(working copy)
@@ -33,6 +33,7 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.api.JackrabbitRepository;
 import org.apache.jackrabbit.core.config.ConfigurationException;
 import org.apache.jackrabbit.core.config.RepositoryConfig;
@@ -56,11 +57,6 @@
         LoggerFactory.getLogger(TransientRepository.class);
 
     /**
-     * Buffer size for copying the default repository configuration file.
-     */
-    private static final int BUFFER_SIZE = 4096;
-
-    /**
      * Resource path of the default repository configuration file.
      */
     private static final String DEFAULT_REPOSITORY_XML = "repository.xml";
@@ -220,13 +216,8 @@
                             InputStream input =
                                 TransientRepository.class.getResourceAsStream(
                                         DEFAULT_REPOSITORY_XML);
-                            byte[] buffer = new byte[BUFFER_SIZE];
                             try {
-                                int n = input.read(buffer);
-                                while (n != -1) {
-                                    output.write(buffer, 0, n);
-                                    n = input.read(buffer);
-                                }
+                                IOUtils.copy(input, output);
                             } finally {
                                input.close();
                             }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/TextExtractorJob.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/TextExtractorJob.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/TextExtractorJob.java	(working copy)
@@ -18,19 +18,20 @@
 
 import EDU.oswego.cs.dl.util.concurrent.FutureResult;
 import EDU.oswego.cs.dl.util.concurrent.Callable;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.AutoCloseInputStream;
+import org.apache.commons.io.output.DeferredFileOutputStream;
 import org.apache.jackrabbit.extractor.TextExtractor;
 import org.apache.jackrabbit.util.LazyFileInputStream;
 import org.slf4j.LoggerFactory;
 import org.slf4j.Logger;
 
+import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.io.Reader;
 import java.io.IOException;
 import java.io.File;
-import java.io.FileOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.io.BufferedWriter;
 import java.io.InputStreamReader;
 import java.io.StringReader;
 import java.lang.reflect.InvocationTargetException;
@@ -179,69 +180,30 @@
      * @return a reader to the temp file.
      */
     private Reader getSwappedOutReader(Reader r) {
-        final File temp;
+        DeferredFileOutputStream buffer =
+            new DeferredFileOutputStream(16 * 1024, "extractor", null, null);
         try {
-            temp = File.createTempFile("extractor", null);
-        } catch (IOException e) {
-            // unable to create temp file
-            // return reader as is
-            return r;
-        }
-        Writer out;
-        try {
-            out = new BufferedWriter(new OutputStreamWriter(
-                            new FileOutputStream(temp), ENCODING_UTF8));
-        } catch (IOException e) {
-            // should never happend actually
-            if (!temp.delete()) {
-                temp.deleteOnExit();
-            }
-            return r;
-        }
-
-        // spool into temp file
-        char[] buffer = new char[1024];
-        int len;
-        InputStream in = null;
-        try {
             try {
-                while ((len = r.read(buffer)) >= 0) {
-                    out.write(buffer, 0, len);
-                }
-                out.close();
+                IOUtils.copy(r, buffer, ENCODING_UTF8);
             } finally {
                 r.close();
             }
-            in = new LazyFileInputStream(temp);
 
-            return new InputStreamReader(in, ENCODING_UTF8) {
-                public void close() throws IOException {
-                    super.close();
-                    // delete file
-                    if (!temp.delete()) {
-                        temp.deleteOnExit();
+            InputStream input;
+            final File file = buffer.getFile();
+            if (file != null) {
+                input = new AutoCloseInputStream(new LazyFileInputStream(file) {
+                    public void close() throws IOException {
+                        super.close();
+                        file.delete();
                     }
-                }
-            };
-        } catch (IOException e) {
-            // do some clean up
-            try {
-                out.close();
-            } catch (IOException e1) {
-                // ignore
+                });
+            } else {
+                input = new ByteArrayInputStream(buffer.getData());
             }
-
-            if (in != null) {
-                try {
-                    in.close();
-                } catch (IOException e1) {
-                    // ignore
-                }
-            }
-
-            if (!temp.delete()) {
-                temp.deleteOnExit();
-            }
+            return new InputStreamReader(input, ENCODING_UTF8);
+        } catch (IOException e) {
+            log.warn("Failed to swap out reader", e);
             // use empty string reader as fallback
             return new StringReader("");
         }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java	(revision 628076)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/TempFileInputStream.java	(working copy)
@@ -1,118 +0,0 @@
-/*
- * 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.
- */
-package org.apache.jackrabbit.core.data.db;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-/**
- * An input stream from a temp file that self-destructs when fully read or closed.
- */
-public class TempFileInputStream extends InputStream {
-
-    private final File file;
-    private final InputStream in;
-    private boolean closed;
-
-    /**
-     * Copy the data to a file and close the input stream afterwards.
-     *
-     * @param in the input stream
-     * @param file the target file
-     * @return the size of the file
-     */
-    public static long writeToFileAndClose(InputStream in, File file) throws IOException {
-        OutputStream out = new FileOutputStream(file);
-        byte[] b = new byte[4096];
-        while (true) {
-            int n = in.read(b);
-            if (n < 0) {
-                break;
-            }
-            out.write(b, 0, n);
-        }
-        out.close();
-        in.close();
-        return file.length();
-    }
-
-    /**
-     * Construct a new temporary file input stream.
-     * The file is deleted if the input stream is closed or fully read.
-     * Deleting is only attempted once.
-     *
-     * @param file the temporary file
-     */
-    TempFileInputStream(File file) throws FileNotFoundException {
-        this.file = file;
-        in = new BufferedInputStream(new FileInputStream(file));
-    }
-
-    private int closeIfEOF(int read) throws IOException {
-        if (read < 0) {
-            close();
-        }
-        return read;
-    }
-
-    public void close() throws IOException {
-        if (!closed) {
-            in.close();
-            file.delete();
-            closed = true;
-        }
-    }
-
-    public int available() throws IOException {
-        return in.available();
-    }
-
-    public void mark(int readlimit) {
-        in.mark(readlimit);
-    }
-
-    public boolean markSupported() {
-        return in.markSupported();
-    }
-
-    public long skip(long n) throws IOException {
-        return in.skip(n);
-    }
-
-    public void reset() throws IOException {
-        in.reset();
-    }
-
-    public int read(byte[] b, int off, int len) throws IOException {
-        return closeIfEOF(in.read(b, off, len));
-    }
-
-    public int read(byte[] b) throws IOException {
-        return closeIfEOF(in.read(b));
-    }
-
-    public int read() throws IOException {
-        return closeIfEOF(in.read());
-    }
-
-}
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java	(revision 628263)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/db/DbDataStore.java	(working copy)
@@ -16,12 +16,15 @@
  */
 package org.apache.jackrabbit.core.data.db;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.AutoCloseInputStream;
+import org.apache.commons.io.input.CountingInputStream;
+import org.apache.commons.io.output.DeferredFileOutputStream;
 import org.apache.jackrabbit.core.data.DataIdentifier;
 import org.apache.jackrabbit.core.data.DataRecord;
 import org.apache.jackrabbit.core.data.DataStore;
 import org.apache.jackrabbit.core.data.DataStoreException;
 import org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager;
-import org.apache.jackrabbit.core.persistence.bundle.util.TrackingInputStream;
 import org.apache.jackrabbit.core.persistence.bundle.util.ConnectionRecoveryManager.StreamWrapper;
 import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.uuid.UUID;
@@ -29,7 +32,9 @@
 import org.slf4j.LoggerFactory;
 
 import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.ref.WeakReference;
@@ -279,7 +284,6 @@
      */
     public DataRecord addRecord(InputStream stream) throws DataStoreException {
         ResultSet rs = null;
-        TempFileInputStream fileInput = null;
         ConnectionRecoveryManager conn = getConnection();
         try {
             conn.setAutoReconnect(false);
@@ -309,23 +313,22 @@
             }
             MessageDigest digest = getDigest();
             DigestInputStream dIn = new DigestInputStream(stream, digest);
-            TrackingInputStream in = new TrackingInputStream(dIn);
+            CountingInputStream in = new CountingInputStream(dIn);
             StreamWrapper wrapper;
             if (STORE_SIZE_MINUS_ONE.equals(storeStream)) {
                 wrapper = new StreamWrapper(in, -1);
             } else if (STORE_SIZE_MAX.equals(storeStream)) {
                 wrapper = new StreamWrapper(in, Integer.MAX_VALUE);
             } else if (STORE_TEMP_FILE.equals(storeStream)) {
-                File temp = moveToTempFile(in);
-                fileInput = new TempFileInputStream(temp);
-                long length = temp.length();
-                wrapper = new StreamWrapper(fileInput, length);
+                CountingInputStream count = new CountingInputStream(stream);
+                InputStream copy = copyAndClose(count);
+                wrapper = new StreamWrapper(copy, count.getByteCount());
             } else {
                 throw new DataStoreException("Unsupported stream store algorithm: " + storeStream);
             }
             conn.executeStmt(updateDataSQL, new Object[]{wrapper, tempId});
             now = System.currentTimeMillis();
-            long length = in.getPosition();
+            long length = in.getByteCount();
             DataIdentifier identifier = new DataIdentifier(digest.digest());
             usesIdentifier(identifier);
             id = identifier.toString();
@@ -366,28 +369,49 @@
         } finally {
             conn.closeSilently(rs);
             putBack(conn);
-            if (fileInput != null) {
-                try {
-                    fileInput.close();
-                } catch (IOException e) {
-                    throw convert("Can not close temporary file", e);
-                }
-            }
         }
     }
 
     /**
-     * Creates a temp file and copies the data there.
-     * The input stream is closed afterwards.
+     * Reads the given input stream into an internal buffer or a temporary
+     * file and returns a new input stream for reading the buffered content.
+     * The potential temporary file is automatically removed when the
+     * returned stream is fully read, closed, or finalized.
+     * <p>
+     * The given input stream is closed.
      *
-     * @param in the input stream
-     * @return the file
-     * @throws IOException
+     * @param in the original input stream
+     * @return buffered copy of the input stream
+     * @throws IOException if the stream could not be copied
      */
-    private File moveToTempFile(InputStream in) throws IOException {
-        File temp = File.createTempFile("dbRecord", null);
-        TempFileInputStream.writeToFileAndClose(in, temp);
-        return temp;
+    private InputStream copyAndClose(InputStream in) throws IOException {
+        DeferredFileOutputStream buffer =
+            new DeferredFileOutputStream(16 * 1024, "dbRecord", null, null);
+        try {
+            try {
+                IOUtils.copy(in, buffer);
+            } finally {
+                in.close();
+            }
+        } catch (IOException e) {
+            File file = buffer.getFile();
+            if (file != null) {
+                file.delete();
+            }
+            throw e;
+        }
+
+        final File file = buffer.getFile();
+        if (file != null) {
+            return new AutoCloseInputStream(new FileInputStream(file) {
+                public void close() throws IOException {
+                    super.close();
+                    file.delete();
+                }
+            });
+        } else {
+            return new ByteArrayInputStream(buffer.getData());
+        }
     }
 
     /**
@@ -658,12 +682,11 @@
             if (!rs.next()) {
                 throw new DataStoreException("Record not found: " + identifier);
             }
-            InputStream in = new BufferedInputStream(rs.getBinaryStream(2));
             if (copyWhenReading) {
-                File temp = moveToTempFile(in);
-                in = new TempFileInputStream(temp);
+                return copyAndClose(rs.getBinaryStream(2));
+            } else {
+                return new BufferedInputStream(rs.getBinaryStream(2));
             }
-            return in;
         } catch (Exception e) {
             throw convert("Can not read identifier " + identifier, e);
         } finally {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/data/FileDataStore.java	(working copy)
@@ -22,6 +22,7 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.ref.WeakReference;
+import java.security.DigestOutputStream;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.util.ArrayList;
@@ -29,6 +30,8 @@
 import java.util.List;
 import java.util.WeakHashMap;
 
+import org.apache.commons.io.IOUtils;
+
 /**
  * Simple file-based data store. Data records are stored as normal files
  * named using a message digest of the contained binary stream.
@@ -160,16 +163,10 @@
             temporary = newTemporaryFile();
             // Copy the stream to the temporary file and calculate the
             // stream length and the message digest of the stream
-            long length = 0;
             MessageDigest digest = MessageDigest.getInstance(DIGEST);
-            OutputStream output = new FileOutputStream(temporary);
+            OutputStream output =  new FileOutputStream(temporary);
             try {
-                byte[] b = new byte[4096];
-                for (int n = input.read(b); n != -1; n = input.read(b)) {
-                    output.write(b, 0, n);
-                    digest.update(b, 0, n);
-                    length += n;
-                }
+                IOUtils.copy(input, new DigestOutputStream(output, digest));
             } finally {
                 output.close();
             }
@@ -191,6 +188,12 @@
                             + " to " + file.getAbsolutePath()
                             + " (media read only?)");
                 }
+            // Sanity checks on the record file. These should never fail,
+            // but better safe than sorry...
+            } else if (!file.isFile()) {
+                throw new IOException("Not a file: " + file);
+            } else if (file.length() != temporary.length()) {
+                throw new IOException(DIGEST + " collision: " + file);
             } else {
                 long now = System.currentTimeMillis();
                 if (file.lastModified() < now) {
@@ -198,15 +201,6 @@
                 }
             }
 
-            // Sanity checks on the record file. These should never fail,
-            // but better safe than sorry...
-            if (!file.isFile()) {
-                throw new IOException("Not a file: " + file);
-            }
-            if (file.length() != length) {
-                throw new IOException(DIGEST + " collision: " + file);
-            }
-
             return new FileDataRecord(identifier, file);
         } catch (NoSuchAlgorithmException e) {
             throw new DataStoreException(DIGEST + " not available", e);
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/InternalValue.java	(working copy)
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.value;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.core.data.DataStore;
 import org.apache.jackrabbit.core.fs.FileSystemResource;
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
@@ -472,11 +473,7 @@
         try {
             return createTemporary(stream);
         } finally {
-            try {
-                stream.close();
-            } catch (IOException e) {
-                // ignore
-            }
+            IOUtils.closeQuietly(stream);
         }
     }
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBFileValue.java	(working copy)
@@ -22,6 +22,8 @@
 
 import javax.jcr.RepositoryException;
 
+import org.apache.commons.io.IOUtils;
+
 /**
  * Represents binary data which is backed by a resource or byte[].
  * Unlike <code>BinaryValue</code> it has no state, i.e.
@@ -98,16 +100,9 @@
     public void spool(OutputStream out) throws RepositoryException, IOException {
         InputStream in = getStream();
         try {
-            byte[] buffer = new byte[0x2000];
-            int read;
-            while ((read = in.read(buffer)) > 0) {
-                out.write(buffer, 0, read);
-            }
+            IOUtils.copy(in, out);
         } finally {
-            try {
-                in.close();
-            } catch (IOException ignore) {
-            }
+            IOUtils.closeQuietly(in);
         }
     }
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/value/BLOBInTempFile.java	(working copy)
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core.value;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.CountingOutputStream;
 import org.apache.jackrabbit.util.TransientFileFactory;
 
 import java.io.File;
@@ -56,23 +58,13 @@
             TransientFileFactory fileFactory = TransientFileFactory.getInstance();
             file = fileFactory.createTransientFile("bin", null, null);
             out = new FileOutputStream(file);
-            byte[] buffer = new byte[4 * 1024];
-            while (true) {
-                int len = in.read(buffer);
-                if (len < 0) {
-                    break;
-                }
-                out.write(buffer, 0, len);
-                length += len;
-            }
+            CountingOutputStream count = new CountingOutputStream(out);
+            IOUtils.copy(in, count);
+            length = count.getByteCount();
         } catch (IOException e) {
             throw new RepositoryException("Error creating temporary file", e);
         } finally {
-            try {
-                in.close();
-            } catch (IOException e) {
-                // ignore
-            }
+            IOUtils.closeQuietly(in);
             if (out != null) {
                 try {
                     out.close();
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/PropertyState.java	(working copy)
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.core.state;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.CountingInputStream;
 import org.apache.jackrabbit.core.PropertyId;
 import org.apache.jackrabbit.core.NodeId;
 import org.apache.jackrabbit.core.ItemId;
@@ -274,12 +276,8 @@
                         BLOBFileValue blob = val.getBLOBFileValue();
                         InputStream in = blob.getStream();
                         out.writeLong(blob.getLength());
-                        byte[] buf = new byte[0x2000];
                         try {
-                            int read;
-                            while ((read = in.read(buf)) > 0) {
-                                out.write(buf, 0, read);
-                            }
+                            IOUtils.copy(in, out);
                         } finally {
                             in.close();
                         }
@@ -329,43 +327,37 @@
     }
 
     private InternalValue createInternalValueFromInputStream(
-            final InputStream stream, final long length)
+            InputStream stream, final long length)
             throws RepositoryException {
-        return InternalValue.create(new InputStream() {
+        return InternalValue.create(new CountingInputStream(stream) {
 
-            private long consumed = 0;
-
             public int read() throws IOException {
-                if (consumed >= length) {
+                if (getByteCount() >= length) {
                     return -1;  // eof
                 }
-                int b = stream.read();
-                consumed++;
-                return b;
+                return super.read();
             }
 
+            public int read(byte[] b) throws IOException {
+                return read(b, 0, b.length);
+            }
+
             public int read(byte[] b, int off, int len) throws IOException {
-                if (consumed >= length) {
-                    return -1;  // eof
+                len = Math.min(len, (int) (length - getByteCount()));
+                if (len >= 0) {
+                    return super.read(b, off, len);
+                } else {
+                    return -1;
                 }
-                if ((consumed + len) > length) {
-                    len = (int) (length - consumed);
-                }
-                int read = stream.read(b, off, len);
-                consumed += read;
-                return read;
             }
 
             public long skip(long n) throws IOException {
-                if (consumed >= length && n > 0) {
-                    return -1;  // eof
+                n = Math.min(n, length - getByteCount());
+                if (n >= 0) {
+                    return super.skip(n);
+                } else {
+                    return -1;
                 }
-                if ((consumed + n) > length) {
-                    n = length - consumed;
-                }
-                long skipped = stream.skip(n);
-                consumed += skipped;
-                return skipped;
             }
 
             public void close() {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java	(revision 628156)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java	(working copy)
@@ -21,6 +21,7 @@
 import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
 import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
 import org.apache.commons.collections.map.ReferenceMap;
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.api.JackrabbitRepository;
 import org.apache.jackrabbit.commons.AbstractRepository;
 import org.apache.jackrabbit.core.cluster.ClusterContext;
@@ -455,11 +456,7 @@
                     try {
                         reader.read(chars);
                     } finally {
-                        try {
-                            reader.close();
-                        } catch (IOException ioe) {
-                            // ignore
-                        }
+                        IOUtils.closeQuietly(reader);
                     }
                     return NodeId.valueOf(new String(chars));
                 } catch (Exception e) {
@@ -499,11 +496,7 @@
                     try {
                         writer.write(ROOT_NODE_ID.toString());
                     } finally {
-                        try {
-                            writer.close();
-                        } catch (IOException ioe) {
-                            // ignore
-                        }
+                        IOUtils.closeQuietly(writer);
                     }
                     return ROOT_NODE_ID;
                 } catch (Exception e) {
Index: jackrabbit-core/pom.xml
===================================================================
--- jackrabbit-core/pom.xml	(revision 628156)
+++ jackrabbit-core/pom.xml	(working copy)
@@ -254,6 +254,10 @@
       <artifactId>commons-collections</artifactId>
     </dependency>
     <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+    </dependency>
+    <dependency>
       <groupId>javax.jcr</groupId>
       <artifactId>jcr</artifactId>
     </dependency>
Index: pom.xml
===================================================================
--- pom.xml	(revision 628076)
+++ pom.xml	(working copy)
@@ -711,6 +711,11 @@
         <version>1.7.0</version>
       </dependency>
       <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>1.4</version>
+      </dependency>
+      <dependency>
         <groupId>org.apache.geronimo.specs</groupId>
         <artifactId>geronimo-jta_1.0.1B_spec</artifactId>
         <version>1.0.1</version>
