This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new acf5994  REST refactoring.
acf5994 is described below

commit acf59946f90ebf9c4b0bfa45258b9f6277a948c1
Author: JamesBognar <[email protected]>
AuthorDate: Fri Mar 5 13:45:28 2021 -0500

    REST refactoring.
---
 TODO.txt                                           |   1 +
 .../main/ConfigurablePropertyCodeGenerator.java    |   6 +-
 .../main/java/org/apache/juneau/config/Config.java |   4 +-
 .../juneau/config/store/ConfigClasspathStore.java  |   2 +-
 .../apache/juneau/jena/RdfSerializerSession.java   |   9 +-
 .../main/java/org/apache/juneau/BeanSession.java   |  11 +-
 .../org/apache/juneau/assertions/Assertions.java   |  74 ++-
 .../java/org/apache/juneau/cp/BasicFileFinder.java |   9 +-
 .../main/java/org/apache/juneau/cp/LocalFile.java  |   5 +-
 .../apache/juneau/html/HtmlSerializerSession.java  |   7 +-
 .../juneau/http/entity/AbstractHttpEntity.java     |   8 +-
 .../apache/juneau/http/entity/BasicHttpEntity.java |   2 +
 ...InputStreamEntity.java => ByteArrayEntity.java} | 100 ++-
 .../{InputStreamEntity.java => FileEntity.java}    |  83 ++-
 .../juneau/http/entity/InputStreamEntity.java      |  47 +-
 .../apache/juneau/http/entity/StringEntity.java    |   8 +-
 .../java/org/apache/juneau/internal/IOUtils.java   | 714 +++++++++++----------
 .../apache/juneau/json/JsonSerializerSession.java  |   9 +-
 .../juneau/msgpack/MsgPackSerializerSession.java   |  12 +-
 .../java/org/apache/juneau/parser/ParserPipe.java  |   6 +-
 .../apache/juneau/transforms/InputStreamSwap.java  |   9 +-
 .../org/apache/juneau/transforms/ReaderSwap.java   |   5 +-
 .../apache/juneau/uon/UonSerializerSession.java    |   9 +-
 .../urlencoding/UrlEncodingSerializerSession.java  |  10 +-
 .../java/org/apache/juneau/utils/ManifestFile.java |   3 +-
 .../apache/juneau/xml/XmlSerializerSession.java    |   9 +-
 .../microservice/resources/DirectoryResource.java  |   4 +-
 .../apache/juneau/rest/test/TestMicroservice.java  |   8 +-
 .../jetty/JettyMicroserviceBuilder.java            |  11 +-
 .../jetty/resources/DebugResource.java             |   3 +-
 .../apache/juneau/rest/client/ResponseBody.java    |  17 +-
 .../org/apache/juneau/rest/client/RestRequest.java |   8 +-
 .../juneau/rest/mock/MockServletRequest.java       |  14 +-
 .../java/org/apache/juneau/rest/RequestBody.java   |   2 +-
 .../juneau/rest/reshandlers/DefaultHandler.java    |   8 +-
 .../rest/reshandlers/InputStreamHandler.java       |   7 +-
 .../juneau/rest/reshandlers/ReaderHandler.java     |   7 +-
 .../rest/util/CachingHttpServletRequest.java       |   6 +-
 .../apache/juneau/rest/widget/MenuItemWidget.java  |   3 +-
 .../juneau/config/store/ConfigFileStoreTest.java   |   9 +-
 .../http/remote/Remote_BodyAnnotation_Test.java    |  11 +-
 .../http/remote/Remote_CommonInterfaces_Test.java  |   8 +-
 .../remote/Remote_RemoteOpAnnotation_Test.java     |  56 +-
 .../http/remote/Remote_RequestAnnotation_Test.java |  12 +-
 .../remote/Remote_ResponseAnnotation_Test.java     |   6 +-
 .../juneau/httppart/OpenApiPartParser_Test.java    |  14 +-
 .../apache/juneau/rest/annotation/Body_Test.java   |  22 +-
 .../rest/client/RestClient_Response_Body_Test.java |  10 +-
 .../transforms/InputStreamBase64SwapTest.java      |   2 +-
 .../juneau/utils/ByteArrayInOutStreamTest.java     |   2 +-
 .../java/org/apache/juneau/utils/IOPipeTest.java   | 285 --------
 .../java/org/apache/juneau/utils/IOUtilsTest.java  |   2 +-
 52 files changed, 740 insertions(+), 959 deletions(-)

diff --git a/TODO.txt b/TODO.txt
index 5d3bc3b..b47edb0 100644
--- a/TODO.txt
+++ b/TODO.txt
@@ -16,3 +16,4 @@ HttpRuntimeException?
 Add ExceptionHeader
 REST query/formdata/path parts should extend from PartGroup class.
 Eliminate PartSupplier and HeaderSupplier?
+Replace ThrowableUtils.assertFieldNotNull() and other methods.
diff --git a/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java 
b/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
index 7d69922..f79f317 100644
--- a/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
+++ b/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
@@ -11,6 +11,8 @@
 // * specific language governing permissions and limitations under the 
License.                                              *
 // 
***************************************************************************************************************************
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 import java.lang.reflect.*;
 import java.lang.reflect.Method;
