diff --git a/applications/test/IndirectList2/IndirectList2.H b/applications/test/IndirectList2/IndirectList2.H
new file mode 100644
index 0000000000000000000000000000000000000000..9ce440695a00c7d33dd8056e5c50160288ff1f91
--- /dev/null
+++ b/applications/test/IndirectList2/IndirectList2.H
@@ -0,0 +1,162 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2010 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::IndirectList2
+
+Description
+    A List with indirect addressing.
+
+SourceFiles
+    IndirectListI.H
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef IndirectList2_H
+#define IndirectList2_H
+
+#include "UIndirectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class IndirectListAddressing Declaration
+\*---------------------------------------------------------------------------*/
+
+//- A helper class for storing addresses.
+class IndirectListAddressing
+{
+    // Private data
+
+        //- Storage for the list addressing
+        List<label> addressing_;
+
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        IndirectListAddressing(const IndirectListAddressing&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const IndirectListAddressing&);
+
+protected:
+
+    // Constructors
+
+        //- Construct by copying the addressing array
+        explicit inline IndirectListAddressing(const UList<label>& addr);
+
+        //- Construct by transferring addressing array
+        explicit inline IndirectListAddressing(const Xfer<List<label> >& addr);
+
+
+    // Member Functions
+
+        // Access
+
+            //- Return the list addressing
+            inline const List<label>& addressing() const;
+
+        // Edit
+
+            //- Reset addressing
+            inline void resetAddressing(const UList<label>&);
+            inline void resetAddressing(const Xfer<List<label> >&);
+
+};
+
+
+/*---------------------------------------------------------------------------*\
+                        Class IndirectList2 Declaration
+\*---------------------------------------------------------------------------*/
+
+template<class T>
+class IndirectList2
+:
+    private IndirectListAddressing,
+    public  UIndirectList<T>
+{
+    // Private Member Functions
+
+        //- Disable default assignment operator
+        void operator=(const IndirectList2<T>&);
+
+        //- Disable assignment from UIndirectList
+        void operator=(const UIndirectList<T>&);
+
+public:
+
+    // Constructors
+
+        //- Construct given the complete list and the addressing array
+        inline IndirectList2(const UList<T>&, const UList<label>&);
+
+        //- Construct given the complete list and by transferring addressing
+        inline IndirectList2(const UList<T>&, const Xfer<List<label> >&);
+
+        //- Copy constructor
+        inline IndirectList2(const IndirectList2<T>&);
+
+        //- Construct from UIndirectList
+        explicit inline IndirectList2(const UIndirectList<T>&);
+
+
+    // Member Functions
+
+
+        // Access
+
+            //- Return the list addressing
+            using UIndirectList<T>::addressing;
+
+        // Edit
+
+            //- Reset addressing
+            using IndirectListAddressing::resetAddressing;
+
+
+        // Member Operators
+
+            //- Assignment operator
+            using UIndirectList<T>::operator=;
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "IndirectList2I.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/test/IndirectList2/IndirectList2I.H b/applications/test/IndirectList2/IndirectList2I.H
new file mode 100644
index 0000000000000000000000000000000000000000..66b4e0de844533dea90142dff515e3c70991d76e
--- /dev/null
+++ b/applications/test/IndirectList2/IndirectList2I.H
@@ -0,0 +1,136 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+
+inline Foam::IndirectListAddressing::IndirectListAddressing
+(
+    const UList<label>& addr
+)
+:
+    addressing_(addr)
+{}
+
+
+inline Foam::IndirectListAddressing::IndirectListAddressing
+(
+    const Xfer<List<label> >& addr
+)
+:
+    addressing_(addr)
+{}
+
+
+template<class T>
+inline Foam::IndirectList2<T>::IndirectList2
+(
+    const UList<T>& completeList,
+    const UList<label>& addr
+)
+:
+    IndirectListAddressing(addr),
+    UIndirectList<T>
+    (
+        completeList,
+        IndirectListAddressing::addressing()
+    )
+{}
+
+
+template<class T>
+inline Foam::IndirectList2<T>::IndirectList2
+(
+    const UList<T>& completeList,
+    const Xfer<List<label> >& addr
+)
+:
+    IndirectListAddressing(addr),
+    UIndirectList<T>
+    (
+        completeList,
+        IndirectListAddressing::addressing()
+    )
+{}
+
+
+template<class T>
+inline Foam::IndirectList2<T>::IndirectList2
+(
+    const IndirectList2<T>& lst
+)
+:
+    IndirectListAddressing(lst.addressing()),
+    UIndirectList<T>
+    (
+        lst.completeList(),
+        IndirectListAddressing::addressing()
+    )
+{}
+
+
+template<class T>
+inline Foam::IndirectList2<T>::IndirectList2
+(
+    const UIndirectList<T>& lst
+)
+:
+    IndirectListAddressing(lst.addressing()),
+    UIndirectList<T>
+    (
+        lst.completeList(),
+        IndirectListAddressing::addressing()
+    )
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline const Foam::List<Foam::label>&
+Foam::IndirectListAddressing::addressing() const
+{
+    return addressing_;
+}
+
+
+inline void Foam::IndirectListAddressing::resetAddressing
+(
+    const UList<label>& addr
+)
+{
+    addressing_ = addr;
+}
+
+
+inline void Foam::IndirectListAddressing::resetAddressing
+(
+    const Xfer<List<label> >& addr
+)
+{
+    addressing_.transfer(addr());
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/IndirectList2/IndirectListTest2.C b/applications/test/IndirectList2/IndirectListTest2.C
new file mode 100644
index 0000000000000000000000000000000000000000..14d7d4dbae63c2c17901d2e0fe8e0a56cf208149
--- /dev/null
+++ b/applications/test/IndirectList2/IndirectListTest2.C
@@ -0,0 +1,101 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 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 "IndirectList2.H"
+#include "IOstreams.H"
+
+using namespace Foam;
+
+template<class ListType>
+void printInfo(const ListType& lst)
+{
+    Info<< "addr: " << lst.addressing() << nl
+        << "list: " << lst << nl
+        << endl;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    List<double> completeList(10);
+
+    forAll(completeList, i)
+    {
+        completeList[i] = 0.1*i;
+    }
+
+    Info<< "raw : " << completeList << nl << endl;
+
+
+    List<label> addresses(5);
+    addresses[0] = 1;
+    addresses[1] = 0;
+    addresses[2] = 7;
+    addresses[3] = 8;
+    addresses[4] = 5;
+
+    IndirectList2<double> idl1(completeList, addresses);
+
+    printInfo(idl1);
+
+    addresses[4] = 1;
+    addresses[3] = 0;
+    addresses[2] = 7;
+    addresses[1] = 8;
+    addresses[0] = 5;
+
+    idl1.resetAddressing(addresses.xfer());
+
+    printInfo(idl1);
+
+    // test copying
+    UIndirectList<double> uidl1(idl1);
+    IndirectList2<double> idl2(uidl1);
+    IndirectList2<double> idl3(idl2);
+
+    printInfo(uidl1);
+
+    idl1.resetAddressing(List<label>());
+//    idl2.resetAddressing(List<label>());
+
+    Info<<"after resetAddressing:" << nl << endl;
+
+    printInfo(uidl1);
+    printInfo(idl1);
+    printInfo(idl2);
+    printInfo(idl3);
+
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/IndirectList2/Make/files b/applications/test/IndirectList2/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..c6dab96e20b74e41bfec7e2be0e13e6b4d57d129
--- /dev/null
+++ b/applications/test/IndirectList2/Make/files
@@ -0,0 +1,3 @@
+IndirectListTest2.C
+
+EXE = $(FOAM_USER_APPBIN)/IndirectListTest2
diff --git a/applications/test/IndirectList2/Make/options b/applications/test/IndirectList2/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..6a9e9810b3d5ce6684bdaf03143933480ff45e42
--- /dev/null
+++ b/applications/test/IndirectList2/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/PackedList/PackedListTest.C b/applications/test/PackedList/PackedListTest.C
index ad5c7b3342422e9640b1ec9201672da20d753079..7d47532f1bae230ed6395c532c6f3803db1e7929 100644
--- a/applications/test/PackedList/PackedListTest.C
+++ b/applications/test/PackedList/PackedListTest.C
@@ -166,7 +166,7 @@ int main(int argc, char *argv[])
 
         if (args.optionFound("info"))
         {
-            packLst.print(Info);
+            packLst.printInfo(Info);
         }
 
         Info<< nl;
diff --git a/applications/test/PackedList1/PackedListTest1.C b/applications/test/PackedList1/PackedListTest1.C
index 4ee366854b04662ce3738f58abab87ce09a0a00f..e26b08e804738f2cd5a6b6f9209f464a24051aea 100644
--- a/applications/test/PackedList1/PackedListTest1.C
+++ b/applications/test/PackedList1/PackedListTest1.C
@@ -42,42 +42,42 @@ int main(int argc, char *argv[])
 
     Info<< "\ntest allocation with value\n";
     PackedList<3> list1(5,1);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign uniform value\n";
     list1 = 3;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign uniform value (with overflow)\n";
     list1 = -1;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest zero\n";
     list1 = 0;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest set() with default argument (max_value)\n";
     list1.set(1);
     list1.set(3);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest unset() with in-range and out-of-range\n";
     list1.unset(3);
     list1.unset(100000);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign between references\n";
     list1[2] = 3;
     list1[4] = list1[2];
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign between references, with chaining\n";
     list1[0] = list1[4] = 1;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign between references, with chaining and auto-vivify\n";
     list1[1] = list1[8] = list1[10] = list1[14] = 2;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
 
     Info<< "\ntest operator== between references\n";
@@ -126,7 +126,7 @@ int main(int argc, char *argv[])
     {
         const PackedList<3>& constLst = list1;
         Info<< "\ntest operator[] const with out-of-range index\n";
-        constLst.print(Info);
+        constLst.printInfo(Info, true);
         if (constLst[20])
         {
             Info<< "[20] is true (unexpected)\n";
@@ -136,7 +136,7 @@ int main(int argc, char *argv[])
             Info<< "[20] is false (expected) list size should be unchanged "
                 << "(const)\n";
         }
-        constLst.print(Info);
+        constLst.printInfo(Info, true);
 
         Info<< "\ntest operator[] non-const with out-of-range index\n";
         if (list1[20])
@@ -148,7 +148,7 @@ int main(int argc, char *argv[])
             Info<< "[20] is false (expected) but list was resized?? "
                 << "(non-const)\n";
         }
-        list1.print(Info);
+        list1.printInfo(Info, true);
     }
 
 
@@ -157,85 +157,85 @@ int main(int argc, char *argv[])
     {
         Info<< "[20] is false, as expected\n";
     }
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest resize with value (without reallocation)\n";
     list1.resize(8, list1.max_value());
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest flip() function\n";
     list1.flip();
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\nre-flip()\n";
     list1.flip();
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest set() function\n";
     list1.set(1, 5);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign bool\n";
     list1 = false;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest assign bool\n";
     list1 = true;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest resize without value (with reallocation)\n";
     list1.resize(12);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest resize with value (with reallocation)\n";
     list1.resize(25, list1.max_value());
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest resize smaller (should not touch allocation)\n";
     list1.resize(8);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest append() operation\n";
     list1.append(2);
     list1.append(3);
     list1.append(4);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest reserve() operation\n";
     list1.reserve(32);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest shrink() operation\n";
     list1.shrink();
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest setCapacity() operation\n";
     list1.setCapacity(15);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest setCapacity() operation\n";
     list1.setCapacity(100);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest operator[] assignment\n";
     list1[16] = 5;
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest operator[] assignment with auto-vivify\n";
     list1[36] = list1.max_value();
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest setCapacity smaller\n";
     list1.setCapacity(24);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest resize much smaller\n";
     list1.resize(150);
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest trim\n";
     list1.trim();
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     // add in some misc values
     list1[31] = 1;
@@ -245,40 +245,40 @@ int main(int argc, char *argv[])
     Info<< "\ntest iterator\n";
     PackedList<3>::iterator iter = list1.begin();
     Info<< "begin():";
-    iter.print(Info) << "\n";
+    iter.printInfo(Info) << "\n";
 
     Info<< "iterator:" << iter() << "\n";
     iter() = 5;
-    iter.print(Info);
-    list1.print(Info);
+    iter.printInfo(Info);
+    list1.printInfo(Info, true);
 
     iter = list1[31];
     Info<< "iterator:" << iter() << "\n";
-    iter.print(Info);
+    iter.printInfo(Info);
 
 
     Info<< "\ntest get() method\n";
     Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n";
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
     Info<< "\ntest iterator indexing\n";
     Info<< "cend() ";
-    list1.cend().print(Info) << "\n";
+    list1.cend().printInfo(Info) << "\n";
 
     {
         Info<< "\ntest assignment of iterator\n";
-        list1.print(Info);
+        list1.printInfo(Info, true);
         Info<< "cend()\n";
-        list1.end().print(Info);
+        list1.end().printInfo(Info);
         PackedList<3>::iterator cit = list1[100];
         Info<< "out-of-range: ";
-        cit.print(Info);
+        cit.printInfo(Info);
         cit = list1[15];
         Info<< "in-range: ";
-        cit.print(Info);
+        cit.printInfo(Info);
         Info<< "out-of-range: ";
         cit = list1[1000];
-        cit.print(Info);
+        cit.printInfo(Info);
     }
 
 
@@ -289,7 +289,7 @@ int main(int argc, char *argv[])
         ++cit
     )
     {
-        cit.print(Info);
+        cit.printInfo(Info);
     }
 
     Info<< "\ntest operator[] auto-vivify\n";
@@ -304,16 +304,16 @@ int main(int argc, char *argv[])
     Info<< "size after write:" << list1.size() << "\n";
     Info<< "list[45]:" << list1[45] << "\n";
     list1[49] = list1[100];
-    list1.print(Info);
+    list1.printInfo(Info, true);
 
 
     Info<< "\ntest copy constructor + append\n";
     PackedList<3> list2(list1);
     list2.append(4);
     Info<< "source list:\n";
-    list1.print(Info);
+    list1.printInfo(Info, true);
     Info<< "destination list:\n";
-    list2.print(Info);
+    list2.printInfo(Info, true);
 
     Info<< "\ntest pattern that fills all bits\n";
     PackedList<4> list3(8, 8);
@@ -323,29 +323,50 @@ int main(int argc, char *argv[])
     list3[pos--] = list3.max_value();
     list3[pos--] = 0;
     list3[pos--] = list3.max_value();
-    list3.print(Info);
+    list3.printInfo(Info, true);
 
     Info<< "removed final value: " << list3.remove() << endl;
-    list3.print(Info);
+    list3.printInfo(Info, true);
 
+    Info<<"list: " << list3 << endl;
 
-    List<bool> list4(4, true);
+
+    List<bool> list4(16, false);
     {
-        const List<bool>& constLst = list4;
+        // fill with some values
+        forAll(list4, i)
+        {
+            list4[i] = i % 3;
+        }
+
+        const UList<bool>& constLst = list4;
         Info<< "\ntest operator[] const with out-of-range index\n";
         Info<< constLst << endl;
-        if (constLst[20])
+        if (constLst[100])
         {
-            Info<< "[20] is true (unexpected)\n";
+            Info<< "[100] is true (unexpected)\n";
         }
         else
         {
-            Info<< "[20] is false (expected) list size should be unchanged "
-                << "(const)\n";
+            Info<< "[100] is false (expected) "
+                << "list size should be unchanged (const)\n";
         }
         Info<< constLst << endl;
     }
 
+
+    PackedBoolList listb(list4);
+
+    Info<< "copied from bool list " << endl;
+    listb.printInfo(Info, true);
+
+    {
+        labelList indices = listb.used();
+
+        Info<< "indices: " << indices << endl;
+    }
+
+
     Info<< "\n\nDone.\n";
 
     return 0;
diff --git a/applications/test/PackedList3/PackedListTest3.C b/applications/test/PackedList3/PackedListTest3.C
index 5ff6ee8644b69c0da56f6d7defeea63e2f3f9bab..7b27ffda09a81c4c7f1faf17a8e7081b65229a2c 100644
--- a/applications/test/PackedList3/PackedListTest3.C
+++ b/applications/test/PackedList3/PackedListTest3.C
@@ -33,7 +33,6 @@ Description
 #include "StaticHashTable.H"
 #include "cpuTime.H"
 #include <vector>
-#include "PackedList.H"
 #include "PackedBoolList.H"
 
 using namespace Foam;
@@ -57,7 +56,7 @@ int main(int argc, char *argv[])
     {
         if ((i % nReport) == 0 && i)
         {
-            Info<< "i:" << i << " in " << timer.cpuTimeIncrement() << " s" 
+            Info<< "i:" << i << " in " << timer.cpuTimeIncrement() << " s"
                 <<endl;
         }
         packed[i] = 1;
diff --git a/applications/test/PackedList4/Make/files b/applications/test/PackedList4/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..0704f9b826eb283cb3c734dc0cd290154e10d9aa
--- /dev/null
+++ b/applications/test/PackedList4/Make/files
@@ -0,0 +1,3 @@
+PackedListTest4.C
+
+EXE = $(FOAM_USER_APPBIN)/PackedListTest4
diff --git a/applications/test/PackedList4/Make/options b/applications/test/PackedList4/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/applications/test/PackedList4/PackedListTest4.C b/applications/test/PackedList4/PackedListTest4.C
new file mode 100644
index 0000000000000000000000000000000000000000..a500de01d36f283481ca92c62ef038d22cfe4e1e
--- /dev/null
+++ b/applications/test/PackedList4/PackedListTest4.C
@@ -0,0 +1,207 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 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/>.
+
+Application
+
+Description
+
+\*---------------------------------------------------------------------------*/
+
+#include "uLabel.H"
+#include "IOstreams.H"
+#include "PackedBoolList.H"
+#include "IStringStream.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+//  Main program:
+
+int main(int argc, char *argv[])
+{
+    PackedBoolList list1(20);
+    // set every third one on
+    forAll(list1, i)
+    {
+        list1[i] = !(i % 3);
+    }
+
+    Info<< "\nalternating bit pattern\n";
+    list1.printInfo(Info, true);
+
+    PackedBoolList list2 = ~list1;
+
+    Info<< "\ncomplementary bit pattern\n";
+    list2.printBits(Info);
+
+    // set every other on
+    forAll(list2, i)
+    {
+        list2[i] = !(i % 2);
+    }
+
+    Info<< "\nalternating bit pattern\n";
+    list2.printBits(Info);
+
+    list2.resize(28, false);
+    list2.resize(34, true);
+    list2.resize(40, false);
+    for (label i=0; i < 4; ++i)
+    {
+        list2[i] = true;
+    }
+
+    Info<< "\nresized with false, 6 true + 6 false, bottom 4 bits true\n";
+    list2.printInfo(Info, true);
+
+    labelList list2Labels = list2.used();
+
+    Info<< "\noperator|\n";
+
+    list1.printBits(Info);
+    list2.printBits(Info);
+    Info<< "==\n";
+    (list1 | list2).printBits(Info);
+
+    Info<< "\noperator& : does trim\n";
+    (list1 & list2).printBits(Info);
+
+    Info<< "\noperator^\n";
+    (list1 ^ list2).printBits(Info);
+
+
+    Info<< "\noperator|=\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 |= list2).printBits(Info);
+    }
+
+    Info<< "\noperator|= with UList<label>\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 |= list2Labels).printBits(Info);
+    }
+
+    Info<< "\noperator&=\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 &= list2).printBits(Info);
+    }
+
+    Info<< "\noperator+=\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 += list2).printBits(Info);
+    }
+
+    Info<< "\noperator+= with UList<label>\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 += list2Labels).printBits(Info);
+    }
+
+    Info<< "\noperator-=\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 -= list2).printBits(Info);
+    }
+
+    Info<< "\noperator-= with UList<label>\n";
+    {
+        PackedBoolList list3 = list1;
+        (list3 -= list2Labels).printBits(Info);
+    }
+
+    PackedBoolList list4
+    (
+        IStringStream
+        (
+            "(1 n 1 n 1 n 1 1 off 0 0 f f 0 y yes y true y false on t)"
+        )()
+    );
+
+    Info<< "\ntest Istream constructor\n";
+
+    list4.printInfo(Info, true);
+    Info<< list4 << " indices: " << list4.used()() <<endl;
+
+    Info<< "\nassign from labelList\n";
+    list4 = labelList
+    (
+        IStringStream
+        (
+            "(0 1 2 3 12 13 14 19 20 21)"
+        )()
+    );
+
+    list4.printInfo(Info, true);
+    Info<< list4 << " indices: " << list4.used()() <<endl;
+
+    Info<< "\nassign from indices\n";
+    list4.read
+    (
+        IStringStream
+        (
+            "{0 1 2 3 12 13 14 19 20 21}"
+        )()
+    );
+
+
+    list4.printInfo(Info, true);
+    Info<< list4 << " indices: " << list4.used()() <<endl;
+
+    List<bool> boolLst(list4.size());
+    forAll(list4, i)
+    {
+        boolLst[i] = list4[i];
+    }
+
+    Info<< "List<bool>: " << boolLst <<endl;
+
+
+    // check roundabout assignments
+    PackedList<2> pl2
+    (
+        IStringStream
+        (
+            "{(0 3)(1 3)(2 3)(3 3)(12 3)(13 3)(14 3)(19 3)(20 3)(21 3)}"
+        )()
+    );
+
+    Info<< "roundabout assignment: " << pl2 << endl;
+
+    list4.clear();
+    forAll(pl2, i)
+    {
+        list4[i] = pl2[i];
+    }
+
+    list4.write(Info, true) << endl;
+
+    list4.writeEntry("PackedBoolList", Info);
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/bin/doxyFilt b/bin/tools/doxyFilter
similarity index 89%
rename from bin/doxyFilt
rename to bin/tools/doxyFilter
index 7f337e539c5d6dc56e531b16e70bdd7fa23adf77..c49851a502c18160d27156874977045b7ee24531 100755
--- a/bin/doxyFilt
+++ b/bin/tools/doxyFilter
@@ -23,7 +23,7 @@
 #     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 #
 # Script
