diff --git a/applications/test/IStringStream/Test-IStringStream.C b/applications/test/IStringStream/Test-IStringStream.C
index cd8ba0e2a6165cba7df6db65c52fb59aa27e2874..b265b15a61f747492bd13552a1bd941cabb0e8df 100644
--- a/applications/test/IStringStream/Test-IStringStream.C
+++ b/applications/test/IStringStream/Test-IStringStream.C
@@ -36,20 +36,22 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-    IStringStream testStream(Foam::string("1002 sfsd sdfsd"));
+    IStringStream testStream(Foam::string("  1002  abcd  defg;"));
 
     label i(readLabel(testStream));
 
-    Info<< i << endl;
+    Info<< "label=" << i << nl;
 
-    word bla(testStream);
-    word bla2(testStream);
+    word w1(testStream);
+    word w2(testStream);
 
-    Info<< bla << tab << bla2 << endl;
+    Info<< "word=" << w1 << nl;
+    Info<< "word=" << w2 << nl;
 
-    wordList wl(IStringStream("(hello1")());
+    testStream.reset("(hello1)");
 
-    Info<< wl << endl;
+    wordList wl(testStream);
+    Info<< wl << nl;
 
     Info<< "\nEnd\n" << endl;
 
diff --git a/applications/test/IndirectList/Test-IndirectList.C b/applications/test/IndirectList/Test-IndirectList.C
index 4727ed52484299843af5648239a65488ba177fa9..449af8ca7d412c6becc83f27026df6cdabdbd296 100644
--- a/applications/test/IndirectList/Test-IndirectList.C
+++ b/applications/test/IndirectList/Test-IndirectList.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,15 +27,18 @@ Description
 
 #include "IndirectList.H"
 #include "IOstreams.H"
+#include "Fstream.H"
 #include "ListOps.H"
 #include "labelIndList.H"
+#include "argList.H"
 
 using namespace Foam;
 
 template<class ListType>
 void printInfo(const ListType& lst)
 {
-    Info<< "addr: " << flatOutput(lst.addressing()) << nl
+    Info<< "full: " << flatOutput(lst.completeList()) << nl
+        << "addr: " << flatOutput(lst.addressing()) << nl
         << "list: " << flatOutput(lst) << nl
         << endl;
 }
@@ -61,6 +64,15 @@ void testFind(const T& val, const ListType& lst)
 
 int main(int argc, char *argv[])
 {
+    argList::addOption
+    (
+        "binary",
+        "file",
+        "write lists in binary to specified file"
+    );
+
+    argList args(argc, argv);
+
     List<label> completeList(20);
 
     forAll(completeList, i)
@@ -104,6 +116,55 @@ int main(int argc, char *argv[])
     printInfo(idl2);
     printInfo(idl3);
 
+    fileName binaryOutput;
+    if (args.optionReadIfPresent("binary", binaryOutput))
+    {
+        Info<<"Writing output to " << binaryOutput << endl;
+
+        OFstream os(binaryOutput, IOstream::BINARY);
+
+        os.writeEntry("idl1", idl1);
+        os.writeEntry("idl2", idl2);
+        os.writeEntry("idl3", idl3);
+    }
+
+    if (Pstream::parRun())
+    {
+        if (Pstream::master())
+        {
+            Pout<< "full: " << flatOutput(idl3.completeList()) << nl
+                << "send: " << flatOutput(idl3) << endl;
+
+            for
+            (
+                int slave = Pstream::firstSlave();
+                slave <= Pstream::lastSlave();
+                ++slave
+            )
+            {
+                OPstream toSlave(Pstream::commsTypes::scheduled, slave);
+                toSlave << idl3;
+            }
+        }
+        else
+        {
+            // From master
+            IPstream fromMaster
+            (
+                Pstream::commsTypes::scheduled,
+                Pstream::masterNo()
+            );
+
+            List<label> recv(fromMaster);
+
+            Pout<<"recv: " << flatOutput(recv) << endl;
+        }
+
+        // MPI barrier
+        bool barrier = true;
+        Pstream::scatter(barrier);
+    }
+
     Info<< "End\n" << endl;
 
     return 0;
diff --git a/applications/test/OListStream/Make/files b/applications/test/OListStream/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..583b8e7f0699df33e7deb8b5a2487d7e39c37f43
--- /dev/null
+++ b/applications/test/OListStream/Make/files
@@ -0,0 +1,3 @@
+Test-OListStream.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-OListStream
diff --git a/applications/test/OListStream/Make/options b/applications/test/OListStream/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..4e772fdf9d7bc94221d127458f9d2ca32850fe69
--- /dev/null
+++ b/applications/test/OListStream/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/OListStream/Test-OListStream.C b/applications/test/OListStream/Test-OListStream.C
new file mode 100644
index 0000000000000000000000000000000000000000..adbbc722d596072b691b89a3f0bb93b197e79a45
--- /dev/null
+++ b/applications/test/OListStream/Test-OListStream.C
@@ -0,0 +1,79 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "OListStream.H"
+#include "wordList.H"
+#include "IOstreams.H"
+#include "argList.H"
+
+using namespace Foam;
+
+Ostream& toString(Ostream& os, const UList<char>& list)
+{
+    os << '"';
+    for (const char c : list)
+    {
+        os << c;
+    }
+    os << '"';
+
+    return os;
+}
+
+
+void printInfo(const OListStream& buf)
+{
+    Info<< nl << buf.size() << " chars (" << buf.capacity() << " capacity) ";
+    toString(Info, buf.list()) << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    // Buffer storage
+    DynamicList<char> storage(8);
+
+    OListStream obuf(std::move(storage));
+    obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
+
+    printInfo(obuf);
+
+    obuf.rewind();
+    obuf << 100;
+
+    printInfo(obuf);
+
+    Info<< "\nEnd\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/UIBufStream/Make/files b/applications/test/UIBufStream/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..611f5337be73caa53f9565cf46683f476625dfa5
--- /dev/null
+++ b/applications/test/UIBufStream/Make/files
@@ -0,0 +1,3 @@
+Test-UIBufStream.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-UIBufStream
diff --git a/applications/test/UIBufStream/Make/options b/applications/test/UIBufStream/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..4e772fdf9d7bc94221d127458f9d2ca32850fe69
--- /dev/null
+++ b/applications/test/UIBufStream/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/UIBufStream/Test-UIBufStream.C b/applications/test/UIBufStream/Test-UIBufStream.C
new file mode 100644
index 0000000000000000000000000000000000000000..f183d623ab7983eec345005e3108f0e3c17e5f58
--- /dev/null
+++ b/applications/test/UIBufStream/Test-UIBufStream.C
@@ -0,0 +1,88 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "UIBufStream.H"
+#include "UOBufStream.H"
+#include "wordList.H"
+#include "IOstreams.H"
+#include "argList.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    // Buffer storage
+    DynamicList<char> storage(1000);
+
+    UOBufStream obuf(storage);
+    obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
+
+    Info<<"formatted: " << obuf.size() << " chars" << endl;
+
+    // Match size
+    storage.resize(obuf.size());
+
+    Info<<"as string: " << string(storage.cdata(), storage.size()) << endl;
+
+    // Attach input buffer - could also do without previous resize
+
+    UIBufStream ibuf(storage, storage.size());
+
+    token t;
+
+    while (ibuf.good())
+    {
+        ibuf >> t;
+        if (t.good())
+        {
+            Info<<"token: " << t << endl;
+        }
+    }
+
+    Info<< nl << "Repeat..." << endl;
+    ibuf.rewind();
+
+    while (ibuf.good())
+    {
+        ibuf >> t;
+        if (t.good())
+        {
+            Info<<"token: " << t << endl;
+        }
+    }
+
+
+    Info<< "\nEnd\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C b/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C
index 6d1d65b20e21c2f2b7583fdcda1dfd2a54cf0579..87851fcef4a2ee0e9e0c110a8249c2de2a0043f0 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C
@@ -91,10 +91,10 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
             // Write size (so it is valid dictionary entry) and start delimiter
             os << Size << token::BEGIN_BLOCK;
 
-            // Write contents
+            // Contents
             os << L[0];
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_BLOCK;
         }
         else if
@@ -103,31 +103,31 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList
          || (Size <= unsigned(shortListLen) && contiguous<T>())
         )
         {
-            // Write start delimiter
+            // Start delimiter
             os << token::BEGIN_LIST;
 
-            // Write contents
+            // Contents
             forAll(L, i)
             {
                 if (i) os << token::SPACE;
                 os << L[i];
             }
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_LIST;
         }
         else
         {
-            // Write start delimiter
+            // Start delimiter
             os << nl << token::BEGIN_LIST << nl;
 
-            // Write contents
+            // Contents
             forAll(L, i)
             {
                 os << L[i] << nl;
             }
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_LIST << nl;
         }
     }