@@ -251,7 +253,7 @@ public class ConfigurablePropertyCodeGenerator {
                                System.err.println("@FluentSetters not present 
on class " + c.getName());
 
                        System.out.println("Processing " + f.getName());
-                       String s = IOUtils.read(f);
+                       String s = read(f);
 
                        int i1 = s.indexOf("<FluentSetters>"), i2 = 
s.indexOf("</FluentSetters>");
                        String cpSection = null;
@@ -348,7 +350,7 @@ public class ConfigurablePropertyCodeGenerator {
                        }
 
                        s = s.substring(0, i1+15) + sb.toString() + "\n\n\t// " 
+ s.substring(i2);
-                       IOUtils.write(f, new StringReader(s));
+                       pipe(new StringReader(s), f);
                }
 
                System.out.println("DONE");
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
index 5cf85d0..7fae5fe 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
@@ -15,6 +15,7 @@ package org.apache.juneau.config;
 import static org.apache.juneau.config.ConfigMod.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.beans.*;
 import java.io.*;
@@ -30,7 +31,6 @@ import org.apache.juneau.config.event.*;
 import org.apache.juneau.config.internal.*;
 import org.apache.juneau.config.store.*;
 import org.apache.juneau.config.vars.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
@@ -1764,7 +1764,7 @@ public final class Config extends Context implements 
ConfigEventListener, Writab
         */
        public Config load(Reader contents, boolean synchronous) throws 
IOException, InterruptedException {
                checkWrite();
-               configMap.load(IOUtils.read(contents), synchronous);
+               configMap.load(read(contents), synchronous);
                return this;
        }
 
diff --git 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
index 79faedb..b3eae66 100644
--- 
a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
+++ 
b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigClasspathStore.java
@@ -86,7 +86,7 @@ public class ConfigClasspathStore extends ConfigStore {
                ClassLoader cl = Thread.currentThread().getContextClassLoader();
                try (InputStream in = cl.getResourceAsStream(name)) {
                        if (in != null)
-                               cache.put(name, IOUtils.read(in, IOUtils.UTF8));
+                               cache.put(name, IOUtils.read(in));
                }
                return emptyIfNull(cache.get(name));
        }
diff --git 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index 503f987..4f0bf43 100644
--- 
a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ 
b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -14,8 +14,9 @@ package org.apache.juneau.jena;
 
 import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfSerializer.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
-import java.io.IOException;
+import java.io.*;
 import java.util.*;
 
 import org.apache.jena.rdf.model.*;
@@ -266,8 +267,10 @@ public final class RdfSerializerSession extends 
WriterSerializerSession {
                                default: n = serializeToContainer(c, eType, 
m.createSeq());
                        }
 
-               } else if (sType.isReader() || sType.isInputStream()) {
-                       n = 
m.createLiteral(encodeTextInvalidChars(IOUtils.read(o)));
+               } else if (sType.isReader()) {
+                       n = 
m.createLiteral(encodeTextInvalidChars(read((Reader)o)));
+               } else if (sType.isInputStream()) {
+                       n = 
m.createLiteral(encodeTextInvalidChars(read((InputStream)o)));
 
                } else {
                        n = 
m.createLiteral(encodeTextInvalidChars(toString(o)));
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 2d6db4e..30c12f1 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -14,6 +14,7 @@ package org.apache.juneau;
 
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -473,9 +474,9 @@ public class BeanSession extends Session {
 
                        if (to.isByteArray()) {
                                if (from.isInputStream())
-                                       return 
(T)IOUtils.readBytes((InputStream)value, 1024);
+                                       return (T)readBytes((InputStream)value);
                                if (from.isReader())
-                                       return 
(T)IOUtils.read((Reader)value).getBytes();
+                                       return 
(T)read((Reader)value).getBytes();
                                if (to.hasMutaterFrom(from))
                                        return to.mutateFrom(value);
                                if (from.hasMutaterTo(to))
@@ -1153,9 +1154,9 @@ public class BeanSession extends Session {
        }
 
        /**
-        * Creates either an {@link OMap} or {@link AMap} depending on whether 
the key type is 
+        * Creates either an {@link OMap} or {@link AMap} depending on whether 
the key type is
         * String or something else.
-        * 
+        *
         * @param mapMeta The metadata of the map to create.
         * @return A new map.
         */
@@ -1503,7 +1504,7 @@ public class BeanSession extends Session {
                return super.toMap()
                        .a("Context", ctx.toMap())
                        .a(
-                               "BeanSession", 
+                               "BeanSession",
                                OMap
                                        .create()
                                        .filtered()
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
index 8daac05..b941e50 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/assertions/Assertions.java
@@ -12,12 +12,13 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.assertions;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 import java.time.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.internal.*;
 
 /**
  * Main class for creation of assertions for testing.
@@ -36,7 +37,7 @@ public class Assertions {
         * @param value The date being wrapped.
         * @return A new {@link DateAssertion} object.  Never <jk>null</jk>.
         */
-       public static DateAssertion assertDate(Date value) {
+       public static final DateAssertion assertDate(Date value) {
                return DateAssertion.create(value);
        }
 
@@ -52,7 +53,7 @@ public class Assertions {
         * @param value The date being wrapped.
         * @return A new {@link DateAssertion} object.  Never <jk>null</jk>.
         */
-       public static DateAssertion assertDate(Optional<Date> value) {
+       public static final DateAssertion assertDate(Optional<Date> value) {
                assertArgNotNull("value", value);
                return assertDate(value.orElse(null));
        }
@@ -69,7 +70,7 @@ public class Assertions {
         * @param value The date being wrapped.
         * @return A new {@link ZonedDateTimeAssertion} object.  Never 
<jk>null</jk>.
         */
-       public static ZonedDateTimeAssertion assertZonedDateTime(ZonedDateTime 
value) {
+       public static final ZonedDateTimeAssertion 
assertZonedDateTime(ZonedDateTime value) {
                return ZonedDateTimeAssertion.create(value);
        }
 
@@ -85,7 +86,7 @@ public class Assertions {
         * @param value The date being wrapped.
         * @return A new {@link ZonedDateTimeAssertion} object.  Never 
<jk>null</jk>.
         */
-       public static ZonedDateTimeAssertion 
assertZonedDateTime(Optional<ZonedDateTime> value) {
+       public static final ZonedDateTimeAssertion 
assertZonedDateTime(Optional<ZonedDateTime> value) {
                assertArgNotNull("value", value);
                return assertZonedDateTime(value.orElse(null));
        }
@@ -102,7 +103,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link IntegerAssertion} object.  Never <jk>null</jk>.
         */
-       public static IntegerAssertion assertInteger(Integer value) {
+       public static final IntegerAssertion assertInteger(Integer value) {
                return IntegerAssertion.create(value);
        }
 
@@ -118,7 +119,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link IntegerAssertion} object.  Never <jk>null</jk>.
         */
-       public static IntegerAssertion assertInteger(Optional<Integer> value) {
+       public static final IntegerAssertion assertInteger(Optional<Integer> 
value) {
                assertArgNotNull("value", value);
                return assertInteger(value.orElse(null));
        }
@@ -135,7 +136,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link LongAssertion} object.  Never <jk>null</jk>.
         */
-       public static LongAssertion assertLong(Long value) {
+       public static final LongAssertion assertLong(Long value) {
                return LongAssertion.create(value);
        }
 
@@ -151,7 +152,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link LongAssertion} object.  Never <jk>null</jk>.
         */
-       public static LongAssertion assertLong(Optional<Long> value) {
+       public static final LongAssertion assertLong(Optional<Long> value) {
                assertArgNotNull("value", value);
                return assertLong(value.orElse(null));
        }
@@ -168,7 +169,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link LongAssertion} object.  Never <jk>null</jk>.
         */
-       public static ComparableAssertion assertComparable(Comparable<?> value) 
{
+       public static final ComparableAssertion assertComparable(Comparable<?> 
value) {
                return ComparableAssertion.create(value);
        }
 
@@ -184,7 +185,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link ObjectAssertion} object.  Never <jk>null</jk>.
         */
-       public static <V> ObjectAssertion<V> assertObject(V value) {
+       public static final <V> ObjectAssertion<V> assertObject(V value) {
                return ObjectAssertion.create(value);
        }
 
@@ -200,7 +201,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link ObjectAssertion} object.  Never <jk>null</jk>.
         */
-       public static <V> ObjectAssertion<V> assertObject(Optional<V> value) {
+       public static final <V> ObjectAssertion<V> assertObject(Optional<V> 
value) {
                assertArgNotNull("value", value);
                return assertObject(value.orElse(null));
        }
@@ -217,7 +218,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link BeanAssertion} object.  Never <jk>null</jk>.
         */
-       public static <V> BeanAssertion<V> assertBean(V value) {
+       public static final <V> BeanAssertion<V> assertBean(V value) {
                return BeanAssertion.create(value);
        }
 
@@ -233,7 +234,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link BeanAssertion} object.  Never <jk>null</jk>.
         */
-       public static <V> BeanAssertion<V> assertBean(Optional<V> value) {
+       public static final <V> BeanAssertion<V> assertBean(Optional<V> value) {
                assertArgNotNull("value", value);
                return assertBean(value.orElse(null));
        }
@@ -250,7 +251,7 @@ public class Assertions {
         * @param value The string being wrapped.
         * @return A new {@link StringAssertion} object.  Never <jk>null</jk>.
         */
-       public static StringAssertion assertString(Object value) {
+       public static final StringAssertion assertString(Object value) {
                return StringAssertion.create(value);
        }
 
@@ -266,7 +267,7 @@ public class Assertions {
         * @param value The string being wrapped.
         * @return A new {@link StringAssertion} object.  Never <jk>null</jk>.
         */
-       public static StringAssertion assertString(Optional<?> value) {
+       public static final StringAssertion assertString(Optional<?> value) {
                assertArgNotNull("value", value);
                return assertString(value.orElse(null));
        }
@@ -283,7 +284,7 @@ public class Assertions {
         * @param value The boolean being wrapped.
         * @return A new {@link BooleanAssertion} object.  Never <jk>null</jk>.
         */
-       public static BooleanAssertion assertBoolean(Boolean value) {
+       public static final BooleanAssertion assertBoolean(Boolean value) {
                return BooleanAssertion.create(value);
        }
 
@@ -299,7 +300,7 @@ public class Assertions {
         * @param value The boolean being wrapped.
         * @return A new {@link BooleanAssertion} object.  Never <jk>null</jk>.
         */
-       public static BooleanAssertion assertBoolean(Optional<Boolean> value) {
+       public static final BooleanAssertion assertBoolean(Optional<Boolean> 
value) {
                assertArgNotNull("value", value);
                return assertBoolean(value.orElse(null));
        }
@@ -316,7 +317,7 @@ public class Assertions {
         * @param value The throwable being wrapped.
         * @return A new {@link ThrowableAssertion} object.  Never 
<jk>null</jk>.
         */
-       public static <V extends Throwable> ThrowableAssertion<V> 
assertThrowable(V value) {
+       public static final <V extends Throwable> ThrowableAssertion<V> 
assertThrowable(V value) {
                return ThrowableAssertion.create(value);
        }
 
@@ -332,7 +333,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link ArrayAssertion} object.  Never <jk>null</jk>.
         */
-       public static ArrayAssertion assertArray(Object value) {
+       public static final ArrayAssertion assertArray(Object value) {
                return ArrayAssertion.create(value);
        }
 
@@ -348,7 +349,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link CollectionAssertion} object.  Never 
<jk>null</jk>.
         */
-       public static CollectionAssertion assertCollection(Collection<?> value) 
{
+       public static final CollectionAssertion assertCollection(Collection<?> 
value) {
                return CollectionAssertion.create(value);
        }
 
@@ -364,7 +365,7 @@ public class Assertions {
         * @param value The object being wrapped.
         * @return A new {@link ListAssertion} object.  Never <jk>null</jk>.
         */
-       public static ListAssertion assertList(List<?> value) {
+       public static final ListAssertion assertList(List<?> value) {
                return ListAssertion.create(value);
        }
 
@@ -381,7 +382,7 @@ public class Assertions {
         * @return A new {@link MapAssertion} object.  Never <jk>null</jk>.
         */
        @SuppressWarnings("rawtypes")
-       public static MapAssertion assertMap(Map value) {
+       public static final MapAssertion assertMap(Map value) {
                return MapAssertion.create(value);
        }
 
@@ -400,7 +401,7 @@ public class Assertions {
         * @param snippet The snippet of code to execute.
         * @return A new assertion object.  Never <jk>null</jk>.
         */
-       public static ThrowableAssertion<Throwable> assertThrown(Snippet 
snippet) {
+       public static final ThrowableAssertion<Throwable> assertThrown(Snippet 
snippet) {
                return assertThrown(Throwable.class, snippet);
        }
 
@@ -421,7 +422,7 @@ public class Assertions {
         * @return A new assertion object.  Never <jk>null</jk>.
         */
        @SuppressWarnings("unchecked")
-       public static <T extends Throwable> ThrowableAssertion<Throwable> 
assertThrown(Class<T> type, Snippet snippet) {
+       public static final <T extends Throwable> ThrowableAssertion<Throwable> 
assertThrown(Class<T> type, Snippet snippet) {
                try {
                        snippet.run();
                } catch (Throwable e) {
@@ -441,12 +442,15 @@ public class Assertions {
         *      
<jsm>assertStream</jsm>(<jv>myStream</jv>).asHex().is(<js>"666F6F"</js>);
         * </p>
         *
-        * @param value The input stream being wrapped.
+        * @param value
+        *      The input stream being wrapped.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
         * @return A new {@link ByteArrayAssertion} object.  Never 
<jk>null</jk>.
         * @throws IOException If thrown while reading contents from stream.
         */
-       public static ByteArrayAssertion assertStream(InputStream value) throws 
IOException {
-               return assertBytes(value == null ? null : 
IOUtils.readBytes(value));
+       public static final ByteArrayAssertion assertStream(InputStream value) 
throws IOException {
+               return assertBytes(value == null ? null : readBytes(value));
        }
 
        /**
@@ -462,7 +466,7 @@ public class Assertions {
         * @return A new {@link ByteArrayAssertion} object.  Never 
<jk>null</jk>.
         * @throws IOException If thrown while reading contents from stream.
         */
-       public static ByteArrayAssertion assertStream(Optional<InputStream> 
value) throws IOException {
+       public static final ByteArrayAssertion 
assertStream(Optional<InputStream> value) throws IOException {
                assertArgNotNull("value", value);
                return assertStream(value.orElse(null));
        }
@@ -479,7 +483,7 @@ public class Assertions {
         * @param value The byte array being wrapped.
         * @return A new {@link ByteArrayAssertion} object.  Never 
<jk>null</jk>.
         */
-       public static ByteArrayAssertion assertBytes(byte[] value) {
+       public static final ByteArrayAssertion assertBytes(byte[] value) {
                return ByteArrayAssertion.create(value);
        }
 
@@ -495,7 +499,7 @@ public class Assertions {
         * @param value The byte array being wrapped.
         * @return A new {@link ByteArrayAssertion} object.  Never 
<jk>null</jk>.
         */
-       public static ByteArrayAssertion assertBytes(Optional<byte[]> value) {
+       public static final ByteArrayAssertion assertBytes(Optional<byte[]> 
value) {
                assertArgNotNull("value", value);
                return assertBytes(value.orElse(null));
        }
@@ -513,8 +517,8 @@ public class Assertions {
         * @return A new {@link StringAssertion} object.  Never <jk>null</jk>.
         * @throws IOException If thrown while reading contents from reader.
         */
-       public static StringAssertion assertReader(Reader value) throws 
IOException {
-               return assertString(value == null ? null : IOUtils.read(value));
+       public static final StringAssertion assertReader(Reader value) throws 
IOException {
+               return assertString(read(value));
        }
 
        /**
@@ -530,7 +534,7 @@ public class Assertions {
         * @return A new {@link StringAssertion} object.  Never <jk>null</jk>.
         * @throws IOException If thrown while reading contents from reader.
         */
-       public static StringAssertion assertReader(Optional<Reader> value) 
throws IOException {
+       public static final StringAssertion assertReader(Optional<Reader> 
value) throws IOException {
                assertArgNotNull("value", value);
                return assertReader(value.orElse(null));
        }
@@ -544,7 +548,7 @@ public class Assertions {
         * @return The same argument.
         * @throws IllegalArgumentException Constructed exception.
         */
-       public static <T> T assertArgNotNull(String arg, T o) throws 
IllegalArgumentException {
+       public static final <T> T assertArgNotNull(String arg, T o) throws 
IllegalArgumentException {
                if (o == null)
                        throw new BasicIllegalArgumentException("Argument 
''{0}'' cannot be null", arg);
                return o;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
index 4e431ed..ba74dbc 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/BasicFileFinder.java
@@ -15,6 +15,7 @@ package org.apache.juneau.cp;
 import static org.apache.juneau.internal.FileUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ObjectUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 import static java.util.Arrays.*;
 import static java.util.stream.Collectors.*;
 
@@ -100,18 +101,18 @@ public class BasicFileFinder implements FileFinder {
 
        @Override /* FileFinder */
        public final Optional<String> getString(String name) throws IOException 
{
-               return Optional.ofNullable(IOUtils.read(find(name, 
null).orElse(null), IOUtils.UTF8));
+               return Optional.ofNullable(read(find(name, null).orElse(null)));
        }
 
        @Override /* FileFinder */
        public Optional<String> getString(String name, Locale locale) throws 
IOException {
-               return Optional.ofNullable(IOUtils.read(find(name, 
locale).orElse(null), IOUtils.UTF8));
+               return Optional.ofNullable(read(find(name, 
locale).orElse(null)));
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
        // Implementation methods
        
//-----------------------------------------------------------------------------------------------------------------
-       
+
        /**
         * The main implementation method for finding files.
         *
@@ -168,7 +169,7 @@ public class BasicFileFinder implements FileFinder {
 
                return Optional.of(lf.read());
        }
-       
+
        /**
         * Returns the candidate file names for the specified file name in the 
specified locale.
         *
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/LocalFile.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/LocalFile.java
index 23c71e2..b180947 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/LocalFile.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/cp/LocalFile.java
@@ -13,12 +13,11 @@
 package org.apache.juneau.cp;
 
 import static org.apache.juneau.assertions.Assertions.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.nio.file.*;
 
-import org.apache.juneau.internal.*;
-
 /**
  * Identifies a file located either on the classpath or file system.
  *
@@ -92,7 +91,7 @@ public class LocalFile {
         */
        public LocalFile cache() throws IOException {
                synchronized(this) {
-                       this.cache = IOUtils.readBytes(read());
+                       this.cache = readBytes(read());
                }
                return this;
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index e477249..5bc1b66 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -15,6 +15,7 @@ package org.apache.juneau.html;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.internal.ObjectUtils.*;
 import static org.apache.juneau.xml.XmlSerializerSession.ContentResult.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.*;
@@ -23,7 +24,6 @@ import java.util.regex.*;
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.html.annotation.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
 import org.apache.juneau.xml.*;
@@ -288,7 +288,10 @@ public class HtmlSerializerSession extends 
XmlSerializerSession {
                        if (sType.isReader() || sType.isInputStream()) {
                                pop();
                                indent -= xIndent;
-                               IOUtils.pipe(o, out);
+                               if (sType.isReader())
+                                       pipe((Reader)o, out);
+                               else
+                                       pipe((InputStream)o, out);
                                return ContentResult.CR_MIXED;
                        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/AbstractHttpEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/AbstractHttpEntity.java
index e11ec9c..1e5bae9 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/AbstractHttpEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/AbstractHttpEntity.java
@@ -12,6 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.http.entity;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 
 import org.apache.http.*;
@@ -149,7 +151,7 @@ public abstract class AbstractHttpEntity extends 
org.apache.http.entity.Abstract
         * @throws IOException If a problem occurred while trying to read the 
byte array.
         */
        public String asString() throws IOException {
-               return IOUtils.read(getContent());
+               return read(getContent());
        }
 
        /**
@@ -159,9 +161,7 @@ public abstract class AbstractHttpEntity extends 
org.apache.http.entity.Abstract
         * @throws IOException If a problem occurred while trying to read the 
byte array.
         */
        public byte[] asBytes() throws IOException {
-               try (InputStream o = getContent()) {
-                       return o == null ? null : IOUtils.readBytes(o);
-               }
+               return readBytes(getContent());
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java
index 9e6e484..a292d17 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/BasicHttpEntity.java
@@ -338,6 +338,7 @@ public class BasicHttpEntity extends 
org.apache.http.entity.BasicHttpEntity {
                }
        }
 
+       @SuppressWarnings("deprecation")
        @Override
        public void writeTo(OutputStream os) throws IOException {
                tryCache();
@@ -393,6 +394,7 @@ public class BasicHttpEntity extends 
org.apache.http.entity.BasicHttpEntity {
         * @return The byte array contents.
         * @throws IOException If object could not be read.
         */
+       @SuppressWarnings("deprecation")
        protected byte[] readBytes(Object o) throws IOException {
                return IOUtils.readBytes(o);
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
similarity index 53%
copy from 
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
copy to 
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
index 85b2758..fba9a36 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/ByteArrayEntity.java
@@ -13,123 +13,97 @@
 package org.apache.juneau.http.entity;
 
 import static org.apache.juneau.assertions.Assertions.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
-import java.util.concurrent.atomic.*;
 
 import org.apache.juneau.http.header.*;
-import org.apache.juneau.internal.*;
 
 /**
- * A streamed, non-repeatable entity that obtains its content from an {@link 
InputStream}.
+ * A repeatable entity that obtains its content from a byte array.
  */
-public class InputStreamEntity extends AbstractHttpEntity {
+public class ByteArrayEntity extends AbstractHttpEntity {
 
-       private final InputStream content;
-       private final long length;
-       private AtomicReference<byte[]> bytes = new AtomicReference<>();
+       private final byte[] content;
+       private final long maxLength;
 
        /**
-        * Creates a new {@link InputStreamEntity} object.
+        * Creates a new {@link ByteArrayEntity} object.
         *
         * <p>
         * Assumes no content type.
         *
         * @param content The entity content.  Can be <jk>null<jk>.
-        * @return A new {@link InputStreamEntity} object.
+        * @return A new {@link ByteArrayEntity} object.
         */
-       public static InputStreamEntity of(InputStream content) {
-               return new InputStreamEntity(content, -1, null);
+       public static ByteArrayEntity of(byte[] content) {
+               return new ByteArrayEntity(content, -1, null);
        }
 
        /**
-        * Creates a new {@link InputStreamEntity} object.
+        * Creates a new {@link ByteArrayEntity} object.
         *
         * @param content The entity content.  Can be <jk>null<jk>.
+        * @param maxLength The content maximum length, or <c>-1</c> to read 
the entire byte array.
         * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @param length The content length, or <c>-1</c> if not known.
-        * @return A new {@link InputStreamEntity} object.
+        * @return A new {@link ByteArrayEntity} object.
         */
-       public static InputStreamEntity of(InputStream content, long length, 
ContentType contentType) {
-               return new InputStreamEntity(content, length, contentType);
+       public static ByteArrayEntity of(byte[] content, long maxLength, 
ContentType contentType) {
+               return new ByteArrayEntity(content, maxLength, contentType);
        }
 
        /**
         * Constructor.
         *
         * @param content The entity content.  Can be <jk>null</jk>.
+        * @param maxLength The content maximum length, or <c>-1</c> to read 
the entire byte array.
         * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @param length The content length, or <c>-1</c> if not known.
         */
-       public InputStreamEntity(InputStream content, long length, ContentType 
contentType) {
-               this.content = content == null ? IOUtils.EMPTY_INPUT_STREAM : 
content;
-               this.length = length;
+       public ByteArrayEntity(byte[] content, long maxLength, ContentType 
contentType) {
+               this.content = content == null ? new byte[0] : content;
+               this.maxLength = maxLength;
                setContentType(contentType);
        }
 
+       @Override /* AbstractHttpEntity */
+       public String asString() throws IOException {
+               return new String(content, UTF8);
+       }
+
+       @Override /* AbstractHttpEntity */
+       public byte[] asBytes() throws IOException {
+               return content;
+       }
+
        @Override /* HttpEntity */
        public boolean isRepeatable() {
-               return false;
+               return true;
        }
 
        @Override /* HttpEntity */
        public long getContentLength() {
-               return length;
+               return content.length;
        }
 
        @Override /* HttpEntity */
        public InputStream getContent() throws IOException {
-               byte[] b = bytes.get();
-               return b == null ? content : new ByteArrayInputStream(b);
-       }
-
-       @Override /* AbstractHttpEntity */
-       public InputStreamEntity cache() throws IOException {
-               byte[] b = bytes.get();
-               if (b == null) {
-                       b = IOUtils.readBytes(content);
-                       bytes.set(b);
-               }
-               return this;
+               return new ByteArrayInputStream(content);
        }
 
        /**
-        * Writes bytes from the {@code InputStream} this entity was constructed
-        * with to an {@code OutputStream}.  The content length
-        * determines how many bytes are written.  If the length is unknown 
({@code -1}), the
-        * stream will be completely consumed (to the end of the stream).
+        * Writes the contents of the byte array directly to the output stream.
+        *
+        * The content length determines how many bytes are written.
+        * If the length is unknown ({@code -1}), the stream will be completely 
consumed (to the end of the stream).
         */
        @Override
        public void writeTo(OutputStream out) throws IOException {
                assertArgNotNull("out", out);
-               InputStream is = getContent();
-               try {
-                       byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
-                       int readLen;
-                       if (length < 0) {
-                               // consume until EOF
-                               while ((readLen = is.read(buffer)) != -1) {
-                                       out.write(buffer, 0, readLen);
-                               }
-                       } else {
-                               // consume no more than length
-                               long remaining = length;
-                               while (remaining > 0) {
-                                       readLen = is.read(buffer, 0, 
(int)Math.min(OUTPUT_BUFFER_SIZE, remaining));
-                                       if (readLen == -1) {
-                                               break;
-                                       }
-                                       out.write(buffer, 0, readLen);
-                                       remaining -= readLen;
-                               }
-                       }
-               } finally {
-                       is.close();
-               }
+               pipe(content, out, (int)maxLength);
        }
 
        @Override /* HttpEntity */
        public boolean isStreaming() {
-               return bytes.get() == null;
+               return false;
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
similarity index 64%
copy from 
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
copy to 
juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
index 85b2758..7507ee2 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/FileEntity.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.http.entity;
 
 import static org.apache.juneau.assertions.Assertions.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.concurrent.atomic.*;
@@ -21,37 +22,35 @@ import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 
 /**
- * A streamed, non-repeatable entity that obtains its content from an {@link 
InputStream}.
+ * A repeatable entity that obtains its content from a {@link File}.
  */
-public class InputStreamEntity extends AbstractHttpEntity {
+public class FileEntity extends AbstractHttpEntity {
 
-       private final InputStream content;
-       private final long length;
+       private final File content;
        private AtomicReference<byte[]> bytes = new AtomicReference<>();
 
        /**
-        * Creates a new {@link InputStreamEntity} object.
+        * Creates a new {@link FileEntity} object.
         *
         * <p>
         * Assumes no content type.
         *
         * @param content The entity content.  Can be <jk>null<jk>.
-        * @return A new {@link InputStreamEntity} object.
+        * @return A new {@link FileEntity} object.
         */
-       public static InputStreamEntity of(InputStream content) {
-               return new InputStreamEntity(content, -1, null);
+       public static FileEntity of(File content) {
+               return new FileEntity(content, null);
        }
 
        /**
-        * Creates a new {@link InputStreamEntity} object.
+        * Creates a new {@link FileEntity} object.
         *
         * @param content The entity content.  Can be <jk>null<jk>.
         * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @param length The content length, or <c>-1</c> if not known.
-        * @return A new {@link InputStreamEntity} object.
+        * @return A new {@link FileEntity} object.
         */
-       public static InputStreamEntity of(InputStream content, long length, 
ContentType contentType) {
-               return new InputStreamEntity(content, length, contentType);
+       public static FileEntity of(File content, ContentType contentType) {
+               return new FileEntity(content, contentType);
        }
 
        /**
@@ -59,35 +58,44 @@ public class InputStreamEntity extends AbstractHttpEntity {
         *
         * @param content The entity content.  Can be <jk>null</jk>.
         * @param contentType The entity content type, or <jk>null</jk> if not 
specified.
-        * @param length The content length, or <c>-1</c> if not known.
         */
-       public InputStreamEntity(InputStream content, long length, ContentType 
contentType) {
-               this.content = content == null ? IOUtils.EMPTY_INPUT_STREAM : 
content;
-               this.length = length;
+       public FileEntity(File content, ContentType contentType) {
+               this.content = content;
                setContentType(contentType);
        }
 
+       @Override /* AbstractHttpEntity */
+       public String asString() throws IOException {
+               return read(content);
+       }
+
+       @Override /* AbstractHttpEntity */
+       public byte[] asBytes() throws IOException {
+               cache();
+               return bytes.get();
+       }
+
        @Override /* HttpEntity */
        public boolean isRepeatable() {
-               return false;
+               return true;
        }
 
        @Override /* HttpEntity */
        public long getContentLength() {
-               return length;
+               return content == null ? 0 : content.length();
        }
 
        @Override /* HttpEntity */
        public InputStream getContent() throws IOException {
                byte[] b = bytes.get();
-               return b == null ? content : new ByteArrayInputStream(b);
+               return b == null ? new FileInputStream(content) : new 
ByteArrayInputStream(b);
        }
 
        @Override /* AbstractHttpEntity */
-       public InputStreamEntity cache() throws IOException {
+       public FileEntity cache() throws IOException {
                byte[] b = bytes.get();
                if (b == null) {
-                       b = IOUtils.readBytes(content);
+                       b = readBytes(content);
                        bytes.set(b);
                }
                return this;
@@ -102,34 +110,19 @@ public class InputStreamEntity extends AbstractHttpEntity 
{
        @Override
        public void writeTo(OutputStream out) throws IOException {
                assertArgNotNull("out", out);
-               InputStream is = getContent();
-               try {
-                       byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
-                       int readLen;
-                       if (length < 0) {
-                               // consume until EOF
-                               while ((readLen = is.read(buffer)) != -1) {
-                                       out.write(buffer, 0, readLen);
-                               }
-                       } else {
-                               // consume no more than length
-                               long remaining = length;
-                               while (remaining > 0) {
-                                       readLen = is.read(buffer, 0, 
(int)Math.min(OUTPUT_BUFFER_SIZE, remaining));
-                                       if (readLen == -1) {
-                                               break;
-                                       }
-                                       out.write(buffer, 0, readLen);
-                                       remaining -= readLen;
-                               }
+
+               byte[] b = bytes.get();
+               if (b != null) {
+                       out.write(b);
+               } else {
+                       try (InputStream is = getContent()) {
+                               IOUtils.pipe(is, out);
                        }
-               } finally {
-                       is.close();
                }
        }
 
        @Override /* HttpEntity */
        public boolean isStreaming() {
-               return bytes.get() == null;
+               return false;
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
index 85b2758..dabbc05 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/InputStreamEntity.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.http.entity;
 
 import static org.apache.juneau.assertions.Assertions.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.concurrent.atomic.*;
@@ -27,7 +28,7 @@ public class InputStreamEntity extends AbstractHttpEntity {
 
        private final InputStream content;
        private final long length;
-       private AtomicReference<byte[]> bytes = new AtomicReference<>();
+       private final AtomicReference<byte[]> bytes = new AtomicReference<>();
 
        /**
         * Creates a new {@link InputStreamEntity} object.
@@ -67,6 +68,17 @@ public class InputStreamEntity extends AbstractHttpEntity {
                setContentType(contentType);
        }
 
+       @Override /* AbstractHttpEntity */
+       public String asString() throws IOException {
+               return new String(asBytes(), UTF8);
+       }
+
+       @Override /* AbstractHttpEntity */
+       public byte[] asBytes() throws IOException {
+               cache();
+               return bytes.get();
+       }
+
        @Override /* HttpEntity */
        public boolean isRepeatable() {
                return false;
@@ -87,7 +99,9 @@ public class InputStreamEntity extends AbstractHttpEntity {
        public InputStreamEntity cache() throws IOException {
                byte[] b = bytes.get();
                if (b == null) {
-                       b = IOUtils.readBytes(content);
+                       try (InputStream is = getContent()) {
+                               b = readBytes(is, (int)length);
+                       }
                        bytes.set(b);
                }
                return this;
@@ -102,29 +116,14 @@ public class InputStreamEntity extends AbstractHttpEntity 
{
        @Override
        public void writeTo(OutputStream out) throws IOException {
                assertArgNotNull("out", out);
-               InputStream is = getContent();
-               try {
-                       byte[] buffer = new byte[OUTPUT_BUFFER_SIZE];
-                       int readLen;
-                       if (length < 0) {
-                               // consume until EOF
-                               while ((readLen = is.read(buffer)) != -1) {
-                                       out.write(buffer, 0, readLen);
-                               }
-                       } else {
-                               // consume no more than length
-                               long remaining = length;
-                               while (remaining > 0) {
-                                       readLen = is.read(buffer, 0, 
(int)Math.min(OUTPUT_BUFFER_SIZE, remaining));
-                                       if (readLen == -1) {
-                                               break;
-                                       }
-                                       out.write(buffer, 0, readLen);
-                                       remaining -= readLen;
-                               }
+
+               byte[] b = bytes.get();
+               if (b != null) {
+                       pipe(b, out, (int)length);
+               } else {
+                       try (InputStream is = getContent()) {
+                               pipe(is, out, length);
                        }
-               } finally {
-                       is.close();
                }
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
index 4110cad..2093372 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/entity/StringEntity.java
@@ -35,7 +35,7 @@ public class StringEntity extends AbstractHttpEntity {
 
        private final String content;
        private final Charset charset;
-       private AtomicReference<byte[]> bytes = new AtomicReference<>();
+       private final AtomicReference<byte[]> bytes = new AtomicReference<>();
 
        /**
         * Creates a new {@link StringEntity} object.
@@ -122,8 +122,10 @@ public class StringEntity extends AbstractHttpEntity {
        private byte[] getBytes() {
                byte[] b = bytes.get();
                if (b == null) {
-                        b = content.getBytes(charset == null ? IOUtils.UTF8 : 
charset);
-                        bytes.set(b);
+                       synchronized(bytes) {
+                                b = content.getBytes(charset == null ? 
IOUtils.UTF8 : charset);
+                                bytes.set(b);
+                       }
                }
                return b;
        }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/IOUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/IOUtils.java
index f19195d..7842b10 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/IOUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/IOUtils.java
@@ -12,13 +12,10 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.internal;
 
-import static org.apache.juneau.internal.ThrowableUtils.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
 import java.io.*;
 import java.nio.charset.*;
+import java.util.*;
 
-import org.apache.juneau.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -37,155 +34,399 @@ public final class IOUtils {
                }
        };
 
+       private static final int BUFF_SIZE = 1024;
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Piping utilities.
+       
//-----------------------------------------------------------------------------------------------------------------
+
        /**
-        * Reads the contents of a file into a string.
+        * Pipes the contents of the specified <c>Reader</c> to the specified 
file.
         *
-        * @param path The path of the file to read using default character 
encoding.
-        * @return The contents of the reader as a string, or <jk>null</jk> if 
file does not exist.
-        * @throws IOException If a problem occurred trying to read from the 
reader.
+        * @param in
+        *      The reader to pipe from.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Reader is automatically closed.
+        * @param out
+        *      The file to write the output to.
+        *      <br>Can be <jk>null</jk>.
+        * @return
+        *      The number of characters piped.
+        * @throws IOException Thrown by underlying stream.
         */
-       public static String readFile(String path) throws IOException {
-               return read(new File(path));
+       public static long pipe(Reader in, File out) throws IOException {
+               if (out == null || in == null)
+                       return 0;
+               try (Writer w = FileWriterBuilder.create(out).build()) {
+                       return pipe(in, w);
+               }
        }
 
        /**
-        * Reads the specified object to a <c>String</c>.
+        * Pipes the contents of the specified <c>Reader</c> to the specified 
<c>Writer</c>.
+        *
+        * @param in
+        *      The reader to pipe from.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Reader is automatically closed.
+        * @param out
+        *      The file to write the output to.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Writer is flushed but not automatically closed.
+        * @return
+        *      The number of characters piped.
+        * @throws IOException Thrown by underlying stream.
+        */
+       public static long pipe(Reader in, Writer out) throws IOException {
+               if (out == null || in == null)
+                       return 0;
+               long total = 0;
+               try (Reader in2 = in) {
+                       char[] buffer = new char[buffSize(-1)];
+                       int readLen;
+                       while ((readLen = in.read(buffer)) != -1) {
+                               out.write(buffer, 0, readLen);
+                               total += readLen;
+                       }
+               }
+               out.flush();
+               return total;
+       }
+
+       /**
+        * Pipes the contents of the specified <c>Reader</c> to the specified 
<c>Writer</c> a line at a time.
         *
         * <p>
-        * Can be any of the following object types:
-        * <ul>
-        *      <li>{@link CharSequence}
-        *      <li>{@link File}
-        *      <li>{@link Reader}
-        *      <li>{@link InputStream}
-        *      <li><code><jk>byte</jk>[]</code>
-        * </ul>
-        *
-        * @param in The object to read.
-        * @return The object serialized to a string, or <jk>null</jk> if it 
wasn't a supported type.
+        * Writer is flushed after every line.  Typically useful when writing 
to consoles.
+        *
+        * @param in
+        *      The reader to pipe from.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Reader is automatically closed.
+        * @param out
+        *      The file to write the output to.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Writer is flushed but not automatically closed.
+        * @return
+        *      The number of characters piped.
         * @throws IOException Thrown by underlying stream.
         */
-       public static String read(Object in) throws IOException {
-               if (in == null)
-                       return null;
-               if (in instanceof CharSequence)
-                       return in.toString();
-               if (in instanceof File)
-                       return read((File)in);
-               if (in instanceof Reader)
-                       return read((Reader)in);
-               if (in instanceof InputStream)
-                       return read((InputStream)in);
-               if (in instanceof byte[])
-                       return read(new ByteArrayInputStream((byte[])in));
-               throw new IOException("Cannot convert object of type 
'"+in.getClass().getName()+"' to a String.");
+       public static long pipeLines(Reader in, Writer out) throws IOException {
+               if (in == null || out == null)
+                       return 0;
+               long total = 0;
+               try (Reader in2 = in) {
+                       try (Scanner s = new Scanner(in2)) {
+                               while (s.hasNextLine()) {
+                                       String l = s.nextLine();
+                                       if (l != null) {
+                                               out.write(l);
+                                               out.write("\n");
+                                               out.flush();
+                                               total += l.length() + 1;
+                                       }
+                               }
+                       }
+               }
+               return total;
+       }
+
+       /**
+        * Pipes the contents of the specified input stream to the writer.
+        *
+        * @param in
+        *      The stream to pipe from.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Streams is automatically closed.
+        * @param out
+        *      The writer to pipe to.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @return
+        *      The number of bytes written.
+        * @throws IOException Thrown by underlying stream.
+        */
+       public static long pipe(InputStream in, Writer out) throws IOException {
+               if (in == null || out == null)
+                       return 0;
+               return pipe(new InputStreamReader(in, UTF8), out);
        }
 
        /**
-        * Same as {@link #read(Object)} but appends all the input into a 
single String.
+        * Pipes the contents of the specified object into the output stream.
+        *
+        * <p>
+        * The input stream is closed, the output stream is not.
         *
-        * @param in The objects to read.
-        * @return The objects serialized to a string, never <jk>null</jk>.
+        * @param in
+        *      The input to pipe from.
+        * @param out
+        *      The writer to pipe to.
         * @throws IOException Thrown by underlying stream.
         */
-       public static String readAll(Object...in) throws IOException {
-               if (in.length == 1)
-                       return read(in[0]);
-               StringWriter sw = new StringWriter();
-               for (Object o : in)
-                       sw.write(emptyIfNull(read(o)));
-               return sw.toString();
+       @Deprecated
+       public static void pipe(Object in, OutputStream out) throws IOException 
{
+               IOPipe.create(in, out).run();
+       }
+
+       /**
+        * Pipes the specified input stream to the specified output stream.
+        *
+        * <p>
+        * Either stream is not automatically closed.
+        *
+        * @param in
+        *      The input stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @param out
+        *      The output stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @return The number of bytes written.
+        * @throws IOException If thrown from either stream.
+        */
+       public static long pipe(InputStream in, OutputStream out) throws 
IOException {
+               try (InputStream in2 = in) {
+                       return pipe(in, out, -1);
+               }
+       }
+
+       /**
+        * Pipes the specified input stream to the specified output stream.
+        *
+        * <p>
+        * Either stream is not automatically closed.
+        *
+        * @param in
+        *      The input stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @param out
+        *      The output stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @param maxBytes
+        *      The maximum number of bytes or <c>-1</c> to read the entire 
input stream.
+        * @return The number of bytes written.
+        * @throws IOException If thrown from either stream.
+        */
+       public static long pipe(InputStream in, OutputStream out, long 
maxBytes) throws IOException {
+               if (in == null || out == null)
+                       return 0;
+               byte[] buffer = new byte[buffSize(maxBytes)];
+               int readLen;
+               long total = 0;
+               if (maxBytes < 0) {
+                       while ((readLen = in.read(buffer)) != -1) {
+                               out.write(buffer, 0, readLen);
+                               total += readLen;
+                       }
+               } else {
+                       long remaining = maxBytes;
+                       while (remaining > 0) {
+                               readLen = in.read(buffer, 0, 
buffSize(remaining));
+                               if (readLen == -1)
+                                       break;
+                               out.write(buffer, 0, readLen);
+                               total += readLen;
+                               remaining -= readLen;
+                       }
+               }
+               out.flush();
+               return total;
+       }
+
+       /**
+        * Pipes the specified reader to the specified output stream.
+        *
+        * @param in
+        *      The input reader.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @param out
+        *      The output stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @return The number of bytes written.
+        * @throws IOException If thrown from output stream.
+        */
+       public static long pipe(Reader in, OutputStream out) throws IOException 
{
+               if (in == null || out == null)
+                       return 0;
+               long total = 0;
+               try (Reader in2 = in) {
+                       OutputStreamWriter osw = new OutputStreamWriter(out, 
UTF8);
+                       int i;
+                       char[] b = new char[BUFF_SIZE];
+                       while ((i = in.read(b)) > 0) {
+                               total += i;
+                               osw.write(b, 0, i);
+                       }
+                       osw.flush();
+               }
+               return total;
+       }
+
+       /**
+        * Pipes the specified byte array to the specified output stream.
+        *
+        * @param in
+        *      The input byte array.
+        *      <br>Can be <jk>null</jk>.
+        * @param out
+        *      The output stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @param maxBytes
+        *      The maximum number of bytes or <c>-1</c> to read the entire 
byte array.
+        * @return The number of bytes written.
+        * @throws IOException If thrown from output stream.
+        */
+       public static final long pipe(byte[] in, OutputStream out, int 
maxBytes) throws IOException {
+               if (in == null || out == null)
+                       return 0;
+               int length = (maxBytes < 0 || maxBytes > in.length ) ? 
in.length : maxBytes;
+               out.write(in, 0, length);
+               return length;
+       }
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Reading utilities.
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       /**
+        * Reads the specified byte array containing UTF-8 into a string.
+        *
+        * @param in
+        *      The input.
+        *      <br>Can be <jk>null</jk>.
+        * @return The new string, or <jk>null</jk> if the input was null.
+        */
+       public static String read(byte[] in) {
+               return read(in, UTF8);
+       }
+
+       /**
+        * Reads the specified byte array into a string.
+        *
+        * @param in
+        *      The input.
+        *      <br>Can be <jk>null</jk>.
+        * @param charset The character set to use for decoding.
+        * @return The new string, or <jk>null</jk> if the input was null.
+        */
+       public static String read(byte[] in, Charset charset) {
+               if (in == null)
+                       return null;
+               return new String(in, charset);
        }
 
        /**
         * Reads the contents of a file into a string.
         *
-        * @param in The file to read using default character encoding.
-        * @return The contents of the reader as a string, or <jk>null</jk> if 
file does not exist.
+        * <p>
+        * Assumes default character encoding.
+        *
+        * @param in
+        *      The file to read.
+        *      <br>Can be <jk>null</jk>.
+        * @return
+        *      The contents of the reader as a string, or <jk>null</jk> if 
file does not exist.
         * @throws IOException If a problem occurred trying to read from the 
reader.
         */
        public static String read(File in) throws IOException {
                if (in == null || ! in.exists())
                        return null;
                try (Reader r = FileReaderBuilder.create(in).build()) {
-                       return read(r, 0, 1024);
+                       return read(r, in.length());
                }
        }
 
        /**
         * Reads the contents of a reader into a string.
         *
-        * @param in The input reader.
-        * @return The contents of the reader as a string.
+        * @param in
+        *      The input reader.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @return
+        *      The contents of the reader as a string, or <jk>null</jk> if the 
reader was <jk>null</jk>.
         * @throws IOException If a problem occurred trying to read from the 
reader.
         */
        public static String read(Reader in) throws IOException {
-               return read(in, 0, 1024);
+               try (Reader in2 = in) {
+                       return read(in, -1);
+               }
        }
 
        /**
-        * Reads the contents of an input stream into a string using the 
specified charset.
+        * Reads the specified input into a {@link String} until the end of the 
input is reached.
         *
-        * @param in The input stream.
-        * @param cs The charset of the contents of the input stream.
-        * @return The contents of the reader as a string.  <jk>null</jk> if 
input stream was null.
-        * @throws IOException If a problem occurred trying to read from the 
input stream.
+        * @param in
+        *      The input reader.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>String is automatically closed.
+        * @param expectedLength
+        *      Specify a positive number if the length of the input is known, 
or <c>-1</c> if unknown.
+        * @return
+        *      The contents of the reader as a string, or <jk>null</jk> if the 
reader was <jk>null</jk>.
+        * @throws IOException If a problem occurred trying to read from the 
reader.
         */
-       public static String read(InputStream in, Charset cs) throws 
IOException {
+       public static String read(Reader in, long expectedLength) throws 
IOException {
                if (in == null)
                        return null;
-               return read(new InputStreamReader(in, cs));
+               try (Reader in2 = in) {
+                       StringBuilder sb = new 
StringBuilder(buffSize(expectedLength)); // Assume they're ASCII characters.
+                       char[] buf = new char[buffSize(expectedLength)];
+                       int i = 0;
+                       while ((i = in2.read(buf)) != -1)
+                               sb.append(buf, 0, i);
+                       return sb.toString();
+               }
        }
 
        /**
-        * Reads the contents of an input stream into a string using the system 
default charset.
+        * Reads the contents of an input stream into a string.
+        *
+        * <p>
+        * Assumes UTF-8 encoding.
         *
-        * @param in The input stream.
-        * @return The contents of the reader as a string, or <jk>null</jk> if 
the input stream is null.
+        * @param in
+        *      The input stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @return
+        *      The contents of the reader as a string, or <jk>null</jk> if the 
input stream was <jk>null</jk>.
         * @throws IOException If a problem occurred trying to read from the 
input stream.
         */
        public static String read(InputStream in) throws IOException {
-               if (in == null)
-                       return null;
-               return read(new InputStreamReader(in, 
Charset.defaultCharset()));
+               return read(in, UTF8);
        }
 
        /**
-        * Reads the specified input into a {@link String} until the end of the 
input is reached.
-        *
-        * <p>
-        * The {@code Reader} is automatically closed.
-        *
-        * <p>
-        * If the {@code Reader} is not an instance of a {@code 
BufferedReader}, then it gets wrapped in a
-        * {@code BufferedReader}.
+        * Reads the contents of an input stream into a string using the 
specified charset.
         *
-        * @param in The input reader.
-        * @param length Specify a positive number if the length of the input 
is known.
-        * @param bufferSize Specify the buffer size to use.
-        * @return The contents of the reader as a string.  <jk>null</jk> if 
reader was null.
-        * @throws IOException If a problem occurred trying to read from the 
reader.
+        * @param in
+        *      The input stream.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @param cs
+        *      The charset of the contents of the input stream.
+        * @return
+        *      The contents of the reader as a string or <jk>null</jk> if 
input stream was <jk>null</jk>.
+        * @throws IOException If a problem occurred trying to read from the 
input stream.
         */
-       public static String read(Reader in, int length, int bufferSize) throws 
IOException {
+       public static String read(InputStream in, Charset cs) throws 
IOException {
                if (in == null)
                        return null;
-               if (bufferSize == 0)
-                       bufferSize = 1024;
-               length = (length <= 0 ? bufferSize : length);
-               StringBuilder sb = new StringBuilder(length); // Assume they're 
ASCII characters.
-               try {
-                       char[] buf = new char[Math.min(bufferSize, length)];
-                       int i = 0;
-                       while ((i = in.read(buf)) != -1)
-                               sb.append(buf, 0, i);
-                       return sb.toString();
-               } finally {
-                       in.close();
+               try (InputStreamReader isr = new InputStreamReader(in, cs)) {
+                       return read(isr);
                }
        }
 
        /**
-        * Read the specified object into a byte array.
+        * Shortcut for calling <c>readBytes(in, 1024);</c>
         *
         * @param in
         *      The object to read into a byte array.
@@ -197,12 +438,11 @@ public final class IOUtils {
         *              <li>{@link CharSequence}
         *              <li>{@link File}
         *      </ul>
-        * @param buffSize
-        *      The buffer size to use.
         * @return The contents of the stream as a byte array.
         * @throws IOException Thrown by underlying stream or if object is not 
a supported type.
         */
-       public static byte[] readBytes(Object in, int buffSize) throws 
IOException {
+       @Deprecated
+       public static byte[] readBytes(Object in) throws IOException {
                if (in == null)
                        return new byte[0];
                if (in instanceof byte[])
@@ -210,42 +450,48 @@ public final class IOUtils {
                if (in instanceof CharSequence)
                        return in.toString().getBytes(UTF8);
                if (in instanceof InputStream)
-                       return readBytes((InputStream)in, buffSize);
+                       return readBytes((InputStream)in);
                if (in instanceof Reader)
-                       return read((Reader)in, 0, buffSize).getBytes(UTF8);
+                       return read((Reader)in, 0).getBytes(UTF8);
                if (in instanceof File)
-                       return readBytes((File)in, buffSize);
+                       return readBytes((File)in);
                throw new IOException("Cannot convert object of type 
'"+in.getClass().getName()+"' to a byte array.");
        }
 
        /**
-        * Read the specified input stream into a byte array.
+        * Reads the specified input stream into the specified byte array.
         *
         * @param in
-        *      The stream to read into a byte array.
-        * @return The contents of the stream as a byte array.
+        *      The input stream to read.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @return A byte array containing the contents.  Never <jk>null</jk>.
         * @throws IOException Thrown by underlying stream.
         */
        public static byte[] readBytes(InputStream in) throws IOException {
-               return in == null ? null : readBytes(in, 1024);
+               try (InputStream in2 = in) {
+                       return readBytes(in2, -1);
+               }
        }
 
        /**
-        * Read the specified input stream into a byte array.
+        * Reads the specified input stream into the specified byte array.
         *
         * @param in
-        *      The stream to read into a byte array.
-        * @param buffSize
-        *      The buffer size to use.
-        * @return The contents of the stream as a byte array.
+        *      The input stream to read.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is not automatically closed.
+        * @param maxBytes
+        *      The maximum number of bytes or <c>-1</c> to read the entire 
stream.
+        * @return A byte array containing the contents.  Never <jk>null</jk>.
         * @throws IOException Thrown by underlying stream.
         */
-       public static byte[] readBytes(InputStream in, int buffSize) throws 
IOException {
-               if (buffSize == 0)
-                       buffSize = 1024;
-               ByteArrayOutputStream buff = new 
ByteArrayOutputStream(buffSize);
+       public static byte[] readBytes(InputStream in, int maxBytes) throws 
IOException {
+               if (in == null)
+                       return new byte[0];
+               ByteArrayOutputStream buff = new 
ByteArrayOutputStream(buffSize(maxBytes));
                int nRead;
-               byte[] b = new byte[buffSize];
+               byte[] b = new byte[buffSize(maxBytes)];
                while ((nRead = in.read(b, 0, b.length)) != -1)
                        buff.write(b, 0, nRead);
                buff.flush();
@@ -261,7 +507,7 @@ public final class IOUtils {
         * @throws IOException Thrown by underlying stream.
         */
        public static byte[] readBytes(File in) throws IOException {
-               return readBytes(in, 1024);
+               return readBytes(in, -1);
        }
 
        /**
@@ -269,128 +515,40 @@ public final class IOUtils {
         *
         * @param in
         *      The file to read into a byte array.
-        * @param buffSize
-        *      The buffer size to use.
+        * @param maxBytes
+        *      The maximum number of bytes to read, or <jk>-1</jk> to read all 
bytes.
         * @return The contents of the file as a byte array.
         * @throws IOException Thrown by underlying stream.
         */
-       public static byte[] readBytes(File in, int buffSize) throws 
IOException {
-               if (buffSize == 0)
-                       buffSize = 1024;
-               if (! (in.exists() && in.canRead()))
+       public static byte[] readBytes(File in, int maxBytes) throws 
IOException {
+               if (in == null || ! (in.exists() && in.canRead()))
                        return new byte[0];
-               buffSize = Math.min((int)in.length(), buffSize);
-               try (FileInputStream fis = new FileInputStream(in)) {
-                       return readBytes(fis, buffSize);
+               try (FileInputStream is = new FileInputStream(in)) {
+                       return readBytes(is, maxBytes);
                }
        }
 
        /**
-        * Shortcut for calling <c>readBytes(in, 1024);</c>
+        * Reads the specified input stream into the specified byte array.
         *
         * @param in
-        *      The object to read into a byte array.
-        *      <br>Can be any of the following types:
-        *      <ul>
-        *              <li><code><jk>byte</jk>[]</code>
-        *              <li>{@link InputStream}
-        *              <li>{@link Reader}
-        *              <li>{@link CharSequence}
-        *              <li>{@link File}
-        *      </ul>
-        * @return The contents of the stream as a byte array.
-        * @throws IOException Thrown by underlying stream or if object is not 
a supported type.
-        */
-       public static byte[] readBytes(Object in) throws IOException {
-               return readBytes(in, 1024);
-       }
-
-       /**
-        * Same as {@link #readBytes(Object)} but appends all the input into a 
single byte array.
-        *
-        * @param in The objects to read.
-        * @return The objects serialized to a byte array, never <jk>null</jk>.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public static byte[] readBytes(Object...in) throws IOException {
-               if (in.length == 1)
-                       return readBytes(in[0]);
-        try (final ByteArrayOutputStream buff = new 
ByteArrayOutputStream(1024)) {
-                       for (Object o : in) {
-                               byte[] bo = readBytes(o);
-                               if (bo != null)
-                                       buff.write(bo);
-                       }
-                       buff.flush();
-                       return buff.toByteArray();
-        }
-       }
-
-       /**
-        * Writes the contents of the specified <c>Reader</c> to the specified 
file.
-        *
-        * @param out The file to write the output to.
-        * @param in The reader to pipe from.
-        * @return The number of characters written to the file.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public static int write(File out, Reader in) throws IOException {
-               assertFieldNotNull(out, "out");
-               assertFieldNotNull(in, "in");
-               try (Writer w = FileWriterBuilder.create(out).build()) {
-                       return IOPipe.create(in, w).run();
-               }
-       }
-
-       /**
-        * Writes the contents of the specified <c>InputStream</c> to the 
specified file.
-        *
-        * @param out The file to write the output to.
-        * @param in The input stream to pipe from.
-        * @return The number of characters written to the file.
+        *      The input stream to read.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>Stream is automatically closed.
+        * @return A byte array containing the contents.  Never <jk>null</jk>.
         * @throws IOException Thrown by underlying stream.
         */
-       public static int write(File out, InputStream in) throws IOException {
-               assertFieldNotNull(out, "out");
-               assertFieldNotNull(in, "in");
-               try (OutputStream os = new FileOutputStream(out)) {
-                       return IOPipe.create(in, os).run();
+       public static byte[] readBytes(Reader in) throws IOException {
+               if (in == null)
+                       return new byte[0];
+               try (Reader in2 = in) {
+                       return read(in2, -1).getBytes();
                }
        }
 
-       /**
-        * Pipes the contents of the specified object into the writer.
-        *
-        * <p>
-        * The reader is closed, the writer is not.
-        *
-        * @param in
-        *      The input to pipe from.
-        *      Can be any of the types defined by {@link #toReader(Object)}.
-        * @param out
-        *      The writer to pipe to.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public static void pipe(Object in, Writer out) throws IOException {
-               IOPipe.create(in, out).run();
-       }
-
-       /**
-        * Pipes the contents of the specified object into the output stream.
-        *
-        * <p>
-        * The input stream is closed, the output stream is not.
-        *
-        * @param in
-        *      The input to pipe from.
-        *      Can be any of the types defined by {@link 
#toInputStream(Object)}.
-        * @param out
-        *      The writer to pipe to.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public static void pipe(Object in, OutputStream out) throws IOException 
{
-               IOPipe.create(in, out).run();
-       }
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Other utilities.
+       
//-----------------------------------------------------------------------------------------------------------------
 
        /**
         * Wraps the specified reader in a buffered reader.
@@ -400,7 +558,7 @@ public final class IOUtils {
         *      The reader wrapped in a {@link BufferedReader}, or the original 
{@link Reader} if it's already a buffered
         *      reader.
         */
-       public static Reader getBufferedReader(Reader r) {
+       public static Reader toBufferedReader(Reader r) {
                if (r == null || r instanceof BufferedReader || r instanceof 
StringReader)
                        return r;
                return new BufferedReader(r);
@@ -414,7 +572,8 @@ public final class IOUtils {
         * @throws IOException Thrown by underlying stream.
         */
        public static long count(InputStream is) throws IOException {
-               assertFieldNotNull(is, "is");
+               if (is == null)
+                       return 0;
                long c = 0;
                long i;
                try {
@@ -434,7 +593,8 @@ public final class IOUtils {
         * @throws IOException Thrown by underlying stream.
         */
        public static long count(Reader r) throws IOException {
-               assertFieldNotNull(r, "r");
+               if (r == null)
+                       return 0;
                long c = 0;
                long i;
                try {
@@ -447,31 +607,6 @@ public final class IOUtils {
        }
 
        /**
-        * Given the specified <js>"Content-Length"</js> header value, return 
an appropriate buffer size.
-        *
-        * <p>
-        * The maximum buffer size is 1MB.
-        *
-        * @param contentLength The value of the <js>"Content-Length"</js> 
header.
-        * @return The appropriate buffer size.
-        */
-       public static int getBufferSize(String contentLength) {
-               try {
-                       if (isNotEmpty(contentLength)) {
-                               long l = Long.decode(contentLength);
-                               if (l > 1048576)
-                                       return 1048576;
-                               if (l <= 0)
-                                       return 8192;
-                               return (int)l;
-                       }
-               } catch (Exception e) {
-                       return 8192;
-               }
-               return 8192;
-       }
-
-       /**
         * Close input stream and ignore any exceptions.
         *
         * <p>
@@ -602,85 +737,6 @@ public final class IOUtils {
        }
 
        /**
-        * Converts an object to a <c>Reader</c>.
-        *
-        * @param o
-        *      The object to convert to a reader.
-        *      Can be any of the following:
-        *      <ul>
-        *              <li>{@link InputStream}
-        *              <li>{@link Reader}
-        *              <li>{@link File}
-        *              <li>{@link CharSequence}
-        *              <li><code><jk>byte</jk>[]</code>
-        *              <li><code><jk>null</jk></code> - Returns <jk>null</jk>.
-        *      </ul>
-        * @return The object converted to a reader.
-        * @throws IOException If file could not be read.
-        * @throws IllegalArgumentException If invalid object passed in.
-        */
-       public static Reader toReader(Object o) throws IOException {
-               if (o == null)
-                       return null;
-               if (o instanceof CharSequence)
-                       return new StringReader(o.toString());
-               if (o instanceof File)
-                       return new FileReader((File)o);
-               if (o instanceof Reader)
-                       return (Reader)o;
-               if (o instanceof InputStream)
-                       return new InputStreamReader((InputStream)o, "UTF-8");
-               if (o instanceof byte[])
-                       return new InputStreamReader(new 
ByteArrayInputStream((byte[])o), "UTF-8");
-               throw new BasicIllegalArgumentException("Invalid object of type 
{0} passed to IOUtils.toReader(Object)", o.getClass());
-       }
-
-       /**
-        * Converts an object to an <c>InputStream</c>.
-        *
-        * @param o
-        *      The object to convert to an input stream.
-        *      Can be any of the following:
-        *      <ul>
-        *              <li>{@link InputStream}
-        *              <li>{@link Reader}
-        *              <li>{@link File}
-        *              <li>{@link CharSequence} - Converted to UTF-8 stream.
-        *              <li><code><jk>byte</jk>[]</code>
-        *              <li><code><jk>null</jk></code> - Returns <jk>null</jk>.
-        *      </ul>
-        * @return The object converted to an input stream.
-        * @throws IOException If file could not be read.
-        * @throws IllegalArgumentException If invalid object passed in.
-        */
-       public static InputStream toInputStream(Object o) throws IOException {
-               if (o == null)
-                       return null;
-               if (o instanceof InputStream)
-                       return (InputStream)o;
-               if (o instanceof File)
-                       return new FileInputStream((File)o);
-               if (o instanceof byte[])
-                       return new ByteArrayInputStream((byte[])o);
-               if (o instanceof CharSequence)
-                       return new 
ByteArrayInputStream(((CharSequence)o).toString().getBytes(UTF8));
-               if (o instanceof Reader)
-                       return new 
ByteArrayInputStream(IOUtils.read((Reader)o).getBytes(UTF8));
-               throw new BasicIllegalArgumentException("Invalid object of type 
{0} passed to IOUtils.toInputStream(Object)", o.getClass());
-       }
-
-       /**
-        * Writes the specified string to the specified file.
-        *
-        * @param path The file path.
-        * @param contents The new file contents.
-        * @throws IOException Thrown by underlying stream.
-        */
-       public static void write(String path, String contents) throws 
IOException {
-               write(new File(path), new StringReader(contents));
-       }
-
-       /**
         * Loads a text file from either the file system or classpath.
         *
         * @param name The file name.
@@ -713,4 +769,8 @@ public final class IOUtils {
                }
                return null;
        }
+
+       private static final int buffSize(long max) {
+               return (max > 0 && max < BUFF_SIZE) ? (int)max : BUFF_SIZE;
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
index a55026d..379ed5f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
@@ -12,12 +12,13 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.json;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
 
@@ -152,8 +153,10 @@ public class JsonSerializerSession extends 
WriterSerializerSession {
                        serializeCollection(out, (Collection) o, eType);
                } else if (sType.isArray()) {
                        serializeCollection(out, toList(sType.getInnerClass(), 
o), eType);
-               } else if (sType.isReader() || sType.isInputStream()) {
-                       IOUtils.pipe(o, out);
+               } else if (sType.isReader()) {
+                       pipe((Reader)o, out);
+               } else if (sType.isInputStream()) {
+                       pipe((InputStream)o, out);
                } else {
                        out.stringValue(toString(o));
                }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
index 25d4692..71adf86 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
@@ -12,12 +12,13 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.msgpack;
 
-import java.io.IOException;
+import static org.apache.juneau.internal.IOUtils.*;
+
+import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
 
@@ -134,8 +135,11 @@ public final class MsgPackSerializerSession extends 
OutputStreamSerializerSessio
                else if (sType.isArray()) {
                        serializeCollection(out, toList(sType.getInnerClass(), 
o), eType);
                }
-               else if (sType.isReader() || sType.isInputStream()) {
-                       IOUtils.pipe(o, out);
+               else if (sType.isReader()) {
+                       pipe((Reader)o, out);
+               }
+               else if (sType.isInputStream()) {
+                       pipe((InputStream)o, out);
                }
                else
                        out.appendString(toString(o));
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserPipe.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserPipe.java
index 3220d93..88c1f98 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserPipe.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserPipe.java
@@ -157,7 +157,7 @@ public final class ParserPipe implements Closeable {
 
                if (input instanceof InputStream) {
                        if (debug) {
-                               byte[] b = readBytes((InputStream)input, 1024);
+                               byte[] b = readBytes((InputStream)input);
                                inputString = toHex(b);
                                inputStream = new ByteArrayInputStream(b);
                        } else {
@@ -275,7 +275,7 @@ public final class ParserPipe implements Closeable {
         * @throws IOException Thrown by underlying stream.
         */
        public Reader getBufferedReader() throws IOException {
-               return IOUtils.getBufferedReader(getReader());
+               return toBufferedReader(getReader());
        }
 
        /**
@@ -298,7 +298,7 @@ public final class ParserPipe implements Closeable {
         */
        public String asString() throws IOException {
                if (inputString == null)
-                       inputString = IOUtils.read(getReader());
+                       inputString = read(getReader());
                return inputString;
        }
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/InputStreamSwap.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/InputStreamSwap.java
index f4f5b22..615b10b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/InputStreamSwap.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/InputStreamSwap.java
@@ -13,11 +13,11 @@
 package org.apache.juneau.transforms;
 
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.transform.*;
 
 /**
@@ -91,12 +91,15 @@ public abstract class InputStreamSwap extends 
StringSwap<InputStream> {
        /**
         * Convert the specified input stream to a byte array.
         *
-        * @param is The input stream to convert to bytes.
+        * @param is
+        *      The input stream to convert to bytes.
+        *      <br>Can be <jk>null</jk>.
+        *      <br>The stream is automatically closed.
         * @return The byte array.
         * @throws IOException Thrown by input stream.
         */
        protected byte[] toBytes(InputStream is) throws IOException {
-               return IOUtils.readBytes(is);
+               return readBytes(is);
        }
 
 
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ReaderSwap.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ReaderSwap.java
index 3b635af..dca7709 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ReaderSwap.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/ReaderSwap.java
@@ -12,10 +12,11 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.transforms;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.transform.*;
 
 /**
@@ -28,6 +29,6 @@ public class ReaderSwap extends StringSwap<Reader> {
         */
        @Override /* PojoSwap */
        public String swap(BeanSession session, Reader r) throws Exception {
-               return IOUtils.read(r);
+               return read(r);
        }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
index 6b43d71..4388c1b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
@@ -12,6 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.uon;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 import java.util.*;
 
@@ -161,8 +163,11 @@ public class UonSerializerSession extends 
WriterSerializerSession implements Htt
                else if (sType.isArray()) {
                        serializeCollection(out, toList(sType.getInnerClass(), 
o), eType);
                }
-               else if (sType.isReader() || sType.isInputStream()) {
-                       IOUtils.pipe(o, out);
+               else if (sType.isReader()) {
+                       pipe((Reader)o, out);
+               }
+               else if (sType.isInputStream()) {
+                       pipe((InputStream)o, out);
                }
                else {
                        out.appendObject(o, false);
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index adf03c8..0ed9a54 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -13,14 +13,14 @@
 package org.apache.juneau.urlencoding;
 
 import static org.apache.juneau.internal.ArrayUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
-import java.io.IOException;
+import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
 import org.apache.juneau.uon.*;
@@ -127,8 +127,10 @@ public class UrlEncodingSerializerSession extends 
UonSerializerSession {
                } else if (sType.isCollection() || sType.isArray()) {
                        Map m = sType.isCollection() ? 
getCollectionMap((Collection)o) : getCollectionMap(o);
                        serializeCollectionMap(out, m, getClassMeta(Map.class, 
Integer.class, Object.class));
-               } else if (sType.isReader() || sType.isInputStream()) {
-                       IOUtils.pipe(o, out);
+               } else if (sType.isReader()) {
+                       pipe((Reader)o, out);
+               } else if (sType.isInputStream()) {
+                       pipe((InputStream)o, out);
                } else {
                        // All other types can't be serialized as key/value 
pairs, so we create a
                        // mock key/value pair with a "_value" key.
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ManifestFile.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ManifestFile.java
index 4d17fdf..3e3348f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ManifestFile.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/ManifestFile.java
@@ -20,7 +20,6 @@ import java.util.*;
 import java.util.jar.*;
 
 import org.apache.juneau.collections.*;
-import org.apache.juneau.internal.*;
 
 /**
  * Utility class for working with Jar manifest files.
@@ -91,7 +90,7 @@ public class ManifestFile extends OMap {
         * @throws IOException If a problem occurred while trying to read the 
manifest file.
         */
        public ManifestFile(Reader r) throws IOException {
-               load(new Manifest(IOUtils.toInputStream(r)));
+               load(new Manifest(new 
ByteArrayInputStream(read(r).getBytes(UTF8))));
        }
 
        /**
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index 5bde3dc..6a7b74b 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -17,8 +17,9 @@ import static org.apache.juneau.xml.XmlSerializer.*;
 import static org.apache.juneau.xml.XmlSerializerSession.ContentResult.*;
 import static org.apache.juneau.xml.XmlSerializerSession.JsonType.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
-import java.io.IOException;
+import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 
@@ -469,8 +470,10 @@ public class XmlSerializerSession extends 
WriterSerializerSession {
                                serializeCollection(out, o, sType, eType, 
pMeta, isMixedOrText);
                                if (isCollapsed)
                                        this.indent++;
-                       } else if (sType.isReader() || sType.isInputStream()) {
-                               IOUtils.pipe(o, out);
+                       } else if (sType.isReader()) {
+                               pipe((Reader)o, out);
+                       } else if (sType.isInputStream()) {
+                               pipe((InputStream)o, out);
                        } else {
                                if (isXmlText(format, sType))
                                        out.append(toString(o));
diff --git 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
index d6ff6b1..b6e7c14 100755
--- 
a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
+++ 
b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/DirectoryResource.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.microservice.resources;
 
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.*;
@@ -29,7 +30,6 @@ import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.helper.*;
-import org.apache.juneau.utils.*;
 
 /**
  * REST resource that allows access to a file system directory.
@@ -191,7 +191,7 @@ public class DirectoryResource extends BasicRestServlet {
                File f = getFile(path);
 
                try (OutputStream os = new BufferedOutputStream(new 
FileOutputStream(f))) {
-                       IOPipe.create(is, os).run();
+                       pipe(is, os);
                } catch (IOException e) {
                        throw new InternalServerError(e);
                }
diff --git 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
index 7b87be9..55bae24 100644
--- 
a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
+++ 
b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
@@ -20,7 +20,6 @@ import org.apache.http.*;
 import org.apache.http.client.*;
 import org.apache.http.impl.client.*;
 import org.apache.http.protocol.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.microservice.jetty.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.client.*;
@@ -158,14 +157,11 @@ public class TestMicroservice {
        private static int dumpCount = 0;
 
        public static void jettyDump(RequestLine rl, StatusLine sl) {
-               try {
+               try (FileWriter fw = new 
FileWriter(microservice.getConfig().getString("Logging/logDir") + 
"/jetty-thread-dump-"+(dumpCount++)+".log")) {
                        String dump = microservice.getServer().dump();
-                       FileWriter fw = new 
FileWriter(microservice.getConfig().getString("Logging/logDir") + 
"/jetty-thread-dump-"+(dumpCount++)+".log");
                        fw.append("RequestLine = [" + rl + "]\n");
                        fw.append("StatusLine = [" + sl + "]\n");
-                       IOUtils.pipe(dump, fw);
-                       fw.flush();
-                       fw.close();
+                       fw.append(dump);
                } catch (Exception e) {
                        e.printStackTrace();
                }
diff --git 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroserviceBuilder.java
 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroserviceBuilder.java
index 57071a4..d9576bc 100644
--- 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroserviceBuilder.java
+++ 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroserviceBuilder.java
@@ -12,6 +12,8 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.microservice.jetty;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 import java.util.*;
 import java.util.logging.*;
@@ -22,7 +24,6 @@ import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.config.*;
 import org.apache.juneau.config.store.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.microservice.*;
 import org.apache.juneau.microservice.console.*;
 import org.apache.juneau.rest.*;
@@ -108,13 +109,13 @@ public class JettyMicroserviceBuilder extends 
MicroserviceBuilder {
         */
        public JettyMicroserviceBuilder jettyXml(Object jettyXml, boolean 
resolveVars) throws IOException {
                if (jettyXml instanceof String)
-                       this.jettyXml = 
IOUtils.read(resolveFile(jettyXml.toString()));
+                       this.jettyXml = read(resolveFile(jettyXml.toString()));
                else if (jettyXml instanceof File)
-                       this.jettyXml = IOUtils.read((File)jettyXml);
+                       this.jettyXml = read((File)jettyXml);
                else if (jettyXml instanceof InputStream)
-                       this.jettyXml = IOUtils.read((InputStream)jettyXml);
+                       this.jettyXml = read((InputStream)jettyXml);
                else if (jettyXml instanceof Reader)
-                       this.jettyXml = IOUtils.read((Reader)jettyXml);
+                       this.jettyXml = read((Reader)jettyXml);
                else
                        throw new BasicRuntimeException("Invalid object type 
passed to jettyXml(Object)", jettyXml == null ? null : 
jettyXml.getClass().getName());
                this.jettyXmlResolveVars = resolveVars;
diff --git 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
index 3bdf75b..b07a081 100644
--- 
a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
+++ 
b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/resources/DebugResource.java
@@ -15,7 +15,6 @@ package org.apache.juneau.microservice.jetty.resources;
 import java.io.*;
 
 import org.apache.juneau.html.annotation.HtmlDocConfig;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.microservice.jetty.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -71,7 +70,7 @@ public class DebugResource extends BasicRestServlet {
        public String createJettyDump(RestRequest req, RestResponse res) throws 
Exception {
                String dump = 
JettyMicroservice.getInstance().getServer().dump();
                try (FileWriter fw = new 
FileWriter(req.getConfig().getString("Logging/logDir") + 
"/jetty-thread-dump.log")) {
-                       IOUtils.pipe(dump, fw);
+                       fw.write(dump);
                }
                return "OK";
        }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
index 768bc19..e78067e 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
@@ -200,7 +200,7 @@ public class ResponseBody implements HttpEntity {
                                return new ByteArrayInputStream(body);
 
                        if (cached) {
-                               body = IOUtils.readBytes(entity.getContent());
+                               body = readBytes(entity.getContent());
                                response.close();
                                return new ByteArrayInputStream(body);
                        }
@@ -314,7 +314,11 @@ public class ResponseBody implements HttpEntity {
        public byte[] asBytes() throws RestCallException {
                if (body == null) {
                        try {
-                               body = IOUtils.readBytes(entity.getContent());
+                               if (entity instanceof AbstractHttpEntity) {
+                                       body = 
((AbstractHttpEntity)entity).asBytes();
+                               } else {
+                                       body = readBytes(entity.getContent());
+                               }
                        } catch (IOException e) {
                                throw new RestCallException(response, e, "Could 
not read response body.");
                        } finally {
@@ -345,7 +349,7 @@ public class ResponseBody implements HttpEntity {
         * @throws IOException If an IO exception occurred.
         */
        public RestResponse pipeTo(OutputStream os) throws IOException {
-               IOPipe.create(asInputStream(), os).run();
+               pipe(asInputStream(), os);
                return response;
        }
 
@@ -450,7 +454,10 @@ public class ResponseBody implements HttpEntity {
         * @throws IOException If an IO exception occurred.
         */
        public RestResponse pipeTo(Writer w, Charset charset, boolean byLines) 
throws IOException {
-               IOPipe.create(asReader(charset), w).byLines(byLines).run();
+               if (byLines)
+                       pipeLines(asReader(charset), w);
+               else
+                       pipe(asReader(charset), w);
                return response;
        }
 
@@ -868,7 +875,7 @@ public class ResponseBody implements HttpEntity {
        public String asString() throws RestCallException {
                cache();
                try (Reader r = asReader()) {
-                       return read(r).toString();
+                       return read(r);
                } catch (IOException e) {
                        response.close();
                        throw new RestCallException(response, e, "Could not 
read response body.");
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
index 74520d3..5b7d958 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
@@ -17,6 +17,7 @@ import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.AddFlag.*;
 import static org.apache.juneau.httppart.HttpPartType.*;
 import static org.apache.juneau.http.HttpEntities.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -43,7 +44,6 @@ import org.apache.juneau.http.entity.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.http.part.*;
 import org.apache.juneau.httppart.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.oapi.*;
@@ -1411,9 +1411,9 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                try {
                        String q = null;
                        if (value instanceof Reader)
-                               q = IOUtils.read((Reader)value);
+                               q = read((Reader)value);
                        else if (value instanceof InputStream)
-                               q = IOUtils.read((InputStream)value);
+                               q = read((InputStream)value);
                        else
                                q = stringify(value);  // Works for 
NameValuePairs.
                        uriBuilder.setCustomQuery(q);
@@ -2905,7 +2905,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                else if (input2 instanceof HttpEntity)
                                        entity = (HttpEntity)input2;
                                else if (input2 instanceof Reader)
-                                       entity = 
stringEntity(IOUtils.read((Reader)input2), getRequestContentType(TEXT_PLAIN), 
null);
+                                       entity = 
stringEntity(read((Reader)input2), getRequestContentType(TEXT_PLAIN), null);
                                else if (input2 instanceof InputStream)
                                        entity = 
streamEntity((InputStream)input2, -1, 
getRequestContentType(ContentType.APPLICATION_OCTET_STREAM));
                                else if (serializer != null)
diff --git 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
index dcccfac..323c5b7 100644
--- 
a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
+++ 
b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockServletRequest.java
@@ -14,6 +14,7 @@ package org.apache.juneau.rest.mock;
 
 import static org.apache.juneau.http.HttpHeaders.*;
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.security.*;
@@ -553,13 +554,8 @@ public class MockServletRequest implements 
HttpServletRequest {
        @Override /* HttpServletRequest */
        public Map<String,String[]> getParameterMap() {
                if ("POST".equalsIgnoreCase(method)) {
-                       if (formDataMap == null) {
-                               try {
-                                       formDataMap = 
RestUtils.parseQuery(IOUtils.read(body));
-                               } catch (IOException e) {
-                                       e.printStackTrace();
-                               }
-                       }
+                       if (formDataMap == null)
+                               formDataMap = RestUtils.parseQuery(read(body));
                        return formDataMap;
                }
                return queryDataMap;
@@ -933,9 +929,9 @@ public class MockServletRequest implements 
HttpServletRequest {
                        if (value instanceof byte[])
                                this.body = (byte[])value;
                        else if (value instanceof Reader)
-                               this.body = 
IOUtils.read((Reader)value).getBytes();
+                               this.body = readBytes((Reader)value);
                        else if (value instanceof InputStream)
-                               this.body = 
IOUtils.readBytes((InputStream)value, 1024);
+                               this.body = readBytes((InputStream)value);
                        else if (value instanceof CharSequence)
                                this.body = 
((CharSequence)value).toString().getBytes();
                        else if (value != null)
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
index 063a38d..830665a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestBody.java
@@ -522,7 +522,7 @@ public class RequestBody {
         */
        public RequestBody cache() throws IOException {
                if (body == null)
-                       body = readBytes(getInputStream(), 1024);
+                       body = readBytes(getInputStream());
                return this;
        }
 
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
index baa75a3..0ee046f 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
@@ -15,6 +15,7 @@ package org.apache.juneau.rest.reshandlers;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.http.HttpHeaders.*;
 import static org.apache.juneau.httppart.HttpPartType.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -31,7 +32,6 @@ import org.apache.juneau.http.response.*;
 import org.apache.juneau.rest.util.FinishablePrintWriter;
 import org.apache.juneau.rest.util.FinishableServletOutputStream;
 import org.apache.juneau.serializer.*;
-import org.apache.juneau.utils.*;
 
 /**
  * Response handler for POJOs not handled by other handlers.
@@ -253,13 +253,11 @@ public class DefaultHandler implements ResponseHandler {
                                res.setContentType("text/plain");
                        if (o instanceof InputStream) {
                                try (OutputStream os = 
res.getNegotiatedOutputStream()) {
-                                       IOPipe.create(o, os).run();
-                                       os.flush();
+                                       pipe((InputStream)o, os);
                                }
                        } else if (o instanceof Reader) {
                                try (FinishablePrintWriter w = 
res.getNegotiatedWriter()) {
-                                       IOPipe.create(o, w).run();
-                                       w.flush();
+                                       pipe((Reader)o, w);
                                        w.finish();
                                }
                        } else {
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/InputStreamHandler.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/InputStreamHandler.java
index ce43833..caae090 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/InputStreamHandler.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/InputStreamHandler.java
@@ -12,11 +12,12 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.reshandlers;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 
 import org.apache.juneau.rest.*;
 import org.apache.juneau.http.response.*;
-import org.apache.juneau.utils.*;
 
 /**
  * Response handler for {@link InputStream} objects.
@@ -37,8 +38,8 @@ public final class InputStreamHandler implements 
ResponseHandler {
        public boolean handle(RestCall call) throws IOException, NotAcceptable, 
BasicHttpException {
                RestResponse res = call.getRestResponse();
                if (res.isOutputType(InputStream.class)) {
-                       try (OutputStream os = res.getNegotiatedOutputStream()) 
{
-                               IOPipe.create(res.getOutput(InputStream.class), 
os).run();
+                       try (InputStream is = res.getOutput(InputStream.class); 
OutputStream os = res.getNegotiatedOutputStream()) {
+                               pipe(is, os);
                        }
                        return true;
                }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/ReaderHandler.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/ReaderHandler.java
index 02bb9e5..a0abb36 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/ReaderHandler.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/ReaderHandler.java
@@ -12,11 +12,12 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.reshandlers;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.*;
 
 import org.apache.juneau.rest.*;
 import org.apache.juneau.http.response.*;
-import org.apache.juneau.utils.*;
 
 /**
  * Response handler for {@link Reader} objects.
@@ -34,8 +35,8 @@ public final class ReaderHandler implements ResponseHandler {
        public boolean handle(RestCall call) throws IOException, NotAcceptable, 
BasicHttpException {
                RestResponse res = call.getRestResponse();
                if (res.isOutputType(Reader.class)) {
-                       try (Writer w = res.getNegotiatedWriter()) {
-                               IOPipe.create(res.getOutput(Reader.class), 
w).run();
+                       try (Reader r = res.getOutput(Reader.class); Writer w = 
res.getNegotiatedWriter()) {
+                               pipe(r, w);
                        }
                        return true;
                }
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/CachingHttpServletRequest.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/CachingHttpServletRequest.java
index 2bf49fd..3f1e83d 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/CachingHttpServletRequest.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/util/CachingHttpServletRequest.java
@@ -12,14 +12,14 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.rest.util;
 
+import static org.apache.juneau.internal.IOUtils.*;
+
 import java.io.IOException;
 
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 
-import org.apache.juneau.internal.IOUtils;
-
 /**
  * Wraps an {@link HttpServletRequest} and preloads the body into memory for 
debugging purposes.
  */
@@ -48,7 +48,7 @@ public class CachingHttpServletRequest extends 
HttpServletRequestWrapper {
         */
        protected CachingHttpServletRequest(HttpServletRequest req) throws 
IOException {
                super(req);
-               this.body = IOUtils.readBytes(req.getInputStream());
+               this.body = readBytes(req.getInputStream());
        }
 
        @Override
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
index 1f2b4b3..e62c45a 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/widget/MenuItemWidget.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.rest.widget;
 
 import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
@@ -147,7 +148,7 @@ public abstract class MenuItemWidget extends Widget {
                Object o = getContent(req, res);
                if (o instanceof Reader) {
                        try (Reader r = (Reader)o; Writer w = new 
StringBuilderWriter(sb)) {
-                               IOUtils.pipe(r, w);
+                               pipe(r, w);
                        }
                } else if (o instanceof CharSequence) {
                        sb.append((CharSequence)o);
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
index 270196b..51bf5e1 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/config/store/ConfigFileStoreTest.java
@@ -14,6 +14,7 @@ package org.apache.juneau.config.store;
 
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.concurrent.*;
@@ -170,9 +171,9 @@ public class ConfigFileStoreTest {
                                        latch.countDown();
                        }
                });
-               IOUtils.write(new File(DIR, "Z.ini"), new StringReader("zzz"));
-               IOUtils.write(new File(DIR, "X.cfg"), new StringReader("xxx"));
-               IOUtils.write(new File(DIR, "Y.cfg"), new StringReader("yyy"));
+               pipe(new StringReader("zzz"), new File(DIR, "Z.ini"));
+               pipe(new StringReader("xxx"), new File(DIR, "X.cfg"));
+               pipe(new StringReader("yyy"), new File(DIR, "Y.cfg"));
                if (! latch.await(10, TimeUnit.SECONDS))
                        throw new Exception("CountDownLatch never reached 
zero.");
        }
@@ -232,7 +233,7 @@ public class ConfigFileStoreTest {
                assertFalse(cs.exists("foo.cfg"));
                assertFalse(cs.exists("foo"));
 
-               IOUtils.write(new File("Foox.cfg"), new StringReader("xxx"));
+               pipe(new StringReader("xxx"), new File("Foox.cfg"));
                assertTrue(cs.exists("Foox.cfg"));
                assertTrue(cs.exists("Foox"));
                new File("Foox.cfg").delete();
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_BodyAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_BodyAnnotation_Test.java
index 06a028a..c2d3bfd 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_BodyAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_BodyAnnotation_Test.java
@@ -15,6 +15,8 @@ package org.apache.juneau.http.remote;
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
 import static org.apache.juneau.http.HttpParts.*;
+import static org.apache.juneau.internal.IOUtils.*;
+
 
 import java.io.*;
 import java.util.*;
@@ -25,7 +27,6 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.http.part.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.rest.annotation.*;
@@ -100,25 +101,25 @@ public class Remote_BodyAnnotation_Test {
                @RestPost
                public String x7(@Body Reader b, @Header("Content-Type") String 
ct) throws Exception {
                        assertEquals("text/plain",ct);
-                       return IOUtils.read(b);
+                       return read(b);
                }
 
                @RestPost
                public String x8(@Body InputStream b, @Header("Content-Type") 
String ct) throws Exception {
                        assertEquals("application/octet-stream",ct);
-                       return IOUtils.read(b);
+                       return read(b);
                }
 
                @RestPost
                public String x9(@Body Reader b, @Header("Content-Type") String 
ct) throws Exception {
                        assertTrue(ct.startsWith("text/plain"));
-                       return IOUtils.read(b);
+                       return read(b);
                }
 
                @RestPost
                public String x10(@Body Reader b, @Header("Content-Type") 
String ct) throws IOException {
                        assertEquals("application/x-www-form-urlencoded",ct);
-                       return IOUtils.read(b);
+                       return read(b);
                }
        }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_CommonInterfaces_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_CommonInterfaces_Test.java
index a436801..5b4677f 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_CommonInterfaces_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_CommonInterfaces_Test.java
@@ -17,6 +17,7 @@ import static org.apache.juneau.http.HttpHeaders.*;
 import static org.apache.juneau.http.HttpResponses.*;
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
@@ -24,7 +25,6 @@ import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.http.annotation.Query;
 import org.apache.juneau.http.entity.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.config.*;
 import org.apache.juneau.rest.helper.*;
@@ -212,7 +212,7 @@ public class Remote_CommonInterfaces_Test {
        public void d01_httpResource() throws Exception {
                D x = MockRestClient.build(D1.class).getRemote(D.class);
                BasicHttpResource sr = x.httpResource();
-               assertEquals("foo",IOUtils.read(sr.getContent()));
+               assertEquals("foo",read(sr.getContent()));
                assertEquals("foo",sr.getStringHeader("Foo"));
                assertEquals("\"bar\"",sr.getStringHeader("ETag"));
                
assertEquals("text/foo",sr.getContentType().getValue().toString());
@@ -846,8 +846,8 @@ public class Remote_CommonInterfaces_Test {
        @Test
        public void g01_reader_inputStream() throws Exception {
                G x = MockRestClient.build(G1.class).getRemote(G.class);
-               assertEquals("foo",IOUtils.read(x.reader()));
-               assertEquals("foo",IOUtils.read(x.inputStream()));
+               assertEquals("foo",read(x.reader()));
+               assertEquals("foo",read(x.inputStream()));
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteOpAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteOpAnnotation_Test.java
index 1aaefe6..94104ba 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteOpAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RemoteOpAnnotation_Test.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http.remote;
 
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.concurrent.*;
@@ -21,7 +22,6 @@ import java.util.concurrent.*;
 import org.apache.http.*;
 import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Response;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.config.*;
 import org.apache.juneau.rest.mock.*;
@@ -147,19 +147,19 @@ public class Remote_RemoteOpAnnotation_Test {
                B1 x = remote(B.class,B1.class);
                x.x1();
                assertEquals("foo",x.x2());
-               
assertEquals("foo",IOUtils.read(x.x3().getEntity().getContent()));
-               assertEquals("foo",IOUtils.read(x.x4()));
-               assertEquals("foo",IOUtils.read(x.x5()));
+               assertEquals("foo",read(x.x3().getEntity().getContent()));
+               assertEquals("foo",read(x.x4()));
+               assertEquals("foo",read(x.x5()));
                x.x6().get();
                assertEquals("foo",x.x7().get());
-               
assertEquals("foo",IOUtils.read(x.x8().get().getEntity().getContent()));
-               assertEquals("foo",IOUtils.read(x.x9().get()));
-               assertEquals("foo",IOUtils.read(x.x10().get()));
+               assertEquals("foo",read(x.x8().get().getEntity().getContent()));
+               assertEquals("foo",read(x.x9().get()));
+               assertEquals("foo",read(x.x10().get()));
                x.x11().get();
                assertEquals("foo",x.x12().get());
-               
assertEquals("foo",IOUtils.read(x.x13().get().getEntity().getContent()));
-               assertEquals("foo",IOUtils.read(x.x14().get()));
-               assertEquals("foo",IOUtils.read(x.x15().get()));
+               
assertEquals("foo",read(x.x13().get().getEntity().getContent()));
+               assertEquals("foo",read(x.x14().get()));
+               assertEquals("foo",read(x.x15().get()));
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -194,17 +194,17 @@ public class Remote_RemoteOpAnnotation_Test {
        public void c01_returnTypes_json() throws Exception {
                C1 x = MockRestClient.buildJson(C.class).getRemote(C1.class);
                assertEquals("foo",x.postX1("foo"));
-               
assertEquals("'foo'",IOUtils.read(x.postX2("foo").getEntity().getContent()));
-               assertEquals("'foo'",IOUtils.read(x.postX3("foo")));
-               assertEquals("'foo'",IOUtils.read(x.postX4("foo")));
+               
assertEquals("'foo'",read(x.postX2("foo").getEntity().getContent()));
+               assertEquals("'foo'",read(x.postX3("foo")));
+               assertEquals("'foo'",read(x.postX4("foo")));
                assertEquals("foo",x.postX5("foo").get());
-               
assertEquals("'foo'",IOUtils.read(x.postX6("foo").get().getEntity().getContent()));
-               assertEquals("'foo'",IOUtils.read(x.postX7("foo").get()));
-               assertEquals("'foo'",IOUtils.read(x.postX8("foo").get()));
+               
assertEquals("'foo'",read(x.postX6("foo").get().getEntity().getContent()));
+               assertEquals("'foo'",read(x.postX7("foo").get()));
+               assertEquals("'foo'",read(x.postX8("foo").get()));
                assertEquals("foo",x.postX9("foo").get());
-               
assertEquals("'foo'",IOUtils.read(x.postX10("foo").get().getEntity().getContent()));
-               assertEquals("'foo'",IOUtils.read(x.postX11("foo").get()));
-               assertEquals("'foo'",IOUtils.read(x.postX12("foo").get()));
+               
assertEquals("'foo'",read(x.postX10("foo").get().getEntity().getContent()));
+               assertEquals("'foo'",read(x.postX11("foo").get()));
+               assertEquals("'foo'",read(x.postX12("foo").get()));
        }
 
        
//-----------------------------------------------------------------------------------------------------------------
@@ -239,17 +239,17 @@ public class Remote_RemoteOpAnnotation_Test {
        public void d01_returnTypes_partSerialization() throws Exception {
                D1 x = 
MockRestClient.create(D.class).openApi().build().getRemote(D1.class);
                assertEquals("foo",x.postX1("foo"));
-               
assertEquals("foo",IOUtils.read(x.postX2("foo").getEntity().getContent()));
-               assertEquals("foo",IOUtils.read(x.postX3("foo")));
-               assertEquals("foo",IOUtils.read(x.postX4("foo")));
+               
assertEquals("foo",read(x.postX2("foo").getEntity().getContent()));
+               assertEquals("foo",read(x.postX3("foo")));
+               assertEquals("foo",read(x.postX4("foo")));
                assertEquals("foo",x.postX5("foo").get());
-               
assertEquals("foo",IOUtils.read(x.postX6("foo").get().getEntity().getContent()));
-               assertEquals("foo",IOUtils.read(x.postX7("foo").get()));
-               assertEquals("foo",IOUtils.read(x.postX8("foo").get()));
+               
assertEquals("foo",read(x.postX6("foo").get().getEntity().getContent()));
+               assertEquals("foo",read(x.postX7("foo").get()));
+               assertEquals("foo",read(x.postX8("foo").get()));
                assertEquals("foo",x.postX9("foo").get());
-               
assertEquals("foo",IOUtils.read(x.postX10("foo").get().getEntity().getContent()));
-               assertEquals("foo",IOUtils.read(x.postX11("foo").get()));
-               assertEquals("foo",IOUtils.read(x.postX12("foo").get()));
+               
assertEquals("foo",read(x.postX10("foo").get().getEntity().getContent()));
+               assertEquals("foo",read(x.postX11("foo").get()));
+               assertEquals("foo",read(x.postX12("foo").get()));
        }
 
        
//------------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
index 637ae73..10951ca 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_RequestAnnotation_Test.java
@@ -14,6 +14,7 @@ package org.apache.juneau.http.remote;
 
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
@@ -23,7 +24,6 @@ import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.http.annotation.Path;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.mock.*;
 import org.apache.juneau.testutils.*;
@@ -41,7 +41,7 @@ public class Remote_RequestAnnotation_Test {
                @RestOp(path="/{x}")
                public String post(@Body Reader r, @Header("X") String h, 
@Query("x") String q, @Path("x") String p) throws Exception {
                        return OMap.of(
-                               "body",IOUtils.read(r),
+                               "body",read(r),
                                "header",h,
                                "query",q,
                                "path",p
@@ -90,7 +90,7 @@ public class Remote_RequestAnnotation_Test {
                @RestOp(path="/{x}")
                public String post(@Body Reader r, @Header("X") String h, 
@Query("x") String q, @Path("x") String p) throws Exception {
                        return OMap.of(
-                               "body",IOUtils.read(r),
+                               "body",read(r),
                                "header",h,
                                "query",q,
                                "path",p
@@ -146,7 +146,7 @@ public class Remote_RequestAnnotation_Test {
                @RestOp(path="/{x}")
                public String post(@Body Reader r, @Header("X") String h, 
@Query("x") String q, @Path("x") String p) throws Exception {
                        return OMap.of(
-                               "body",IOUtils.read(r),
+                               "body",read(r),
                                "header",h,
                                "query",q,
                                "path",p
@@ -202,7 +202,7 @@ public class Remote_RequestAnnotation_Test {
                @RestOp(path="/{x}")
                public String post(@Body Reader r, @Header("X") String h, 
@Query("x") String q, @Path("x") String p) throws Exception {
                        return OMap.of(
-                               "body",IOUtils.read(r),
+                               "body",read(r),
                                "header",h,
                                "query",q,
                                "path",p
@@ -250,7 +250,7 @@ public class Remote_RequestAnnotation_Test {
                @RestOp(path="/{x}")
                public String post(@Body Reader r, @Header("X") String h, 
@Query("x") String q, @Path("x") String p) throws Exception {
                        return OMap.of(
-                               "body",IOUtils.read(r),
+                               "body",read(r),
                                "header",h,
                                "query",q,
                                "path",p
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_ResponseAnnotation_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_ResponseAnnotation_Test.java
index 14e7d88..d2bfbce 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_ResponseAnnotation_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/http/remote/Remote_ResponseAnnotation_Test.java
@@ -15,12 +15,12 @@ package org.apache.juneau.http.remote;
 import static org.apache.juneau.assertions.Assertions.*;
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.annotation.Response;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.rest.RestResponse;
 import org.apache.juneau.rest.annotation.*;
@@ -75,7 +75,7 @@ public class Remote_ResponseAnnotation_Test {
        @Test
        public void a01_basic() throws Exception {
                A1a x = remote(A.class,A1b.class).get();
-               assertEquals("foo",IOUtils.read(x.getBody()));
+               assertEquals("foo",read(x.getBody()));
                assertEquals("x",x.getHeader());
                assertEquals(201,x.getStatus());
        }
@@ -93,7 +93,7 @@ public class Remote_ResponseAnnotation_Test {
        @Test
        public void a02_unannotatedMethod() throws Exception {
                A2a x = remote(A.class,A2b.class).get();
-               assertEquals("foo",IOUtils.read(x.getBody()));
+               assertEquals("foo",read(x.getBody()));
        }
 
        @Rest
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/httppart/OpenApiPartParser_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/httppart/OpenApiPartParser_Test.java
index 56bcaf7..a3fc6a3 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/httppart/OpenApiPartParser_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/httppart/OpenApiPartParser_Test.java
@@ -17,13 +17,13 @@ import static org.junit.runners.MethodSorters.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.assertions.Assertions.*;
 import static org.apache.juneau.httppart.HttpPartSchema.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.collections.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.oapi.*;
 import org.apache.juneau.parser.*;
@@ -214,8 +214,8 @@ public class OpenApiPartParser_Test {
                HttpPartSchema s = T_BYTE;
                String in = base64Encode("foo".getBytes());
                assertEquals("foo", parse(s, in, String.class));
-               assertEquals("foo", IOUtils.read(parse(s, in, 
InputStream.class)));
-               assertEquals("foo", IOUtils.read(parse(s, in, Reader.class)));
+               assertEquals("foo", read(parse(s, in, InputStream.class)));
+               assertEquals("foo", read(parse(s, in, Reader.class)));
                assertEquals("C1-foo", parse(s, in, C1.class).toString());
        }
 
@@ -224,8 +224,8 @@ public class OpenApiPartParser_Test {
                HttpPartSchema s = T_BINARY;
                String in = toHex("foo".getBytes());
                assertEquals("foo", parse(s, in, String.class));
-               assertEquals("foo", IOUtils.read(parse(s, in, 
InputStream.class)));
-               assertEquals("foo", IOUtils.read(parse(s, in, Reader.class)));
+               assertEquals("foo", read(parse(s, in, InputStream.class)));
+               assertEquals("foo", read(parse(s, in, Reader.class)));
                assertEquals("C1-foo", parse(s, in, C1.class).toString());
        }
 
@@ -234,8 +234,8 @@ public class OpenApiPartParser_Test {
                HttpPartSchema s = T_BINARY_SPACED;
                String in = toSpacedHex("foo".getBytes());
                assertEquals("foo", parse(s, in, String.class));
-               assertEquals("foo", IOUtils.read(parse(s, in, 
InputStream.class)));
-               assertEquals("foo", IOUtils.read(parse(s, in, Reader.class)));
+               assertEquals("foo", read(parse(s, in, InputStream.class)));
+               assertEquals("foo", read(parse(s, in, Reader.class)));
                assertEquals("C1-foo", parse(s, in, C1.class).toString());
        }
 
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Body_Test.java 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Body_Test.java
index 38adffe..54429f8 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Body_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Body_Test.java
@@ -14,6 +14,7 @@ package org.apache.juneau.rest.annotation;
 
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.*;
@@ -23,7 +24,6 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.http.annotation.HasQuery;
 import org.apache.juneau.http.annotation.Query;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.rest.client.*;
@@ -89,11 +89,11 @@ public class Body_Test {
                }
                @RestPut(path="/InputStream")
                public String k(@Body InputStream b) throws Exception {
-                       return IOUtils.read(b);
+                       return read(b);
                }
                @RestPut(path="/Reader")
                public String l(@Body Reader b) throws Exception {
-                       return IOUtils.read(b);
+                       return read(b);
                }
                @RestPut(path="/InputStreamTransform")
                public A14 m(@Body A14 b) throws Exception {
@@ -101,7 +101,7 @@ public class Body_Test {
                }
                public static class A14 {
                        String s;
-                       public A14(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
+                       public A14(InputStream in) throws Exception { this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
                @RestPut(path="/ReaderTransform")
@@ -110,7 +110,7 @@ public class Body_Test {
                }
                public static class A15 {
                        private String s;
-                       public A15(Reader in) throws Exception { this.s = 
IOUtils.read(in); }
+                       public A15(Reader in) throws Exception { this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
                @RestPut(path="/StringTransform")
@@ -452,7 +452,7 @@ public class Body_Test {
                @Body
                public static class B4 {
                        String s;
-                       public B4(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
+                       public B4(InputStream in) throws Exception { this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
                @RestPut(path="/ReaderTransform")
@@ -462,7 +462,7 @@ public class Body_Test {
                @Body
                public static class B5 {
                        private String s;
-                       public B5(Reader in) throws Exception { this.s = 
IOUtils.read(in); }
+                       public B5(Reader in) throws Exception { this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
        }
@@ -538,7 +538,7 @@ public class Body_Test {
                }
                public static class D2 {
                        String s;
-                       public D2(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
+                       public D2(InputStream in) throws Exception { this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
                @RestPut(path="/ReaderTransform")
@@ -547,7 +547,7 @@ public class Body_Test {
                }
                public static class D3 {
                        private String s;
-                       public D3(Reader in) throws Exception{ this.s = 
IOUtils.read(in); }
+                       public D3(Reader in) throws Exception{ this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
                @RestPut(path="/StringTransformBodyOnPojo")
@@ -567,7 +567,7 @@ public class Body_Test {
                @Body
                public static class D5 {
                        String s;
-                       public D5(InputStream in) throws Exception { this.s = 
IOUtils.read(in); }
+                       public D5(InputStream in) throws Exception { this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
 
@@ -578,7 +578,7 @@ public class Body_Test {
                @Body
                public static class D6 {
                        private String s;
-                       public D6(Reader in) throws Exception{ this.s = 
IOUtils.read(in); }
+                       public D6(Reader in) throws Exception{ this.s = 
read(in); }
                        @Override public String toString() { return s; }
                }
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
index 18a57fa..5a76b00 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Response_Body_Test.java
@@ -16,6 +16,7 @@ import static org.apache.juneau.assertions.Assertions.*;
 import static org.apache.juneau.http.HttpHeaders.*;
 import static org.junit.Assert.*;
 import static org.junit.runners.MethodSorters.*;
+import static org.apache.juneau.internal.IOUtils.*;
 
 import java.io.*;
 import java.util.*;
@@ -28,7 +29,6 @@ import org.apache.http.entity.*;
 import org.apache.http.entity.ContentType;
 import org.apache.http.message.*;
 import org.apache.juneau.*;
-import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.*;
@@ -149,7 +149,7 @@ public class RestClient_Response_Body_Test {
                assertReader(r).is("{f:1}");
 
                x.entity(inputStreamEntity("{f:1}"));
-               r = x.get("/bean").run().getBody().asReader(IOUtils.UTF8);
+               r = x.get("/bean").run().getBody().asReader(UTF8);
                assertReader(r).is("{f:1}");
 
                x.entity(inputStreamEntity("{f:1}"));
@@ -179,7 +179,7 @@ public class RestClient_Response_Body_Test {
                assertString(sw.toString()).is("{f:1}");
 
                sw = new StringWriter();
-               
client().build().get("/bean").run().getBody().pipeTo(sw,IOUtils.UTF8);
+               client().build().get("/bean").run().getBody().pipeTo(sw,UTF8);
                assertString(sw.toString()).is("{f:1}");
        }
 
@@ -187,7 +187,7 @@ public class RestClient_Response_Body_Test {
                String x;
                public static A7a fromReader(Reader r) throws IOException {
                        A7a x = new A7a();
-                       x.x = IOUtils.read(r);
+                       x.x = read(r);
                        return x;
                }
        }
@@ -196,7 +196,7 @@ public class RestClient_Response_Body_Test {
                String x;
                public static A7b fromInputStream(InputStream is) throws 
IOException {
                        A7b x = new A7b();
-                       x.x = IOUtils.read(is);
+                       x.x = read(is);
                        return x;
                }
        }
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/transforms/InputStreamBase64SwapTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/transforms/InputStreamBase64SwapTest.java
index 5e9ea61..7290106 100644
--- 
a/juneau-utest/src/test/java/org/apache/juneau/transforms/InputStreamBase64SwapTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/transforms/InputStreamBase64SwapTest.java
@@ -64,7 +64,7 @@ public class InputStreamBase64SwapTest extends 
OneWayStringSwapTest<InputStream>
                                "[2] null",
                                null,
                                SWAP,
-                               null,
+                               "",
                                BS
                        },
                });
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/utils/ByteArrayInOutStreamTest.java
 
b/juneau-utest/src/test/java/org/apache/juneau/utils/ByteArrayInOutStreamTest.java
index 95e5fe7..929e98f 100755
--- 
a/juneau-utest/src/test/java/org/apache/juneau/utils/ByteArrayInOutStreamTest.java
+++ 
b/juneau-utest/src/test/java/org/apache/juneau/utils/ByteArrayInOutStreamTest.java
@@ -31,7 +31,7 @@ public class ByteArrayInOutStreamTest {
        public void testBasic() throws Exception {
                InputStream is = new 
ByteArrayInputStream("foobar".getBytes(UTF8));
                ByteArrayInOutStream baios = new ByteArrayInOutStream();
-               IOPipe.create(is, baios).run();
+               pipe(is, baios);
                assertEquals("foobar", read(baios.getInputStream()));
        }
 }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/utils/IOPipeTest.java 
b/juneau-utest/src/test/java/org/apache/juneau/utils/IOPipeTest.java
deleted file mode 100755
index 3ae1f79..0000000
--- a/juneau-utest/src/test/java/org/apache/juneau/utils/IOPipeTest.java
+++ /dev/null
@@ -1,285 +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.juneau.utils;
-
-import static org.apache.juneau.assertions.Assertions.*;
-import static org.apache.juneau.internal.IOUtils.*;
-import static org.junit.Assert.*;
-import static org.junit.runners.MethodSorters.*;
-
-import java.io.*;
-
-import org.apache.juneau.utils.IOPipe.*;
-import org.junit.*;
-
-@FixMethodOrder(NAME_ASCENDING)
-public class IOPipeTest {
-
-       
//====================================================================================================
-       // IOPipe(Object input, Object output)
-       
//====================================================================================================
-       @Test
-       public void testConstructor() throws Exception {
-               assertThrown(()->IOPipe.create(null, new 
StringWriter())).isType(IllegalArgumentException.class);
-               assertThrown(()->IOPipe.create(new StringReader(""), 
null)).isType(IllegalArgumentException.class);
-               assertThrown(()->IOPipe.create(new Integer(1), new 
StringWriter())).isType(IllegalArgumentException.class);
-               assertThrown(()->IOPipe.create("", new 
Integer(1))).isType(IllegalArgumentException.class);
-       }
-
-       
//====================================================================================================
-       // closeOut()
-       // close(boolean in, boolean out)
-       
//====================================================================================================
-       @Test
-       public void testClose() throws Exception {
-               TestReader in;
-               TestWriter out;
-               TestInputStream in2;
-               TestOutputStream out2;
-
-               in = new TestReader("foobar");
-               out = new TestWriter();
-               IOPipe.create(in, out).run();
-               assertTrue(in.closed);
-               assertFalse(out.closed);
-               assertEquals("foobar", out.toString());
-
-               in = new TestReader("foobar");
-               out = new TestWriter();
-               IOPipe.create(in, out).closeOut().run();
-               assertTrue(in.closed);
-               assertTrue(out.closed);
-               assertEquals("foobar", out.toString());
-
-               in = new TestReader("foobar");
-               out = new TestWriter();
-               IOPipe.create(in, out).close(false, true).run();
-               assertFalse(in.closed);
-               assertTrue(out.closed);
-               assertEquals("foobar", out.toString());
-
-               in2 = new TestInputStream("foobar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in2, out2).run();
-               assertTrue(in2.closed);
-               assertFalse(out2.closed);
-               assertEquals("foobar", out2.toString());
-
-               in2 = new TestInputStream("foobar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in2, out2).closeOut().run();
-               assertTrue(in2.closed);
-               assertTrue(out2.closed);
-               assertEquals("foobar", out2.toString());
-
-               in2 = new TestInputStream("foobar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in2, out2).close(false, true).run();
-               assertFalse(in2.closed);
-               assertTrue(out2.closed);
-               assertEquals("foobar", out2.toString());
-
-               in = new TestReader("foobar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in, out2).run();
-               assertTrue(in.closed);
-               assertFalse(out2.closed);
-               assertEquals("foobar", out.toString());
-
-               in = new TestReader("foobar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in, out2).closeOut().run();
-               assertTrue(in.closed);
-               assertTrue(out2.closed);
-               assertEquals("foobar", out.toString());
-
-               in = new TestReader("foobar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in, out2).close(false, true).run();
-               assertFalse(in.closed);
-               assertTrue(out2.closed);
-               assertEquals("foobar", out.toString());
-
-               in2 = new TestInputStream("foobar");
-               out = new TestWriter();
-               IOPipe.create(in2, out).run();
-               assertTrue(in2.closed);
-               assertFalse(out.closed);
-               assertEquals("foobar", out2.toString());
-
-               in2 = new TestInputStream("foobar");
-               out = new TestWriter();
-               IOPipe.create(in2, out).closeOut().run();
-               assertTrue(in2.closed);
-               assertTrue(out.closed);
-               assertEquals("foobar", out2.toString());
-
-               in2 = new TestInputStream("foobar");
-               out = new TestWriter();
-               IOPipe.create(in2, out).close(false, true).run();
-               assertFalse(in2.closed);
-               assertTrue(out.closed);
-               assertEquals("foobar", out2.toString());
-       }
-
-
-       public static class TestReader extends StringReader {
-               boolean closed;
-
-               public TestReader(String s) {
-                       super(s);
-               }
-
-               @Override /* Reader */
-               public void close() {
-                       closed = true;
-               }
-       }
-
-       public static class TestWriter extends StringWriter {
-               boolean closed;
-
-               public TestWriter() {
-                       super();
-               }
-
-               @Override /* Writer */
-               public void close() {
-                       closed = true;
-               }
-       }
-
-       public static class TestInputStream extends ByteArrayInputStream {
-               boolean closed;
-
-               public TestInputStream(String s) {
-                       super(s.getBytes());
-               }
-
-               @Override /* InputStream */
-               public void close() throws IOException {
-                       super.close();
-                       closed = true;
-               }
-       }
-
-       public static class TestOutputStream extends ByteArrayOutputStream {
-               boolean closed;
-
-               public TestOutputStream() {
-                       super();
-               }
-
-               @Override /* OutputStream */
-               public void close() throws IOException {
-                       super.close();
-                       closed = true;
-               }
-
-               @Override /* Object */
-               public String toString() {
-                       return new String(this.toByteArray(), UTF8);
-               }
-       }
-
-       
//====================================================================================================
-       // byLines()
-       // byLines(boolean)
-       
//====================================================================================================
-       @Test
-       public void testByLines() throws Exception {
-               TestReader in;
-               TestWriter out;
-
-               in = new TestReader("foo\nbar");
-               out = new TestWriter() {
-                       @Override public void write(String s) {
-                               super.write("["+s+"]");
-                       }
-               };
-               IOPipe.create(in, out).byLines().run();
-               assertEquals("[foo][][bar][]", 
out.toString().replaceAll("[\\r\\n]", ""));
-
-               in = new TestReader("foo\nbar");
-               out = new TestWriter() {
-                       @Override public void write(String s) {
-                               super.write("["+s+"]");
-                       }
-               };
-               IOPipe.create(in, out).byLines(true).run();
-               assertEquals("[foo][][bar][]", 
out.toString().replaceAll("[\\r\\n]", ""));
-
-               in = new TestReader("foo\nbar");
-               out = new TestWriter() {
-                       @Override public void write(String s) {
-                               super.write("["+s+"]");
-                       }
-               };
-               IOPipe.create(in, out).byLines(false).run();
-               assertEquals("foo\nbar", out.toString());
-       }
-
-       
//====================================================================================================
-       // lineProcessor()
-       
//====================================================================================================
-       @Test
-       public void testLineProcessor() throws Exception {
-               TestReader in;
-               TestWriter out;
-               LineProcessor lp = new LineProcessor() {
-                       @Override /* LineProcessor */
-                       public String process(String line) {
-                               return "[" + line + "]";
-                       }
-               };
-
-               in = new TestReader("foo\nbar");
-               out = new TestWriter();
-               IOPipe.create(in, out).lineProcessor(lp).run();
-               assertEquals("[foo][bar]", 
out.toString().replaceAll("[\\r\\n]", ""));
-
-               LineProcessor lp2 = new LineProcessor() {
-                       @Override /* LineProcessor */
-                       public String process(String line) {
-                               return line.equals("foo") ? null : line;
-                       }
-               };
-               in = new TestReader("foo\nbar");
-               out = new TestWriter();
-               IOPipe.create(in, out).lineProcessor(lp2).run();
-               assertEquals("bar", out.toString().replaceAll("[\\r\\n]", ""));
-
-               TestInputStream in2;
-               TestOutputStream out2;
-               in2 = new TestInputStream("foo\nbar");
-               out2 = new TestOutputStream();
-               IOPipe.create(in2, out2).lineProcessor(lp).run();
-               assertEquals("[foo][bar]", 
out2.toString().replaceAll("[\\r\\n]", ""));
-       }
-
-       
//====================================================================================================
-       // buffSize()
-       
//====================================================================================================
-       @Test
-       public void testBuffSize() throws Exception {
-               TestReader in;
-               TestWriter out;
-
-               in = new TestReader("foobar");
-               out = new TestWriter();
-               IOPipe.create(in, out).buffSize(1).run();
-               assertEquals("foobar", out.toString().replaceAll("[\\r\\n]", 
""));
-
-               assertThrown(()->IOPipe.create(in, 
out).buffSize(0)).isType(IllegalArgumentException.class);
-       }
-}
diff --git 
a/juneau-utest/src/test/java/org/apache/juneau/utils/IOUtilsTest.java 
b/juneau-utest/src/test/java/org/apache/juneau/utils/IOUtilsTest.java
index ded7580..36b45b9 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/utils/IOUtilsTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/utils/IOUtilsTest.java
@@ -37,7 +37,7 @@ public class IOUtilsTest {
 
                in = new TestReader("foobar");
                out = new TestWriter();
-               IOPipe.create(in, out).run();
+               pipe(in, out);
                assertTrue(in.closed);
                assertFalse(out.closed);
                assertEquals("foobar", out.toString());

Reply via email to