-#     doxyFilt
+#     doxyFilter
 #
 # Description
 #     pass-through filter for doxygen
@@ -43,19 +43,19 @@ then
     dirName=${filePath%/[^/]*}
     fileName=${filePath##*/}
 
-    awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt.awk
+    awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilter.awk
 
     case "$1" in
     */applications/solvers/*.C | */applications/utilities/*.C )
-        awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-top.awk
+        awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilter-top.awk
         ;;
 #    */applications/solvers/*.H | */applications/utilities/*.H )
-#        awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-ignore.awk
+#        awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilter-ignore.awk
 #        ;;
    esac
 
     awk -f $awkScript $1 | \
-    sed -f $WM_PROJECT_DIR/bin/tools/doxyFilt.sed \
+    sed -f $WM_PROJECT_DIR/bin/tools/doxyFilter.sed \
         -e s@%filePath%@$filePath@g \
         -e s@%fileName%@$fileName@g \
         -e s@%dirName%@$dirName@g
diff --git a/bin/tools/doxyFilt-ignore.awk b/bin/tools/doxyFilter-ignore.awk
similarity index 98%
rename from bin/tools/doxyFilt-ignore.awk
rename to bin/tools/doxyFilter-ignore.awk
index ebbacc7177a5840e05b5324e209aa33dcacd9cea..0d85702b34e907eb6f5ba961077e62cc79107e5d 100644
--- a/bin/tools/doxyFilt-ignore.awk
+++ b/bin/tools/doxyFilter-ignore.awk
@@ -22,7 +22,7 @@
 #     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 #
 # Script
-#     doxyFilt-ignore.awk
+#     doxyFilter-ignore.awk
 #
 # Description
 #     - Prefix file contents with doxygen @file tag and %filePath% tag
diff --git a/bin/tools/doxyFilt-top.awk b/bin/tools/doxyFilter-top.awk
similarity index 98%
rename from bin/tools/doxyFilt-top.awk
rename to bin/tools/doxyFilter-top.awk
index 97b96ff7b46133db1823cf94f53c607cfcbd7752..856e6621d4b4275d7d4817c5821b3c56d639ec1d 100644
--- a/bin/tools/doxyFilt-top.awk
+++ b/bin/tools/doxyFilter-top.awk
@@ -22,7 +22,7 @@
 #     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 #
 # Script
-#     doxyFilt-top.awk
+#     doxyFilter-top.awk
 #
 # Description
 #     Only output the first /* ... */ comment section found in the file
diff --git a/bin/tools/doxyFilt.awk b/bin/tools/doxyFilter.awk
similarity index 99%
rename from bin/tools/doxyFilt.awk
rename to bin/tools/doxyFilter.awk
index da65c3ded70bc070fbbf2df11978963937ba847b..1e37d0e33b46ea92c51d00d80e1ca3c2503bf98b 100644
--- a/bin/tools/doxyFilt.awk
+++ b/bin/tools/doxyFilter.awk
@@ -22,7 +22,7 @@
 #     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 #
 # Script
-#     doxyFilt.awk
+#     doxyFilter.awk
 #
 # Description
 #     Converts cocoon style sentinel strings into doxygen style strings
diff --git a/bin/tools/doxyFilt.sed b/bin/tools/doxyFilter.sed
similarity index 99%
rename from bin/tools/doxyFilt.sed
rename to bin/tools/doxyFilter.sed
index 4aaa7adb0e59a09eb0cf78ea04dcb0914d98ddb4..45a15019e132f41d41b84452bd47e5c46528debc 100644
--- a/bin/tools/doxyFilt.sed
+++ b/bin/tools/doxyFilter.sed
@@ -1,6 +1,6 @@
 # -----------------------------------------------------------------------------
 # Script
-#     doxyFilt.sed
+#     doxyFilter.sed
 #
 # Description
 #     Transform human-readable tags such as 'Description' into the Doxygen
diff --git a/bin/tools/pre-commit-hook b/bin/tools/pre-commit-hook
index 7d41b2e11c8284267345939f7ab9f5974fd87fb1..b0ca86f0202a82db0fa2b32c12ef314ae9bb202a 100755
--- a/bin/tools/pre-commit-hook
+++ b/bin/tools/pre-commit-hook
@@ -45,6 +45,9 @@
 # Note
 #     Using "git commit --no-verify" it is possible to override the hook.
 #
+#     By supplying arguments to the hook, it can also be used to manually
+#     test the specified files/directories for standards conformance.
+#
 #------------------------------------------------------------------------------
 die()
 {
@@ -52,13 +55,14 @@ die()
     echo '-----------------------' 1>&2
     echo '' 1>&2
     echo "$@" 1>&2
+    echo '' 1>&2
     exit 1
 }
 
 #-----------------------------------------------------------------------------
 # Check content that will be added by this commit.
 
-if git rev-parse --verify -q HEAD > /dev/null
+if git rev-parse --verify HEAD > /dev/null 2>&1
 then
     against=HEAD
 else
@@ -66,10 +70,30 @@ else
     against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 fi
 
-# list of all files
-fileList=$(git diff-index --name-only $against --)
-unset badFiles
+# called manually with arguments for the files/directories to be tested?
+if [ "$#" -gt 0 ]
+then
+    case "$1" in
+    -h | -help)
+        die "interactive usage: supply list of files/directories to check"
+        ;;
+    esac
 
+    # obtain list of all specified files/directories
+    fileList=$(git ls-files -- $@ 2>/dev/null)
+else
+    # list of all files to be committed
+    fileList=$(git diff-index --cached --name-only $against --)
+fi
+
+#
+# no files changed: can skip all the checks
+# this usage can correspond to a 'git commit --amend'
+#
+[ -n "$fileList" ] || exit 0
+
+
+unset badFiles
 # join list of files with this amount of space
 Indent="    "
 
@@ -97,16 +121,18 @@ dieOnBadFiles()
 #
 checkIllegalCode()
 {
+    echo "pre-commit: check bad strings/characters etc ..." 1>&2
+
     reBad="(N""abla|"$'\t'")"
     msgBad="N""abla or <TAB>"
 
     badFiles=$(
     for f in $fileList
     do
-        # parse line numbers from this:
-        #        path/fileName:<lineNr>:   contents
-        lines=$(git grep --cached -n -E -e "$reBad" -- "$f" |
-            sed -e 's@^[^:]*:\([0-9]*\):.*@\1@' |
+        # parse line numbers from grep output:
+        #        <lineNr>:   contents
+        lines=$(git grep --cached -E -hn -e "$reBad" -- "$f" |
+            sed -e 's@:.*@@' |
             tr '\n' ' '
         )
         [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -123,18 +149,22 @@ checkIllegalCode()
 checkCopyright()
 {
     year=$(date +%Y)
+    echo "pre-commit: check copyright ..." 1>&2
 
     badFiles=$(
     for f in $fileList
     do
-        # parse line numbers from this:
-        #        path/fileName:<lineNr>:   contents
-        # for Copyright lines without the current year
-        lines=$(git grep --cached -n -e Copyright -- "$f" |
-            sed -n \
-                -e '/OpenCFD/{ ' \
-                -e "/$year/b"   \
-                -e 's@^[^:]*:\([0-9]*\):.*@\1@p }' |
+        # NB: need to have OpenCFD on a separate line to prevent
+        #     this check being caught by itself!
+        #
+        # parse line numbers from grep output:
+        #        <lineNr>:   contents
+        #
+        lines=$(git grep --cached -F -hn -e Copyright \
+            --and -e OpenCFD \
+            --and --not -e "$year" \
+            -- "$f" |
+            sed -e 's@:.*@@' |
             tr '\n' ' '
         )
         [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -150,16 +180,18 @@ checkCopyright()
 #
 checkLineLength()
 {
+    echo "pre-commit: check line lengths ..." 1>&2
+
     badFiles=$(
     for f in $fileList
     do
         # limit to *.[CH] files
         case "$f" in
         (*.[CH])
-            # parse line numbers from this:
-            #        path/fileName:<lineNr>:   contents
-            lines=$(git grep --cached -n -e ".\{81,\}" -- "$f" |
-                sed -e 's@^[^:]*:\([0-9]*\):.*@\1@' |
+            # parse line numbers from grep output:
+            #        <lineNr>:   contents
+            lines=$(git grep --cached -hn -e '^.\{81,\}' -- "$f" |
+                sed -e 's@:.*@@' |
                 tr '\n' ' '
             )
             [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -177,18 +209,20 @@ checkLineLength()
 #
 checkLineLengthNonComments()
 {
+    echo "pre-commit: check line lengths ..." 1>&2
+
     badFiles=$(
     for f in $fileList
     do
         # limit to *.[CH] files
         case "$f" in
         (*.[CH])
-            # parse line numbers from this (strip comment lines):
-            #        path/fileName:<lineNr>:   contents
-            lines=$(git grep --cached -n -e ".\{81,\}" -- "$f" |
-                sed -n \
-                    -e '\@^[^:]*:[^:]*: *//.*@b' \
-                    -e 's@^[^:]*:\([0-9]*\):.*@\1@p' |
+            # parse line numbers from grep output:
+            #        <lineNr>:   contents
+            lines=$(git grep --cached -hn -e '^.\{81,\}' \
+                --and --not -e "^ *//" \
+                -- "$f" |
+                sed -e 's@:.*@@' |
                 tr '\n' ' '
             )
             [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
@@ -205,18 +239,20 @@ checkLineLengthNonComments()
 #
 checkLineLengthNonDirective()
 {
+    echo "pre-commit: check line lengths ..." 1>&2
+
     badFiles=$(
     for f in $fileList
     do
         # limit to *.[CH] files
         case "$f" in
         (*.[CH])
-            # parse line numbers from this (strip comment lines):
-            #        path/fileName:<lineNr>:   contents
-            lines=$(git grep --cached -n -e ".\{81,\}" -- "$f" |
-                sed -n \
-                    -e '\@^[^:]*:[^:]*: *#.*@b' \
-                    -e 's@^[^:]*:\([0-9]*\):.*@\1@p' |
+            # parse line numbers from grep output:
+            #        <lineNr>:   contents
+            lines=$(git grep --cached -hn -e '^.\{81,\}' \
+                --and --not -e "^ *#" \
+                -- "$f" |
+                sed -e 's@:.*@@' |
                 tr '\n' ' '
             )
             [ -n "$lines" ] && echo "$Indent$f -- lines: $lines"
diff --git a/doc/Doxygen/Doxyfile b/doc/Doxygen/Doxyfile
index 68ff8430b205ad285cfc0e03936441425d305b3c..79bc3b71cf63254707d46d8c7b5221b48e177ebf 100644
--- a/doc/Doxygen/Doxyfile
+++ b/doc/Doxygen/Doxyfile
@@ -567,7 +567,7 @@ IMAGE_PATH             =
 # to standard output.  If FILTER_PATTERNS is specified, this tag will be
 # ignored.
 
-INPUT_FILTER           = doxyFilt
+INPUT_FILTER           = $(WM_PROJECT_DIR)/bin/tools/doxyFilter
 
 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
 # basis.  Doxygen will compare the file name with each pattern and apply the
diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile
index 1b1f98598fc3317b734a46a5d5ca16b585b855fa..1445ad0bc21bfe9eff1be2e6f5fdf04eef92b5ce 100644
--- a/doc/doxygen/Doxyfile
+++ b/doc/doxygen/Doxyfile
@@ -669,7 +669,7 @@ IMAGE_PATH             =
 # If FILTER_PATTERNS is specified, this tag will be
 # ignored.
 
-INPUT_FILTER           = doxyFilt
+INPUT_FILTER           = $(WM_PROJECT_DIR)/bin/tools/doxyFilter
 
 # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
 # basis.
diff --git a/doc/tools/find-trailingspace b/doc/tools/find-trailingspace
new file mode 100755
index 0000000000000000000000000000000000000000..a04ee94d460a1ae21ab90cc6ec56b9e9a84ea3b7
--- /dev/null
+++ b/doc/tools/find-trailingspace
@@ -0,0 +1,17 @@
+#!/bin/bash
+# -----------------------------------------------------------------------------
+# Script
+#     find-trailingspace
+#
+# Description
+#     Search for files with trailing whitesapce
+#
+# -----------------------------------------------------------------------------
+set -x
+cd $WM_PROJECT_DIR || exit 1
+
+tab=$'\t'
+
+git grep -c -E "[ $tab]+"'$' -- $@
+
+#------------------------------------------------------------------ end-of-file
diff --git a/src/OSspecific/POSIX/regExp.H b/src/OSspecific/POSIX/regExp.H
index edc8ddd6c01f792f80188a031fc0d5669633ba62..cd140fe8522b5a35863be5aadce340e00d2d80b5 100644
--- a/src/OSspecific/POSIX/regExp.H
+++ b/src/OSspecific/POSIX/regExp.H
@@ -157,7 +157,7 @@ public:
         //  The begin-of-line (^) and end-of-line ($) anchors are implicit
         bool match(const string&, List<string>& groups) const;
 
-        //- Return true if the regex was found in within string
+        //- Return true if the regex was found within string
         bool search(const std::string& str) const
         {
             return std::string::npos != find(str);
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 599d30fa094cbc485f9c9a170c7d4f89a379052f..d9548b67b10db88609ca0f132f6652b569fff356 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -52,8 +52,8 @@ $(strings)/word/word.C
 $(strings)/word/wordIO.C
 $(strings)/fileName/fileName.C
 $(strings)/fileName/fileNameIO.C
-$(strings)/keyType/keyTypeIO.C
-$(strings)/wordRe/wordReIO.C
+$(strings)/keyType/keyType.C
+$(strings)/wordRe/wordRe.C
 
 primitives/hashes/Hasher/Hasher.C
 
@@ -66,7 +66,8 @@ primitives/random/Random.C
 containers/HashTables/HashTable/HashTableCore.C
 containers/HashTables/StaticHashTable/StaticHashTableCore.C
 containers/Lists/SortableList/ParSortableListName.C
-containers/Lists/PackedList/PackedListName.C
+containers/Lists/PackedList/PackedListCore.C
+containers/Lists/PackedList/PackedBoolList.C
 containers/Lists/ListOps/ListOps.C
 containers/LinkedLists/linkTypes/SLListBase/SLListBase.C
 containers/LinkedLists/linkTypes/DLListBase/DLListBase.C
@@ -328,7 +329,7 @@ $(cellShape)/cellShapeEqual.C
 $(cellShape)/cellShapeIO.C
 $(cellShape)/cellShapeIOList.C
 
-meshes/patchIdentifier/patchIdentifier.C
+meshes/Identifiers/patch/patchIdentifier.C
 
 polyMesh = meshes/polyMesh
 
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
index 4831b98106b734f93ffa0bb70f6e252d6090b5e7..fdf1a3c931f2cfdb031760143cb9beed86c8eef4 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
@@ -180,13 +180,22 @@ public:
         // Member Operators
 
             //- Append an element at the end of the list
-            inline void append(const T&);
+            inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
+            (
+                const T&
+            );
 
             //- Append a List at the end of this list
-            inline void append(const UList<T>&);
+            inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
+            (
+                const UList<T>&
+            );
 
             //- Append a UIndirectList at the end of this list
-            inline void append(const UIndirectList<T>&);
+            inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
+            (
+                const UIndirectList<T>&
+            );
 
             //- Remove and return the top element
             inline T remove();
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
index f6ff8e99698839b2a33483ec8e405276c28bab53..bbe24d11c29e876b22dbb5bdbea38be7d4053837 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
@@ -305,7 +305,8 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::xfer()
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
+inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
 (
     const T& t
 )
@@ -314,11 +315,13 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
     setSize(elemI + 1);
 
     this->operator[](elemI) = t;
+    return *this;
 }
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
+inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
 (
     const UList<T>& lst
 )
@@ -339,11 +342,13 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
     {
         this->operator[](nextFree++) = lst[elemI];
     }
+    return *this;
 }
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
+inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
 (
     const UIndirectList<T>& lst
 )
@@ -355,6 +360,7 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
     {
         this->operator[](nextFree++) = lst[elemI];
     }
+    return *this;
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/List/ListIO.C b/src/OpenFOAM/containers/Lists/List/ListIO.C
index 984971ecc4694557a325373eea0336bb27fcf819..a70cc8f9e6b578d0a2d039ff61687676ff0f9969 100644
--- a/src/OpenFOAM/containers/Lists/List/ListIO.C
+++ b/src/OpenFOAM/containers/Lists/List/ListIO.C
@@ -135,7 +135,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L)
                 << exit(FatalIOError);
         }
 
-        // Putback the openning bracket
+        // Putback the opening bracket
         is.putBack(firstToken);
 
         // Now read as a singly-linked list
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C
new file mode 100644
index 0000000000000000000000000000000000000000..79a383a685e76556b0e3be9372e913d39b9f117d
--- /dev/null
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C
@@ -0,0 +1,375 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "PackedBoolList.H"
+#include "IOstreams.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+bool Foam::PackedBoolList::bitorPrepare
+(
+    const PackedList<1>& lst,
+    label& maxPackLen
+)
+{
+    const StorageList& lhs = this->storage();
+    const StorageList& rhs = lst.storage();
+
+    const label packLen1 = this->packedLength();
+    const label packLen2 = lst.packedLength();
+
+
+    // check how the lists interact and if bit trimming is needed
+    bool needTrim = false;
+    maxPackLen = packLen1;
+
+    if (packLen1 == packLen2)
+    {
+        // identical packed lengths - only resize if absolutely necessary
+        if
+        (
+            this->size() != lst.size()
+         && maxPackLen
+         && rhs[maxPackLen-1] > lhs[maxPackLen-1]
+        )
+        {
+            // second list has a higher bit set
+            // extend addressable area and use trim
+            resize(lst.size());
+            needTrim = true;
+        }
+    }
+    else if (packLen2 < packLen1)
+    {
+        // second list is shorter, this limits the or
+        maxPackLen = packLen2;
+    }
+    else
+    {
+        // second list is longer, find the highest bit set
+        for (label storeI = packLen1; storeI < packLen2; ++storeI)
+        {
+            if (rhs[storeI])
+            {
+                maxPackLen = storeI+1;
+            }
+        }
+
+        // the upper limit moved - resize for full coverage and trim later
+        if (maxPackLen > packLen1)
+        {
+            resize(maxPackLen * packing());
+            needTrim = true;
+        }
+    }
+
+    return needTrim;
+}
+
+
+template<class LabelListType>
+Foam::label Foam::PackedBoolList::setIndices(const LabelListType& indices)
+{
+    // no better information, just guess something about the size
+    reserve(indices.size());
+
+    label cnt = 0;
+    forAll(indices, elemI)
+    {
+        if (set(indices[elemI]))
+        {
+            ++cnt;
+        }
+    }
+
+    return cnt;
+}
+
+
+template<class LabelListType>
+Foam::label Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
+{
+    label cnt = 0;
+    forAll(indices, elemI)
+    {
+        if (unset(indices[elemI]))
+        {
+            ++cnt;
+        }
+    }
+
+    return cnt;
+}
+
+
+template<class LabelListType>
+Foam::label Foam::PackedBoolList::subsetIndices(const LabelListType& indices)
+{
+    // handle trivial case
+    if (empty() || indices.empty())
+    {
+        clear();
+        return 0;
+    }
+
+    // normal case
+    PackedBoolList anded;
+    anded.reserve(size());
+
+    label cnt = 0;
+    forAll(indices, elemI)
+    {
+        const label& index = indices[elemI];
+        if (operator[](index))
+        {
+            anded.set(index);
+            ++cnt;
+        }
+    }
+
+    transfer(anded);
+    return cnt;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::PackedBoolList::PackedBoolList(Istream& is)
+:
+    PackedList<1>()
+{
+    is  >> *this;
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::PackedBoolList::set(const PackedList<1>& lst)
+{
+    // extend addressable area if needed, return maximum size possible
+    label len = 0;
+    const bool needTrim = bitorPrepare(lst, len);
+
+    // operate directly with the underlying storage
+    StorageList& lhs = this->storage();
+    const StorageList& rhs = lst.storage();
+
+    for (label i=0; i < len; ++i)
+    {
+        lhs[i] |= rhs[i];
+    }
+
+    if (needTrim)
+    {
+        trim();
+    }
+}
+
+
+Foam::label Foam::PackedBoolList::set(const UList<label>& indices)
+{
+    return setIndices(indices);
+}
+
+
+Foam::label Foam::PackedBoolList::set(const UIndirectList<label>& indices)
+{
+    return setIndices(indices);
+}
+
+
+void Foam::PackedBoolList::unset(const PackedList<1>& lst)
+{
+    // operate directly with the underlying storage
+    StorageList& lhs = this->storage();
+    const StorageList& rhs = lst.storage();
+
+    // overlapping storage size
+    const label len = min(this->packedLength(), lst.packedLength());
+
+    for (label i=0; i < len; ++i)
+    {
+        lhs[i] &= ~rhs[i];
+    }
+}
+
+
+Foam::label Foam::PackedBoolList::unset(const UList<label>& indices)
+{
+    return unsetIndices(indices);
+}
+
+
+Foam::label Foam::PackedBoolList::unset(const UIndirectList<label>& indices)
+{
+    return unsetIndices(indices);
+}
+
+
+void Foam::PackedBoolList::subset(const PackedList<1>& lst)
+{
+    // shrink addressable area if needed
+    if (this->size() > lst.size())
+    {
+        this->resize(lst.size());
+    }
+
+    // operate directly with the underlying storage
+    StorageList& lhs = this->storage();
+    const StorageList& rhs = lst.storage();
+
+    const label len = this->packedLength();
+
+    for (label i=0; i < len; ++i)
+    {
+        lhs[i] &= rhs[i];
+    }
+}
+
+
+Foam::label Foam::PackedBoolList::subset(const UList<label>& indices)
+{
+    return subsetIndices(indices);
+}
+
+
+Foam::label Foam::PackedBoolList::subset(const UIndirectList<label>& indices)
+{
+    return subsetIndices(indices);
+}
+
+
+Foam::Xfer<Foam::labelList> Foam::PackedBoolList::used() const
+{
+    labelList lst(this->count());
+
+    if (lst.size())
+    {
+        label nElem = 0;
+
+        forAll(*this, elemI)
+        {
+            if (get(elemI))
+            {
+                lst[nElem++] = elemI;
+            }
+        }
+
+        lst.setSize(nElem);
+    }
+
+    return lst.xfer();
+}
+
+
+// * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * * //
+
+Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const UList<bool>& lst)
+{
+    this->setSize(lst.size());
+
+    // overwrite with new true/false values
+    forAll(*this, elemI)
+    {
+        set(elemI, lst[elemI]);
+    }
+
+    return *this;
+}
+
+
+Foam::PackedBoolList&
+Foam::PackedBoolList::operator^=(const PackedList<1>& lst)
+{
+    // extend addressable area if needed, return maximum size possible
+    label len = 0;
+    const bool needTrim = bitorPrepare(lst, len);
+
+    // operate directly with the underlying storage
+    StorageList& lhs = this->storage();
+    const StorageList& rhs = lst.storage();
+
+    for (label i=0; i < len; ++i)
+    {
+        lhs[i] ^= rhs[i];
+    }
+
+    if (needTrim)
+    {
+        trim();
+    }
+
+    return *this;
+}
+
+
+// * * * * * * * * * * * * * *  Global Operators * * * * * * * * * * * * * * //
+
+Foam::PackedBoolList Foam::operator&
+(
+    const PackedBoolList& lst1,
+    const PackedBoolList& lst2
+)
+{
+    PackedBoolList result(lst1);
+    result &= lst2;
+
+    // trim to bits actually used
+    result.trim();
+
+    return result;
+}
+
+
+Foam::PackedBoolList Foam::operator^
+(
+    const PackedBoolList& lst1,
+    const PackedBoolList& lst2
+)
+{
+    PackedBoolList result(lst1);
+    result ^= lst2;
+
+    // trim to bits actually used
+    result.trim();
+
+    return result;
+}
+
+
+Foam::PackedBoolList Foam::operator|
+(
+    const PackedBoolList& lst1,
+    const PackedBoolList& lst2
+)
+{
+    PackedBoolList result(lst1);
+    result |= lst2;
+    return result;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H
new file mode 100644
index 0000000000000000000000000000000000000000..2058d4eb930cc1ec9326275630ba0933d513f93b
--- /dev/null
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H
@@ -0,0 +1,296 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 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::PackedBoolList
+
+Description
+    A bit-packed bool list.
+
+    In addition to the obvious memory advantage over using a
+    List\<bool\>, this class also provides a number of bit-like
+    operations.
+
+SourceFiles
+    PackedBoolListI.H
+    PackedBoolList.C
+
+SeeAlso
+    Foam::PackedList
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PackedBoolList_H
+#define PackedBoolList_H
+
+#include "PackedList.H"
+#include "UIndirectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                       Class PackedBoolList Declaration
+\*---------------------------------------------------------------------------*/
+
+class PackedBoolList
+:
+    public PackedList<1>
+{
+    // Private Member Functions
+
+        //- Preparation, resizing before a bitor operation
+        //  returns true if the later result needs trimming
+        bool bitorPrepare(const PackedList<1>& lst, label& maxPackLen);
+
+        //- Set the listed indices. Return number of elements changed.
+        //  Does auto-vivify for non-existent entries.
+        template<class LabelListType>
+        label setIndices(const LabelListType& indices);
+
+        //- Unset the listed indices. Return number of elements changed.
+        //  Never auto-vivify entries.
+        template<class LabelListType>
+        label unsetIndices(const LabelListType& indices);
+
+        //- Subset with the listed indices. Return number of elements subsetted.
+        template<class LabelListType>
+        label subsetIndices(const LabelListType& indices);
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        inline PackedBoolList();
+
+        //- Construct from Istream
+        PackedBoolList(Istream&);
+
+        //- Construct with given size, initializes list to 0
+        explicit inline PackedBoolList(const label size);
+
+        //- Construct with given size and value for all elements
+        inline PackedBoolList(const label size, const bool val);
+
+        //- Copy constructor
+        inline PackedBoolList(const PackedBoolList&);
+
+        //- Copy constructor
+        explicit inline PackedBoolList(const PackedList<1>&);
+
+        //- Construct by transferring the parameter contents
+        inline PackedBoolList(const Xfer<PackedBoolList>&);
+
+        //- Construct by transferring the parameter contents
+        inline PackedBoolList(const Xfer<PackedList<1> >&);
+
+        //- Construct from a list of bools
+        explicit inline PackedBoolList(const UList<bool>&);
+
+        //- Construct from a list of labels
+        //  using the labels as indices to indicate which bits are set
+        explicit inline PackedBoolList(const UList<label>& indices);
+
+        //- Construct from a list of labels
+        //  using the labels as indices to indicate which bits are set
+        explicit inline PackedBoolList(const UIndirectList<label>& indices);
+
+        //- Clone
+        inline autoPtr<PackedBoolList> clone() const;
+
+
+    // Member Functions
+
+        // Access
+
+            using PackedList<1>::set;
+            using PackedList<1>::unset;
+
+            //- Set specified bits.
+            void set(const PackedList<1>&);
+
+            //- Set the listed indices. Return number of elements changed.
+            //  Does auto-vivify for non-existent entries.
+            label set(const UList<label>& indices);
+
+            //- Set the listed indices. Return number of elements changed.
+            //  Does auto-vivify for non-existent entries.
+            label set(const UIndirectList<label>& indices);
+
+            //- Unset specified bits.
+            void unset(const PackedList<1>&);
+
+            //- Unset the listed indices. Return number of elements changed.
+            //  Never auto-vivify entries.
+            label unset(const UList<label>& indices);
+
+            //- Unset the listed indices. Return number of elements changed.
+            //  Never auto-vivify entries.
+            label unset(const UIndirectList<label>& indices);
+
+            //- Subset with the specified list.
+            void subset(const PackedList<1>&);
+
+            //- Subset with the listed indices.
+            //  Return number of elements subsetted.
+            label subset(const UList<label>& indices);
+
+            //- Subset with the listed indices.
+            //  Return number of elements subsetted.
+            label subset(const UIndirectList<label>& indices);
+
+
+            //- Return indices of the used (true) elements as a list of labels
+            Xfer<labelList> used() const;
+
+
+        // Edit
+
+            //- Transfer the contents of the argument list into this list
+            //  and annul the argument list.
+            inline void transfer(PackedBoolList&);
+
+            //- Transfer the contents of the argument list into this list
+            //  and annul the argument list.
+            inline void transfer(PackedList<1>&);
+
+            //- Transfer contents to the Xfer container
+            inline Xfer<PackedBoolList> xfer();
+
+
+    // Member Operators
+
+            //- Assignment of all entries to the given value.
+            inline PackedBoolList& operator=(const bool val);
+
+            //- Assignment operator.
+            inline PackedBoolList& operator=(const PackedBoolList&);
+
+            //- Assignment operator.
+            inline PackedBoolList& operator=(const PackedList<1>&);
+
+            //- Assignment operator.
+            PackedBoolList& operator=(const UList<bool>&);
+
+            //- Assignment operator,
+            //  using the labels as indices to indicate which bits are set
+            inline PackedBoolList& operator=(const UList<label>& indices);
+
+            //- Assignment operator,
+            //  using the labels as indices to indicate which bits are set
+            inline PackedBoolList& operator=(const UIndirectList<label>&);
+
+            //- Complement operator
+            inline PackedBoolList operator~() const;
+
+            //- And operator (lists may be dissimilar sizes)
+            inline PackedBoolList& operator&=(const PackedList<1>&);
+
+            //- And operator (lists may be dissimilar sizes)
+            //  using the labels as indices to indicate which bits are set
+            inline PackedBoolList& operator&=(const UList<label>& indices);
+
+            //- And operator (lists may be dissimilar sizes)
+            //  using the labels as indices to indicate which bits are set
+            inline PackedBoolList& operator&=(const UIndirectList<label>&);
+
+            //- Xor operator (lists may be dissimilar sizes)
+            //  Retains unique entries
+            PackedBoolList& operator^=(const PackedList<1>&);
+
+            //- Or operator (lists may be dissimilar sizes)
+            inline PackedBoolList& operator|=(const PackedList<1>&);
+
+            //- Or operator (lists may be dissimilar sizes),
+            //  using the labels as indices to indicate which bits are set
+            inline PackedBoolList& operator|=(const UList<label>& indices);
+
+            //- Or operator (lists may be dissimilar sizes),
+            //  using the labels as indices to indicate which bits are set
+            inline PackedBoolList& operator|=(const UIndirectList<label>&);
+
+
+            //- Add entries to this list, synonymous with the or operator
+            inline PackedBoolList& operator+=(const PackedList<1>&);
+
+            //- Add entries to this list, synonymous with the or operator
+            inline PackedBoolList& operator+=(const UList<label>& indices);
+
+            //- Add entries to this list, synonymous with the or operator
+            inline PackedBoolList& operator+=(const UIndirectList<label>&);
+
+            //- Remove entries from this list - unset the specified bits
+            inline PackedBoolList& operator-=(const PackedList<1>&);
+
+            //- Remove entries from this list - unset the specified bits
+            inline PackedBoolList& operator-=(const UList<label>& indices);
+
+            //- Remove entries from this list - unset the specified bits
+            inline PackedBoolList& operator-=(const UIndirectList<label>&);
+
+};
+
+
+// Global Operators
+
+//- Intersect lists - the result is trimmed to the smallest intersecting size
+PackedBoolList operator&
+(
+    const PackedBoolList& lst1,
+    const PackedBoolList& lst2
+);
+
+
+//- Combine to form a unique list (xor)
+//  The result is trimmed to the smallest intersecting size
+PackedBoolList operator^
+(
+    const PackedBoolList& lst1,
+    const PackedBoolList& lst2
+);
+
+
+//- Combine lists
+PackedBoolList operator|
+(
+    const PackedBoolList& lst1,
+    const PackedBoolList& lst2
+);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "PackedBoolListI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H
new file mode 100644
index 0000000000000000000000000000000000000000..edbbc8d0071628c6d56e43b9b57618df8467db9e
--- /dev/null
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H
@@ -0,0 +1,277 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2010-2010 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/>.
+
+\*---------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+inline Foam::PackedBoolList::PackedBoolList()
+:
+    PackedList<1>()
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const label size)
+:
+    PackedList<1>(size)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList
+(
+    const label size,
+    const bool val
+)
+:
+    PackedList<1>(size, (val ? 1u : 0u))
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const PackedBoolList& lst)
+:
+    PackedList<1>(lst)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const PackedList<1>& lst)
+:
+    PackedList<1>(lst)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedBoolList>& lst)
+:
+    PackedList<1>()
+{
+    transfer(lst());
+}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const Xfer<PackedList<1> >& lst)
+:
+    PackedList<1>(lst)
+{}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst)
+:
+    PackedList<1>()
+{
+    operator=(lst);
+}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const UList<label>& indices)
+:
+    PackedList<1>(indices.size(), 0u)
+{
+    set(indices);
+}
+
+
+inline Foam::PackedBoolList::PackedBoolList(const UIndirectList<label>& indices)
+:
+    PackedList<1>(indices.size(), 0u)
+{
+    set(indices);
+}
+
+
+inline Foam::autoPtr<Foam::PackedBoolList>
+Foam::PackedBoolList::clone() const
+{
+    return autoPtr<PackedBoolList>(new PackedBoolList(*this));
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline void Foam::PackedBoolList::transfer(PackedBoolList& lst)
+{
+    PackedList<1>::transfer(static_cast<PackedList<1>&>(lst));
+}
+
+
+inline void Foam::PackedBoolList::transfer(PackedList<1>& lst)
+{
+    PackedList<1>::transfer(lst);
+}
+
+
+inline Foam::Xfer<Foam::PackedBoolList> Foam::PackedBoolList::xfer()
+{
+    return xferMove(*this);
+}
+
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const bool val)
+{
+    PackedList<1>::operator=(val);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const PackedBoolList& lst)
+{
+    PackedList<1>::operator=(lst);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const PackedList<1>& lst)
+{
+    PackedList<1>::operator=(lst);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const UList<label>& indices)
+{
+    clear();
+    set(indices);
+
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator=(const UIndirectList<label>& indices)
+{
+    clear();
+    set(indices);
+
+    return *this;
+}
+
+
+inline Foam::PackedBoolList
+Foam::PackedBoolList::operator~() const
+{
+    PackedBoolList result(*this);
+    result.flip();
+
+    return result;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
+{
+    subset(lst);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator&=(const UList<label>& indices)
+{
+    subset(indices);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator&=(const UIndirectList<label>& indices)
+{
+    subset(indices);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
+{
+    set(lst);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator|=(const UList<label>& indices)
+{
+    set(indices);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator|=(const UIndirectList<label>& indices)
+{
+    set(indices);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator+=(const PackedList<1>& lst)
+{
+    return operator|=(lst);
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator+=(const UList<label>& indices)
+{
+    return operator|=(indices);
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator+=(const UIndirectList<label>& indices)
+{
+    return operator|=(indices);
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator-=(const PackedList<1>& lst)
+{
+    unset(lst);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator-=(const UList<label>& indices)
+{
+    unset(indices);
+    return *this;
+}
+
+
+inline Foam::PackedBoolList&
+Foam::PackedBoolList::operator-=(const UIndirectList<label>& indices)
+{
+    unset(indices);
+    return *this;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
index 6bc8d79eada3b2a37b8126829d3d67a8182a2d27..98a6d2740ad13e8aa10072c59533e468ecf9f990 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
@@ -24,35 +24,11 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "PackedList.H"
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-template<unsigned nBits>
-Foam::PackedList<nBits>::PackedList(const label size, const unsigned int val)
-:
-    StorageList(packedLength(size), 0u),
-    size_(size)
-{
-    operator=(val);
-}
-
-
-template<unsigned nBits>
-Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
-:
-    StorageList(packedLength(lst.size()), 0u),
-    size_(lst.size())
-{
-    forAll(lst, i)
-    {
-        set(i, lst[i]);
-    }
-}
+#include "IOstreams.H"
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-
 #if (UINT_MAX == 0xFFFFFFFF)
 // 32-bit counting, Hamming weight method
 #   define COUNT_PACKEDBITS(sum, x)                                           \
@@ -82,25 +58,10 @@ unsigned int Foam::PackedList<nBits>::count() const
 
     if (size_)
     {
-        // mask value for complete segments
-        unsigned int mask = maskLower(packing());
-
-        const unsigned int endSeg = size_ / packing();
-        const unsigned int endOff = size_ % packing();
-
-        // count bits in complete segments
-        for (unsigned i = 0; i < endSeg; ++i)
-        {
-            register unsigned int bits = StorageList::operator[](i) & mask;
-            COUNT_PACKEDBITS(c, bits);
-        }
-
-        // count bits in partial segment
-        if (endOff)
+        const label packLen = packedLength();
+        for (label i = 0; i < packLen; ++i)
         {
-            mask = maskLower(endOff);
-
-            register unsigned int bits = StorageList::operator[](endSeg) & mask;
+            register unsigned int bits = StorageList::operator[](i);
             COUNT_PACKEDBITS(c, bits);
         }
     }
@@ -117,64 +78,60 @@ bool Foam::PackedList<nBits>::trim()
         return false;
     }
 
-    // mask value for complete segments
-    unsigned int mask = maskLower(packing());
-
-    label currElem = packedLength(size_) - 1;
-    unsigned int endOff = size_ % packing();
-
-    // clear trailing bits on final segment
-    if (endOff)
-    {
-        StorageList::operator[](currElem) &= maskLower(endOff);
-    }
-
-    // test entire segment
-    while (currElem > 0 && !(StorageList::operator[](currElem) &= mask))
+    const label oldSize = size_;
+    for (label storeI = packedLength()-1; storeI >= 0; --storeI)
     {
-        currElem--;
-    }
-
-    // test segment
-    label newsize = (currElem + 1) * packing();
-
-    // mask for the final segment
-    mask = max_value() << (nBits * (packing() - 1));
+        size_ = storeI * packing();
+        unsigned int bits = StorageList::operator[](storeI);
 
-    for (endOff = packing(); endOff >= 1; --endOff, --newsize)
-    {
-        if (StorageList::operator[](currElem) & mask)
+        // found some bits
+        if (bits)
         {
+            while (bits)
+            {
+                bits >>= nBits;
+                ++size_;
+            }
             break;
         }
-
-        mask >>= nBits;
     }
 
-    if (size_ == newsize)
-    {
-        return false;
-    }
-
-    size_ = newsize;
-    return false;
+    return (size_ != oldSize);
 }
 
 
 template<unsigned nBits>
 void Foam::PackedList<nBits>::flip()
 {
-    label packLen = packedLength(size_);
+    if (!size_)
+    {
+        return;
+    }
+
+    // mask value for complete segments
+    const unsigned int mask = maskLower(packing());
 
-    for (label i=0; i < packLen; i++)
+    const label packLen = packedLength();
+    for (label i=0; i < packLen; ++i)
     {
-        StorageList::operator[](i) = ~StorageList::operator[](i);
+        StorageList::operator[](i) = mask & ~StorageList::operator[](i);
+    }
+
+    // mask off the final partial segment
+    {
+        const unsigned int off = size_ % packing();
+        if (off)
+        {
+            const unsigned int seg = size_ / packing();
+
+            StorageList::operator[](seg) &= maskLower(off);
+        }
     }
 }
 
 
 template<unsigned nBits>
-Foam::labelList Foam::PackedList<nBits>::values() const
+Foam::Xfer<Foam::labelList> Foam::PackedList<nBits>::values() const
 {
     labelList elems(size_);
 
@@ -182,12 +139,16 @@ Foam::labelList Foam::PackedList<nBits>::values() const
     {
         elems[i] = get(i);
     }
-    return elems;
+
+    return elems.xfer();
 }
 
 
 template<unsigned nBits>
-Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
+Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::printInfo
+(
+    Ostream& os
+) const
 {
     os  << "iterator<"  << label(nBits) << "> ["
         << this->index_ << "]"
@@ -201,78 +162,396 @@ Foam::Ostream& Foam::PackedList<nBits>::iteratorBase::print(Ostream& os) const
 
 
 template<unsigned nBits>
-Foam::Ostream& Foam::PackedList<nBits>::print(Ostream& os) const
+Foam::Ostream& Foam::PackedList<nBits>::printBits
+(
+    Ostream& os,
+    const bool fullOutput
+) const
 {
-    const label packLen = packedLength(size_);
-
-    os  << "PackedList<" << nBits << ">"
-        << " max_value:" << max_value()
-        << " packing:"   << packing() << nl
-        << " count: "     << count() << nl
-        << " size/capacity: " << size_ << "/" << capacity() << nl
-        << " storage/capacity: " << packLen << "/" << StorageList::size()
-        << "\n(\n";
+    const label packLen = packedLength();
 
     // mask value for complete segments
     unsigned int mask = maskLower(packing());
+    const label outputLen = fullOutput ? StorageList::size() : packLen;
 
-    for (label i=0; i < packLen; i++)
+    os  << "(\n";
+    for (label i=0; i < outputLen; ++i)
     {
         const StorageType& rawBits = StorageList::operator[](i);
 
         // the final segment may not be full, modify mask accordingly
-        if (i+1 == packLen)
+        if (i == packLen-1)
         {
-            unsigned int endOff = size_ % packing();
+            const unsigned int off = size_ % packing();
 
-            if (endOff)
-            {
-                mask = maskLower(endOff);
-            }
-            else
+            if (off)
             {
-                continue;
+                mask = maskLower(off);
             }
         }
+        else if (i == packLen)
+        {
+            // no mask for unaddressed bit
+            mask = 0u;
+        }
+
 
         for (unsigned int testBit = (1u << max_bits()); testBit; testBit >>= 1)
         {
             if (mask & testBit)
             {
+                // addressable region
                 if (rawBits & testBit)
                 {
-                    os << '1';
+                    os  << '1';
                 }
                 else
                 {
-                    os << '-';
+                    os  << '-';
                 }
             }
             else
             {
-                os << 'x';
+                if (rawBits & testBit)
+                {
+                    os  << '!';
+                }
+                else
+                {
+                    os  << '.';
+                }
+            }
+        }
+        os  << '\n';
+    }
+    os  << ")\n";
+
+    return os;
+}
+
+
+template<unsigned nBits>
+Foam::Ostream& Foam::PackedList<nBits>::printInfo
+(
+    Ostream& os,
+    const bool fullOutput
+) const
+{
+    os  << "PackedList<" << nBits << ">"
+        << " max_value:" << max_value()
+        << " packing:"   << packing() << nl
+        << " count: "     << count() << nl
+        << " size/capacity: " << size_ << "/" << capacity() << nl
+        << " storage/capacity: "
+        << packedLength() << "/" << StorageList::size()
+        << "\n";
+
+    return printBits(os, fullOutput);
+}
+
+
+template<unsigned nBits>
+Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
+{
+    PackedList<nBits>& lst = *this;
+
+    lst.clear();
+    is.fatalCheck("PackedList<nBits>::read(Istream&)");
+
+    token firstTok(is);
+    is.fatalCheck
+    (
+        "PackedList<nBits>::read(Istream&) : "
+        "reading first token"
+    );
+
+    if (firstTok.isLabel())
+    {
+        const label sz = firstTok.labelToken();
+
+        // Set list length to that read
+        lst.resize(sz);
+
+        // Read list contents depending on data format
+        if (is.format() == IOstream::ASCII)
+        {
+            // Read beginning of contents
+            const char delimiter = is.readBeginList("PackedList<nBits>");
+
+            if (sz)
+            {
+                if (delimiter == token::BEGIN_LIST)
+                {
+                    for (register label i=0; i<sz; ++i)
+                    {
+                        lst[i] = lst.readValue(is);
+
+                        is.fatalCheck
+                        (
+                            "PackedList<nBits>::read(Istream&) : "
+                            "reading entry"
+                        );
+                    }
+                }
+                else if (delimiter == token::BEGIN_BLOCK)
+                {
+                    // assign for all entries
+                    lst = lst.readValue(is);
+
+                    is.fatalCheck
+                    (
+                        "PackedList<nBits>::read(Istream&) : "
+                        "reading the single entry"
+                    );
+                }
+                else
+                {
+                    FatalIOErrorIn
+                    (
+                        "PackedList<nBits>::read(Istream&)",
+                        is
+                    )
+                        << "incorrect list token, expected '(' or '{', found "
+                        << firstTok.info()
+                        << exit(FatalIOError);
+                }
+            }
+
+            // Read end of contents
+            is.readEndList("PackedList<nBits>");
+        }
+        else
+        {
+            if (sz)
+            {
+                is.read
+                (
+                    reinterpret_cast<char*>(lst.storage().data()),
+                    lst.byteSize()
+                );
+
+                is.fatalCheck
+                (
+                    "PackedList<nBits>::read(Istream&) : "
+                    "reading the binary block"
+                );
+            }
+        }
+    }
+    else if (firstTok.isPunctuation())
+    {
+        if (firstTok.pToken() == token::BEGIN_LIST)
+        {
+            token nextTok(is);
+            is.fatalCheck("PackedList<nBits>::read(Istream&)");
+
+            while
+            (
+                !(   nextTok.isPunctuation()
+                  && nextTok.pToken() == token::END_LIST
+                 )
+            )
+            {
+                is.putBack(nextTok);
+                lst.append(lst.readValue(is));
+
+                is  >> nextTok;
+                is.fatalCheck("PackedList<nBits>::read(Istream&)");
+            }
+        }
+        else if (firstTok.pToken() == token::BEGIN_BLOCK)
+        {
+            token nextTok(is);
+            is.fatalCheck("PackedList<nBits>::read(Istream&)");
+
+            while
+            (
+                !(   nextTok.isPunctuation()
+                  && nextTok.pToken() == token::END_BLOCK
+                 )
+            )
+            {
+                is.putBack(nextTok);
+                lst.setPair(is);
+
+                is  >> nextTok;
+                is.fatalCheck("PackedList<nBits>::read(Istream&)");
             }
         }
-        os << '\n';
+        else
+        {
+            FatalIOErrorIn
+            (
+                "PackedList<nBits>::read(Istream&)",
+                is
+            )
+                << "incorrect first token, expected '(', found "
+                << firstTok.info()
+                << exit(FatalIOError);
+        }
+    }
+    else
+    {
+        FatalIOErrorIn
+        (
+            "PackedList<nBits>::read(Istream&)",
+            is
+        )
+            << "incorrect first token, expected <int>, '(' or '{', found "
+            << firstTok.info()
+            << exit(FatalIOError);
+    }
+
+    return is;
+}
+
+
+template<unsigned nBits>
+Foam::Ostream& Foam::PackedList<nBits>::write
+(
+    Ostream& os,
+    const bool indexedOutput
+) const
+{
+    const PackedList<nBits>& lst = *this;
+    const label sz = lst.size();
+
+    // Write list contents depending on data format
+    if (os.format() == IOstream::ASCII)
+    {
+        bool uniform = false;
+
+        if (sz > 1 && !indexedOutput)
+        {
+            uniform = true;
+
+            forAll(lst, i)
+            {
+                if (lst[i] != lst[0])
+                {
+                    uniform = false;
+                    break;
+                }
+            }
+        }
+
+        if (uniform)
+        {
+            // uniform values:
+            os  << sz << token::BEGIN_BLOCK << lst[0] << token::END_BLOCK;
+        }
+        else if (indexedOutput)
+        {
+            // indexed output
+            os  << nl << token::BEGIN_BLOCK << nl;
+
+            for
+            (
+                typename PackedList<nBits>::const_iterator iter = lst.cbegin();
+                iter != lst.cend();
+                ++iter
+            )
+            {
+                if (iter.writeIfSet(os))
+                {
+                    os  << nl;
+                }
+            }
+
+            os  << token::END_BLOCK << nl;
+        }
+        else if (sz < 11)
+        {
+            // short list:
+            os  << sz << token::BEGIN_LIST;
+            forAll(lst, i)
+            {
+                if (i)
+                {
+                    os  << token::SPACE;
+                }
+                os  << lst[i];
+            }
+            os  << token::END_LIST;
+        }
+        else
+        {
+            // longer list:
+            os  << nl << sz << nl << token::BEGIN_LIST;
+            forAll(lst, i)
+            {
+                os  << nl << lst[i];
+            }
+            os  << nl << token::END_LIST << nl;
+        }
+    }
+    else
+    {
+        os  << nl << sz << nl;
+        if (sz)
+        {
+            os.write
+            (
+                reinterpret_cast<const char*>(lst.storage().cdata()),
+                lst.byteSize()
+            );
+        }
     }
-    os << ")\n";
 
     return os;
 }
 
 
+template<unsigned nBits>
+void Foam::PackedList<nBits>::writeEntry(Ostream& os) const
+{
+    os  << *this;
+}
+
+
+template<unsigned nBits>
+void Foam::PackedList<nBits>::writeEntry
+(
+    const word& keyword,
+    Ostream& os
+) const
+{
+    os.writeKeyword(keyword);
+    writeEntry(os);
+    os  << token::END_STATEMENT << endl;
+}
+
+
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 template<unsigned nBits>
-void Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
+Foam::PackedList<nBits>&
+Foam::PackedList<nBits>::operator=(const PackedList<nBits>& lst)
 {
     StorageList::operator=(lst);
     size_ = lst.size();
+    return *this;
+}
+
+
+template<unsigned nBits>
+Foam::PackedList<nBits>&
+Foam::PackedList<nBits>::operator=(const UList<label>& lst)
+{
+    setCapacity(lst.size());
+    size_ = lst.size();
+
+    forAll(lst, i)
+    {
+        set(i, lst[i]);
+    }
+    return *this;
 }
 
 
 template<unsigned nBits>
-void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
+Foam::PackedList<nBits>&
+Foam::PackedList<nBits>::operator=(const UIndirectList<label>& lst)
 {
     setCapacity(lst.size());
     size_ = lst.size();
@@ -281,19 +560,24 @@ void Foam::PackedList<nBits>::operator=(const UList<label>& lst)
     {
         set(i, lst[i]);
     }
+    return *this;
 }
 
 
-// * * * * * * * * * * * * * * * Ostream Operator *  * * * * * * * * * * * * //
+// * * * * * * * * * * * * * *  Friend Operators * * * * * * * * * * * * * * //
+
+template<unsigned nBits>
+Foam::Istream& Foam::operator>>(Istream& is, PackedList<nBits>& lst)
+{
+    return lst.read(is);
+}
 
-//template<unsigned nBits>
-//Foam::Ostream& ::Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
-//{
-//    os << lst();
-//    return os;
-//}
 
+template<unsigned nBits>
+Foam::Ostream& Foam::operator<<(Ostream& os, const PackedList<nBits>& lst)
+{
+    return lst.write(os, false);
+}
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
index 76c0e97b80924e905048006b10702faf7c2cd05d..f4cdce7aab9be39c71f8584712aa94c371b5008a 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
@@ -72,6 +72,23 @@ Note
         list[8] = 1;
     @endcode
 
+    Also note that all unused internal storage elements are guaranteed to
+    always be bit-wise zero. This property must not be violated by any
+    inheriting classes.
+
+    In addition to the normal output format, PackedList also supports a
+    compact ASCII format that may be convenient for user input in some
+    situations. The general format is a group of index/value pairs:
+    @verbatim
+        { (index1 value1) (index2 value2) (index3 value3) }
+    @endverbatim
+    The bool specialization just uses the indices corresponding to
+    non-zero entries instead of a index/value pair:
+    @verbatim
+        { index1 index2 index3 }
+    @endverbatim
+    In both cases, the supplied indices can be randomly ordered.
+
 SeeAlso
     Foam::DynamicList
 
@@ -85,6 +102,7 @@ SourceFiles
 #define PackedList_H
 
 #include "labelList.H"
+#include "UIndirectList.H"
 #include "StaticAssert.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -92,18 +110,34 @@ SourceFiles
 namespace Foam
 {
 
+// Forward declaration of classes
+class Istream;
+class Ostream;
+
 // Forward declaration of friend functions and operators
 template<unsigned nBits> class PackedList;
 
-// template<unsigned nBits>
-// Ostream& operator<<(Ostream&, const PackedList<nBits>&);
+template<unsigned nBits>
+Istream& operator>>(Istream&, PackedList<nBits>&);
+template<unsigned nBits>
+Ostream& operator<<(Ostream&, const PackedList<nBits>&);
 
 
 /*---------------------------------------------------------------------------*\
-                      Class PackedListName Declaration
+                       Class PackedListCore Declaration
 \*---------------------------------------------------------------------------*/
 
-TemplateName(PackedList);
+//- Template-invariant bits for PackedList
+struct PackedListCore
+{
+    //- Construct null
+    PackedListCore()
+    {}
+
+    //- Define template name and debug
+    ClassName("PackedList");
+};
+
 
 /*---------------------------------------------------------------------------*\
                          Class PackedList Declaration
@@ -112,25 +146,39 @@ TemplateName(PackedList);
 template<unsigned nBits=1>
 class PackedList
 :
+    public PackedListCore,
     private List<unsigned int>
 {
+protected:
+
     typedef unsigned int      StorageType;
     typedef List<StorageType> StorageList;
 
-    //- nBits must be positive (non-zero) and fit within the storage
-    //  For simplicity, assume 8-bit bytes
-    StaticAssert(nBits && nBits < (sizeof(StorageType) << 3));
+    // Protected Member Functions
 
-    // Private data
+        //- Calculate the list length when packed
+        inline static label packedLength(const label);
 
-        //- Number of nBits entries
-        label size_;
+        //- Read a list entry (allows for specialization)
+        inline static unsigned int readValue(Istream&);
 
-    // Private Member Functions
+        //- Read an index/value pair and set accordingly.
+        //  For bool specialization, read a single index value
+        inline void setPair(Istream&);
 
-        //- Calculate the list length when packed
-        inline static label packedLength(const label);
+private:
+
+    //- nBits must be positive (non-zero) and fit within the storage.
+    //  For efficiency, however, require packing at least 2 items otherwise
+    //  it is more efficient to use a normal list.
+    //  Thus max nBits is 1/2 of the base storage size.
+    //  For simplicity, assume 8-bit bytes in the assert.
+    StaticAssert(nBits && nBits <= (sizeof(StorageType) << 2));
+
+    // Private data
 
+        //- Number of nBits entries
+        label size_;
 
 public:
 
@@ -163,20 +211,26 @@ public:
         //- Null constructor
         inline PackedList();
 
-        //- Construct with given size, initializes list to 0.
+        //- Construct with given size, initializes list to 0
         explicit inline PackedList(const label size);
 
-        //- Construct with given size and value for all elements.
-        PackedList(const label size, const unsigned val);
+        //- Construct with given size and value for all elements
+        inline PackedList(const label size, const unsigned val);
 
-        //- Copy constructor.
+        //- Construct from Istream
+        inline PackedList(Istream&);
+
+        //- Copy constructor
         inline PackedList(const PackedList<nBits>&);
 
         //- Construct by transferring the parameter contents
         inline PackedList(const Xfer<PackedList<nBits> >&);
 
         //- Construct from a list of labels
-        explicit PackedList(const UList<label>&);
+        explicit inline PackedList(const UList<label>&);
+
+        //- Construct from an indirect list of labels
+        explicit inline PackedList(const UIndirectList<label>&);
 
         //- Clone
         inline autoPtr< PackedList<nBits> > clone() const;
@@ -209,30 +263,52 @@ public:
             inline bool unset(const label);
 
             //- Return the underlying packed storage
+            //  Manipulate with utmost caution
             inline List<unsigned int>& storage();
 
             //- Return the underlying packed storage
             inline const List<unsigned int>& storage() const;
 
+            //- The list length when packed
+            inline label packedLength() const;
+
+            //- Return the binary size in number of characters
+            //  used in the underlying storage
+            inline label byteSize() const;
+
             //- Count number of bits set, O(log(n))
             //  Uses the Hamming weight (population count) method
             //  http://en.wikipedia.org/wiki/Hamming_weight
             unsigned int count() const;
 
-            //- Return the values as a labelList
-            labelList values() const;
+            //- Return the values as a list of labels
+            Xfer<labelList> values() const;
+
+            //- Print bit patterns, optionally output unused elements
+            //
+            // addressable bits:
+            //   on: '1', off: '-'
+            //
+            // non-addressable bits:
+            //   on: '!', off: '.'
+            //
+            Ostream& printBits(Ostream&, const bool fullOutput=false) const;
+
+            //- Print information and bit patterns (with printBits)
+            Ostream& printInfo(Ostream&, const bool fullOutput=false) const;
 
-            //- Print values and information
-            Ostream& print(Ostream&) const;
 
         // Edit
 
             //- Trim any trailing zero elements
             bool trim();
 
-            //- Invert the bits in the addressable region.
+            //- Invert the bits in the addressable region
             void flip();
 
+            //- Clear all bits
+            inline void reset();
+
             //- Alter the size of the underlying storage.
             //  The addressed size will be truncated if needed to fit, but will
             //  remain otherwise untouched.
@@ -240,10 +316,10 @@ public:
 
             //- Reset addressable list size, does not shrink the allocated size.
             //  Optionally specify a value for new elements.
-            inline void resize(const label, const unsigned int& val = 0);
+            inline void resize(const label, const unsigned int& val = 0u);
 
             //- Alias for resize()
-            inline void setSize(const label, const unsigned int& val = 0);
+            inline void setSize(const label, const unsigned int& val = 0u);
 
             //- Reserve allocation space for at least this size.
             //  Never shrinks the allocated size.
@@ -269,10 +345,43 @@ public:
             inline Xfer<PackedList<nBits> > xfer();
 
 
+        // IO
+
+            //- Clear list and read from stream
+            Istream& read(Istream&);
+
+            //- Write, optionally with indexedOutput
+            //
+            // The indexed output may be convenient in some situations.
+            // The general format is a group of index/value pairs:
+            //  @verbatim
+            //      { (index1 value1) (index2 value2) (index3 value3) }
+            // @endverbatim
+            // The bool specialization just uses the indices corresponding to
+            // non-zero entries instead of a index/value pair:
+            // @verbatim
+            //     { index1 index2 index3 }
+            // @endverbatim
+            //
+            // Note the indexed output is only supported for ASCII streams.
+            Ostream& write
+            (
+                Ostream&,
+                const bool indexedOutput=false
+            ) const;
+
+
+            //- Write as a dictionary entry
+            void writeEntry(Ostream&) const;
+
+            //- Write as a dictionary entry with keyword
+            void writeEntry(const word& keyword, Ostream&) const;
+
+
     // Member operators
 
             //- Append a value at the end of the list
-            inline void append(const unsigned int val);
+            inline PackedList<nBits>& append(const unsigned int val);
 
             //- Remove and return the last element
             inline unsigned int remove();
@@ -287,23 +396,16 @@ public:
             inline iteratorBase operator[](const label);
 
             //- Assignment of all entries to the given value. Takes linear time.
-            inline void operator=(const unsigned int val);
-
-            //- Assignment operator. Takes linear time.
-            void operator=(const PackedList<nBits>&);
-
-            //- Assignment operator. Takes linear time.
-            void operator=(const UList<label>&);
+            inline PackedList<nBits>& operator=(const unsigned int val);
 
+            //- Assignment operator.
+            PackedList<nBits>& operator=(const PackedList<nBits>&);
 
-        // Ostream operator
+            //- Assignment operator.
+            PackedList<nBits>& operator=(const UList<label>&);
 
-         // // Write PackedList to Ostream.
-         // friend Ostream& operator<< <nBits>
-         // (
-         //     Ostream&,
-         //     const PackedList<nBits>&
-         // );
+            //- Assignment operator.
+            PackedList<nBits>& operator=(const UIndirectList<label>&);
 
 
     // Iterators and helpers
@@ -347,6 +449,15 @@ public:
 
         public:
 
+            // Member Functions
+
+                //- Return the element index corresponding to the iterator
+                inline label key() const;
+
+                //- Write index/value for a non-zero entry
+                //  The bool specialization writes the index only
+                inline bool writeIfSet(Ostream&) const;
+
             // Member Operators
 
                 //- Compare values (not positions)
@@ -365,8 +476,8 @@ public:
                 //  Never auto-vivify entries.
                 inline operator unsigned int () const;
 
-            //- Print value and information
-            Ostream& print(Ostream&) const;
+            //- Print information and values
+            Ostream& printInfo(Ostream&) const;
         };
 
 
@@ -376,11 +487,12 @@ public:
             public iteratorBase
         {
 
-            //- Disallow copy constructor from const_iterator -
-            //  violates const-ness!
+            //- Disallow copy constructor from const_iterator
+            //  This would violate const-ness!
             iterator(const const_iterator&);
 
-            //- Disallow assignment from const_iterator - violates const-ness!
+            //- Disallow assignment from const_iterator
+            //  This would violate const-ness!
             void operator=(const const_iterator&);
 
 
@@ -497,6 +609,21 @@ public:
         //- const_iterator set to beyond the end of the PackedList
         inline const_iterator end() const;
 
+
+    // IOstream Operators
+
+        friend Istream& operator>> <nBits>
+        (
+            Istream&,
+            PackedList<nBits>&
+        );
+
+        friend Ostream& operator<< <nBits>
+        (
+            Ostream&,
+            const PackedList<nBits>&
+        );
+
 };
 
 
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListName.C b/src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
similarity index 96%
rename from src/OpenFOAM/containers/Lists/PackedList/PackedListName.C
rename to src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
index 11b38eef54a51b514160500683710eee77952cc6..f596ab39578915d10fdba63120eceb90449570f5 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedListName.C
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
@@ -27,6 +27,7 @@ License
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-defineTypeNameAndDebug(Foam::PackedListName, 0);
+defineTypeNameAndDebug(Foam::PackedListCore, 0);
+
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
index c3059a142fc6c773e77ffe752f0453362040c586..ecae704274b20cc203d4f66f2ac9ad959aa14ab6 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
+++ b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
@@ -67,11 +67,117 @@ inline Foam::label Foam::PackedList<nBits>::packedLength(const label nElem)
 }
 
 
+namespace Foam
+{
+    // Template specialization for bool entries
+    template<>
+    inline unsigned int Foam::PackedList<1>::readValue(Istream& is)
+    {
+        return readBool(is);
+    }
+
+    // Template specialization for bool entries
+    template<>
+    inline void Foam::PackedList<1>::setPair(Istream& is)
+    {
+        set(readLabel(is), true);
+    }
+
+    // Template specialization for bool entries
+    template<>
+    inline bool Foam::PackedList<1>::iteratorBase::writeIfSet(Ostream& os) const
+    {
+        if (this->get())
+        {
+            os  << index_;
+
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+}
+
+
+template<unsigned nBits>
+inline unsigned int Foam::PackedList<nBits>::readValue(Istream& is)
+{
+    const unsigned int val = readLabel(is);
+
+    if (val > max_value())
+    {
+        FatalIOErrorIn
+        (
+            "PackedList<nBits>::readValue(Istream&)",
+            is
+        )
+            << "Out-of-range value " << val << " for PackedList<" << nBits
+            << ">. Maximum permitted value is " << max_value() << "."
+            << exit(FatalIOError);
+    }
+
+    return val;
+}
+
+
+template<unsigned nBits>
+inline void Foam::PackedList<nBits>::setPair(Istream& is)
+{
+    is.readBegin("Tuple2<label, unsigned int>");
+
+    const label ind = readLabel(is);
+    const unsigned int val = readLabel(is);
+
+    is.readEnd("Tuple2<label, unsigned int>");
+
+    if (val > max_value())
+    {
+        FatalIOErrorIn
+        (
+            "PackedList<nBits>::setPair(Istream&)",
+            is
+        )
+            << "Out-of-range value " << val << " for PackedList<" << nBits
+            << "> at index " << ind
+            << ". Maximum permitted value is " << max_value() << "."
+            << exit(FatalIOError);
+    }
+
+    set(ind, val);
+
+    // Check state of Istream
+    is.check("PackedList<nBits>::setPair(Istream&)");
+}
+
+
+template<unsigned nBits>
+inline bool Foam::PackedList<nBits>::iteratorBase::writeIfSet(Ostream& os) const
+{
+    const label val = this->get();
+
+    if (val)
+    {
+        os  << token::BEGIN_LIST
+            << index_ << token::SPACE << val
+            << token::END_LIST;
+
+        return true;
+    }
+    else
+    {
+        return false;
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList()
 :
+    PackedListCore(),
     StorageList(),
     size_(0)
 {}
@@ -80,14 +186,45 @@ inline Foam::PackedList<nBits>::PackedList()
 template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList(const label size)
 :
+    PackedListCore(),
     StorageList(packedLength(size), 0u),
     size_(size)
 {}
 
 
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::PackedList
+(
+    const label size,
+    const unsigned int val
+)
+:
+    PackedListCore(),
+    StorageList(packedLength(size), 0u),
+    size_(size)
+{
+    if (val)
+    {
+        operator=(val);
+    }
+}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::PackedList(Istream& is)
+:
+    PackedListCore(),
+    StorageList(),
+    size_(0)
+{
+    read(is);
+}
+
+
 template<unsigned nBits>
 inline Foam::PackedList<nBits>::PackedList(const PackedList<nBits>& lst)
 :
+    PackedListCore(),
     StorageList(lst),
     size_(lst.size_)
 {}
@@ -100,6 +237,34 @@ inline Foam::PackedList<nBits>::PackedList(const Xfer<PackedList<nBits> >& lst)
 }
 
 
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::PackedList(const UList<label>& lst)
+:
+    PackedListCore(),
+    StorageList(packedLength(lst.size()), 0u),
+    size_(lst.size())
+{
+    forAll(lst, i)
+    {
+        set(i, lst[i]);
+    }
+}
+
+
+template<unsigned nBits>
+inline Foam::PackedList<nBits>::PackedList(const UIndirectList<label>& lst)
+:
+    PackedListCore(),
+    StorageList(packedLength(lst.size()), 0u),
+    size_(lst.size())
+{
+    forAll(lst, i)
+    {
+        set(i, lst[i]);
+    }
+}
+
+
 template<unsigned nBits>
 inline Foam::autoPtr<Foam::PackedList<nBits> >
 Foam::PackedList<nBits>::clone() const
@@ -151,27 +316,34 @@ Foam::PackedList<nBits>::iteratorBase::set(const unsigned int val)
     const unsigned int seg = index_ / packing();
     const unsigned int off = index_ % packing();
 
+    const unsigned int startBit = nBits * off;
+    const unsigned int mask = max_value() << startBit;
+
     unsigned int& stored = list_->StorageList::operator[](seg);
     const unsigned int prev = stored;
 
-    const unsigned int startBit = nBits * off;
-    const unsigned int maskNew  = max_value() << startBit;
-
-    if (val & ~max_value())
+    if (val >= max_value())
     {
         // overflow is max_value, fill everything
-        stored |= maskNew;
+        stored |= mask;
     }
     else
     {
-        stored &= ~maskNew;
-        stored |= maskNew & (val << startBit);
+        stored &= ~mask;
+        stored |= mask & (val << startBit);
     }
 
     return prev != stored;
 }
 
 
+template<unsigned nBits>
+inline Foam::label Foam::PackedList<nBits>::iteratorBase::key() const
+{
+    return index_;
+}
+
+
 template<unsigned nBits>
 inline bool Foam::PackedList<nBits>::iteratorBase::operator==
 (
@@ -564,24 +736,27 @@ inline bool Foam::PackedList<nBits>::empty() const
 template<unsigned nBits>
 inline void Foam::PackedList<nBits>::resize
 (
-    const label nElem,
+    const label newSize,
     const unsigned int& val
 )
 {
-    reserve(nElem);
+    reserve(newSize);
+
+    const label oldSize = size_;
+    size_ = newSize;
 
-    if (nElem > size_)
+    if (size_ > oldSize)
     {
         // fill new elements or newly exposed elements
-        if (size_)
+        if (val)
         {
             // fill value for complete segments
             unsigned int fill = val;
 
-            if (fill & ~max_value())
+            if (val >= max_value())
             {
-                // overflow is max_value, fill everything
-                fill = ~0u;
+                // fill everything
+                fill = maskLower(packing());
             }
             else
             {
@@ -591,36 +766,64 @@ inline void Foam::PackedList<nBits>::resize
                 }
             }
 
-            unsigned int seg = size_ / packing();
-            unsigned int off = size_ % packing();
-
-            // partial segment, preserve existing value
-            if (off)
+            // fill in complete segments
+            const label oldLen = packedLength(oldSize);
+            const label newLen = packedLength(size_);
+            for (label i=oldLen; i < newLen; ++i)
             {
-                unsigned int maskOld = maskLower(off);
+                StorageList::operator[](i) = fill;
+            }
 
-                StorageList::operator[](seg) &= maskOld;
-                StorageList::operator[](seg) |= ~maskOld & fill;
+            // finish previous partial segment, preserve existing value
+            {
+                const unsigned int off = oldSize % packing();
+                if (off)
+                {
+                    const unsigned int seg = oldSize / packing();
+                    const unsigned int mask = maskLower(off);
 
-                // continue with the next segment
-                seg++;
+                    StorageList::operator[](seg) &= mask;
+                    StorageList::operator[](seg) |= ~mask & fill;
+                }
             }
 
-            unsigned int endSeg = nElem / packing();
-            // fill in complete elements
-            while (seg < endSeg)
+
+            // mask off the (new) final partial segment
             {
-                StorageList::operator[](seg++) = fill;
+                const unsigned int off = size_ % packing();
+                if (off)
+                {
+                    const unsigned int seg = size_ / packing();
+
+                    StorageList::operator[](seg) &= maskLower(off);
+                }
             }
         }
-        else
+    }
+    else if (size_ < oldSize)
+    {
+        // resize shrinking
+        // - clear newly exposed elements
+
+        // fill in complete segments
+        const label oldLen = packedLength(oldSize);
+        const label newLen = packedLength(size_);
+        for (label i=newLen; i < oldLen; ++i)
         {
-            // no original size - simply flood-fill
-            operator=(val);
+            StorageList::operator[](i) = 0u;
         }
-    }
 
-    size_ = nElem;
+        // mask off the final partial segment
+        {
+            const unsigned int off = size_ % packing();
+            if (off)
+            {
+                const unsigned int seg = size_ / packing();
+
+                StorageList::operator[](seg) &= maskLower(off);
+            }
+        }
+    }
 }
 
 
@@ -648,21 +851,27 @@ inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
 {
     StorageList::setSize(packedLength(nElem), 0u);
 
-    // truncate addressed size too?
+    // truncate addressed size too
     if (size_ > nElem)
     {
         size_ = nElem;
+
+        // mask off the final partial segment
+        const unsigned int off = size_ % packing();
+        if (off)
+        {
+            const unsigned int seg = size_ / packing();
+
+            StorageList::operator[](seg) &= maskLower(off);
+        }
     }
 }
 
 
 template<unsigned nBits>
-inline void Foam::PackedList<nBits>::reserve
-(
-    const label nElem
-)
+inline void Foam::PackedList<nBits>::reserve(const label nElem)
 {
-    label len = packedLength(nElem);
+    const label len = packedLength(nElem);
 
     // need more capacity?
     if (len > StorageList::size())
@@ -681,9 +890,17 @@ inline void Foam::PackedList<nBits>::reserve
 }
 
 
+template<unsigned nBits>
+inline void Foam::PackedList<nBits>::reset()
+{
+    StorageList::operator=(0u);
+}
+
+
 template<unsigned nBits>
 inline void Foam::PackedList<nBits>::clear()
 {
+    reset();
     size_ = 0;
 }
 
@@ -699,9 +916,8 @@ inline void Foam::PackedList<nBits>::clearStorage()
 template<unsigned nBits>
 inline void Foam::PackedList<nBits>::shrink()
 {
-    label len = packedLength(size_);
-
-    // we have unused space?
+    // any uneed space allocated?
+    const label len = packedLength();
     if (len < StorageList::size())
     {
         StorageList::setSize(len);
@@ -722,6 +938,20 @@ inline const Foam::List<unsigned int>& Foam::PackedList<nBits>::storage() const
 }
 
 
+template<unsigned nBits>
+inline Foam::label Foam::PackedList<nBits>::packedLength() const
+{
+    return packedLength(size_);
+}
+
+
+template<unsigned nBits>
+inline Foam::label Foam::PackedList<nBits>::byteSize() const
+{
+    return packedLength() * sizeof(StorageType);
+}
+
+
 template<unsigned nBits>
 inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
 {
@@ -742,23 +972,14 @@ inline Foam::Xfer<Foam::PackedList<nBits> > Foam::PackedList<nBits>::xfer()
 template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::get(const label i) const
 {
-#   ifdef FULLDEBUG
-    if (i < 0)
-    {
-        FatalErrorIn("PackedList<nBits>::get(const label)")
-            << "negative index " << i << " max=" << size_-1
-            << abort(FatalError);
-    }
-#   endif
-
     // lazy evaluation - return 0 for out-of-range
-    if (i < size_)
+    if (i < 0 || i >= size_)
     {
-        return iteratorBase(this, i).get();
+        return 0;
     }
     else
     {
-        return 0;
+        return iteratorBase(this, i).get();
     }
 }
 
@@ -767,13 +988,13 @@ template<unsigned nBits>
 inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
 {
     // lazy evaluation - return 0 for out-of-range
-    if (i < size_)
+    if (i < 0 || i >= size_)
     {
-        return iteratorBase(this, i).get();
+        return 0;
     }
     else
     {
-        return 0;
+        return iteratorBase(this, i).get();
     }
 }
 
@@ -785,18 +1006,14 @@ inline bool Foam::PackedList<nBits>::set
     const unsigned int val
 )
 {
-#   ifdef FULLDEBUG
     if (i < 0)
     {
-        FatalErrorIn("PackedList<nBits>::set(const label)")
-            << "negative index " << i << " max=" << size_-1
-            << abort(FatalError);
+        // lazy evaluation - ignore out-of-bounds
+        return false;
     }
-#   endif
-
-    // lazy evaluation - increase size on assigment
-    if (i >= size_)
+    else if (i >= size_)
     {
+        // lazy evaluation - increase size on assigment
         resize(i + 1);
     }
 
@@ -807,24 +1024,28 @@ inline bool Foam::PackedList<nBits>::set
 template<unsigned nBits>
 inline bool Foam::PackedList<nBits>::unset(const label i)
 {
-    // lazy - ignore out-of-bounds
+    // lazy evaluation - ignore out-of-bounds
     if (i < 0 || i >= size_)
     {
         return false;
     }
-
-    return iteratorBase(this, i).set(0u);
+    else
+    {
+        return iteratorBase(this, i).set(0u);
+    }
 }
 
 
 template<unsigned nBits>
-inline void Foam::PackedList<nBits>::append(const unsigned int val)
+inline Foam::PackedList<nBits>&
+Foam::PackedList<nBits>::append(const unsigned int val)
 {
-    label elemI = size_;
+    const label elemI = size_;
     reserve(elemI + 1);
     size_++;
 
     iteratorBase(this, elemI).set(val);
+    return *this;
 }
 
 
@@ -855,35 +1076,20 @@ Foam::PackedList<nBits>::operator[](const label i)
 }
 
 
-namespace Foam
-{
-    // specialization for nBits=1
-    template<>
-    inline void Foam::PackedList<1>::operator=(const unsigned int val)
-    {
-        if (val)
-        {
-            StorageList::operator=(~0u);
-        }
-        else
-        {
-            StorageList::operator=(0u);
-        }
-    }
-}
-
-
 template<unsigned nBits>
-inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
+inline Foam::PackedList<nBits>&
+Foam::PackedList<nBits>::operator=(const unsigned int val)
 {
-    if (val)
+    const label packLen = packedLength();
+
+    if (val && size_)
     {
         unsigned int fill = val;
 
-        if (fill & ~max_value())
+        if (val >= max_value())
         {
-            // treat overflow as max_value
-            fill = ~0u;
+            // fill everything
+            fill = maskLower(packing());
         }
         else
         {
@@ -893,12 +1099,31 @@ inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
             }
         }
 
-        StorageList::operator=(fill);
+        for (label i=0; i < packLen; ++i)
+        {
+            StorageList::operator[](i) = fill;
+        }
+
+        // mask off the final partial segment
+        {
+            const unsigned int off = size_ % packing();
+            if (off)
+            {
+                const unsigned int seg = size_ / packing();
+
+                StorageList::operator[](seg) &= maskLower(off);
+            }
+        }
     }
     else
     {
-        StorageList::operator=(0u);
+        for (label i=0; i < packLen; ++i)
+        {
+            StorageList::operator[](i) = 0u;
+        }
     }
+
+    return *this;
 }
 
 
diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C b/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C
index 4cf39c34a7f8baf3b8f2925ea8a58e05295c9bbc..432ab8ac1718d96efb0ada3533ea28232ba72e3a 100644
--- a/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C
+++ b/src/OpenFOAM/db/IOstreams/Sstreams/readHexLabel.C
@@ -22,11 +22,12 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Description
-    Read of a non-delimited hex label
+    Read a non-delimited hex label
 
 \*---------------------------------------------------------------------------*/
 
 #include "readHexLabel.H"
+#include <cctype>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -55,7 +56,7 @@ Foam::label Foam::readHexLabel(ISstream& is)
                 << exit(FatalIOError);
         }
 
-        result *= 16;
+        result <<= 4;
 
         if (isdigit(c))
         {
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/ZoneID.H b/src/OpenFOAM/meshes/Identifiers/DynamicID/DynamicID.H
similarity index 59%
rename from src/OpenFOAM/meshes/polyMesh/zones/ZoneID/ZoneID.H
rename to src/OpenFOAM/meshes/Identifiers/DynamicID/DynamicID.H
index 6191a6d6d8f27c6821e9c8a34fea3a324e427b97..286049ed558d77ca02ccf3801b587c0977c08876 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/ZoneID.H
+++ b/src/OpenFOAM/meshes/Identifiers/DynamicID/DynamicID.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -22,51 +22,48 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Class
-    Foam::ZoneID
+    Foam::DynamicID
 
 Description
-    A class that holds the data needed to identify a zone in a dynamic mesh.
+    A class that holds the data needed to identify things (zones, patches)
+    in a dynamic mesh.
 
-    The zone is identified by name.
-    Its index in the zoneMesh is updated if the mesh has changed.
+    The thing is identified by name.
+    Its indices are updated if the mesh has changed.
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef ZoneID_H
-#define ZoneID_H
+#ifndef DynamicID_H
+#define DynamicID_H
 
-#include "label.H"
-#include "word.H"
-#include "polyMesh.H"
+#include "keyType.H"
+#include "labelList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-template<class ZoneType, class MeshType> class ZoneMesh;
-
 // Forward declaration of friend functions and operators
+template<class> class DynamicID;
 
-template<class ZoneType> class ZoneID;
-
-template<class ZoneType>
-Ostream& operator<<(Ostream&, const ZoneID<ZoneType>&);
+template<class ObjectType>
+Ostream& operator<<(Ostream&, const DynamicID<ObjectType>&);
 
 /*---------------------------------------------------------------------------*\
-                           Class ZoneID Declaration
+                          Class DynamicID Declaration
 \*---------------------------------------------------------------------------*/
 
-template<class ZoneType>
-class ZoneID
+template<class ObjectType>
+class DynamicID
 {
     // Private data
 
         //- Zone name
-        word name_;
+        keyType key_;
 
-        //- Zone index
-        label index_;
+        //- Zone indices
+        labelList indices_;
 
 
 public:
@@ -74,17 +71,17 @@ public:
     // Constructors
 
         //- Construct from name
-        ZoneID(const word& name, const ZoneMesh<ZoneType, polyMesh>& zm)
+        DynamicID(const keyType& key, const ObjectType& obj)
         :
-            name_(name),
-            index_(zm.findZoneID(name))
+            key_(key),
+            indices_(obj.findIndices(key_))
         {}
 
         //- Construct from Istream
-        ZoneID(Istream& is, const ZoneMesh<ZoneType, polyMesh>& zm)
+        DynamicID(Istream& is, const ObjectType& obj)
         :
-            name_(is),
-            index_(zm.findZoneID(name_))
+            key_(is),
+            indices_(obj.findIndices(key_))
         {}
 
 
@@ -96,57 +93,57 @@ public:
         // Access
 
             //- Return name
-            const word& name() const
+            const keyType& name() const
+            {
+                return key_;
+            }
+
+            //- Return indices of matching zones
+            const labelList& indices() const
             {
-                return name_;
+                return indices_;
             }
 
-            //- Return index
+            //- Return index of first matching zone
             label index() const
             {
-                return index_;
+                return indices_.empty() ? -1 : indices_[0];
             }
 
             //- Has the zone been found
             bool active() const
             {
-                return index_ > -1;
+                return !indices_.empty();
             }
 
 
         // Edit
 
             //- Update
-            void update(const ZoneMesh<ZoneType, polyMesh>& zm)
+            void update(const ObjectType& obj)
             {
-                index_ = zm.findZoneID(name_);
+                indices_ = obj.findIndices(key_);
             }
 
 
     // IOstream Operators
 
-        friend Ostream& operator<< <ZoneType>
-        (
-            Ostream& os, const ZoneID<ZoneType>& p
-        );
+        friend Ostream& operator<< <ObjectType>
+        (Ostream&, const DynamicID<ObjectType>&);
 };
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-template<class ZoneType>
-Ostream& operator<<
-(
-    Ostream& os, const ZoneID<ZoneType>& p
-)
+template<class ObjectType>
+Ostream& operator<<(Ostream& os, const DynamicID<ObjectType>& dynId)
 {
     os  << token::BEGIN_LIST
-        << p.name_ << token::SPACE
-        << p.index_
+        << dynId.name() << token::SPACE << dynId.index()
         << token::END_LIST;
 
     // Check state of Ostream
-    os.check("Ostream& operator<<(Ostream&, const ZoneID<ZoneType>&)");
+    os.check("Ostream& operator<<(Ostream&, const DynamicID<ObjectType>&)");
 
     return os;
 }
diff --git a/src/OpenFOAM/meshes/patchIdentifier/patchIdentifier.C b/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.C
similarity index 100%
rename from src/OpenFOAM/meshes/patchIdentifier/patchIdentifier.C
rename to src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.C
diff --git a/src/OpenFOAM/meshes/patchIdentifier/patchIdentifier.H b/src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.H
similarity index 100%
rename from src/OpenFOAM/meshes/patchIdentifier/patchIdentifier.H
rename to src/OpenFOAM/meshes/Identifiers/patch/patchIdentifier.H
diff --git a/src/OpenFOAM/primitives/Lists/PackedBoolList.H b/src/OpenFOAM/meshes/Identifiers/patch/polyPatchID.H
similarity index 83%
rename from src/OpenFOAM/primitives/Lists/PackedBoolList.H
rename to src/OpenFOAM/meshes/Identifiers/patch/polyPatchID.H
index 7dd2c81b7c70cb1a47917b5bcaeb1324ed3324ed..eaa7423601e881ca92d7b29e80c91c468d694524 100644
--- a/src/OpenFOAM/primitives/Lists/PackedBoolList.H
+++ b/src/OpenFOAM/meshes/Identifiers/patch/polyPatchID.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,25 +21,20 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-Typedef
-    Foam::PackedBoolList
-
-Description
-    A bit-packed bool list
-
 \*---------------------------------------------------------------------------*/
 
-#ifndef PackedBoolList_H
-#define PackedBoolList_H
+#ifndef polyPatchID_H
+#define polyPatchID_H
 
-#include "bool.H"
-#include "PackedList.H"
+#include "DynamicID.H"
+#include "polyBoundaryMesh.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    typedef PackedList<> PackedBoolList;
+    //- Foam::polyPatchID
+    typedef DynamicID<polyBoundaryMesh> polyPatchID;
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/ZoneIDs.H b/src/OpenFOAM/meshes/Identifiers/zones/ZoneIDs.H
similarity index 81%
rename from src/OpenFOAM/meshes/polyMesh/zones/ZoneID/ZoneIDs.H
rename to src/OpenFOAM/meshes/Identifiers/zones/ZoneIDs.H
index 0dc0a43c99db5a487585e0176e41474070dc0399..9b7a6415f2a92290a226ef5239b6ab1726921c88 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/ZoneIDs.H
+++ b/src/OpenFOAM/meshes/Identifiers/zones/ZoneIDs.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2010-2010 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -26,21 +26,26 @@ License
 #ifndef ZoneIDs_H
 #define ZoneIDs_H
 
-#include "ZoneID.H"
-#include "pointZone.H"
-#include "faceZone.H"
-#include "cellZone.H"
+#include "DynamicID.H"
+
+#include "cellZoneMeshFwd.H"
+#include "faceZoneMeshFwd.H"
+#include "pointZoneMeshFwd.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    //- Foam::pointZoneID
-    typedef ZoneID<pointZone> pointZoneID;
-    //- Foam::faceZoneID
-    typedef ZoneID<faceZone> faceZoneID;
+
     //- Foam::cellZoneID
-    typedef ZoneID<cellZone> cellZoneID;
+    typedef DynamicID<cellZoneMesh> cellZoneID;
+
+    //- Foam::faceZoneID
+    typedef DynamicID<faceZoneMesh> faceZoneID;
+
+    //- Foam::pointZoneID
+    typedef DynamicID<pointZoneMesh> pointZoneID;
+
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
index 91fbbca6174f0bd0a9ee7f4615e440a417451766..c11b9056bdc01db6689b2a141ee36a0ed9aae4ed 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
@@ -31,6 +31,7 @@ License
 #include "PstreamBuffers.H"
 #include "lduSchedule.H"
 #include "globalMeshData.H"
+#include "stringListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -413,6 +414,66 @@ Foam::wordList Foam::polyBoundaryMesh::physicalTypes() const
 }
 
 
+Foam::labelList Foam::polyBoundaryMesh::findIndices(const keyType& key) const
+{
+    labelList indices;
+
+    if (!key.empty())
+    {
+        if (key.isPattern())
+        {
+            indices = findStrings(key, this->names());
+        }
+        else
+        {
+            indices.setSize(this->size());
+            label nFound = 0;
+            forAll(*this, i)
+            {
+                if (key == operator[](i).name())
+                {
+                    indices[nFound++] = i;
+                }
+            }
+            indices.setSize(nFound);
+        }
+    }
+
+    return indices;
+}
+
+
+Foam::label Foam::polyBoundaryMesh::findIndex(const keyType& key) const
+{
+    if (!key.empty())
+    {
+        if (key.isPattern())
+        {
+            labelList indices = this->findIndices(key);
+
+            // return first element
+            if (!indices.empty())
+            {
+                return indices[0];
+            }
+        }
+        else
+        {
+            forAll(*this, i)
+            {
+                if (key == operator[](i).name())
+                {
+                    return i;
+                }
+            }
+        }
+    }
+
+    // not found
+    return -1;
+}
+
+
 Foam::label Foam::polyBoundaryMesh::findPatchID(const word& patchName) const
 {
     const polyPatchList& patches = *this;
@@ -444,7 +505,11 @@ Foam::label Foam::polyBoundaryMesh::whichPatch(const label faceIndex) const
     // with patch start labels.
     // If the face is internal, return -1;
     // if it is off the end of the list, abort
-    if (faceIndex >= mesh().nFaces())
+    if (faceIndex < mesh().nInternalFaces())
+    {
+        return -1;
+    }
+    else if (faceIndex >= mesh().nFaces())
     {
         FatalErrorIn
         (
@@ -453,10 +518,6 @@ Foam::label Foam::polyBoundaryMesh::whichPatch(const label faceIndex) const
             << abort(FatalError);
     }
 
-    if (faceIndex < mesh().nInternalFaces())
-    {
-        return -1;
-    }
 
     forAll(*this, patchI)
     {
@@ -578,7 +639,7 @@ bool Foam::polyBoundaryMesh::checkParallelSync(const bool report) const
 
     // Have every processor check but only master print error.
 
-    for (label procI = 1; procI < allNames.size(); procI++)
+    for (label procI = 1; procI < allNames.size(); ++procI)
     {
         if
         (
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H
index 5469c6b8b8226acfa195e73bc89bf66d53cca6cc..89bd78a17ae0b16fce0c5f2f7fbbd58ed2c8dbea 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H
@@ -38,6 +38,7 @@ SourceFiles
 #include "polyPatchList.H"
 #include "regIOobject.H"
 #include "labelPair.H"
+#include "HashSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -151,6 +152,12 @@ public:
         //- Return a list of physical types
         wordList physicalTypes() const;
 
+        //- Return patch indices for all matches
+        labelList findIndices(const keyType&) const;
+
+        //- Return patch index for the first match, return -1 if not found
+        label findIndex(const keyType&) const;
+
         //- Find patch index given a name
         label findPatchID(const word& patchName) const;
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/polyPatchID.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/polyPatchID.H
deleted file mode 100644
index 58c7ff4c1542e7075d54969986f36a8d6704f517..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneID/polyPatchID.H
+++ /dev/null
@@ -1,142 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2010 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::polyPatchID
-
-Description
-    A class holds the data needed to identify a patch in a dynamic mesh.
-
-    The patch is identified by name and its index in the boundary mesh
-    is updated if the mesh has changed.
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef polyPatchID_H
-#define polyPatchID_H
-
-#include "polyBoundaryMesh.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// Forward declaration of friend functions and operators
-
-class polyPatchID;
-Ostream& operator<<(Ostream& os, const polyPatchID& p);
-
-
-/*---------------------------------------------------------------------------*\
-                           Class polyPatchID Declaration
-\*---------------------------------------------------------------------------*/
-
-class polyPatchID
-{
-    // Private data
-
-        //- Patch name
-        word name_;
-
-        //- Patch index
-        label index_;
-
-
-public:
-
-    // Constructors
-
-        //- Construct from name
-        polyPatchID(const word& name, const polyBoundaryMesh& bm)
-        :
-            name_(name),
-            index_(bm.findPatchID(name))
-        {}
-
-        //- Construct from Istream
-        polyPatchID(Istream& is, const polyBoundaryMesh& bm)
-        :
-            name_(is),
-            index_(bm.findPatchID(name_))
-        {}
-
-
-    // Member Functions
-
-        // Access
-
-            //- Return name
-            const word& name() const
-            {
-                return name_;
-            }
-
-            //- Return index
-            label index() const
-            {
-                return index_;
-            }
-
-            //- Has the patch been found
-            bool active() const
-            {
-                return index_ > -1;
-            }
-
-
-        // Edit
-
-            //- Update
-            void update(const polyBoundaryMesh& bm)
-            {
-                index_ = bm.findPatchID(name_);
-            }
-
-
-    // Ostream Operator
-
-        friend Ostream& operator<<(Ostream& os, const polyPatchID& p)
-        {
-            os  << token::BEGIN_LIST
-                << p.name_ << token::SPACE
-                << p.index_
-                << token::END_LIST;
-
-            // Check state of Ostream
-            os.check("Ostream& operator<<(Ostream&, const polyPatchID&)");
-
-            return os;
-        }
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
index 3b3ad474b77ba1eb0fab86781d7c99418ce8cba0..2be9064526d30bd9820e0efbbedf6621e6196ed1 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
@@ -250,23 +250,27 @@ Foam::labelList Foam::ZoneMesh<ZoneType, MeshType>::findIndices
 ) const
 {
     labelList indices;
-    if (key.isPattern())
-    {
-        indices = findStrings(key, this->names());
-    }
-    else
+
+    if (!key.empty())
     {
-        indices.setSize(this->size());
-        label nFound = 0;
-        forAll(*this, i)
+        if (key.isPattern())
         {
-            if (key == operator[](i).name())
+            indices = findStrings(key, this->names());
+        }
+        else
+        {
+            indices.setSize(this->size());
+            label nFound = 0;
+            forAll(*this, i)
             {
-                indices[nFound++] = i;
+                if (key == operator[](i).name())
+                {
+                    indices[nFound++] = i;
+                }
             }
+            indices.setSize(nFound);
         }
-        indices.setSize(nFound);
-     }
+    }
 
     return indices;
 }
@@ -278,22 +282,26 @@ Foam::label Foam::ZoneMesh<ZoneType, MeshType>::findIndex
     const keyType& key
 ) const
 {
-    if (key.isPattern())
+    if (!key.empty())
     {
-        labelList indices = this->findIndices(key);
-        // return first element
-        if (!indices.empty())
+        if (key.isPattern())
         {
-            return indices[0];
+            labelList indices = this->findIndices(key);
+
+            // return first element
+            if (!indices.empty())
+            {
+                return indices[0];
+            }
         }
-    }
-    else
-    {
-        forAll(*this, i)
+        else
         {
-            if (key == operator[](i).name())
+            forAll(*this, i)
             {
-                return i;
+                if (key == operator[](i).name())
+                {
+                    return i;
+                }
             }
         }
     }
@@ -332,6 +340,24 @@ Foam::label Foam::ZoneMesh<ZoneType, MeshType>::findZoneID
 }
 
 
+template<class ZoneType, class MeshType>
+Foam::PackedBoolList Foam::ZoneMesh<ZoneType, MeshType>::findMatching
+(
+    const keyType& key
+) const
+{
+    PackedBoolList lst;
+
+    const labelList indices = this->findIndices(key);
+    forAll(indices, i)
+    {
+        lst |= static_cast<const labelList&>(this->operator[](indices[i]));
+    }
+
+    return lst;
+}
+
+
 template<class ZoneType, class MeshType>
 void Foam::ZoneMesh<ZoneType, MeshType>::clearAddressing()
 {
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
index 15f715df5c8bc7a91f54cc44c602e5447d140b7d..c825d483da3e9c00faedd704374f1389a34ca78e 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
@@ -25,7 +25,7 @@ Class
     Foam::ZoneMesh
 
 Description
-    List of mesh zones
+    A list of mesh zones.
 
 SourceFiles
     ZoneMesh.C
@@ -37,8 +37,9 @@ SourceFiles
 
 #include "List.H"
 #include "regIOobject.H"
-#include "HashSet.H"
 #include "pointFieldsFwd.H"
+#include "Map.H"
+#include "PackedBoolList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -131,15 +132,18 @@ public:
         //- Return a list of zone names
         wordList names() const;
 
-        //- Find zone index given a name
-        label findZoneID(const word& zoneName) const;
-
         //- Return zone indices for all matches
         labelList findIndices(const keyType&) const;
 
         //- Return zone index for the first match, return -1 if not found
         label findIndex(const keyType&) const;
 
+        //- Find zone index given a name
+        label findZoneID(const word& zoneName) const;
+
+        //- Mark cells that match the zone specification
+        PackedBoolList findMatching(const keyType&) const;
+
         //- Clear addressing
         void clearAddressing();
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C
index 6e76afc1c5367e2ed1ebfce7ad8282a44d0e29b2..2464e980471b713a390d7599c530a0fdc9d19e76 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.C
@@ -47,7 +47,7 @@ const char * const Foam::cellZone::labelsName = "cellLabels";
 Foam::cellZone::cellZone
 (
     const word& name,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const label index,
     const cellZoneMesh& zm
 )
@@ -86,7 +86,7 @@ Foam::cellZone::cellZone
 Foam::cellZone::cellZone
 (
     const cellZone& cz,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const label index,
     const cellZoneMesh& zm
 )
@@ -154,7 +154,14 @@ void Foam::cellZone::operator=(const cellZone& zn)
 }
 
 
-void Foam::cellZone::operator=(const labelList& addr)
+void Foam::cellZone::operator=(const unallocLabelList& addr)
+{
+    clearAddressing();
+    labelList::operator=(addr);
+}
+
+
+void Foam::cellZone::operator=(const Xfer<labelList>& addr)
 {
     clearAddressing();
     labelList::operator=(addr);
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
index 54b5ba9eb01debfa9c50fade5a3043ebf0066dce..71d686339f4e0fdff9dce627063b9864776c3828 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/cellZone/cellZone.H
@@ -113,7 +113,7 @@ public:
         cellZone
         (
             const word& name,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index,
             const cellZoneMesh&
         );
@@ -141,7 +141,7 @@ public:
         cellZone
         (
             const cellZone&,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index,
             const cellZoneMesh&
         );
@@ -169,7 +169,7 @@ public:
         //  and zone mesh
         virtual autoPtr<cellZone> clone
         (
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index,
             const cellZoneMesh& zm
         ) const
@@ -222,11 +222,14 @@ public:
 
     // Member Operators
 
-        //- Assign to zone clearing demand-driven data
+        //- Assign to zone, clearing demand-driven data
         void operator=(const cellZone&);
 
-        //- Assign addressing clearing demand-driven data
-        void operator=(const labelList&);
+        //- Assign addressing, clearing demand-driven data
+        void operator=(const unallocLabelList&);
+
+        //- Assign addressing, clearing demand-driven data
+        void operator=(const Xfer<labelList>&);
 
 
     // I-O
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
index 4bd7874649fdc34400c087048388bedfa8ea0a85..47b61806da80cb5f993262e9bf0e7031908d2f4c 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.C
@@ -180,7 +180,7 @@ void Foam::faceZone::checkAddressing() const
 Foam::faceZone::faceZone
 (
     const word& name,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const boolList& fm,
     const label index,
     const faceZoneMesh& zm
@@ -242,7 +242,7 @@ Foam::faceZone::faceZone
 Foam::faceZone::faceZone
 (
     const faceZone& fz,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const boolList& fm,
     const label index,
     const faceZoneMesh& zm
@@ -392,7 +392,7 @@ void Foam::faceZone::clearAddressing()
 
 void Foam::faceZone::resetAddressing
 (
-    const labelList& addr,
+    const unallocLabelList& addr,
     const boolList& flipMap
 )
 {
@@ -414,7 +414,7 @@ void Foam::faceZone::updateMesh(const mapPolyMesh& mpm)
 
     forAll(*this, i)
     {
-        label faceI = operator[](i);
+        const label faceI = operator[](i);
 
         if (faceMap[faceI] >= 0)
         {
@@ -454,7 +454,7 @@ bool Foam::faceZone::checkParallelSync(const bool report) const
         boolList neiZoneFlip(mesh.nFaces()-mesh.nInternalFaces(), false);
         forAll(*this, i)
         {
-            label faceI = operator[](i);
+            const label faceI = operator[](i);
 
             if (!mesh.isInternalFace(faceI))
             {
@@ -469,13 +469,12 @@ bool Foam::faceZone::checkParallelSync(const bool report) const
 
         forAll(*this, i)
         {
-            label faceI = operator[](i);
-
-            label patchI = bm.whichPatch(faceI);
+            const label faceI = operator[](i);
+            const label patchI = bm.whichPatch(faceI);
 
             if (patchI != -1 && bm[patchI].coupled())
             {
-                label bFaceI = faceI-mesh.nInternalFaces();
+                const label bFaceI = faceI-mesh.nInternalFaces();
 
                 // Check face in zone on both sides
                 if (myZoneFace[bFaceI] != neiZoneFace[bFaceI])
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
index b8d617232d490f95128c0a2f94b65485bbf0470d..19c6cf7ab1adab9996a0d0ffa96be7d3dc54e2bc 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/faceZone/faceZone.H
@@ -154,7 +154,7 @@ public:
         faceZone
         (
             const word& name,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const boolList& fm,
             const label index,
             const faceZoneMesh& zm
@@ -184,7 +184,7 @@ public:
         faceZone
         (
             const faceZone&,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const boolList& fm,
             const label index,
             const faceZoneMesh&
@@ -214,7 +214,7 @@ public:
         //  and zone mesh
         virtual autoPtr<faceZone> clone
         (
-            const labelList& addr,
+            const unallocLabelList& addr,
             const boolList& fm,
             const label index,
             const faceZoneMesh& zm
@@ -279,7 +279,7 @@ public:
         virtual void clearAddressing();
 
         //- Reset addressing and flip map (clearing demand-driven data)
-        virtual void resetAddressing(const labelList&, const boolList&);
+        virtual void resetAddressing(const unallocLabelList&, const boolList&);
 
         //- Check zone definition. Return true if in error.
         virtual bool checkDefinition(const bool report = false) const;
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
index a37a786ae2b9c52f85e6460c8e7cfea440e170b0..071387bd8ddcf232ec874e6660f1cee4c1eac9c6 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.C
@@ -47,7 +47,7 @@ const char* const Foam::pointZone::labelsName = "pointLabels";
 Foam::pointZone::pointZone
 (
     const word& name,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const label index,
     const pointZoneMesh& zm
 )
@@ -86,7 +86,7 @@ Foam::pointZone::pointZone
 Foam::pointZone::pointZone
 (
     const pointZone& pz,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const label index,
     const pointZoneMesh& zm
 )
@@ -198,7 +198,14 @@ void Foam::pointZone::operator=(const pointZone& zn)
 }
 
 
-void Foam::pointZone::operator=(const labelList& addr)
+void Foam::pointZone::operator=(const unallocLabelList& addr)
+{
+    clearAddressing();
+    labelList::operator=(addr);
+}
+
+
+void Foam::pointZone::operator=(const Xfer<labelList>& addr)
 {
     clearAddressing();
     labelList::operator=(addr);
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
index 22079a9407cf46706fc59a36640c1e5a7e6d5c9c..858dae3a95cf31fdb61491c5b711d67e0cafcfdf 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/pointZone/pointZone.H
@@ -112,7 +112,7 @@ public:
         pointZone
         (
             const word& name,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index,
             const pointZoneMesh&
         );
@@ -140,7 +140,7 @@ public:
         pointZone
         (
             const pointZone&,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index,
             const pointZoneMesh&
         );
@@ -170,7 +170,7 @@ public:
         (
             const pointZoneMesh& zm,
             const label index,
-            const labelList& addr
+            const unallocLabelList& addr
         ) const
         {
             return autoPtr<pointZone>
@@ -222,11 +222,14 @@ public:
 
     // Member Operators
 
-        //- Assign to zone clearing demand-driven data
+        //- Assign to zone, clearing demand-driven data
         void operator=(const pointZone&);
 
-        //- Assign addressing clearing demand-driven data
-        void operator=(const labelList&);
+        //- Assign addressing, clearing demand-driven data
+        void operator=(const unallocLabelList&);
+
+        //- Assign addressing, clearing demand-driven data
+        void operator=(const Xfer<labelList>&);
 
 
     // I-O
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C
index b97e28c937f3778272908cc0489f379d5cc93e1c..31af839b084d28ec77fa1011b42f01bc74a3328a 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.C
@@ -85,7 +85,7 @@ void Foam::zone::calcLookupMap() const
 Foam::zone::zone
 (
     const word& name,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const label index
 )
 :
@@ -128,7 +128,7 @@ Foam::zone::zone
 Foam::zone::zone
 (
     const zone& z,
-    const labelList& addr,
+    const unallocLabelList& addr,
     const label index
 )
 :
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
index 9bec4b6cdb8f8aefb00bb971b24c6ed26966466f..e7f3a920b15053a702e38ba7b244661a3dedea7c 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/zone/zone.H
@@ -101,7 +101,7 @@ public:
         zone
         (
             const word& name,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index
         );
 
@@ -127,7 +127,7 @@ public:
         zone
         (
             const zone&,
-            const labelList& addr,
+            const unallocLabelList& addr,
             const label index
         );
 
diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.C b/src/OpenFOAM/primitives/bools/Switch/Switch.C
index 0b87ca6e2764648ded5bc6113dde8fc88f9687cc..3a227f99b4a42fd69466a8d73e795ebb1bc7466c 100644
--- a/src/OpenFOAM/primitives/bools/Switch/Switch.C
+++ b/src/OpenFOAM/primitives/bools/Switch/Switch.C
@@ -37,6 +37,7 @@ const char* Foam::Switch::names[Foam::Switch::INVALID+1] =
     "off",   "on",
     "no",    "yes",
     "n",     "y",
+    "f",     "t",
     "none",  "true",  // is there a reasonable counterpart to "none"?
     "invalid"
 };
@@ -54,18 +55,39 @@ Foam::Switch::switchType Foam::Switch::asEnum
     {
         if (str == names[sw])
         {
-            // convert n/y to no/yes - perhaps should deprecate y/n
-            if (sw == Switch::NO_1 || sw == Switch::NONE)
+            // handle aliases
+            switch (sw)
             {
-                return Switch::NO;
-            }
-            else if (sw == Switch::YES_1)
-            {
-                return Switch::YES;
-            }
-            else
-            {
-                return switchType(sw);
+                case Switch::NO_1:
+                case Switch::NONE:
+                {
+                    return Switch::NO;
+                    break;
+                }
+
+                case Switch::YES_1:
+                {
+                    return Switch::YES;
+                    break;
+                }
+
+                case Switch::FALSE_1:
+                {
+                    return Switch::FALSE;
+                    break;
+                }
+
+                case Switch::TRUE_1:
+                {
+                    return Switch::TRUE;
+                    break;
+                }
+
+                default:
+                {
+                    return switchType(sw);
+                    break;
+                }
             }
         }
     }
diff --git a/src/OpenFOAM/primitives/bools/Switch/Switch.H b/src/OpenFOAM/primitives/bools/Switch/Switch.H
index e68be1a2de8db66503617be0dcc6d2308dfcf3af..027d313a0aa68258c728359a1907e0863bb7e2fd 100644
--- a/src/OpenFOAM/primitives/bools/Switch/Switch.H
+++ b/src/OpenFOAM/primitives/bools/Switch/Switch.H
@@ -26,7 +26,7 @@ Class
 
 Description
     A simple wrapper around bool so that it can be read as a word:
-    true/false, on/off, yes/no or y/n or none.
+    true/false, on/off, yes/no, y/n, t/f, or none.
 
 SourceFiles
     Switch.C
@@ -78,6 +78,8 @@ public:
         #undef YES
         #undef NO_1
         #undef YES_1
+        #undef FALSE_1
+        #undef TRUE_1
         #undef NONE
         #undef PLACEHOLDER
         #undef INVALID
@@ -86,11 +88,12 @@ public:
         //  These also correspond to the entries in names.
         enum switchType
         {
-            FALSE = 0,  TRUE  = 1,
-            OFF   = 2,  ON    = 3,
-            NO    = 4,  YES   = 5,
-            NO_1  = 6,  YES_1 = 7,
-            NONE  = 8,  PLACEHOLDER = 9,
+            FALSE   = 0,  TRUE   = 1,
+            OFF     = 2,  ON     = 3,
+            NO      = 4,  YES    = 5,
+            NO_1    = 6,  YES_1  = 7,
+            FALSE_1 = 8,  TRUE_1 = 9,
+            NONE    = 10, PLACEHOLDER = 11,
             INVALID
         };
 
diff --git a/src/OpenFOAM/primitives/strings/fileName/fileName.H b/src/OpenFOAM/primitives/strings/fileName/fileName.H
index dce6d6a90730e871073990a75a4ad782ed507642..8eae249c52ceba16c67bbf61481ac52332aeb3aa 100644
--- a/src/OpenFOAM/primitives/strings/fileName/fileName.H
+++ b/src/OpenFOAM/primitives/strings/fileName/fileName.H
@@ -93,6 +93,8 @@ public:
 
         static const char* const typeName;
         static int debug;
+
+        //- An empty fileName
         static const fileName null;
 
 
diff --git a/src/OpenFOAM/primitives/strings/keyType/keyTypeIO.C b/src/OpenFOAM/primitives/strings/keyType/keyType.C
similarity index 67%
rename from src/OpenFOAM/primitives/strings/keyType/keyTypeIO.C
rename to src/OpenFOAM/primitives/strings/keyType/keyType.C
index 9ba61ee510db713dd77080e3e24655cbe0cf361e..5f8c6956b748e117c08d7ac10fc372365bb606b2 100644
--- a/src/OpenFOAM/primitives/strings/keyType/keyTypeIO.C
+++ b/src/OpenFOAM/primitives/strings/keyType/keyType.C
@@ -22,24 +22,54 @@ License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
 Description
-    Istream constructor and IOstream operators for word.
+    Istream constructor and IOstream operators for keyType.
 
 \*---------------------------------------------------------------------------*/
 
 #include "keyType.H"
+#include "regExp.H"
 #include "IOstreams.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::keyType Foam::keyType::null;
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::keyType::keyType(Istream& is)
 :
-    word()
+    word(),
+    isPattern_(false)
+{
+    is  >> *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::keyType::match
+(
+    const std::string& str,
+    bool literalMatch
+) const
 {
-    is >> *this;
+    if (literalMatch || !isPattern_)
+    {
+        // check as string
+        return (str == *this);
+    }
+    else
+    {
+        // check as regex
+        return regExp(*this).match(str);
+    }
 }
 
 
-Foam::Istream& Foam::operator>>(Istream& is, keyType& w)
+// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
+
+Foam::Istream& Foam::operator>>(Istream& is, keyType& kw)
 {
     token t(is);
 
@@ -51,15 +81,16 @@ Foam::Istream& Foam::operator>>(Istream& is, keyType& w)
 
     if (t.isWord())
     {
-        w = t.wordToken();
+        kw = t.wordToken();
     }
     else if (t.isString())
     {
-        // Assign from string. Sets regular expression.
-        w = t.stringToken();
+        // Assign from string. Set as regular expression.
+        kw = t.stringToken();
+        kw.isPattern_ = true;
 
         // flag empty strings as an error
-        if (w.empty())
+        if (kw.empty())
         {
             is.setBad();
             FatalIOErrorIn("operator>>(Istream&, keyType&)", is)
@@ -86,9 +117,9 @@ Foam::Istream& Foam::operator>>(Istream& is, keyType& w)
 }
 
 
-Foam::Ostream& Foam::operator<<(Ostream& os, const keyType& w)
+Foam::Ostream& Foam::operator<<(Ostream& os, const keyType& kw)
 {
-    os.write(w);
+    os.write(kw);
     os.check("Ostream& operator<<(Ostream&, const keyType&)");
     return os;
 }
diff --git a/src/OpenFOAM/primitives/strings/keyType/keyType.H b/src/OpenFOAM/primitives/strings/keyType/keyType.H
index 8cf22f9473b8832be0d4397a926b22ae2c14262c..964044150fcaf45c81c125118b1f6e35463f5c0f 100644
--- a/src/OpenFOAM/primitives/strings/keyType/keyType.H
+++ b/src/OpenFOAM/primitives/strings/keyType/keyType.H
@@ -32,7 +32,6 @@ Description
 
 SourceFiles
     keyType.C
-    keyTypeIO.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -52,14 +51,14 @@ class Ostream;
 
 
 /*---------------------------------------------------------------------------*\
-                          Class keyType Declaration
+                           Class keyType Declaration
 \*---------------------------------------------------------------------------*/
 
 class keyType
 :
     public word
 {
-    // Private member data
+    // Private data
 
         //- Is the keyType a pattern (regular expression)
         bool isPattern_;
@@ -71,6 +70,11 @@ class keyType
 
 public:
 
+    // Static data members
+
+        //- An empty keyType
+        static const keyType null;
+
 
     // Constructors
 
@@ -80,19 +84,21 @@ public:
         //- Construct as copy
         inline keyType(const keyType&);
 
-        //- Construct as copy of word
+        //- Construct as copy of word. Not treated as a regular expression
         inline keyType(const word&);
 
-        //- Construct as copy of string. Expect it to be regular expression.
+        //- Construct as copy of string. Treat as regular expression.
         inline keyType(const string&);
 
-        //- Construct as copy of character array
+        //- Construct as copy of character array.
+        //  Not treated as a regular expression
         inline keyType(const char*);
 
-        //- Construct as copy of std::string
+        //- Construct as copy of std::string with specified treatment
         inline keyType(const std::string&, const bool isPattern);
 
         //- Construct from Istream
+        //  Treat as regular expression if surrounded by quotation marks.
         keyType(Istream&);
 
 
@@ -101,15 +107,24 @@ public:
         //- Should be treated as a match rather than a literal string
         inline bool isPattern() const;
 
+        //- Smart match as regular expression or as a string
+        //  Optionally force a literal match only
+        bool match(const std::string&, bool literalMatch=false) const;
+
     // Member operators
 
         // Assignment
 
+            //- Assignment operator
             inline const keyType& operator=(const keyType&);
+
+            //- Assign as word, not as non regular expression
             inline const keyType& operator=(const word&);
 
-            //- Assign from regular expression.
+            //- Assign as regular expression
             inline const keyType& operator=(const string&);
+
+            //- Assign as word, not as non regular expression
             inline const keyType& operator=(const char*);
 
 
diff --git a/src/OpenFOAM/primitives/strings/keyType/keyTypeI.H b/src/OpenFOAM/primitives/strings/keyType/keyTypeI.H
index 653ea8786ef4deceaec95196dfe9135ab623b20f..72752f3ddd34dc79174db2951fdba472febcf168 100644
--- a/src/OpenFOAM/primitives/strings/keyType/keyTypeI.H
+++ b/src/OpenFOAM/primitives/strings/keyType/keyTypeI.H
@@ -23,10 +23,6 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 inline Foam::keyType::keyType()
@@ -50,7 +46,6 @@ inline Foam::keyType::keyType(const word& s)
 {}
 
 
-// Construct as copy of string. Expect it to be regular expression
 inline Foam::keyType::keyType(const string& s)
 :
     word(s, false),
@@ -58,7 +53,6 @@ inline Foam::keyType::keyType(const string& s)
 {}
 
 
-// Construct as copy of character array
 inline Foam::keyType::keyType(const char* s)
 :
     word(s, false),
@@ -66,7 +60,6 @@ inline Foam::keyType::keyType(const char* s)
 {}
 
 
-//- Construct as copy of std::string
 inline Foam::keyType::keyType
 (
     const std::string& s,
diff --git a/src/OpenFOAM/primitives/strings/string/string.H b/src/OpenFOAM/primitives/strings/string/string.H
index fe50c5b530f12f9042cbeb00d961b82b26ba549f..254ffbba0f9e608ff77a610148b27c30c0dea9f5 100644
--- a/src/OpenFOAM/primitives/strings/string/string.H
+++ b/src/OpenFOAM/primitives/strings/string/string.H
@@ -82,6 +82,8 @@ public:
 
         static const char* const typeName;
         static int debug;
+
+        //- An empty string
         static const string null;
 
 
@@ -143,6 +145,9 @@ public:
         template<class String>
         static inline string quotemeta(const string&, const char quote='\\');
 
+        //- True when strings match literally
+        inline bool match(const std::string&) const;
+
         //- Avoid masking the normal std::string replace
         using std::string::replace;
 
diff --git a/src/OpenFOAM/primitives/strings/string/stringI.H b/src/OpenFOAM/primitives/strings/string/stringI.H
index 70a8b6f972d8e52cc6cb34d3c813269107c1922a..83f4ed0c45bdc036db5650bf8349e54cdb706242 100644
--- a/src/OpenFOAM/primitives/strings/string/stringI.H
+++ b/src/OpenFOAM/primitives/strings/string/stringI.H
@@ -176,6 +176,12 @@ inline String Foam::string::validate(const string& str)
     return ss;
 }
 
+inline bool Foam::string::match(const std::string& str) const
+{
+    // check as string
+    return (str == *this);
+}
+
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/primitives/strings/word/word.H b/src/OpenFOAM/primitives/strings/word/word.H
index a30eb10d1bccf315e00fae1588eb25dc77036412..032803084dca6644a2c2df3ee215ce5212325474 100644
--- a/src/OpenFOAM/primitives/strings/word/word.H
+++ b/src/OpenFOAM/primitives/strings/word/word.H
@@ -73,6 +73,8 @@ public:
 
         static const char* const typeName;
         static int debug;
+
+        //- An empty word
         static const word null;
 
 
diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordReIO.C b/src/OpenFOAM/primitives/strings/wordRe/wordRe.C
similarity index 91%
rename from src/OpenFOAM/primitives/strings/wordRe/wordReIO.C
rename to src/OpenFOAM/primitives/strings/wordRe/wordRe.C
index eff08be77b0ac93d0afb18f1aede40073cd0fb17..693ae0535dbffb97ed6c5eb1499584a75a58b679 100644
--- a/src/OpenFOAM/primitives/strings/wordRe/wordReIO.C
+++ b/src/OpenFOAM/primitives/strings/wordRe/wordRe.C
@@ -27,7 +27,12 @@ License
 #include "IOstreams.H"
 #include "InfoProxy.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::wordRe Foam::wordRe::null;
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::wordRe::wordRe(Istream& is)
 :
@@ -38,6 +43,8 @@ Foam::wordRe::wordRe(Istream& is)
 }
 
 
+// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
+
 Foam::Istream& Foam::operator>>(Istream& is, wordRe& w)
 {
     token t(is);
diff --git a/src/OpenFOAM/primitives/strings/wordRe/wordRe.H b/src/OpenFOAM/primitives/strings/wordRe/wordRe.H
index 99bfb1188a39672eac85e3fb112f3ac3ed16a165..16d86b7fcfccc2ab66f761a51143e3e8ceea48a4 100644
--- a/src/OpenFOAM/primitives/strings/wordRe/wordRe.H
+++ b/src/OpenFOAM/primitives/strings/wordRe/wordRe.H
@@ -44,7 +44,6 @@ Note
 
 SourceFiles
     wordRe.C
-    wordReIO.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -84,6 +83,12 @@ class wordRe
 
 public:
 
+    // Static data members
+
+        //- An empty wordRe
+        static const wordRe null;
+
+
     // Public data types
 
         //- Enumeration with compile options
@@ -168,7 +173,7 @@ public:
     //- Searching
 
         //- Smart match as regular expression or as a string
-        //  Optionally specify a literal match only
+        //  Optionally force a literal match only
         inline bool match(const std::string&, bool literalMatch=false) const;
 
     //- Miscellaneous
diff --git a/src/finiteVolume/cfdTools/general/porousMedia/PorousZones.C b/src/finiteVolume/cfdTools/general/porousMedia/PorousZones.C
index 1bb5a0954a88bc3aba2744cce28224b0dfa7326c..aea310c4e27b8de6254fa4e268a413f18e39e886 100644
--- a/src/finiteVolume/cfdTools/general/porousMedia/PorousZones.C
+++ b/src/finiteVolume/cfdTools/general/porousMedia/PorousZones.C
@@ -143,7 +143,7 @@ void Foam::PorousZones<ZoneType>::addResistance
 ) const
 {
     // addResistance for each zone, delaying the correction of the
-    // precessor BCs of AU
+    // processor BCs of AU
     forAll(*this, i)
     {
         this->operator[](i).addResistance(UEqn, AU, false);
diff --git a/src/finiteVolume/cfdTools/general/porousMedia/porousZone.C b/src/finiteVolume/cfdTools/general/porousMedia/porousZone.C
index 4e1020a4f10d6c464662c5b1267d0db62d07e460..e973971fcbd52ccf21f834a82368fe4f8c2c5053 100644
--- a/src/finiteVolume/cfdTools/general/porousMedia/porousZone.C
+++ b/src/finiteVolume/cfdTools/general/porousMedia/porousZone.C
@@ -27,7 +27,6 @@ License
 #include "fvMesh.H"
 #include "fvMatrices.H"
 #include "geometricOneField.H"
-#include "stringListOps.H"
 
 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
 
diff --git a/src/finiteVolume/cfdTools/general/porousMedia/porousZoneTemplates.C b/src/finiteVolume/cfdTools/general/porousMedia/porousZoneTemplates.C
index 4e72859f8005338cd0bd7b148a9284e0a89267d2..28bb7523494f7f4d8c29c0965705b0ff6e9d3a62 100644
--- a/src/finiteVolume/cfdTools/general/porousMedia/porousZoneTemplates.C
+++ b/src/finiteVolume/cfdTools/general/porousMedia/porousZoneTemplates.C
@@ -66,7 +66,7 @@ void Foam::porousZone::addPowerLawResistance
         forAll(cells, i)
         {
             Udiag[cells[i]] +=
-            V[cells[i]]*rho[cells[i]]*C0*pow(magSqr(U[cells[i]]), C1m1b2);
+                V[cells[i]]*rho[cells[i]]*C0*pow(magSqr(U[cells[i]]), C1m1b2);
         }
     }
 }
diff --git a/src/meshTools/indexedOctree/indexedOctree.H b/src/meshTools/indexedOctree/indexedOctree.H
index 6d7f42517693e59451720fe768eafb6a51ce463c..d82603ab4f40ddb98008d900455bf0a34dbf2f2d 100644
--- a/src/meshTools/indexedOctree/indexedOctree.H
+++ b/src/meshTools/indexedOctree/indexedOctree.H
@@ -164,8 +164,8 @@ private:
 
         // Construction
 
-            //- Split list of indices into 8 bins according to where they are in
-            //  relation to mid.
+            //- Split list of indices into 8 bins
+            //  according to where they are in relation to mid.
             void divide
             (
                 const labelList& indices,
@@ -173,8 +173,8 @@ private:
                 labelListList& result
             ) const;
 
-            //- Subdivide the contents node at position contentI. Appends to
-            //  contents.
+            //- Subdivide the contents node at position contentI.
+            //  Appends to contents.
             node divide
             (
                 const treeBoundBox& bb,
diff --git a/src/meshTools/indexedOctree/treeDataCell.C b/src/meshTools/indexedOctree/treeDataCell.C
index 87b5dde12388bde1b1fa3c120c266792f8ed016f..8492f59c4f8cfe7436a05c42c05c4e9d18d4cdda 100644
--- a/src/meshTools/indexedOctree/treeDataCell.C
+++ b/src/meshTools/indexedOctree/treeDataCell.C
@@ -64,29 +64,49 @@ Foam::treeBoundBox Foam::treeDataCell::calcCellBb(const label cellI) const
 }
 
 
+void Foam::treeDataCell::update()
+{
+    if (cacheBb_)
+    {
+        bbs_.setSize(cellLabels_.size());
+
+        forAll(cellLabels_, i)
+        {
+            bbs_[i] = calcCellBb(cellLabels_[i]);
+        }
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 Foam::treeDataCell::treeDataCell
 (
     const bool cacheBb,
     const primitiveMesh& mesh,
-    const labelList& cellLabels
+    const unallocLabelList& cellLabels
 )
 :
     mesh_(mesh),
     cellLabels_(cellLabels),
     cacheBb_(cacheBb)
 {
-    if (cacheBb_)
-    {
-        bbs_.setSize(cellLabels_.size());
+    update();
+}
 
-        forAll(cellLabels_, i)
-        {
-            bbs_[i] = calcCellBb(cellLabels_[i]);
-        }
-    }
+
+Foam::treeDataCell::treeDataCell
+(
+    const bool cacheBb,
+    const primitiveMesh& mesh,
+    const Xfer<labelList>& cellLabels
+)
+:
+    mesh_(mesh),
+    cellLabels_(cellLabels),
+    cacheBb_(cacheBb)
+{
+    update();
 }
 
 
@@ -100,15 +120,7 @@ Foam::treeDataCell::treeDataCell
     cellLabels_(identity(mesh_.nCells())),
     cacheBb_(cacheBb)
 {
-    if (cacheBb_)
-    {
-        bbs_.setSize(cellLabels_.size());
-
-        forAll(cellLabels_, i)
-        {
-            bbs_[i] = calcCellBb(cellLabels_[i]);
-        }
-    }
+    update();
 }
 
 
@@ -159,7 +171,7 @@ bool Foam::treeDataCell::contains
 // nearestPoint.
 void Foam::treeDataCell::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const point& sample,
 
     scalar& nearestDistSqr,
diff --git a/src/meshTools/indexedOctree/treeDataCell.H b/src/meshTools/indexedOctree/treeDataCell.H
index 7e42a6d9066a3e0dcc4b092674d92c9620a5fb07..4bf5ddb5c2379d33f23610a53bd23afa73754075 100644
--- a/src/meshTools/indexedOctree/treeDataCell.H
+++ b/src/meshTools/indexedOctree/treeDataCell.H
@@ -48,7 +48,7 @@ class primitiveMesh;
 template<class Type> class indexedOctree;
 
 /*---------------------------------------------------------------------------*\
-                           Class treeDataCell Declaration
+                        Class treeDataCell Declaration
 \*---------------------------------------------------------------------------*/
 
 class treeDataCell
@@ -72,6 +72,9 @@ class treeDataCell
         //- Calculate cell bounding box
         treeBoundBox calcCellBb(const label cellI) const;
 
+        //- Initialise all member data
+        void update();
+
 public:
 
     // Declare name of the class and its debug switch
@@ -85,7 +88,15 @@ public:
         (
             const bool cacheBb,
             const primitiveMesh&,
-            const labelList&
+            const unallocLabelList&
+        );
+
+        //- Construct from mesh and subset of cells, transferring contents
+        treeDataCell
+        (
+            const bool cacheBb,
+            const primitiveMesh&,
+            const Xfer<labelList>&
         );
 
         //- Construct from mesh. Uses all cells in mesh.
@@ -96,18 +107,18 @@ public:
 
         // Access
 
-            const labelList& cellLabels() const
+            inline const labelList& cellLabels() const
             {
                 return cellLabels_;
             }
 
-            const primitiveMesh& mesh() const
+            inline const primitiveMesh& mesh() const
             {
                 return mesh_;
             }
 
 
-            label size() const
+            inline label size() const
             {
                 return cellLabels_.size();
             }
@@ -153,7 +164,7 @@ public:
             //  Returns actual point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const point& sample,
 
                 scalar& nearestDistSqr,
@@ -165,7 +176,7 @@ public:
             //  Returns point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const linePointRef& ln,
 
                 treeBoundBox& tightest,
@@ -177,7 +188,7 @@ public:
                 notImplemented
                 (
                     "treeDataCell::findNearest"
-                    "(const labelList&, const linePointRef&, ..)"
+                    "(const unallocLabelList&, const linePointRef&, ..)"
                 );
             }
 
diff --git a/src/meshTools/indexedOctree/treeDataEdge.C b/src/meshTools/indexedOctree/treeDataEdge.C
index 0adc3b781cc097098c7368cb0370a35a60a3d5e4..0a65f8ece811c654f65dc1685ada1ee25208e6d1 100644
--- a/src/meshTools/indexedOctree/treeDataEdge.C
+++ b/src/meshTools/indexedOctree/treeDataEdge.C
@@ -43,15 +43,28 @@ Foam::treeBoundBox Foam::treeDataEdge::calcBb(const label edgeI) const
 }
 
 
+void Foam::treeDataEdge::update()
+{
+    if (cacheBb_)
+    {
+        bbs_.setSize(edgeLabels_.size());
+
+        forAll(edgeLabels_, i)
+        {
+            bbs_[i] = calcBb(edgeLabels_[i]);
+        }
+    }
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 Foam::treeDataEdge::treeDataEdge
 (
     const bool cacheBb,
     const edgeList& edges,
     const pointField& points,
-    const labelList& edgeLabels
+    const unallocLabelList& edgeLabels
 )
 :
     edges_(edges),
@@ -59,15 +72,24 @@ Foam::treeDataEdge::treeDataEdge
     edgeLabels_(edgeLabels),
     cacheBb_(cacheBb)
 {
-    if (cacheBb_)
-    {
-        bbs_.setSize(edgeLabels_.size());
+    update();
+}
 
-        forAll(edgeLabels_, i)
-        {
-            bbs_[i] = calcBb(edgeLabels_[i]);
-        }
-    }
+
+Foam::treeDataEdge::treeDataEdge
+(
+    const bool cacheBb,
+    const edgeList& edges,
+    const pointField& points,
+    const Xfer<labelList>& edgeLabels
+)
+:
+    edges_(edges),
+    points_(points),
+    edgeLabels_(edgeLabels),
+    cacheBb_(cacheBb)
+{
+    update();
 }
 
 
@@ -121,7 +143,7 @@ bool Foam::treeDataEdge::overlaps
 // nearestPoint.
 void Foam::treeDataEdge::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const point& sample,
 
     scalar& nearestDistSqr,
@@ -131,7 +153,7 @@ void Foam::treeDataEdge::findNearest
 {
     forAll(indices, i)
     {
-        label index = indices[i];
+        const label index = indices[i];
 
         const edge& e = edges_[edgeLabels_[index]];
 
@@ -153,7 +175,7 @@ void Foam::treeDataEdge::findNearest
 //  Returns point and distance (squared)
 void Foam::treeDataEdge::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const linePointRef& ln,
 
     treeBoundBox& tightest,
@@ -167,7 +189,7 @@ void Foam::treeDataEdge::findNearest
 
     forAll(indices, i)
     {
-        label index = indices[i];
+        const label index = indices[i];
 
         const edge& e = edges_[edgeLabels_[index]];
 
diff --git a/src/meshTools/indexedOctree/treeDataEdge.H b/src/meshTools/indexedOctree/treeDataEdge.H
index 68f3a5924a3602900dfd2fafd735c05b329ee453..8b7e54879fad4f58a0a0013c6e64de273ccc5dca 100644
--- a/src/meshTools/indexedOctree/treeDataEdge.H
+++ b/src/meshTools/indexedOctree/treeDataEdge.H
@@ -81,6 +81,9 @@ class treeDataEdge
         //- Calculate edge bounding box
         treeBoundBox calcBb(const label edgeI) const;
 
+        //- Initialise all member data
+        void update();
+
 public:
 
     // Declare name of the class and its debug switch
@@ -95,7 +98,17 @@ public:
             const bool cacheBb,
             const edgeList& edges,
             const pointField& points,
-            const labelList& edgeLabels
+            const unallocLabelList& edgeLabels
+        );
+
+        //- Construct from selected edges, transferring contents.
+        // !Holds references to edges and points
+        treeDataEdge
+        (
+            const bool cacheBb,
+            const edgeList& edges,
+            const pointField& points,
+            const Xfer<labelList>& edgeLabels
         );
 
 
@@ -139,7 +152,7 @@ public:
             //  Returns actual point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const point& sample,
 
                 scalar& nearestDistSqr,
@@ -151,7 +164,7 @@ public:
             //  Returns point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const linePointRef& ln,
 
                 treeBoundBox& tightest,
diff --git a/src/meshTools/indexedOctree/treeDataFace.C b/src/meshTools/indexedOctree/treeDataFace.C
index bf2bd722e5bc51d8e70ab79355061ce9b6f40710..f8273bec03a5fb0220bf01e9381d109365332f7b 100644
--- a/src/meshTools/indexedOctree/treeDataFace.C
+++ b/src/meshTools/indexedOctree/treeDataFace.C
@@ -76,12 +76,27 @@ void Foam::treeDataFace::update()
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 Foam::treeDataFace::treeDataFace
 (
     const bool cacheBb,
     const primitiveMesh& mesh,
-    const labelList& faceLabels
+    const unallocLabelList& faceLabels
+)
+:
+    mesh_(mesh),
+    faceLabels_(faceLabels),
+    isTreeFace_(mesh.nFaces(), 0),
+    cacheBb_(cacheBb)
+{
+    update();
+}
+
+
+Foam::treeDataFace::treeDataFace
+(
+    const bool cacheBb,
+    const primitiveMesh& mesh,
+    const Xfer<labelList>& faceLabels
 )
 :
     mesh_(mesh),
@@ -467,7 +482,7 @@ bool Foam::treeDataFace::overlaps
 // nearestPoint.
 void Foam::treeDataFace::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const point& sample,
 
     scalar& nearestDistSqr,
@@ -477,7 +492,7 @@ void Foam::treeDataFace::findNearest
 {
     forAll(indices, i)
     {
-        label index = indices[i];
+        const label index = indices[i];
 
         const face& f = mesh_.faces()[faceLabels_[index]];
 
@@ -514,7 +529,7 @@ bool Foam::treeDataFace::intersects
         }
     }
 
-    label faceI = faceLabels_[index];
+    const label faceI = faceLabels_[index];
 
     const vector dir(end - start);
 
diff --git a/src/meshTools/indexedOctree/treeDataFace.H b/src/meshTools/indexedOctree/treeDataFace.H
index 4337f1b78d24ecd72ee3942a6f34aa9b81576b6d..6dbb881dbb5b70715d80a7c854f1f02fda84da94 100644
--- a/src/meshTools/indexedOctree/treeDataFace.H
+++ b/src/meshTools/indexedOctree/treeDataFace.H
@@ -51,7 +51,7 @@ class primitiveMesh;
 class polyPatch;
 
 /*---------------------------------------------------------------------------*\
-                           Class treeDataFace Declaration
+                        Class treeDataFace Declaration
 \*---------------------------------------------------------------------------*/
 
 class treeDataFace
@@ -101,7 +101,15 @@ public:
         (
             const bool cacheBb,
             const primitiveMesh&,
-            const labelList&
+            const unallocLabelList&
+        );
+
+        //- Construct from mesh and subset of faces, transferring contents
+        treeDataFace
+        (
+            const bool cacheBb,
+            const primitiveMesh&,
+            const Xfer<labelList>&
         );
 
         //- Construct from mesh. Uses all faces in mesh.
@@ -115,17 +123,17 @@ public:
 
         // Access
 
-            const labelList& faceLabels() const
+            inline const labelList& faceLabels() const
             {
                 return faceLabels_;
             }
 
-            const primitiveMesh& mesh() const
+            inline const primitiveMesh& mesh() const
             {
                 return mesh_;
             }
 
-            label size() const
+            inline label size() const
             {
                 return faceLabels_.size();
             }
@@ -156,7 +164,7 @@ public:
             //  Returns actual point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const point& sample,
 
                 scalar& nearestDistSqr,
@@ -168,7 +176,7 @@ public:
             //  Returns point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const linePointRef& ln,
 
                 treeBoundBox& tightest,
@@ -180,7 +188,7 @@ public:
                 notImplemented
                 (
                     "treeDataFace::findNearest"
-                    "(const labelList&, const linePointRef&, ..)"
+                    "(const unallocLabelList&, const linePointRef&, ..)"
                 );
             }
 
diff --git a/src/meshTools/indexedOctree/treeDataPoint.C b/src/meshTools/indexedOctree/treeDataPoint.C
index db5f61e00105498d94c2f1eced81464cac87d3a9..ffdbfdd4e091b0777aa5be7fc38cd5ce842a51e5 100644
--- a/src/meshTools/indexedOctree/treeDataPoint.C
+++ b/src/meshTools/indexedOctree/treeDataPoint.C
@@ -36,7 +36,6 @@ defineTypeNameAndDebug(Foam::treeDataPoint, 0);
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 Foam::treeDataPoint::treeDataPoint(const pointField& points)
 :
     points_(points)
@@ -78,7 +77,7 @@ bool Foam::treeDataPoint::overlaps
 // nearestPoint.
 void Foam::treeDataPoint::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const point& sample,
 
     scalar& nearestDistSqr,
@@ -88,7 +87,7 @@ void Foam::treeDataPoint::findNearest
 {
     forAll(indices, i)
     {
-        label index = indices[i];
+        const label index = indices[i];
 
         const point& pt = points_[index];
 
@@ -108,7 +107,7 @@ void Foam::treeDataPoint::findNearest
 //  Returns point and distance (squared)
 void Foam::treeDataPoint::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const linePointRef& ln,
 
     treeBoundBox& tightest,
@@ -122,7 +121,7 @@ void Foam::treeDataPoint::findNearest
 
     forAll(indices, i)
     {
-        label index = indices[i];
+        const label index = indices[i];
 
         const point& shapePt = points_[index];
 
diff --git a/src/meshTools/indexedOctree/treeDataPoint.H b/src/meshTools/indexedOctree/treeDataPoint.H
index c2522120f7c1302d30b9006ed4dcbd8d910f2dd9..236f8139b8dd38f457b2e8408e645b3f9f3e6386 100644
--- a/src/meshTools/indexedOctree/treeDataPoint.H
+++ b/src/meshTools/indexedOctree/treeDataPoint.H
@@ -69,14 +69,14 @@ public:
     // Constructors
 
         //- Construct from components. Holds reference to points!
-        treeDataPoint(const pointField& points);
+        treeDataPoint(const pointField&);
 
 
     // Member Functions
 
         // Access
 
-            label size() const
+            inline label size() const
             {
                 return points_.size();
             }
@@ -107,7 +107,7 @@ public:
             //  Returns actual point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const point& sample,
 
                 scalar& nearestDistSqr,
@@ -119,7 +119,7 @@ public:
             //  Returns point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const linePointRef& ln,
 
                 treeBoundBox& tightest,
diff --git a/src/meshTools/indexedOctree/treeDataPrimitivePatch.C b/src/meshTools/indexedOctree/treeDataPrimitivePatch.C
index ec4bcb543749faca214b7ab973fff7b2ae7c0d21..8fc75b77c500f168f206b89c2942b3d6d09f7bb5 100644
--- a/src/meshTools/indexedOctree/treeDataPrimitivePatch.C
+++ b/src/meshTools/indexedOctree/treeDataPrimitivePatch.C
@@ -477,7 +477,7 @@ void
 Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
 findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const point& sample,
 
     scalar& nearestDistSqr,
@@ -489,7 +489,7 @@ findNearest
 
     forAll(indices, i)
     {
-        label index = indices[i];
+        const label index = indices[i];
 
         const face& f = patch_[index];
 
diff --git a/src/meshTools/indexedOctree/treeDataPrimitivePatch.H b/src/meshTools/indexedOctree/treeDataPrimitivePatch.H
index cf7b0cb1eb8342b535516a7e074128a777b81bac..7c3757504b63cf07c8a4460fd72bd50027ee68d9 100644
--- a/src/meshTools/indexedOctree/treeDataPrimitivePatch.H
+++ b/src/meshTools/indexedOctree/treeDataPrimitivePatch.H
@@ -56,7 +56,7 @@ TemplateName(treeDataPrimitivePatch);
 
 
 /*---------------------------------------------------------------------------*\
-                           Class treeDataPrimitivePatch Declaration
+                   Class treeDataPrimitivePatch Declaration
 \*---------------------------------------------------------------------------*/
 
 template
@@ -151,7 +151,7 @@ public:
             //  Returns actual point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const point& sample,
 
                 scalar& nearestDistSqr,
@@ -163,7 +163,7 @@ public:
             //  Returns point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const linePointRef& ln,
 
                 treeBoundBox& tightest,
@@ -175,7 +175,7 @@ public:
                 notImplemented
                 (
                     "treeDataPrimitivePatch::findNearest"
-                    "(const labelList&, const linePointRef&, ..)"
+                    "(const unallocLabelList&, const linePointRef&, ..)"
                 );
             }
 
diff --git a/src/meshTools/indexedOctree/treeDataTriSurface.C b/src/meshTools/indexedOctree/treeDataTriSurface.C
index e0afe06906adc7e5544491dd2f0357efbf8e7d11..e0f6d1a9df32cd37591245158e4fbce0620d0878 100644
--- a/src/meshTools/indexedOctree/treeDataTriSurface.C
+++ b/src/meshTools/indexedOctree/treeDataTriSurface.C
@@ -313,7 +313,7 @@ bool Foam::treeDataTriSurface::overlaps
 // nearestPoint.
 void Foam::treeDataTriSurface::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const point& sample,
 
     scalar& nearestDistSqr,
@@ -396,7 +396,7 @@ void Foam::treeDataTriSurface::findNearest
 // nearestPoint.
 void Foam::treeDataTriSurface::findNearest
 (
-    const labelList& indices,
+    const unallocLabelList& indices,
     const linePointRef& ln,
 
     treeBoundBox& tightest,
@@ -407,7 +407,7 @@ void Foam::treeDataTriSurface::findNearest
 {
     notImplemented
     (
-        "treeDataTriSurface::findNearest(const labelList&"
+        "treeDataTriSurface::findNearest(const unallocLabelList&"
         ", const linePointRef&, treeBoundBox&, label&, point&, point&) const"
     );
 }
diff --git a/src/meshTools/indexedOctree/treeDataTriSurface.H b/src/meshTools/indexedOctree/treeDataTriSurface.H
index 88f92c0ba4e35d8d411cd68f4e4ee997a14bef08..f602783afefe17913cd2484dd631f587245fd80a 100644
--- a/src/meshTools/indexedOctree/treeDataTriSurface.H
+++ b/src/meshTools/indexedOctree/treeDataTriSurface.H
@@ -91,12 +91,12 @@ public:
 
         // Access
 
-            const triSurface& surface() const
+            inline const triSurface& surface() const
             {
                 return surface_;
             }
 
-            label size() const
+            inline label size() const
             {
                 return surface_.size();
             }
@@ -127,7 +127,7 @@ public:
             //  Returns actual point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const point& sample,
 
                 scalar& nearestDistSqr,
@@ -139,7 +139,7 @@ public:
             //  Returns point and distance (squared)
             void findNearest
             (
-                const labelList& indices,
+                const unallocLabelList& indices,
                 const linePointRef& ln,
 
                 treeBoundBox& tightest,
diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C
index a3fe57cb4a9d4ee7e32708b6e6426a446aacdc36..b777edbdb3c1a0d99713ed601ba0f664e9e313d3 100644
--- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C
+++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C
@@ -290,20 +290,17 @@ Foam::distanceSurface::distanceSurface
     signed_(readBool(dict.lookup("signed"))),
     regularise_(dict.lookupOrDefault("regularise", true)),
     average_(dict.lookupOrDefault("average", false)),
-    zoneName_(word::null),
+    zoneKey_(keyType::null),
     needsUpdate_(true),
     isoSurfPtr_(NULL),
     facesPtr_(NULL)
 {
-//    dict.readIfPresent("zone", zoneName_);
+//    dict.readIfPresent("zone", zoneKey_);
 //
-//    if (debug && zoneName_.size())
+//    if (debug && zoneKey_.size() && mesh.cellZones().findZoneID(zoneKey_) < 0)
 //    {
-//        if (mesh.cellZones().findZoneID(zoneName_) < 0)
-//        {
-//            Info<< "cellZone \"" << zoneName_
-//                << "\" not found - using entire mesh" << endl;
-//        }
+//        Info<< "cellZone " << zoneKey_
+//            << " not found - using entire mesh" << endl;
 //    }
 }
 
diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
index a5b7fe8bda5959ad63e1c9c72304a657adf1d66c..5f777cbacfd01fc091a09189b13d8fd64190e45f 100644
--- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
+++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
@@ -70,8 +70,8 @@ class distanceSurface
         //- Whether to recalculate cell values as average of point values
         const Switch average_;
 
-        //- zone name (if restricted to zones)
-        word zoneName_;
+        //- If restricted to zones, name of this zone or a regular expression
+        keyType zoneKey_;
 
         //- Track if the surface needs an update
         mutable bool needsUpdate_;
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C
index e77d6f74c799f28d7224398f7459414bb5bace68..155e12bbd225213dc706d71acaa1d423b8da2d60 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.C
@@ -205,20 +205,17 @@ Foam::sampledIsoSurfaceCell::sampledIsoSurfaceCell
     isoVal_(readScalar(dict.lookup("isoValue"))),
     regularise_(dict.lookupOrDefault("regularise", true)),
     average_(dict.lookupOrDefault("average", true)),
-    zoneName_(word::null),
+    zoneKey_(keyType::null),
     facesPtr_(NULL),
     prevTimeIndex_(-1),
     meshCells_(0)
 {
-//    dict.readIfPresent("zone", zoneName_);
+//    dict.readIfPresent("zone", zoneKey_);
 //
-//    if (debug && zoneName_.size())
+//    if (debug && zoneKey_.size() && mesh.cellZones().findZoneID(zoneKey_) < 0)
 //    {
-//        if (mesh.cellZones().findZoneID(zoneName_) < 0)
-//        {
-//            Info<< "cellZone \"" << zoneName_
-//                << "\" not found - using entire mesh" << endl;
-//        }
+//        Info<< "cellZone " << zoneKey_
+//            << " not found - using entire mesh" << endl;
 //    }
 }
 
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H
index b779b65e0358f52016652c32e500aff1204ac950..837b3bab76d6569655e752112f2d2ecf3f1b4ef1 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceCell.H
@@ -68,8 +68,8 @@ class sampledIsoSurfaceCell
         //- Whether to recalculate cell values as average of point values
         const Switch average_;
 
-        //- zone name (if restricted to zones)
-        word zoneName_;
+        //- If restricted to zones, name of this zone or a regular expression
+        keyType zoneKey_;
 
         //- triangles converted to faceList
         mutable autoPtr<faceList> facesPtr_;
diff --git a/src/sampling/sampledSurface/sampledPlane/sampledPlane.C b/src/sampling/sampledSurface/sampledPlane/sampledPlane.C
index 3fb02e57c4b6ef62c0be02420c368106b0ce32b3..6c8e0f91a7a0ecd4cf90c08f830c20782cfea183 100644
--- a/src/sampling/sampledSurface/sampledPlane/sampledPlane.C
+++ b/src/sampling/sampledSurface/sampledPlane/sampledPlane.C
@@ -45,21 +45,18 @@ Foam::sampledPlane::sampledPlane
     const word& name,
     const polyMesh& mesh,
     const plane& planeDesc,
-    const word& zoneName
+    const keyType& zoneKey
 )
 :
     sampledSurface(name, mesh),
     cuttingPlane(planeDesc),
-    zoneName_(zoneName),
+    zoneKey_(zoneKey),
     needsUpdate_(true)
 {
-    if (debug && zoneName_.size())
+    if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) < 0)
     {
-        if (mesh.cellZones().findZoneID(zoneName_) < 0)
-        {
-            Info<< "cellZone \"" << zoneName_
-                << "\" not found - using entire mesh" << endl;
-        }
+        Info<< "cellZone " << zoneKey_
+            << " not found - using entire mesh" << endl;
     }
 }
 
@@ -73,7 +70,7 @@ Foam::sampledPlane::sampledPlane
 :
     sampledSurface(name, mesh, dict),
     cuttingPlane(plane(dict.lookup("basePoint"), dict.lookup("normalVector"))),
-    zoneName_(word::null),
+    zoneKey_(keyType::null),
     needsUpdate_(true)
 {
     // make plane relative to the coordinateSystem (Cartesian)
@@ -89,17 +86,13 @@ Foam::sampledPlane::sampledPlane
         static_cast<plane&>(*this) = plane(base, norm);
     }
 
-    dict.readIfPresent("zone", zoneName_);
+    dict.readIfPresent("zone", zoneKey_);
 
-    if (debug && zoneName_.size())
+    if (debug && zoneKey_.size() && mesh.cellZones().findIndex(zoneKey_) < 0)
     {
-        if (mesh.cellZones().findZoneID(zoneName_) < 0)
-        {
-            Info<< "cellZone \"" << zoneName_
-                << "\" not found - using entire mesh" << endl;
-        }
+        Info<< "cellZone " << zoneKey_
+            << " not found - using entire mesh" << endl;
     }
-
 }
 
 
@@ -141,19 +134,15 @@ bool Foam::sampledPlane::update()
 
     sampledSurface::clearGeom();
 
-    label zoneId = -1;
-    if (zoneName_.size())
-    {
-        zoneId = mesh().cellZones().findZoneID(zoneName_);
-    }
+    labelList selectedCells = mesh().cellZones().findMatching(zoneKey_).used();
 
-    if (zoneId < 0)
+    if (selectedCells.empty())
     {
         reCut(mesh(), true);    // always triangulate. Note:Make option?
     }
     else
     {
-        reCut(mesh(), true, mesh().cellZones()[zoneId]);
+        reCut(mesh(), true, selectedCells);
     }
 
     if (debug)
diff --git a/src/sampling/sampledSurface/sampledPlane/sampledPlane.H b/src/sampling/sampledSurface/sampledPlane/sampledPlane.H
index ec530c0a2c355f3f73c1d02367331d29cd633652..f63c6d0bb1794fb62f123657cbf5f9496334441a 100644
--- a/src/sampling/sampledSurface/sampledPlane/sampledPlane.H
+++ b/src/sampling/sampledSurface/sampledPlane/sampledPlane.H
@@ -47,7 +47,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                       Class sampledPlane Declaration
+                        Class sampledPlane Declaration
 \*---------------------------------------------------------------------------*/
 
 class sampledPlane
@@ -57,8 +57,8 @@ class sampledPlane
 {
     // Private data
 
-        //- zone name (if restricted to zones)
-        word zoneName_;
+        //- If restricted to zones, name of this zone or a regular expression
+        keyType zoneKey_;
 
         //- Track if the surface needs an update
         mutable bool needsUpdate_;
@@ -92,7 +92,7 @@ public:
             const word& name,
             const polyMesh& mesh,
             const plane& planeDesc,
-            const word& zoneName = word::null
+            const keyType& zoneKey = word::null
         );
 
         //- Construct from dictionary
diff --git a/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C b/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
index 20da502550bf6cc44734e8b4cf651198cfb0ebb1..3c2d6b1b1c91d8d7d3ea469d0bac96b788d44a5a 100644
--- a/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
+++ b/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.C
@@ -154,7 +154,7 @@ Foam::sampledThresholdCellFaces::sampledThresholdCellFaces
     fieldName_(dict.lookup("field")),
     lowerThreshold_(dict.lookupOrDefault<scalar>("lowerLimit", -VGREAT)),
     upperThreshold_(dict.lookupOrDefault<scalar>("upperLimit", VGREAT)),
-    zoneName_(word::null),
+    zoneKey_(keyType::null),
     triangulate_(dict.lookupOrDefault("triangulate", false)),
     prevTimeIndex_(-1),
     meshCells_(0)
@@ -169,16 +169,12 @@ Foam::sampledThresholdCellFaces::sampledThresholdCellFaces
             << abort(FatalError);
     }
 
-
-//    dict.readIfPresent("zone", zoneName_);
+//    dict.readIfPresent("zone", zoneKey_);
 //
-//    if (debug && zoneName_.size())
+//    if (debug && zoneKey_.size() && mesh.cellZones().findZoneID(zoneKey_) < 0)
 //    {
-//        if (mesh.cellZones().findZoneID(zoneName_) < 0)
-//        {
-//            Info<< "cellZone \"" << zoneName_
-//                << "\" not found - using entire mesh" << endl;
-//        }
+//        Info<< "cellZone " << zoneKey_
+//            << " not found - using entire mesh" << endl;
 //    }
 }
 
diff --git a/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H b/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H
index def4f084f7064e874d1ef7e9a87d95bef7dbbfea..47204a856de1b81d368e7b11a02c465d58f36eab 100644
--- a/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H
+++ b/src/sampling/sampledSurface/thresholdCellFaces/sampledThresholdCellFaces.H
@@ -67,8 +67,8 @@ class sampledThresholdCellFaces
         //- Threshold value
         const scalar upperThreshold_;
 
-        //- zone name (if restricted to zones)
-        word zoneName_;
+        //- If restricted to zones, name of this zone or a regular expression
+        keyType zoneKey_;
 
         //- Triangulated faces or keep faces as is
         bool triangulate_;