diff --git a/src/OpenFOAM/containers/Lists/List/ListIO.C b/src/OpenFOAM/containers/Lists/List/ListIO.C
index b21b6a86648404ed633256ba9d503cf0ec84781f..b29418c24a1c3986fbaebd9a7c2ad54d99e212b8 100644
--- a/src/OpenFOAM/containers/Lists/List/ListIO.C
+++ b/src/OpenFOAM/containers/Lists/List/ListIO.C
@@ -64,10 +64,10 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
     }
     else if (firstToken.isLabel())
     {
-        const label s = firstToken.labelToken();
+        const label sz = firstToken.labelToken();
 
         // Set list length to that read
-        L.setSize(s);
+        L.setSize(sz);
 
         // Read list contents depending on data format
 
@@ -76,11 +76,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
             // Read beginning of contents
             const char delimiter = is.readBeginList("List");
 
-            if (s)
+            if (sz)
             {
                 if (delimiter == token::BEGIN_LIST)
                 {
-                    for (label i=0; i<s; ++i)
+                    for (label i=0; i<sz; ++i)
                     {
                         is >> L[i];
 
@@ -103,7 +103,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
                         "reading the single entry"
                     );
 
-                    for (label i=0; i<s; ++i)
+                    for (label i=0; i<sz; ++i)
                     {
                         L[i] = element;
                     }
@@ -115,11 +115,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
         }
         else
         {
-            // contents are binary and contiguous
+            // Contents are binary and contiguous
 
-            if (s)
+            if (sz)
             {
-                is.read(reinterpret_cast<char*>(L.data()), s*sizeof(T));
+                is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T));
 
                 is.fatalCheck
                 (
diff --git a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C b/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C
index 6aff9ed81e06d6d7578419172a584f261250f73f..594aa01e4dd0171902b2d53726b71c77f6d08c0f 100644
--- a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C
+++ b/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C
@@ -48,19 +48,19 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
     if (firstToken.isLabel())
     {
         // Read size of list
-        const label s = firstToken.labelToken();
+        const label sz = firstToken.labelToken();
 
         // Set list length to that read
-        setSize(s);
+        setSize(sz);
 
         // Read beginning of contents
         const char delimiter = is.readBeginList("PtrList");
 
-        if (s)
+        if (sz)
         {
             if (delimiter == token::BEGIN_LIST)
             {
-                forAll(*this, i)
+                for (label i=0; i<sz; ++i)
                 {
                     set(i, inewt(is));
 
@@ -82,7 +82,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt)
                     "reading the single entry"
                 );
 
-                for (label i=1; i<s; ++i)
+                for (label i=1; i<sz; ++i)
                 {
                     set(i, tPtr->clone());
                 }
diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C
index de49fc74a0cfbba2a7ff382c4733f142716c46b3..b990952e2d44c9d9501b0f0e53553fea3a2f3031 100644
--- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C
+++ b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C
@@ -39,14 +39,16 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
 {
     const UIndirectList<T>& L = *this;
 
+    const label sz = L.size();
+
     // Write list contents depending on data format
     if (os.format() == IOstream::ASCII || !contiguous<T>())
     {
         // Can the contents be considered 'uniform' (ie, identical)?
-        bool uniform = (L.size() > 1 && contiguous<T>());
+        bool uniform = (sz > 1 && contiguous<T>());
         if (uniform)
         {
-            forAll(L, i)
+            for (label i=1; i < sz; ++i)
             {
                 if (L[i] != L[0])
                 {
@@ -58,65 +60,72 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList
 
         if (uniform)
         {
-            // Write size and start delimiter
-            os << L.size() << token::BEGIN_BLOCK;
+            // Size and start delimiter
+            os << sz << token::BEGIN_BLOCK;
 
-            // Write contents
+            // Contents
             os << L[0];
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_BLOCK;
         }
         else if
         (
-            L.size() <= 1 || !shortListLen
-         || (L.size() <= shortListLen && contiguous<T>())
+            sz <= 1 || !shortListLen
+         || (sz <= shortListLen && contiguous<T>())
         )
         {
-            // Write size and start delimiter
-            os << L.size() << token::BEGIN_LIST;
+            // Size and start delimiter
+            os << sz << token::BEGIN_LIST;
 
-            // Write contents
-            forAll(L, i)
+            // Contents
+            for (label i=0; i < sz; ++i)
             {
                 if (i) os << token::SPACE;
                 os << L[i];
             }
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_LIST;
         }
         else
         {
-            // Write size and start delimiter
-            os << nl << L.size() << nl << token::BEGIN_LIST << nl;
+            // Size and start delimiter
+            os << nl << sz << nl << token::BEGIN_LIST << nl;
 
-            // Write contents
-            forAll(L, i)
+            // Contents
+            for (label i=0; i < sz; ++i)
             {
                 os << L[i] << nl;
             }
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_LIST << nl;
         }
     }
     else
     {
         // Contents are binary and contiguous
-        os << nl << L.size() << nl;
+        os << nl << sz << nl;
 
-        if (L.size())
+        if (sz)
         {
-            // This is annoying, and wasteful, but currently no alternative
-            List<T> lst = L();
-
-            // write(...) includes surrounding start/end delimiters
-            os.write
-            (
-                reinterpret_cast<const char*>(lst.cdata()),
-                lst.byteSize()
-            );
+            // The TOTAL number of bytes to be written.
+            // - possibly add start delimiter
+            os.beginRaw(sz*sizeof(T));
+
+            // Contents
+            for (label i=0; i < sz; ++i)
+            {
+                os.writeRaw
+                (
+                    reinterpret_cast<const char*>(&(L[i])),
+                    sizeof(T)
+                );
+            }
+
+            // End delimiter and/or cleanup.
+            os.endRaw();
         }
     }
 
diff --git a/src/OpenFOAM/containers/Lists/UList/UListIO.C b/src/OpenFOAM/containers/Lists/UList/UListIO.C
index efb2ad3ffce3935884d40209ef04f8909eef907e..08d18569172a5261f630f292afe40bb69b69883a 100644
--- a/src/OpenFOAM/containers/Lists/UList/UListIO.C
+++ b/src/OpenFOAM/containers/Lists/UList/UListIO.C
@@ -76,14 +76,16 @@ Foam::Ostream& Foam::UList<T>::writeList
 {
     const UList<T>& L = *this;
 
+    const label sz = L.size();
+
     // Write list contents depending on data format
     if (os.format() == IOstream::ASCII || !contiguous<T>())
     {
         // Can the contents be considered 'uniform' (ie, identical)?
-        bool uniform = (L.size() > 1 && contiguous<T>());
+        bool uniform = (sz > 1 && contiguous<T>());
         if (uniform)
         {
-            forAll(L, i)
+            for (label i=1; i < sz; ++i)
             {
                 if (L[i] != L[0])
                 {
@@ -95,58 +97,62 @@ Foam::Ostream& Foam::UList<T>::writeList
 
         if (uniform)
         {
-            // Write size and start delimiter
-            os << L.size() << token::BEGIN_BLOCK;
+            // Size and start delimiter
+            os << sz << token::BEGIN_BLOCK;
 
-            // Write contents
+            // Contents
             os << L[0];
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_BLOCK;
         }
         else if
         (
-            L.size() <= 1 || !shortListLen
-         || (L.size() <= shortListLen && contiguous<T>())
+            sz <= 1 || !shortListLen
+         || (sz <= shortListLen && contiguous<T>())
         )
         {
-            // Write size and start delimiter
-            os << L.size() << token::BEGIN_LIST;
+            // Size and start delimiter
+            os << sz << token::BEGIN_LIST;
 
-            // Write contents
-            forAll(L, i)
+            // Contents
+            for (label i=0; i < sz; ++i)
             {
                 if (i) os << token::SPACE;
                 os << L[i];
             }
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_LIST;
         }
         else
         {
-            // Write size and start delimiter
-            os << nl << L.size() << nl << token::BEGIN_LIST << nl;
+            // Size and start delimiter
+            os << nl << sz << nl << token::BEGIN_LIST << nl;
 
-            // Write contents
-            forAll(L, i)
+            // Contents
+            for (label i=0; i < sz; ++i)
             {
                 os << L[i] << nl;
             }
 
-            // Write end delimiter
+            // End delimiter
             os << token::END_LIST << nl;
         }
     }
     else
     {
         // Contents are binary and contiguous
-        os << nl << L.size() << nl;
+        os << nl << sz << nl;
 
-        if (L.size())
+        if (sz)
         {
             // write(...) includes surrounding start/end delimiters
-            os.write(reinterpret_cast<const char*>(L.cdata()), L.byteSize());
+            os.write
+            (
+                reinterpret_cast<const char*>(L.cdata()),
+                L.byteSize()
+            );
         }
     }
 
@@ -184,29 +190,29 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
             )
         );
         // Check list length
-        const label s = elems.size();
+        const label sz = elems.size();
 
-        if (s != L.size())
+        if (sz != L.size())
         {
             FatalIOErrorInFunction(is)
-                << "incorrect length for UList. Read " << s
+                << "incorrect length for UList. Read " << sz
                 << " expected " << L.size()
                 << exit(FatalIOError);
         }
-        for (label i=0; i<s; ++i)
+        for (label i=0; i<sz; ++i)
         {
             L[i] = elems[i];
         }
     }
     else if (firstToken.isLabel())
     {
-        const label s = firstToken.labelToken();
+        const label sz = firstToken.labelToken();
 
         // Set list length to that read
-        if (s != L.size())
+        if (sz != L.size())
         {
             FatalIOErrorInFunction(is)
-                << "incorrect length for UList. Read " << s
+                << "incorrect length for UList. Read " << sz
                 << " expected " << L.size()
                 << exit(FatalIOError);
         }
@@ -218,11 +224,11 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
             // Read beginning of contents
             const char delimiter = is.readBeginList("List");
 
-            if (s)
+            if (sz)
             {
                 if (delimiter == token::BEGIN_LIST)
                 {
-                    for (label i=0; i<s; ++i)
+                    for (label i=0; i<sz; ++i)
                     {
                         is >> L[i];
 
@@ -245,7 +251,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
                         "reading the single entry"
                     );
 
-                    for (label i=0; i<s; ++i)
+                    for (label i=0; i<sz; ++i)
                     {
                         L[i] = element;
                     }
@@ -259,9 +265,9 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
         {
             // contents are binary and contiguous
 
-            if (s)
+            if (sz)
             {
-                is.read(reinterpret_cast<char*>(L.data()), s*sizeof(T));
+                is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T));
 
                 is.fatalCheck
                 (
diff --git a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C b/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C
index 2852654dda0f7bf017089075463441f9e7d0044f..33ff3d9878ec65fe9bb7ea869b2d0298c8761157 100644
--- a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C
+++ b/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C
@@ -31,18 +31,20 @@ License
 template<class T>
 Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& L)
 {
-    // Write size and start delimiter
-    os  << nl << indent << L.size() << nl
-        << indent << token::BEGIN_LIST << incrIndent;
+    const label sz = L.size();
 
-    // Write contents
-    forAll(L, i)
+    // Size and start delimiter
+    os  << nl << indent << sz << nl
+        << indent << token::BEGIN_LIST << incrIndent << nl;
+
+    // Contents
+    for (label i=0; i < sz; ++i)
     {
-        os << nl << L[i];
+        os << L[i] << nl;
     }
 
-    // Write end delimiter
-    os << nl << decrIndent << indent << token::END_LIST << nl;
+    // End delimiter
+    os << decrIndent << indent << token::END_LIST << nl;
 
     os.check(FUNCTION_NAME);
     return os;
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C
index fd3889618ea47660ed761cb72e81277653730c61..f1c97306ed5bbde3abdb9dc21521ddc58f469cff 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C
@@ -167,7 +167,7 @@ const std::istream& Foam::IFstream::stdStream() const
 }
 
 
-Foam::Istream& Foam::IFstream::rewind()
+void Foam::IFstream::rewind()
 {
     lineNumber_ = 1;      // Reset line number
 
@@ -195,8 +195,6 @@ Foam::Istream& Foam::IFstream::rewind()
     {
         ISstream::rewind();
     }
-
-    return *this;
 }
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H
index 72f89873c58a92447f7de8320ceac5609d0ee7d5..34f7c7c94838139b7a9e5662b09221d4aeb6549c 100644
--- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H
+++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H
@@ -130,7 +130,7 @@ public:
         virtual const std::istream& stdStream() const;
 
         //- Rewind the stream so that it may be read again
-        virtual Istream& rewind();
+        virtual void rewind();
 
 
       // Print
diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H b/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H
index 77131761969e0ca866f446bbdf277864f912ae3e..24df823bdda34e50b606e0c79a4ead1e8cd270d2 100644
--- a/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H
+++ b/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H
@@ -131,8 +131,8 @@ public:
             //- Read binary block
             virtual Istream& read(char*, std::streamsize) = 0;
 
-            //- Rewind and return the stream so that it may be read again
-            virtual Istream& rewind() = 0;
+            //- Rewind the stream so that it may be read again
+            virtual void rewind() = 0;
 
 
         // Read List punctuation tokens
diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H
index 3604a22d0be60e68812e83f64e6b015aeb04cfb2..916bae2278706c16b128c258c721aa6c8e1e45be 100644
--- a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H
+++ b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H
@@ -97,47 +97,62 @@ public:
         // Write functions
 
             //- Write next token to stream
-            virtual Ostream& write(const token&) = 0;
+            virtual Ostream& write(const token& t) = 0;
 
             //- Write character
-            virtual Ostream& write(const char) = 0;
+            virtual Ostream& write(const char c) = 0;
 
             //- Write character string
-            virtual Ostream& write(const char*) = 0;
+            virtual Ostream& write(const char* str) = 0;
 
             //- Write word
-            virtual Ostream& write(const word&) = 0;
+            virtual Ostream& write(const word& str) = 0;
 
             //- Write keyType
             //  A plain word is written unquoted.
             //  A regular expression is written as a quoted string.
-            virtual Ostream& write(const keyType&);
+            virtual Ostream& write(const keyType& kw);
 
             //- Write string
-            virtual Ostream& write(const string&) = 0;
+            virtual Ostream& write(const string& str) = 0;
 
             //- Write std::string surrounded by quotes.
             //  Optional write without quotes.
             virtual Ostream& writeQuoted
             (
-                const std::string&,
+                const std::string& str,
                 const bool quoted=true
             ) = 0;
 
             //- Write int32_t
-            virtual Ostream& write(const int32_t) = 0;
+            virtual Ostream& write(const int32_t val) = 0;
 
             //- Write int64_t
-            virtual Ostream& write(const int64_t) = 0;
+            virtual Ostream& write(const int64_t val) = 0;
 
             //- Write floatScalar
-            virtual Ostream& write(const floatScalar) = 0;
+            virtual Ostream& write(const floatScalar val) = 0;
 
             //- Write doubleScalar
-            virtual Ostream& write(const doubleScalar) = 0;
+            virtual Ostream& write(const doubleScalar val) = 0;
 
-            //- Write binary block
-            virtual Ostream& write(const char*, std::streamsize) = 0;
+            //- Write binary block.
+            virtual Ostream& write(const char* data, std::streamsize count) = 0;
+
+            //- Emit begin marker for low-level raw binary output.
+            //  The count should indicate the number of bytes for subsequent
+            //  writeRaw calls.
+            virtual Ostream& beginRaw(std::streamsize count) = 0;
+
+            //- Low-level raw binary output.
+            virtual Ostream& writeRaw
+            (
+                const char* data,
+                std::streamsize count
+            ) = 0;
+
+            //- Emit end marker for low-level raw binary output.
+            virtual Ostream& endRaw() = 0;
 
             //- Add indentation characters
             virtual void indent() = 0;
@@ -164,11 +179,11 @@ public:
             void decrIndent();
 
             //- Write the keyword followed by an appropriate indentation
-            virtual Ostream& writeKeyword(const keyType&);
+            virtual Ostream& writeKeyword(const keyType& kw);
 
             //- Write begin block group with the given name
             //  Increments indentation, adds newline.
-            virtual Ostream& beginBlock(const keyType&);
+            virtual Ostream& beginBlock(const keyType& keyword);
 
             //- Write begin block group without a name
             //  Increments indentation, adds newline.
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C
index 333aeca259c72b0a1b8edbc98155725df7aab477..21b412fce39e6779cb8ac03dfeae043a10fdf5c0 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C
@@ -329,10 +329,9 @@ Foam::Istream& Foam::UIPstream::read(char* data, std::streamsize count)
 }
 
 
-Foam::Istream& Foam::UIPstream::rewind()
+void Foam::UIPstream::rewind()
 {
     externalBufPosition_ = 0;
-    return *this;
 }
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
index 4913693741f8b24e50f858947f6ec90b5943a3bd..d0c0f86552985eae47197f514059bdb90e900223 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H
@@ -171,8 +171,8 @@ public:
             //- Read binary block with 8-byte alignment.
             Istream& read(char* data, const std::streamsize count);
 
-            //- Rewind and return the stream so that it may be read again
-            Istream& rewind();
+            //- Rewind the stream so that it may be read again
+            void rewind();
 
 
         // Edit
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C
index 6667389b742231d9e691716d6dc487a3503db62a..eb54b5ea61abc2fcb9dad6c4210f0e0f1f846ebc 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2017 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,15 +26,42 @@ License
 #include "UOPstream.H"
 #include "int.H"
 #include "token.H"
-
 #include <cctype>
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
+inline void Foam::UOPstream::prepareBuffer
+(
+    const size_t count,
+    const size_t align
+)
+{
+    if (!count)
+    {
+        return;
+    }
+
+    // The current output position
+    label pos = sendBuf_.size();
+
+    if (align > 1)
+    {
+        // Align output position. Pads sendBuf_.size() - oldPos characters.
+        pos = align + ((pos - 1) & ~(align - 1));
+    }
+
+    // Extend buffer (as required)
+    sendBuf_.reserve(max(1000, label(pos + count)));
+
+    // Move to the aligned output position
+    sendBuf_.setSize(pos);
+}
+
+
 template<class T>
-inline void Foam::UOPstream::writeToBuffer(const T& t)
+inline void Foam::UOPstream::writeToBuffer(const T& val)
 {
-    writeToBuffer(&t, sizeof(T), sizeof(T));
+    writeToBuffer(&val, sizeof(T), sizeof(T));
 }
 
 
@@ -55,25 +82,26 @@ inline void Foam::UOPstream::writeToBuffer
     const size_t align
 )
 {
-    if (!sendBuf_.capacity())
+    if (!count)
     {
-        sendBuf_.setCapacity(1000);
+        return;
     }
 
-    label alignedPos = sendBuf_.size();
+    prepareBuffer(count, align);
 
-    if (align > 1)
-    {
-        // Align bufPosition. Pads sendBuf_.size() - oldPos characters.
-        alignedPos = align + ((sendBuf_.size() - 1) & ~(align - 1));
-    }
+    // The aligned output position
+    const label pos = sendBuf_.size();
+
+    // Extend the addressable range for direct pointer access
+    sendBuf_.setSize(pos + count);
 
-    // Extend if necessary
-    sendBuf_.setSize(alignedPos + count);
+    char* const __restrict__ buf = (sendBuf_.begin() + pos);
+    const char* const __restrict__ input = reinterpret_cast<const char*>(data);
 
-    const char* dataPtr = reinterpret_cast<const char*>(data);
-    size_t i = count;
-    while (i--) sendBuf_[alignedPos++] = *dataPtr++;
+    for (size_t i = 0; i < count; ++i)
+    {
+        buf[i] = input[i];
+    }
 }
 
 
@@ -135,7 +163,7 @@ Foam::UOPstream::~UOPstream()
     {
         if
         (
-           !UOPstream::write
+            !UOPstream::write
             (
                 commsType_,
                 toProcNo_,
@@ -298,6 +326,41 @@ Foam::Ostream& Foam::UOPstream::write
 }
 
 
+Foam::Ostream& Foam::UOPstream::beginRaw
+(
+    const std::streamsize count
+)
+{
+    if (format() != BINARY)
+    {
+        FatalErrorInFunction
+            << "stream format not binary"
+            << Foam::abort(FatalError);
+    }
+
+    // Alignment = 8, as per write(const char*, streamsize)
+    prepareBuffer(count, 8);
+
+    return *this;
+}
+
+
+Foam::Ostream& Foam::UOPstream::writeRaw
+(
+    const char* data,
+    const std::streamsize count
+)
+{
+    // No check for format() == BINARY since this is either done in the
+    // beginRaw() method, or the caller knows what they are doing.
+
+    // Previously aligned and sizes reserved via beginRaw()
+    writeToBuffer(data, count, 1);
+
+    return *this;
+}
+
+
 void Foam::UOPstream::print(Ostream& os) const
 {
     os  << "Writing from processor " << toProcNo_
diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
index 6ee40e03781dc5042ca3b36d08bcaa639d425671..364b10ccddacf3346cbd593c99f898a0e94b2b00 100644
--- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
+++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2014 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -72,9 +72,12 @@ class UOPstream
 
     // Private Member Functions
 
-        //- Write a T to the transfer buffer
+        //- Prepare buffer for count bytes of output at specified alignment.
+        inline void prepareBuffer(const size_t count, const size_t align);
+
+        //- Write data to the transfer buffer
         template<class T>
-        inline void writeToBuffer(const T& t);
+        inline void writeToBuffer(const T& val);
 
         //- Write a char to the transfer buffer
         inline void writeToBuffer(const char& c);
@@ -182,6 +185,24 @@ public:
             //- Write binary block with 8-byte alignment.
             Ostream& write(const char* data, const std::streamsize count);
 
+            //- Begin marker for low-level raw binary output.
+            //  The count should indicate the number of bytes for subsequent
+            //  writeRaw calls.
+            Ostream& beginRaw(const std::streamsize count);
+
+            //- Low-level raw binary output.
+            Ostream& writeRaw
+            (
+                const char* data,
+                const std::streamsize count
+            );
+
+            //- End marker for low-level raw binary output.
+            Ostream& endRaw()
+            {
+                return *this;
+            }
+
             //- Add indentation characters
             void indent()
             {}
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
index 40c2d8e5950f39b6bc7d929944eb8d4a33f92c23..15ad568f18f0f50f226745b3c9a6d60499c9b91a 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C
@@ -798,7 +798,7 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
 }
 
 
-Foam::Istream& Foam::ISstream::rewind()
+void Foam::ISstream::rewind()
 {
     lineNumber_ = 1;      // Reset line number
 
@@ -807,8 +807,6 @@ Foam::Istream& Foam::ISstream::rewind()
 
     // pubseekpos() rather than seekg() so that it works with gzstream
     stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
-
-    return *this;
 }
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H
index 18890e208734385fb266bfb9aec79d5039c8ac6e..4a2b510b5b16e0313d48a10c3220490715f569a5 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H
@@ -82,7 +82,7 @@ public:
 
     // Constructors
 
-        //- Construct as wrapper around istream
+        //- Construct as wrapper around std::istream
         inline ISstream
         (
             std::istream& is,
@@ -163,8 +163,8 @@ public:
             //- Read binary block
             virtual Istream& read(char* buf, std::streamsize count);
 
-            //- Rewind and return the stream so that it may be read again
-            virtual Istream& rewind();
+            //- Rewind the stream so that it may be read again
+            virtual void rewind();
 
 
         // Stream state functions
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C
index 5dc8a3e6bd9078250ae44ea908c37b79cd015444..5c6f14103e77dd22d074937fc6a3146bbf58d0d8 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C
@@ -210,7 +210,24 @@ Foam::Ostream& Foam::OSstream::write(const doubleScalar val)
 }
 
 
-Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
+Foam::Ostream& Foam::OSstream::write
+(
+    const char* data,
+    const std::streamsize count
+)
+{
+    beginRaw(count);
+    writeRaw(data, count);
+    endRaw();
+
+    return *this;
+}
+
+
+Foam::Ostream& Foam::OSstream::beginRaw
+(
+    const std::streamsize count
+)
 {
     if (format() != BINARY)
     {
@@ -220,8 +237,6 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
     }
 
     os_ << token::BEGIN_LIST;
-    os_.write(buf, count);
-    os_ << token::END_LIST;
 
     setState(os_.rdstate());
 
@@ -229,9 +244,34 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
 }
 
 
+Foam::Ostream& Foam::OSstream::writeRaw
+(
+    const char* data,
+    std::streamsize count
+)
+{
+    // No check for format() == BINARY since this is either done in the
+    // beginRaw() method, or the caller knows what they are doing.
+
+    os_.write(data, count);
+    setState(os_.rdstate());
+
+    return *this;
+}
+
+
+Foam::Ostream& Foam::OSstream::endRaw()
+{
+    os_ << token::END_LIST;
+    setState(os_.rdstate());
+
+    return *this;
+}
+
+
 void Foam::OSstream::indent()
 {
-    for (unsigned short i = 0; i < indentLevel_*indentSize_; i++)
+    for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)
     {
         os_ << ' ';
     }
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H
index 4c6e97fd59386ae6c3c599daaf009fb82e25c107..2dd13c50fb2eb67c5dd8f5aa8582298ce4dd7056 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H
@@ -69,7 +69,7 @@ public:
 
     // Constructors
 
-        //- Construct and set stream status
+        //- Construct as wrapper around std::ostream and set stream status
         OSstream
         (
             std::ostream& os,
@@ -143,7 +143,26 @@ public:
             virtual Ostream& write(const doubleScalar val);
 
             //- Write binary block
-            virtual Ostream& write(const char* buf, std::streamsize count);
+            virtual Ostream& write
+            (
+                const char* data,
+                const std::streamsize count
+            );
+
+            //- Begin marker for low-level raw binary output.
+            //  The count should indicate the number of bytes for subsequent
+            //  writeRaw calls.
+            virtual Ostream& beginRaw(const std::streamsize count);
+
+            //- Low-level raw binary output.
+            virtual Ostream& writeRaw
+            (
+                const char* data,
+                const std::streamsize count
+            );
+
+            //- End marker for low-level raw binary output.
+            virtual Ostream& endRaw();
 
             //- Add indentation characters
             virtual void indent();
diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H
index 1bdbad9adb7dbe9c13c4c7ae3258ce7e61ad7bc5..cee86b47bb61becdd5df0af68b98825c6bd07d61 100644
--- a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H
+++ b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H
@@ -56,8 +56,11 @@ protected:
 
     // Member Data
 
-        //- The allocated stream pointer.
-        StreamType* allocatedPtr_;
+        //- The stream type
+        typedef StreamType stream_type;
+
+        //- The input/output stream.
+        stream_type stream_;
 
 
     // Constructors
@@ -65,56 +68,36 @@ protected:
         //- Construct null
         StringStreamAllocator()
         :
-            allocatedPtr_(new StreamType())
+            stream_()
         {}
 
-        //- Construct from pointer, taking ownership
-        StringStreamAllocator(StreamType* ptr)
-        :
-            allocatedPtr_(ptr)
-        {}
 
-        //- Construct from string
+        //- Copy construct from string
         StringStreamAllocator(const std::string& buffer)
         :
-            allocatedPtr_(new StreamType(buffer))
+            stream_(buffer)
         {}
 
 
     //- Destructor
     ~StringStreamAllocator()
-    {
-        deallocate();
-    }
-
-
-    // Protected Member Functions
-
-        //- Delete the stream pointer
-        void deallocate()
-        {
-            if (allocatedPtr_)
-            {
-                delete allocatedPtr_;
-                allocatedPtr_ = nullptr;
-            }
-        }
+    {}
 
 
 public:
 
     // Public Member Functions
 
-        //- Get the string
+        //- Get the string - as Foam::string rather than std::string
         Foam::string str() const
         {
-            return allocatedPtr_->str();
+            return Foam::string(stream_.str());
         }
 
         //- Set the string
         void str(const std::string& s)
         {
-            allocatedPtr_->str(s);
+            stream_.str(s);
         }
 };
 
@@ -143,7 +126,7 @@ public:
         )
         :
             StringStreamAllocator<std::istringstream>(buffer),
-            ISstream(*allocatedPtr_, name, format, version)
+            ISstream(stream_, name, format, version)
         {}
 
 
@@ -157,7 +140,15 @@ public:
         )
         :
             StringStreamAllocator<std::istringstream>(buffer),
-            ISstream(*allocatedPtr_, name, format, version)
+            ISstream(stream_, name, format, version)
+        {}
+
+
+        //- Construct as copy of content
+        IStringStream(const IStringStream& str)
+        :
+            StringStreamAllocator<std::istringstream>(str.str()),
+            ISstream(stream_, str.name(), str.format(), str.version())
         {}
 
 
@@ -171,12 +162,18 @@ public:
         //- Print description to Ostream
         void print(Ostream& os) const;
 
+        //- Reset the input buffer and rewind the stream
+        void reset(const std::string& s)
+        {
+            this->str(s);
+            this->rewind();
+        }
+
 
     // Member operators
 
         //- Return a non-const reference to const Istream
-        //  Needed for read-constructors where the stream argument is temporary:
-        //  e.g. thing thisThing(IFstream("thingFileName")());
+        //  Needed for read-constructors where the stream argument is temporary.
         Istream& operator()() const
         {
             return const_cast<IStringStream&>(*this);
@@ -207,14 +204,15 @@ public:
         )
         :
             StringStreamAllocator<std::ostringstream>(),
-            OSstream(*allocatedPtr_, "output", format, version)
+            OSstream(stream_, "output", format, version)
         {}
 
-        //- Construct as copy
-        OStringStream(const OStringStream& oss)
+
+        //- Construct as copy of content
+        OStringStream(const OStringStream& str)
         :
-            StringStreamAllocator<std::ostringstream>(oss.str()),
-            OSstream(*allocatedPtr_, oss.name(), oss.format(), oss.version())
+            StringStreamAllocator<std::ostringstream>(str.str()),
+            OSstream(stream_, str.name(), str.format(), str.version())
         {}
 
 
@@ -236,7 +234,7 @@ public:
         void rewind()
         {
             // pubseekpos() instead of seekp() for symmetry with other classes
-            allocatedPtr_->rdbuf()->pubseekpos(0, std::ios_base::out);
+            stream_.rdbuf()->pubseekpos(0, std::ios_base::out);
         }
 
         //- Print description to Ostream
diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C
index c9dae1229471051a350ac5b68b579104bbf4bbdc..c0890dad9d521caeb0935411f7f99e30cadc5741 100644
--- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C
+++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C
@@ -154,7 +154,7 @@ Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
 }
 
 
-Foam::Istream& Foam::ITstream::rewind()
+void Foam::ITstream::rewind()
 {
     tokenIndex_ = 0;
 
@@ -164,8 +164,6 @@ Foam::Istream& Foam::ITstream::rewind()
     }
 
     setGood();
-
-    return *this;
 }
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H
index 26617cb37e6f01edddf7a75c738f1311c21331d7..b8414cc4f23110271be652be7090b583c9a1afed 100644
--- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H
+++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H
@@ -188,8 +188,8 @@ public:
             //- Read binary block
             virtual Istream& read(char*, std::streamsize);
 
-            //- Rewind and return the stream so that it may be read again
-            virtual Istream& rewind();
+            //- Rewind the stream so that it may be read again
+            virtual void rewind();
 
 
         // Edit
diff --git a/src/OpenFOAM/db/IOstreams/dummyISstream/dummyISstream.H b/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H
similarity index 96%
rename from src/OpenFOAM/db/IOstreams/dummyISstream/dummyISstream.H
rename to src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H
index 9477b087914408dc993a15bb5de59fdda198e995..fa0b441dc2da06f19c48af4b38bfeaaede14cad1 100644
--- a/src/OpenFOAM/db/IOstreams/dummyISstream/dummyISstream.H
+++ b/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H
@@ -126,11 +126,10 @@ public:
                 return *this;
             }
 
-            //- Rewind and return the stream so that it may be read again
-            virtual Istream& rewind()
+            //- Rewind the stream so that it may be read again
+            virtual void rewind()
             {
                 NotImplemented;
-                return *this;
             }
 
             //- Return flags of stream
diff --git a/src/OpenFOAM/db/IOstreams/dummyIstream/dummyIstream.H b/src/OpenFOAM/db/IOstreams/dummy/dummyIstream.H
similarity index 97%
rename from src/OpenFOAM/db/IOstreams/dummyIstream/dummyIstream.H
rename to src/OpenFOAM/db/IOstreams/dummy/dummyIstream.H
index 9e8549820db4869fff8b7a11347a90a97614ebd2..b15f892ec21d9955ed41cfc285e26e37d464caa4 100644
--- a/src/OpenFOAM/db/IOstreams/dummyIstream/dummyIstream.H
+++ b/src/OpenFOAM/db/IOstreams/dummy/dummyIstream.H
@@ -127,8 +127,8 @@ public:
                 return *this;
             }
 
-            //- Rewind and return the stream so that it may be read again
-            virtual Istream& rewind()
+            //- Rewind the stream so that it may be read again
+            virtual void rewind()
             {
                 NotImplemented;
                 return *this;
diff --git a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H
index 8a43d3d7b1561245f55a7216698173ae56140242..414259c7951cd0acb0c60c9400fe86ac7b829090 100644
--- a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H
+++ b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H
@@ -47,55 +47,57 @@ class osha1stream;
 class OSHA1stream;
 
 /*---------------------------------------------------------------------------*\
-                        Class sha1streambuf Declaration
+                         Class osha1stream Declaration
 \*---------------------------------------------------------------------------*/
 
-//- A streambuf class for calculating SHA1 digests
-class sha1streambuf
+//- A basic output stream for calculating SHA1 digests
+class osha1stream
 :
-    public std::streambuf
+    virtual public std::ios,
+    public std::ostream
 {
-    // Private data
+    //- A streambuf class for calculating SHA1 digests
+    class sha1buf
+    :
+        public std::streambuf
+    {
+        //- This does all the work and has its own buffering
+        SHA1 sha1_;
 
-    //- This does all the work and has its own buffering
-    SHA1 sha1_;
+    protected:
+        // Protected members
 
-    friend class osha1stream;
+            //- Put sequence of characters
+            virtual std::streamsize xsputn(const char* str, std::streamsize n)
+            {
+                sha1_.append(str, n);
+                return n;
+            }
 
-public:
 
-    // Constructors
+    public:
 
-        //- Construct null
-        sha1streambuf()
-        {}
+        // Constructors
 
-    // Member Functions
+            //- Construct null
+            sha1buf()
+            {}
 
-      // Write
 
-        //- Process unbuffered
-        virtual std::streamsize xsputn(const char* str, std::streamsize n)
-        {
-            sha1_.append(str, n);
-            return n;
-        }
-};
+        // Public member functions
 
+            //- Full access to the sha1
+            inline SHA1& sha1()
+            {
+                return sha1_;
+            }
+    };
 
-/*---------------------------------------------------------------------------*\
-                         Class osha1stream Declaration
-\*---------------------------------------------------------------------------*/
 
-//- A basic output stream for calculating SHA1 digests
-class osha1stream
-:
-    virtual public std::ios,
-    public std::ostream
-{
     // Private data
 
-    sha1streambuf sbuf_;
+        //- Reference to the underlying buffer
+        sha1buf buf_;
 
 public:
 
@@ -104,23 +106,24 @@ public:
         //- Construct null
         osha1stream()
         :
-            std::ostream(&sbuf_)
+            std::ostream(&buf_)
         {}
 
+
     // Member Functions
 
       // Access
 
         //- This hides both signatures of std::basic_ios::rdbuf()
-        sha1streambuf* rdbuf()
+        sha1buf* rdbuf()
         {
-            return &sbuf_;
+            return &buf_;
         }
 
         //- Full access to the sha1
         SHA1& sha1()
         {
-            return sbuf_.sha1_;
+            return buf_.sha1();
         }
 
 };
@@ -135,10 +138,12 @@ class OSHA1streamAllocator
 {
 protected:
 
-    // Member data
+    // Protected data
+
+        typedef osha1stream stream_type;
 
-        //- The allocated stream pointer
-        osha1stream* allocatedPtr_;
+        //- The output stream
+        stream_type stream_;
 
 
     // Constructors
@@ -146,36 +151,37 @@ protected:
         //- Construct null
         OSHA1streamAllocator()
         :
-            allocatedPtr_(new osha1stream())
+            stream_()
         {}
 
 
     //- Destructor
     ~OSHA1streamAllocator()
-    {
-        deallocate();
-    }
+    {}
 
 
+public:
+
     // Member Functions
 
-        //- Delete the stream pointer
-        void deallocate()
+        //- Full access to the sha1
+        SHA1& sha1()
         {
-            if (allocatedPtr_)
-            {
-                delete allocatedPtr_;
-                allocatedPtr_ = nullptr;
-            }
+            return stream_.sha1();
         }
 
 
-public:
+        //- Return SHA1::Digest for the data processed until now
+        SHA1Digest digest()
+        {
+            return stream_.sha1().digest();
+        }
 
-        //- Full access to the sha1
-        SHA1& sha1()
+
+        //- Clear the SHA1 calculation
+        void reset()
         {
-            return allocatedPtr_->sha1();
+            return stream_.sha1().clear();
         }
 
 };
@@ -191,6 +197,7 @@ class OSHA1stream
     public OSHA1streamAllocator,
     public OSstream
 {
+    typedef OSHA1streamAllocator allocator_type;
 
     // Private Member Functions
 
@@ -211,8 +218,8 @@ public:
             versionNumber version=currentVersion
         )
         :
-            OSHA1streamAllocator(),
-            OSstream(*allocatedPtr_, "OSHA1stream", format, version)
+            allocator_type(),
+            OSstream(stream_, "sha1", format, version)
         {}
 
 
@@ -223,23 +230,6 @@ public:
 
     // Member functions
 
-      // Access
-
-        //- Return SHA1::Digest for the data processed until now
-        SHA1Digest digest()
-        {
-            return sha1().digest();
-        }
-
-
-      // Edit
-
-        //- Clear the SHA1 calculation
-        void reset()
-        {
-            sha1().clear();
-        }
-
         //- Clear the SHA1 calculation
         //  \deprecated use reset instead (deprecated Jul 2017)
         void rewind()
diff --git a/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H b/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H
new file mode 100644
index 0000000000000000000000000000000000000000..0696e1a943007b28abac9eba4f540512311f1925
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H
@@ -0,0 +1,266 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::BufStreamAllocator
+
+Description
+    Helper for memory buffer streams such as UIBufStream, UOBufStream
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef BufStreamAllocator_H
+#define BufStreamAllocator_H
+
+#include <type_traits>
+#include <sstream>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                          Class memorybuf Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A streambuf class for using externally allocated memory for its buffer
+class memorybuf
+:
+    public std::streambuf
+{
+protected:
+
+    // Protected members
+
+        //- Set position pointer to relative position
+        virtual std::streampos seekoff
+        (
+            std::streamoff off,
+            std::ios_base::seekdir way,
+            std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
+        )
+        {
+            const bool testin  = which & std::ios_base::in;
+            const bool testout = which & std::ios_base::out;
+
+            if (way == std::ios_base::beg)
+            {
+                if (testin)
+                {
+                    setg(eback(), eback(), egptr());
+                    gbump(off);
+                }
+                if (testout)
+                {
+                    setp(pbase(), epptr());
+                    pbump(off);
+                }
+
+                return off;
+            }
+
+            if (way == std::ios_base::cur)
+            {
+                if (testin)
+                {
+                    gbump(off);
+                }
+                if (testout)
+                {
+                    pbump(off);
+                }
+            }
+            else if (way == std::ios_base::end)
+            {
+                if (testin)
+                {
+                    gbump(off);
+                }
+                if (testout)
+                {
+                    pbump(off);
+                }
+            }
+
+            if (testin)
+            {
+                return gptr() - eback();
+            }
+            if (testout)
+            {
+                return pptr() - pbase();
+            }
+
+            return -1;
+        }
+
+
+        //- Set position pointer to absolute position
+        virtual std::streampos seekpos
+        (
+            std::streampos pos,
+            std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
+        )
+        {
+            return seekoff(pos, std::ios_base::beg, which);
+        }
+
+
+        //- Get sequence of characters
+        virtual std::streamsize xsgetn(char* s, std::streamsize n)
+        {
+            std::streamsize count = 0;
+
+            // some optimization could be possible here
+            while (count < n && gptr() < egptr())
+            {
+                *(s + count++) = *(gptr());
+                gbump(1);
+            }
+
+            return count;
+        }
+
+
+        //- Put sequence of characters
+        virtual std::streamsize xsputn(const char* s, std::streamsize n)
+        {
+            std::streamsize count = 0;
+
+            // some optimization could be possible here
+            while (count < n && pptr() < epptr())
+            {
+                *(pptr()) = *(s + count++);
+                pbump(1);
+            }
+
+            return count;
+        }
+
+
+public:
+
+    // Constructors
+
+        //- Construct for specified buffer
+        memorybuf(char* buffer, std::streamsize num)
+        {
+            setg(buffer, buffer, buffer + num);
+            setp(buffer, buffer + num);
+        }
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                     Class BufStreamAllocator Declaration
+\*---------------------------------------------------------------------------*/
+
+//- An stream/stream-buffer allocator for external buffers
+template<class StreamType, bool Manage=false>
+class BufStreamAllocator
+{
+    // Private data
+
+        //- Storage
+        char *storage_;
+
+        //- The number of bytes in the storage
+        std::streamsize len_;
+
+        //- Reference to the underlying buffer
+        memorybuf buf_;
+
+protected:
+
+    // Protected data
+
+        typedef StreamType stream_type;
+
+        //- The stream pointer
+        stream_type stream_;
+
+
+    // Constructors
+
+        //- Construct with buffer and number of bytes
+        BufStreamAllocator(char *buffer, size_t nbytes)
+        :
+            storage_(buffer),
+            len_(nbytes),
+            buf_(storage_, len_),
+            stream_(&buf_)
+        {}
+
+
+    //- Destructor
+    ~BufStreamAllocator()
+    {
+        // Possible cleanup of storage
+        if (Manage && storage_)
+        {
+            delete storage_;
+            storage_ = nullptr;
+        }
+    }
+
+
+    // Protected Member Functions
+
+
+        //- Position of the get buffer
+        std::streampos tellg() const
+        {
+            return const_cast<stream_type&>(stream_).tellg();
+        }
+
+        //- Position of the put buffer
+        std::streampos tellp() const
+        {
+            return const_cast<stream_type&>(stream_).tellp();
+        }
+
+
+public:
+
+    // Public Member Functions
+
+        //- Move to buffer start, clear errors
+        void rewind()
+        {
+            stream_.rdbuf()->pubseekpos(0);
+            stream_.clear(); // for safety, clear any old errors
+        }
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H
new file mode 100644
index 0000000000000000000000000000000000000000..b3ce64b16957a440a0be1ef6e801641760785ae9
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H
@@ -0,0 +1,230 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::OSCountStream
+
+Description
+    An output stream for calculating byte counts.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef OScountStream_H
+#define OScountStream_H
+
+#include "OSstream.H"
+#include <iostream>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class countstreambuf Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A streambuf class for determining byte counts
+class countstreambuf
+:
+    public std::streambuf
+{
+    // Private data
+
+        //- The number of bytes
+        std::streamsize n_;
+
+protected:
+    // Protected members
+
+        //- Put sequence of characters
+        virtual std::streamsize xsputn(const char* s, std::streamsize num)
+        {
+            n_ += num;
+            return num;
+        }
+
+
+        //- Set position pointer to absolute position
+        //  For the counter, any positioning is ignored and it always acts like
+        //  seekpos(0), which resets the count.
+        virtual std::streampos seekpos
+        (
+            std::streampos sp,
+            std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
+        )
+        {
+            n_ = 0;
+            return 0;
+        }
+
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        countstreambuf()
+        :
+            n_(0)
+        {}
+
+
+    // Access
+
+        //- Get number of bytes counted
+        std::streamsize size() const
+        {
+            return n_;
+        }
+};
+
+
+/*---------------------------------------------------------------------------*\
+                        Class ocountstream Declaration
+\*---------------------------------------------------------------------------*/
+
+//- Trivial output stream for calculating byte counts
+//  Since all output values are discarded, it can also be used as a /dev/null
+//  output buffer as well
+class ocountstream
+:
+    virtual public std::ios,
+    public std::ostream
+{
+    // Private data
+
+    countstreambuf buf_;
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        ocountstream()
+        :
+            std::ostream(&buf_)
+        {}
+
+
+    // Member Functions
+
+      // Access
+
+        //- This hides both signatures of std::basic_ios::rdbuf()
+        countstreambuf* rdbuf()
+        {
+            return &buf_;
+        }
+
+
+        //- Get number of bytes counted
+        std::streamsize size() const
+        {
+            return buf_.size();
+        }
+
+
+        //- Rewind the stream, reset the count
+        void rewind()
+        {
+            buf_.pubseekpos(0);
+            clear();    // for safety, clear any old errors
+        }
+};
+
+
+/*---------------------------------------------------------------------------*\
+                        Class OCountStream Declaration
+\*---------------------------------------------------------------------------*/
+
+//- An output stream for calculating byte counts
+class OCountStream
+:
+    private ocountstream,
+    public OSstream
+{
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        OCountStream(const OCountStream&) = delete;
+
+        //- Disallow default bitwise assignment
+        void operator=(const OCountStream&) = delete;
+
+public:
+
+    // Constructors
+
+        //- Construct and set stream status
+        OCountStream
+        (
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            ocountstream(),
+            OSstream
+            (
+                static_cast<ocountstream&>(*this),
+                "output",
+                format,
+                version
+        )
+        {}
+
+
+    //- Destructor
+    ~OCountStream()
+    {}
+
+
+    // Member functions
+
+      // Access
+
+        //- Return the number of bytes counted
+        using ocountstream::size;
+
+
+      // Edit
+
+        //- Rewind the stream, reset the count, clearing any old errors
+        void rewind()
+        {
+            ocountstream::rewind();
+            setGood();  // resynchronize with internal state
+        }
+
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/memory/OListStream.H b/src/OpenFOAM/db/IOstreams/memory/OListStream.H
new file mode 100644
index 0000000000000000000000000000000000000000..b76b7f6f7fa7b65cd6c46753ee39d0765a3be3c0
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/memory/OListStream.H
@@ -0,0 +1,416 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::OListStream
+
+Description
+    An output stream that writes to a DynamicList.
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef OListStream_H
+#define OListStream_H
+
+#include <sstream>
+#include "DynamicList.H"
+#include "OSstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration
+class OListStreamAllocator;
+
+/*---------------------------------------------------------------------------*\
+                    Class OListStreamAllocator Declaration
+\*---------------------------------------------------------------------------*/
+
+//- An stream/stream-buffer allocator for external buffers
+class OListStreamAllocator
+{
+    //- A streambuf adapter to output to a DynamicList
+    class olistbuf
+    :
+        public std::streambuf
+    {
+        friend OListStreamAllocator;
+
+        //- Underlying list storage
+        DynamicList<char,512> storage_;
+
+
+        //- Adjust buffer pointers to agree with list sizes
+        inline void syncBufferPointers()
+        {
+            setp(storage_.data(), storage_.data() + storage_.capacity());
+            pbump(storage_.size());
+        }
+
+        //- Adjust addressed list size to agree with buffer pointers
+        inline void syncListSize()
+        {
+            storage_.setSize(pptr() - pbase());
+        }
+
+
+    protected:
+
+        // Protected members
+
+            //- Set position pointer to relative position
+            virtual std::streampos seekoff
+            (
+                std::streamoff off,
+                std::ios_base::seekdir way,
+                std::ios_base::openmode which = std::ios_base::out
+            )
+            {
+                const bool testout = which & std::ios_base::out;
+
+                if (way == std::ios_base::beg)
+                {
+                    if (testout)
+                    {
+                        setp(pbase(), epptr());
+                        pbump(off);
+                    }
+
+                    return off;
+                }
+
+                if (way == std::ios_base::cur)
+                {
+                    if (testout)
+                    {
+                        pbump(off);
+                    }
+                }
+                else if (way == std::ios_base::end)
+                {
+                    if (testout)
+                    {
+                        pbump(off);
+                    }
+                }
+
+                if (testout)
+                {
+                    return pptr() - pbase();
+                }
+
+                return -1;
+            }
+
+
+            //- Set position pointer to absolute position
+            virtual std::streampos seekpos
+            (
+                std::streampos pos,
+                std::ios_base::openmode which = std::ios_base::out
+            )
+            {
+                if (which & std::ios_base::out)
+                {
+                    setp(pbase(), epptr());
+                    pbump(pos);
+
+                    return pptr() - pbase();
+                }
+
+                return -1;
+            }
+
+
+            //- Put sequence of characters
+            virtual std::streamsize xsputn(const char* s, std::streamsize n)
+            {
+                const std::streamsize newlen = n + storage_.size();
+
+                if (newlen > storage_.capacity())
+                {
+                    // Either use reserve(), or setCapacity() directly
+                    // with finer control over growth
+                    storage_.reserve(newlen);
+                    syncBufferPointers();
+                }
+
+                std::streamsize count = 0;
+                while (count < n && pptr() < epptr())
+                {
+                    *(pptr()) = *(s + count++);
+                    pbump(1);
+                }
+
+                // Synchronize list size with output
+                syncListSize();
+
+                return count;
+            }
+
+
+    public:
+
+        // Constructors
+
+            //- Construct with an empty list
+            olistbuf()
+            :
+                storage_(1024)
+            {
+                syncBufferPointers();
+            }
+
+
+            //- Construct with a specified number of reserved bytes
+            olistbuf(size_t nbytes)
+            :
+                storage_()
+            {
+                storage_.reserve(std::max(label(nbytes),1024));
+                syncBufferPointers();
+            }
+
+
+            //- Move construct from an existing List
+            olistbuf(List<char>&& buffer)
+            :
+                storage_(std::move(buffer))
+            {
+                syncBufferPointers();
+            }
+
+
+            //- Move construct from an existing DynamicList
+            template<int AnySize>
+            olistbuf(DynamicList<char,AnySize>&& buffer)
+            :
+                storage_(std::move(buffer))
+            {
+                syncBufferPointers();
+            }
+    };
+
+
+    // Private data
+
+        //- Reference to the underlying buffer
+        olistbuf buf_;
+
+
+protected:
+
+    // Protected data
+
+        typedef std::ostream stream_type;
+
+        //- The output stream
+        stream_type stream_;
+
+
+    // Constructors
+
+        //- Construct with an empty list
+        OListStreamAllocator()
+        :
+            buf_(),
+            stream_(&buf_)
+        {}
+
+
+        //- Construct with a specified number of reserved bytes
+        OListStreamAllocator(size_t nbytes)
+        :
+            buf_(nbytes),
+            stream_(&buf_)
+        {}
+
+
+        //- Move construct from an existing List
+        OListStreamAllocator(List<char>&& buffer)
+        :
+            buf_(std::move(buffer)),
+            stream_(&buf_)
+        {}
+
+
+        //- Move construct from an existing DynamicList
+        template<int SizeMin>
+        OListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
+        :
+            buf_(std::move(buffer)),
+            stream_(&buf_)
+        {}
+
+
+    //- Destructor
+    ~OListStreamAllocator()
+    {}
+
+
+public:
+
+    // Member Functions
+
+        //- Content as a list of characters
+        UList<char> list() const
+        {
+            return UList<char>
+            (
+                const_cast<char*>(buf_.storage_.cdata()),
+                buf_.storage_.size()
+            );
+        }
+
+
+        //- Content as a list of characters
+        UList<char>& list()
+        {
+            return static_cast<UList<char>&>(buf_.storage_);
+        }
+
+        //- Return the current list capacity
+        inline label capacity() const
+        {
+            return buf_.storage_.capacity();
+        }
+
+
+        //- Reserve allocation space for at least this size.
+        inline void reserve(const label nElem)
+        {
+            buf_.storage_.reserve(nElem);
+            buf_.syncBufferPointers();
+        }
+
+
+        //- Return the current output position in the buffer
+        //  The same as the DynamicList::size()
+        std::streampos size() const
+        {
+            return const_cast<stream_type&>(stream_).tellp();
+        }
+
+
+        //- Move to buffer start, clear errors
+        void rewind()
+        {
+            buf_.storage_.clear();
+            buf_.syncBufferPointers();
+            stream_.clear(); // for safety, clear any old errors
+        }
+};
+
+
+/*---------------------------------------------------------------------------*\
+                         Class OListStream Declaration
+\*----------------------------------------------d-----------------------------*/
+
+//- An OSstream attached a DynamicList
+class OListStream
+:
+    public OListStreamAllocator,
+    public OSstream
+{
+    typedef OListStreamAllocator allocator_type;
+
+public:
+
+    // Constructors
+
+        //- Construct with an empty list
+        OListStream
+        (
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            allocator_type(),
+            OSstream(stream_, "output", format,version)
+        {}
+
+
+        //- Construct with a specified number of reserved bytes
+        OListStream
+        (
+            size_t nbytes,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            allocator_type(nbytes),
+            OSstream(stream_, "output", format, version)
+        {}
+
+
+        //- Move construct from an existing List
+        OListStream
+        (
+            List<char>&& buffer,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            allocator_type(std::move(buffer)),
+            OSstream(stream_, "output", format, version)
+        {}
+
+
+        //- Move construct from an existing DynamicList
+        template<int SizeMin>
+        OListStream
+        (
+            DynamicList<char,SizeMin>&& buffer,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            allocator_type(std::move(buffer)),
+            OSstream(stream_, "output", format, version)
+        {}
+
+
+    //- Destructor
+    ~OListStream()
+    {}
+
+
+    // Member functions
+
+        //- Rewind the stream, clearing any old errors
+        using allocator_type::rewind;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H b/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H
new file mode 100644
index 0000000000000000000000000000000000000000..e02929f181f7b4c5430b8e24138cc39afa5fcdca
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H
@@ -0,0 +1,168 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::UIBufStream
+
+Description
+    Similar to IStringStream but using an externally managed buffer for its
+    input. This allows the input buffer to be filled (and refilled) from
+    various sources.
+
+    Note that this stream will normally be used as a "one-shot" reader.
+    Caution must be exercised that the referenced buffer remains valid and
+    without any intermediate resizing for the duration of the stream's use.
+
+    An example of possible use:
+    \code
+        DynamicList<char> buffer(4096);   // allocate some large buffer
+
+        nread = something.read(buffer.data(),1024); // fill with content
+        buffer.setSize(nread);            // content size
+
+        // construct dictionary, or something else
+        UIBufStream is(buffer)
+        dictionary dict1(is);
+
+        // sometime later
+        nread = something.read(buffer.data(),2048); // fill with content
+        buffer.setSize(nread);              // content size
+
+        // without intermediate variable
+        dictionary dict2(UIBufStream(buffer)());
+    \endcode
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef UIBufStream_H
+#define UIBufStream_H
+
+#include "BufStreamAllocator.H"
+#include "ISstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class UIBufStream Declaration
+\*---------------------------------------------------------------------------*/
+
+class UIBufStream
+:
+    public BufStreamAllocator<std::istream,false>,
+    public ISstream
+{
+    typedef BufStreamAllocator<std::istream,false> allocator_type;
+
+public:
+
+    // Constructors
+
+        //- Construct using specified buffer and number of bytes
+        UIBufStream
+        (
+            const char* buffer,
+            size_t nbytes,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion,
+            const Foam::string& name="input"
+        )
+        :
+            allocator_type(const_cast<char*>(buffer), nbytes),
+            ISstream(stream_, name, format, version)
+        {}
+
+
+        //- Construct using data area from a List and number of bytes
+        UIBufStream
+        (
+            const UList<char>& buffer,
+            label size,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion,
+            const Foam::string& name="input"
+        )
+        :
+            UIBufStream(buffer.cdata(), size, format,version,name)
+        {}
+
+
+        //- Construct using data area from a List and its inherent storage size
+        //  Uses addressed size, thus no special treatment for a DynamicList
+        UIBufStream
+        (
+            const UList<char>& buffer,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion,
+            const Foam::string& name="input"
+        )
+        :
+            UIBufStream(buffer.cdata(), buffer.size(), format,version,name)
+        {}
+
+
+    //- Destructor
+    ~UIBufStream()
+    {}
+
+
+    // Member functions
+
+        //- Return the current get position in the buffer
+        std::streampos pos() const
+        {
+            return allocator_type::tellg();
+        }
+
+
+        //- Rewind the stream, clearing any old errors
+        virtual void rewind()
+        {
+            allocator_type::rewind();
+            setGood();  // resynchronize with internal state
+        }
+
+
+    // Member operators
+
+        //- A non-const reference to const Istream
+        //  Needed for read-constructors where the stream argument is temporary
+        Istream& operator()() const
+        {
+            return const_cast<Istream&>(static_cast<const Istream&>(*this));
+        }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H b/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H
new file mode 100644
index 0000000000000000000000000000000000000000..6a8df54e7aea3b3eee4f97ff55a7fffc6d10596d
--- /dev/null
+++ b/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H
@@ -0,0 +1,190 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software: you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::UOBufStream
+
+Description
+    Similar to OStringStream but using an externally managed buffer for
+    its output.
+
+    This allows the output buffer to be reused and can make it easier when
+    writing out data.  It is the user's responsibility to ensure proper
+    synchronization in the sizes. Provided that the external buffer is large
+    enough that overflow does not occur, the following usage pattern
+    works.
+
+    \code
+        DynamicList<char> buffer(4096);     // allocate some large buffer
+
+        {
+            UOBufStream os(buffer);
+            os << "content1" << " and more content";
+            buffer.setSize(os.size());      // synchronize sizes
+        }
+
+        something.write(buffer, buffer.size());
+    \endcode
+
+    Although the UOBufStream is quite lightweight, there may be cases
+    where it is preferable to reuse the stream as well.
+    \code
+        DynamicList<char> buffer(4096);     // allocate some large buffer
+
+        UOBufStream os(buffer);
+        os << "content1" << " and more content";
+        buffer.setSize(os.size());          // synchronize sizes
+
+        something.write(buffer, buffer.size());
+
+        os.rewind();
+        os << "content2";
+        buffer.setSize(os.size());      // synchronize sizes
+
+        something.write(buffer, buffer.size());
+
+        // or simply using the output size directly (without sync)
+        os.rewind();
+        os << "content3";
+
+        something.write(buffer, os.size());
+    \endcode
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef UOBufStream_H
+#define UOBufStream_H
+
+#include "BufStreamAllocator.H"
+#include "OSstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declaration
+template<class T, int SizeMin> class DynamicList;
+
+
+/*---------------------------------------------------------------------------*\
+                         Class UOBufStream Declaration
+\*---------------------------------------------------------------------------*/
+
+//- An OSstream attached to an unallocated external buffer
+class UOBufStream
+:
+    public BufStreamAllocator<std::ostream,false>,
+    public OSstream
+{
+    typedef BufStreamAllocator<std::ostream,false> allocator_type;
+
+public:
+
+    // Constructors
+
+        //- Construct using specified buffer and number of bytes
+        UOBufStream
+        (
+            char* buffer,
+            size_t nbytes,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            allocator_type(buffer, nbytes),
+            OSstream(stream_, "output", format,version)
+        {}
+
+
+        //- Construct using data area from a List and number of bytes
+        UOBufStream
+        (
+            UList<char>& buffer,
+            size_t size,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            UOBufStream(buffer.data(), size, format,version)
+        {}
+
+
+        //- Construct using data area from a List and its inherent storage size
+        UOBufStream
+        (
+            UList<char>& buffer,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            UOBufStream(buffer.data(), buffer.size(), format,version)
+        {}
+
+
+        //- Construct using data area from a DynamicList and its capacity
+        template<int SizeMin>
+        UOBufStream
+        (
+            DynamicList<char,SizeMin>& buffer,
+            streamFormat format=ASCII,
+            versionNumber version=currentVersion
+        )
+        :
+            UOBufStream(buffer.data(), buffer.capacity(), format,version)
+        {}
+
+
+    //- Destructor
+    ~UOBufStream()
+    {}
+
+
+    // Member functions
+
+        //- Return the current output position in the buffer
+        std::streampos size() const
+        {
+            return allocator_type::tellp();
+        }
+
+
+        //- Rewind the stream, clearing any old errors
+        void rewind()
+        {
+            allocator_type::rewind();
+            setGood();  // resynchronize with internal state
+        }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //