diff --git a/applications/solvers/combustion/PDRFoam/PDRFoamAutoRefine.C b/applications/solvers/combustion/PDRFoam/PDRFoamAutoRefine.C
index 4005d2d26fbfd79ef43fe36aecb4e67a8277f26a..6f41ca13c70273887444a80de9342daca2887f34 100644
--- a/applications/solvers/combustion/PDRFoam/PDRFoamAutoRefine.C
+++ b/applications/solvers/combustion/PDRFoam/PDRFoamAutoRefine.C
@@ -122,7 +122,7 @@ int main(int argc, char *argv[])
             fvc::makeAbsolute(phi, rho, U);
 
             // Test : disable refinement for some cells
-            PackedBoolList& protectedCell =
+            bitSet& protectedCell =
                 refCast<dynamicRefineFvMesh>(mesh).protectedCell();
 
             if (protectedCell.empty())
diff --git a/applications/solvers/incompressible/pimpleFoam/overPimpleDyMFoam/interpolatedFaces.H b/applications/solvers/incompressible/pimpleFoam/overPimpleDyMFoam/interpolatedFaces.H
index c9dd9cd8fedc506805681af3b4e197f1b4ac17ac..b86e23c3c81842f559f56264ac3ba91c073d8956 100644
--- a/applications/solvers/incompressible/pimpleFoam/overPimpleDyMFoam/interpolatedFaces.H
+++ b/applications/solvers/incompressible/pimpleFoam/overPimpleDyMFoam/interpolatedFaces.H
@@ -2,8 +2,8 @@
 interpolationCellPoint<vector> UInterpolator(HbyA);
 
 // Determine faces on outside of interpolated cells
-PackedBoolList isOwnerInterpolatedFace(mesh.nInternalFaces());
-PackedBoolList isNeiInterpolatedFace(mesh.nInternalFaces());
+bitSet isOwnerInterpolatedFace(mesh.nInternalFaces());
+bitSet isNeiInterpolatedFace(mesh.nInternalFaces());
 
 // Determine donor cells
 labelListList donorCell(mesh.nInternalFaces());
@@ -175,11 +175,11 @@ surfaceVectorField faceNormals(mesh.Sf()/mesh.magSf());
 forAll(isNeiInterpolatedFace, faceI)
 {
     label cellId = -1;
-    if (isNeiInterpolatedFace[faceI])
+    if (isNeiInterpolatedFace.test(faceI))
     {
         cellId = mesh.faceNeighbour()[faceI];
     }
-    else if (isOwnerInterpolatedFace[faceI])
+    else if (isOwnerInterpolatedFace.test(faceI))
     {
         cellId = mesh.faceOwner()[faceI];
     }
diff --git a/applications/test/List/Test-List.C b/applications/test/List/Test-List.C
index 9af25cbe5aed3fabb6a2aa69347f2016568f4a79..979ce9ac5daff66176b78ce9e719d3aed9a180df 100644
--- a/applications/test/List/Test-List.C
+++ b/applications/test/List/Test-List.C
@@ -474,7 +474,7 @@ int main(int argc, char *argv[])
         }
 
         {
-            PackedBoolList select = HashSetOps::bitset(locations);
+            bitSet select = HashSetOps::bitset(locations);
             auto output = ListOps::createWithValue<label>
             (
                 30,
@@ -482,8 +482,8 @@ int main(int argc, char *argv[])
                 100,
                 -1  // default value
             );
-            Info<< "with PackedBoolList: " << flatOutput(output)
-                << " selector: " << flatOutput(select.used()) << nl;
+            Info<< "with bitSet: " << flatOutput(output)
+                << " selector: " << flatOutput(select.toc()) << nl;
         }
 
         {
@@ -516,7 +516,7 @@ int main(int argc, char *argv[])
         }
 
         {
-            PackedBoolList select = HashSetOps::bitset(locations);
+            bitSet select = HashSetOps::bitset(locations);
             auto output = ListOps::createWithValue<label>
             (
                 30,
@@ -524,7 +524,7 @@ int main(int argc, char *argv[])
                 100,
                 -1  // default value
             );
-            Info<< "with PackedBoolList: " << flatOutput(output)
+            Info<< "with bitSet: " << flatOutput(output)
                 << " selector: " << flatOutput(HashSetOps::used(select))
                 << nl;
         }
diff --git a/applications/test/ListOps/Test-ListOps.C b/applications/test/ListOps/Test-ListOps.C
index c4fb44a0f55ffe3ac6a59c8ee315b3fc7b1b8271..64322bdf298c0c43983fc549258fd604aa7cb5e3 100644
--- a/applications/test/ListOps/Test-ListOps.C
+++ b/applications/test/ListOps/Test-ListOps.C
@@ -145,7 +145,7 @@ int main(int argc, char *argv[])
     Info<<"Test reorder - oldToNew:" << nl
         << flatOutput(oldToNew) << nl << nl;
 
-    PackedBoolList bitset
+    bitSet bitset
     (
         ListOps::createWithValue<bool>
         (
diff --git a/applications/test/PackedList/Test-PackedList.C b/applications/test/PackedList/Test-PackedList.C
index 61672ec1b822a652029d85b0b6facf78fd208625..0b82de459156184e5f318eeadd095b76d086c66e 100644
--- a/applications/test/PackedList/Test-PackedList.C
+++ b/applications/test/PackedList/Test-PackedList.C
@@ -32,7 +32,7 @@ Description
 #include "IOobject.H"
 #include "IOstreams.H"
 #include "IFstream.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include <climits>
 
 
@@ -131,7 +131,7 @@ int main(int argc, char *argv[])
         IFstream ifs(srcFile);
         List<label> rawLst(ifs);
 
-        PackedBoolList packLst(rawLst);
+        bitSet packLst(rawLst);
 
         Info<< "size: " << packLst.size() << nl;
 
diff --git a/applications/test/PackedList1/Test-PackedList1.C b/applications/test/PackedList1/Test-PackedList1.C
index ce8bf9bd75accc5b318d17a5c44bd5ca25b79ab2..53bfcb0b79b9c43966ed821fc1e527be63c18912 100644
--- a/applications/test/PackedList1/Test-PackedList1.C
+++ b/applications/test/PackedList1/Test-PackedList1.C
@@ -28,61 +28,100 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "uLabel.H"
+#include "labelRange.H"
+#include "bitSet.H"
+#include "FlatOutput.H"
 #include "IOstreams.H"
-#include "PackedBoolList.H"
 
 using namespace Foam;
 
+template<unsigned Width>
+inline Ostream& report
+(
+    const PackedList<Width>& list,
+    bool showBits = false,
+    bool debugOutput = false
+)
+{
+    Info<< list.info();
+    if (showBits)
+    {
+        list.printBits(Info, debugOutput) << nl;
+    }
+
+    return Info;
+}
+
+
+inline Ostream& report
+(
+    const bitSet& bitset,
+    bool showBits = false,
+    bool debugOutput = false
+)
+{
+    Info<< bitset.info();
+    Info<< "all:" << bitset.all()
+        << " any:" << bitset.any()
+        << " none:" << bitset.none() << nl;
+
+    if (showBits)
+    {
+        bitset.printBits(Info, debugOutput) << nl;
+    }
+
+    return Info;
+}
+
+// BitOps::printBits((Info<< list1.info()), true) << nl;
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 //  Main program:
 
 int main(int argc, char *argv[])
 {
-    Info<< "PackedList max_bits() = " << PackedList<>::max_bits() << nl;
-
     Info<< "\ntest allocation with value\n";
     PackedList<3> list1(5,1);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign uniform value\n";
     list1 = 3;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign uniform value (with overflow)\n";
     list1 = -1;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest zero\n";
     list1 = 0;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest set() with default argument (max_value)\n";
     list1.set(1);
     list1.set(3);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest unset() with in-range and out-of-range\n";
     list1.unset(3);
     list1.unset(100000);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign between references\n";
     list1[2] = 3;
     list1[4] = list1[2];
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign between references, with chaining\n";
     list1[0] = 1;
     list1[4] = 1;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign between references, with chaining and auto-vivify\n";
     list1[1] = 2;
     list1[8] = 2;
     list1[10] = 2;
     list1[14] = 2;
-    list1.printInfo(Info, true);
-
+    report(list1);
 
     Info<< "\ntest operator== between references\n";
     if (list1[1] == list1[8])
@@ -106,7 +145,9 @@ int main(int argc, char *argv[])
     {
         const PackedList<3>& constLst = list1;
         Info<< "\ntest operator[] const with out-of-range index\n";
-        constLst.printInfo(Info, true);
+
+        report(constLst);
+
         if (constLst[20])
         {
             Info<< "[20] is true (unexpected)\n";
@@ -116,7 +157,7 @@ int main(int argc, char *argv[])
             Info<< "[20] is false (expected) list size should be unchanged "
                 << "(const)\n";
         }
-        constLst.printInfo(Info, true);
+        report(constLst);
 
         Info<< "\ntest operator[] non-const with out-of-range index\n";
         if (list1[20])
@@ -128,7 +169,8 @@ int main(int argc, char *argv[])
             Info<< "[20] is false (expected) but list was resized?? "
                 << "(non-const)\n";
         }
-        list1.printInfo(Info, true);
+
+        report(list1);
     }
 
 
@@ -137,94 +179,94 @@ int main(int argc, char *argv[])
     {
         Info<< "[20] is false, as expected\n";
     }
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest resize with value (without reallocation)\n";
-    list1.resize(8, list1.max_value());
-    list1.printInfo(Info, true);
+    list1.resize(8, list1.max_value);
+    report(list1);
 
     Info<< "\ntest flip() function\n";
     list1.flip();
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\nre-flip()\n";
     list1.flip();
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest set() function\n";
     list1.set(1, 5);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign bool\n";
     list1 = false;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest assign bool\n";
     list1 = true;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest resize without value (with reallocation)\n";
     list1.resize(12);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest resize with value (with reallocation)\n";
-    list1.resize(25, list1.max_value());
-    list1.printInfo(Info, true);
+    list1.resize(25, list1.max_value);
+    report(list1);
 
     Info<< "\ntest resize smaller (should not touch allocation)\n";
     list1.resize(8);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest append() operation\n";
     list1.append(2);
     list1.append(3);
     list1.append(4);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest reserve() operation\n";
     list1.reserve(32);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest shrink() operation\n";
     list1.shrink();
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest setCapacity() operation\n";
     list1.setCapacity(15);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest setCapacity() operation\n";
     list1.setCapacity(100);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest operator[] assignment\n";
     list1[16] = 5;
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest operator[] assignment with auto-vivify\n";
-    list1[36] = list1.max_value();
-    list1.printInfo(Info, true);
+    list1[36] = list1.max_value;
+    report(list1);
 
     Info<< "\ntest setCapacity smaller\n";
     list1.setCapacity(24);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest resize much smaller\n";
     list1.resize(150);
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest trim\n";
     list1.trim();
-    list1.printInfo(Info, true);
+    report(list1);
 
-    // add in some misc values
+    // Add in some misc values
     list1[31] = 1;
     list1[32] = 2;
     list1[33] = 3;
 
     Info<< "\ntest get() method\n";
     Info<< "get(10):" << list1.get(10) << " and list[10]:" << list1[10] << "\n";
-    list1.printInfo(Info, true);
+    report(list1);
 
     Info<< "\ntest operator[] auto-vivify\n";
     Info<< "size:" << list1.size() << "\n";
@@ -234,33 +276,34 @@ int main(int argc, char *argv[])
     Info<< "list[45]:" << val << "\n";
     Info<< "size after read:" << list1.size() << "\n";
 
-    list1[45] = list1.max_value();
+    list1[45] = list1.max_value;
     Info<< "size after write:" << list1.size() << "\n";
     Info<< "list[45]:" << list1[45] << "\n";
     list1[49] = list1[100];
-    list1.printInfo(Info, true);
+    report(list1);
 
 
     Info<< "\ntest copy constructor + append\n";
     PackedList<3> list2(list1);
     list2.append(4);
     Info<< "source list:\n";
-    list1.printInfo(Info, true);
+    report(list1);
+
     Info<< "destination list:\n";
-    list2.printInfo(Info, true);
+    report(list2);
 
     Info<< "\ntest pattern that fills all bits\n";
     PackedList<4> list3(8, 8);
 
     label pos = list3.size() - 1;
 
-    list3[pos--] = list3.max_value();
+    list3[pos--] = list3.max_value;
     list3[pos--] = 0;
-    list3[pos--] = list3.max_value();
-    list3.printInfo(Info, true);
+    list3[pos--] = list3.max_value;
+    report(list3);
 
     Info<< "removed final value: " << list3.remove() << endl;
-    list3.printInfo(Info, true);
+    report(list3);
 
     Info<<"list: " << list3 << endl;
 
@@ -289,18 +332,117 @@ int main(int argc, char *argv[])
     }
 
 
-    PackedBoolList listb(list4);
+    bitSet listb(list4);
 
     Info<< "copied from bool list " << endl;
-    listb.printInfo(Info, true);
+    // report(listb);
 
     {
-        labelList indices = listb.used();
+        labelList indices = listb.toc();
 
         Info<< "indices: " << indices << endl;
     }
 
 
+    Info<< nl
+        << "resizing: " << nl;
+    {
+        PackedList<1> list1(81, 1);
+        PackedList<3> list3(27, 5); // ie, 101
+
+        Info<< "initial" << nl; report(list1, true);
+        Info<< "initial" << nl; report(list3, true);
+
+        list1.resize(118, 1);
+        list3.resize(37, 3);
+        Info<< "extend with val" << nl; report(list1, true);
+        Info<< "extend with val" << nl; report(list3, true);
+
+        list1.resize(90, 0);
+        list3.resize(30, 4);
+
+        Info<< "contract with val" << nl; report(list1, true);
+        Info<< "contract with val" << nl; report(list3, true);
+    }
+
+    {
+        bitSet bits(45);
+
+        Info<< "bits" << nl; report(bits, true);
+
+        bits = true;
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.unset(35);
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.resize(39);
+        Info<< "bits" << nl; report(bits, true);
+
+        Info<< "values:" << flatOutput(bits.values()) << nl;
+        Info<< "used:" << flatOutput(bits.toc()) << nl;
+
+        bits.unset(labelRange(-15, 8));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.set(labelRange(-15, 100));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.set(labelRange(-15, 100));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.set(labelRange(150, 15));
+        Info<< "bits" << nl; report(bits, true);
+        bits.set(labelRange(0, 5));
+        Info<< "bits" << nl; report(bits, true);
+
+
+        bits.reset();
+        bits.resize(50);
+
+        Info<< "bits" << nl; report(bits, true);
+        bits.set(labelRange(4, 8));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.set(labelRange(30, 35));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.set(labelRange(80, 12));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.unset(labelRange(35, 16));
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.unset(labelRange(0, 50));
+        bits.resize(100000);
+        bits.set(labelRange(30, 6));
+        bits[33] = false;
+
+        Info<<"used: " << flatOutput(bits.toc()) << endl;
+
+        Info<<"first: " << bits.find_first() << endl;
+        Info<<"next: " << bits.find_next(29) << endl;
+        Info<<"next: " << bits.find_next(30) << endl;
+        Info<<"next: " << bits.find_next(31) << endl;
+
+        Info<<"next: " << bits.find_next(31) << endl;
+
+        bits.set(labelRange(80, 10));
+        bits.resize(100);
+        Info<< "bits" << nl; report(bits, true);
+
+        bits.set(labelRange(125, 10));
+
+        Info<<"next: " << bits.find_next(64) << endl;
+        Info<<"used: " << flatOutput(bits.toc()) << endl;
+
+        for (const auto pos : bits)
+        {
+            Info<<"have: " << pos << nl;
+        }
+
+    }
+
     Info<< "\n\nDone.\n";
 
     return 0;
diff --git a/applications/test/PackedList2/Test-PackedList2.C b/applications/test/PackedList2/Test-PackedList2.C
index 053501e96e2a95b0db6185440bb83500a4948076..f73676983ed8847d769cd1af65b99d31fddc9b36 100644
--- a/applications/test/PackedList2/Test-PackedList2.C
+++ b/applications/test/PackedList2/Test-PackedList2.C
@@ -29,7 +29,7 @@ Description
 
 #include "argList.H"
 #include "boolList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "HashSet.H"
 #include "cpuTime.H"
 #include <vector>
@@ -63,7 +63,7 @@ int main(int argc, char *argv[])
 
     unsigned long sum = 0;
 
-    PackedBoolList packed(n, 1);
+    bitSet packed(n, true);
     boolList unpacked(n, true);
 
     #ifdef TEST_STD_BOOLLIST
diff --git a/applications/test/PackedList3/Make/files b/applications/test/PackedList3/Make/files
deleted file mode 100644
index 3291f428b58586af26cb6a8d71a9c0fd45947e86..0000000000000000000000000000000000000000
--- a/applications/test/PackedList3/Make/files
+++ /dev/null
@@ -1,3 +0,0 @@
-Test-PackedList3.C
-
-EXE = $(FOAM_USER_APPBIN)/Test-PackedList3
diff --git a/applications/test/PackedList4/Make/files b/applications/test/PackedList4/Make/files
deleted file mode 100644
index 6ff803f098d37068a4dc58c98dc75c24799682bb..0000000000000000000000000000000000000000
--- a/applications/test/PackedList4/Make/files
+++ /dev/null
@@ -1,3 +0,0 @@
-Test-PackedList4.C
-
-EXE = $(FOAM_USER_APPBIN)/Test-PackedList4
diff --git a/applications/test/PackedList4/Test-PackedList4.C b/applications/test/PackedList4/Test-PackedList4.C
deleted file mode 100644
index dd8780d7686b6e1ef878e235b4b31397d1c36b77..0000000000000000000000000000000000000000
--- a/applications/test/PackedList4/Test-PackedList4.C
+++ /dev/null
@@ -1,168 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     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 "boolList.H"
-#include "DynamicList.H"
-#include "IOstreams.H"
-#include "PackedBoolList.H"
-#include "ITstream.H"
-#include "StringStream.H"
-#include "FlatOutput.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);
-    list2.flip();
-
-    Info<< "\nflipped 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();
-
-    PackedBoolList list4
-    (
-        ITstream
-        (
-            "input",
-            "(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() << nl;
-
-    Info<< "\nassign from labelList\n";
-    list4.clear();
-    list4.setMany(labelList{0, 1, 2, 3, 12, 13, 14, 19, 20, 21});
-
-    list4.printInfo(Info, true);
-    Info<< list4 << " indices: " << list4.used() << nl;
-
-    // Not yet:
-    // PackedBoolList list5{0, 1, 2, 3, 12, 13, 14, 19, 20, 21};
-    // list5.printInfo(Info, true);
-    // Info<< list5 << " indices: " << list5.used() << nl;
-
-    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() << nl;
-
-    boolList bools(list4.size());
-    forAll(list4, i)
-    {
-        bools[i] = list4[i];
-    }
-
-    Info<< "boolList: " << bools << nl;
-
-    // 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 << nl;
-
-    list4.clear();
-    forAll(pl2, i)
-    {
-        list4[i] = pl2[i];
-    }
-
-    list4.writeList(Info, -1) << nl; // indexed output
-
-    list4.writeEntry("PackedBoolList", Info);
-
-    // Construct from labelUList, labelUIndList
-    {
-        DynamicList<label> indices({10, 50, 300});
-
-        Info<< "set: " << flatOutput(indices) << endl;
-
-        PackedBoolList bools1(indices);
-
-        Info<< "used: " << bools1.size() << " "
-            << flatOutput(bools1.used()) << endl;
-    }
-
-    return 0;
-}
-
-
-// ************************************************************************* //
diff --git a/applications/test/PatchTools/Test-PatchTools.C b/applications/test/PatchTools/Test-PatchTools.C
index 5d4217c0e2f7ed21dec84d39c9d2d84e46da1648..adab0d98bbf647a80a8be27fa8aebceda56cc3af 100644
--- a/applications/test/PatchTools/Test-PatchTools.C
+++ b/applications/test/PatchTools/Test-PatchTools.C
@@ -218,7 +218,7 @@ int main(int argc, char *argv[])
 
         labelList patchEdges;
         labelList coupledEdges;
-        PackedBoolList sameEdgeOrientation;
+        bitSet sameEdgeOrientation;
         PatchTools::matchEdges
         (
             pp,
diff --git a/applications/test/bitSet1/Make/files b/applications/test/bitSet1/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..c87b831b3822887e38841e87c403347063da5c1c
--- /dev/null
+++ b/applications/test/bitSet1/Make/files
@@ -0,0 +1,3 @@
+Test-bitSet1.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-bitSet1
diff --git a/applications/test/PackedList3/Make/options b/applications/test/bitSet1/Make/options
similarity index 100%
rename from applications/test/PackedList3/Make/options
rename to applications/test/bitSet1/Make/options
diff --git a/applications/test/bitSet1/Test-bitSet1.C b/applications/test/bitSet1/Test-bitSet1.C
new file mode 100644
index 0000000000000000000000000000000000000000..111b3af8204d184154538f5b8af62b89e8ecfef3
--- /dev/null
+++ b/applications/test/bitSet1/Test-bitSet1.C
@@ -0,0 +1,84 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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
+    Test-bitSet1
+
+Description
+    Test bitSet functionality
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "boolList.H"
+#include "bitSet.H"
+#include "HashSet.H"
+#include "cpuTime.H"
+#include <vector>
+#include <unordered_set>
+
+using namespace Foam;
+
+inline Ostream& report
+(
+    const bitSet& bitset,
+    bool showBits = false,
+    bool debugOutput = false
+)
+{
+    Info<< "size=" << bitset.size() << "/" << bitset.capacity()
+        << " count=" << bitset.count()
+        << " all:" << bitset.all()
+        << " any:" << bitset.any()
+        << " none:" << bitset.none() << nl;
+
+    Info<< "values: " << flatOutput(bitset) << nl;
+    if (showBits)
+    {
+        bitset.printBits(Info, debugOutput) << nl;
+    }
+
+    return Info;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    bitSet set1(100);
+
+    Info<<"bitSet(label): "; report(set1, true);
+
+    bitSet set2(100, { -1, 10, 25, 45});
+    Info<<"bitSet(label, labels): "; report(set2, true);
+
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/bitSet2/Make/files b/applications/test/bitSet2/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..ff546fa179bec6e84ff981a1105801a184644580
--- /dev/null
+++ b/applications/test/bitSet2/Make/files
@@ -0,0 +1,3 @@
+Test-bitSet2.C
+
+EXE = $(FOAM_USER_APPBIN)/Test-bitSet2
diff --git a/applications/test/PackedList4/Make/options b/applications/test/bitSet2/Make/options
similarity index 100%
rename from applications/test/PackedList4/Make/options
rename to applications/test/bitSet2/Make/options
diff --git a/applications/test/bitSet2/Test-bitSet2.C b/applications/test/bitSet2/Test-bitSet2.C
new file mode 100644
index 0000000000000000000000000000000000000000..a20a14a4702e0399c347ad67f1bf96396e474600
--- /dev/null
+++ b/applications/test/bitSet2/Test-bitSet2.C
@@ -0,0 +1,311 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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
+    Test-bitSet2
+
+Description
+    Test bitSet functionality
+
+\*---------------------------------------------------------------------------*/
+
+#include "uLabel.H"
+#include "boolList.H"
+#include "DynamicList.H"
+#include "IOstreams.H"
+#include "ITstream.H"
+#include "StringStream.H"
+#include "bitSet.H"
+#include "FlatOutput.H"
+
+using namespace Foam;
+
+inline Ostream& report
+(
+    const bitSet& bitset,
+    bool showBits = false,
+    bool debugOutput = false
+)
+{
+    Info<< "size=" << bitset.size() << "/" << bitset.capacity()
+        << " count=" << bitset.count()
+        << " all:" << bitset.all()
+        << " any:" << bitset.any()
+        << " none:" << bitset.none() << nl;
+
+    Info<< "values: " << flatOutput(bitset) << nl;
+    if (showBits)
+    {
+        bitset.printBits(Info, debugOutput) << nl;
+    }
+
+    return Info;
+}
+
+
+template<class UIntType>
+std::string toString(UIntType value, char off='.', char on='1')
+{
+    std::string str(std::numeric_limits<UIntType>::digits, off);
+
+    unsigned n = 0;
+
+    // Starting from most significant bit - makes for easy reading.
+    for
+    (
+        unsigned test = (1u << (std::numeric_limits<UIntType>::digits-1));
+        test;
+        test >>= 1u
+    )
+    {
+        str[n++] = ((value & test) ? on : off);
+    }
+
+    return str;
+}
+
+
+inline bool compare
+(
+    const bitSet& bitset,
+    const std::string& expected
+)
+{
+    const List<unsigned int>& store = bitset.storage();
+
+    std::string has;
+
+    for (label blocki=0; blocki < bitset.nBlocks(); ++blocki)
+    {
+        has += toString(store[blocki]);
+    }
+
+    if (has == expected)
+    {
+        Info<< "pass: " << has << nl;
+        return true;
+    }
+
+    Info<< "fail:   " << has << nl;
+    Info<< "expect: " << expected << nl;
+
+    return false;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+//  Main program:
+
+int main(int argc, char *argv[])
+{
+    bitSet list1(22);
+    // Set every third one on
+    forAll(list1, i)
+    {
+        list1[i] = !(i % 3);
+    }
+    Info<< "\nalternating bit pattern\n";
+    compare(list1, "..........1..1..1..1..1..1..1..1");
+
+    list1.unset(labelRange(13, 20));  // In range
+
+    Info<< "\nafter clear [13,..]\n";
+    compare(list1, "...................1..1..1..1..1");
+
+    report(list1, true);
+
+    list1.unset(labelRange(40, 20));  // out of range
+    Info<< "\nafter clear [40,..]\n";
+    compare(list1, "...................1..1..1..1..1");
+
+    report(list1, true);
+
+
+    Info<< "first: " << list1.find_first()
+        << " last: " << list1.find_last() << endl;
+
+    Info<< "iterate through:";
+    for (const label idx : list1)
+    {
+        Info<<" " << idx;
+    }
+    Info<< nl;
+
+    Info<< "\nalternating bit pattern\n";
+    report(list1, true);
+
+    bitSet list2 = ~list1;
+
+    Info<< "\nflipped bit pattern\n";
+    report(list2, true);
+
+    // set every other on
+    forAll(list2, i)
+    {
+        list2[i] = !(i % 2);
+    }
+
+    Info<< "\nstarting pattern\n";
+    report(list2, true);
+
+    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, [28,34) true + 6 false, bottom 4 bits true\n";
+
+    compare
+    (
+        list2,
+        "1111.......1.1.1.1.1.1.1.1.11111"
+        "..............................11"
+    );
+
+
+    report(list2, true);
+
+    labelList list2Labels = list2.toc();
+
+    Info<< "\noperator|\n";
+
+    list1.printBits(Info);
+    list2.printBits(Info);
+    Info<< "==\n";
+    (list1 | list2).printBits(Info);
+
+    Info<< "\noperator& : does trim\n";
+    report((list1 & list2), true);
+
+    Info<< "\noperator^\n";
+    report((list1 ^ list2), true);
+
+    Info<< "\noperator|=\n";
+    {
+        bitSet list3 = list1;
+        report((list3 |= list2), true);
+    }
+
+    Info<< "\noperator&=\n";
+    {
+        bitSet list3 = list1;
+        report((list3 &= list2), true);
+    }
+
+    Info<< "\noperator^=\n";
+    {
+        bitSet list3 = list1;
+        report((list3 ^= list2), true);
+    }
+
+    Info<< "\noperator-=\n";
+    {
+        bitSet list3 = list1;
+        report((list3 -= list2), true);
+    }
+
+    bitSet list4
+    (
+        ITstream
+        (
+            "input",
+            "(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";
+
+    report(list4, true);
+
+    Info<< "\nclear/assign from labelList\n";
+    list4.clear();
+    list4.setMany(labelList{0, 1, 2, 3, 12, 13, 14, 19, 20, 21});
+
+    report(list4, true);
+
+    // Not yet:
+    // bitSet list5{0, 1, 2, 3, 12, 13, 14, 19, 20, 21};
+    // list5.printInfo(Info, true);
+    // Info<< list5 << " indices: " << list5.toc() << nl;
+
+    Info<< "\nassign from indices\n";
+    list4.read
+    (
+        IStringStream
+        (
+            "{0 1 2 3 12 13 14 19 20 21}"
+        )()
+    );
+
+    report(list4, true);
+    compare(list4, "..........111....111........1111");
+
+    list4.set(labelRange(28, 6));  // extends size
+
+    Info<<"extended\n";
+    compare
+    (
+        list4,
+        "1111......111....111........1111"
+        "..............................11"
+    );
+
+    list4.set(labelRange(40, 6));  // extends size
+    Info<<"extended\n";
+    compare
+    (
+        list4,
+        "1111......111....111........1111"
+        "..................111111......11"
+    );
+
+    list4.unset(labelRange(14, 19));
+    Info<<"cleared [14,33)\n";
+    compare
+    (
+        list4,
+        "..................11........1111"
+        "..................111111......1."
+    );
+
+
+    // Construct from labelUList, labelUIndList
+    {
+        DynamicList<label> indices({10, 50, 300});
+
+        Info<< "set: " << flatOutput(indices) << endl;
+
+        bitSet bools1(indices);
+
+        Info<< "used: " << bools1.size() << " "
+            << flatOutput(bools1.toc()) << endl;
+    }
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/test/bitops/Test-bitops.C b/applications/test/bitops/Test-bitops.C
index fa0dfb63bdbcc3818a0c412ab386fce7a78e5cf8..1030751af572e47b8a57d0d950f3be33e177d896 100644
--- a/applications/test/bitops/Test-bitops.C
+++ b/applications/test/bitops/Test-bitops.C
@@ -27,6 +27,7 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "bool.H"
+#include "BitOps.H"
 #include "IOstreams.H"
 #include "stdFoam.H"
 
@@ -177,6 +178,15 @@ int main(int argc, char *argv[])
 
     printOffset<double>();
 
+
+    Info<<nl << "Test repeat_value" << nl << nl;
+
+    Info<< BitOps::bitInfo<unsigned>(BitOps::repeat_value<unsigned, 3>(1u))
+        << nl;
+
+    Info<< BitOps::bitInfo<unsigned>(BitOps::repeat_value<unsigned>(1u))
+        << nl;
+
     Info << "---\nEnd\n" << endl;
 
     return 0;
diff --git a/applications/test/machine-sizes/Make/files b/applications/test/machine-sizes/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..32f15faa2481f875e9876006132e9c1d37fd7132
--- /dev/null
+++ b/applications/test/machine-sizes/Make/files
@@ -0,0 +1,3 @@
+Test-machine-sizes.cpp
+
+EXE = $(FOAM_USER_APPBIN)/Test-machine-sizes.cpp
diff --git a/applications/test/machine-sizes/Make/options b/applications/test/machine-sizes/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..6a9e9810b3d5ce6684bdaf03143933480ff45e42
--- /dev/null
+++ b/applications/test/machine-sizes/Make/options
@@ -0,0 +1,2 @@
+/* EXE_INC = -I$(LIB_SRC)/cfdTools/include */
+/* EXE_LIBS = -lfiniteVolume */
diff --git a/applications/test/PackedList3/Test-PackedList3.C b/applications/test/machine-sizes/Test-machine-sizes.cpp
similarity index 64%
rename from applications/test/PackedList3/Test-PackedList3.C
rename to applications/test/machine-sizes/Test-machine-sizes.cpp
index 5add8789250e4ab05432e83a3621fa1850114514..8000c093fdb2bca67c6af2306bcab61ffc5df0dc 100644
--- a/applications/test/PackedList3/Test-PackedList3.C
+++ b/applications/test/machine-sizes/Test-machine-sizes.cpp
@@ -21,51 +21,43 @@ License
     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
+    Test the sizeof for basic types.
+    Can be compiled and run without any OpenFOAM libraries.
+
+        g++ -std=c++11 -oTest-machine-sizes Test-machine-sizes.cpp
 
 \*---------------------------------------------------------------------------*/
 
-#include "argList.H"
-#include "cpuTime.H"
-#include "PackedBoolList.H"
+#include <cstdint>
+#include <climits>
+#include <cstdlib>
+#include <iostream>
 
-using namespace Foam;
+template<class T>
+void print(const char* msg)
+{
+    std::cout<< msg << ' ' << sizeof(T) << '\n';
+}
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-
 // Main program:
 
 int main(int argc, char *argv[])
 {
-    const label nLoop = 5;
-    const label n = 100000000;
-    // const label nReport = 1000000;
-
-    cpuTime timer;
-
-    // test inserts
-    PackedBoolList packed;
-    for (label iloop = 0; iloop < nLoop; ++iloop)
-    {
-        for (label i = 0; i < n; ++i)
-        {
-            // if ((i % nReport) == 0 && i)
-            // {
-            //     Info<< "." << flush;
-            // }
-            packed[i] = 1;
-            // Make compiler do something else too
-            packed[i/2] = 0;
-        }
-    }
-    Info<< nl
-        << "insert test: " << nLoop << "*" << n << " elements in "
-        << timer.cpuTimeIncrement() << " s\n\n";
-
-    Info << "\nEnd\n" << endl;
+    std::cout<<"machine sizes\n---\n\n";
+
+    print<short>("short");
+    print<int>("int");
+    print<long>("long");
+    print<long long>("long long");
+    print<float>("float");
+    print<double>("double");
+    print<long double>("long double");
+    print<std::string>("std::string");
+    print<std::string::size_type>("std::string::size_type");
+
+    std::cout << "\n---\nEnd\n\n";
 
     return 0;
 }
diff --git a/applications/test/surfaceMeshConvert/Test-surfaceMeshConvert.C b/applications/test/surfaceMeshConvert/Test-surfaceMeshConvert.C
index ecc08047d26b5d88550b3ca2b56d39d54b2ac79f..68c908920eab70e15d39eed09ff14271d3699f60 100644
--- a/applications/test/surfaceMeshConvert/Test-surfaceMeshConvert.C
+++ b/applications/test/surfaceMeshConvert/Test-surfaceMeshConvert.C
@@ -48,10 +48,6 @@ Usage
 
       - \par -triSurface
         Use triSurface library for input/output
-
-      - \par -keyed
-        Use keyedSurface for input/output
-
 Note
     The filename extensions are used to determine the file format type.
 
@@ -64,7 +60,6 @@ Note
 #include "surfMesh.H"
 #include "surfFields.H"
 #include "surfPointFields.H"
-#include "PackedBoolList.H"
 
 #include "MeshedSurfaces.H"
 #include "ModifiableMeshedSurface.H"
diff --git a/applications/test/syncTools/Test-syncTools.C b/applications/test/syncTools/Test-syncTools.C
index 872d93d3b9be4ef0884a3537c10e06b9f2a7d56b..718063dfd7ec3e6527deaea88e1f34883047dde7 100644
--- a/applications/test/syncTools/Test-syncTools.C
+++ b/applications/test/syncTools/Test-syncTools.C
@@ -406,13 +406,13 @@ void testPointSync(const polyMesh& mesh, Random& rndGen)
     {
         labelList nMasters(mesh.nPoints(), 0);
 
-        PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
+        bitSet isMasterPoint(syncTools::getMasterPoints(mesh));
 
         forAll(isMasterPoint, pointi)
         {
-            if (isMasterPoint[pointi])
+            if (isMasterPoint.test(pointi))
             {
-                nMasters[pointi] = 1;
+                nMasters.set(pointi);
             }
         }
 
@@ -482,13 +482,13 @@ void testEdgeSync(const polyMesh& mesh, Random& rndGen)
     {
         labelList nMasters(edges.size(), 0);
 
-        PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
+        bitSet isMasterEdge(syncTools::getMasterEdges(mesh));
 
         forAll(isMasterEdge, edgeI)
         {
-            if (isMasterEdge[edgeI])
+            if (isMasterEdge.test(edgeI))
             {
-                nMasters[edgeI] = 1;
+                nMasters.set(edgeI);
             }
         }
 
@@ -551,13 +551,13 @@ void testFaceSync(const polyMesh& mesh, Random& rndGen)
     {
         labelList nMasters(mesh.nFaces(), 0);
 
-        PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
+        Bitset isMasterFace(syncTools::getMasterFaces(mesh));
 
         forAll(isMasterFace, facei)
         {
-            if (isMasterFace[facei])
+            if (isMasterFace.test(facei))
             {
-                nMasters[facei] = 1;
+                nMasters.set(facei);
             }
         }
 
diff --git a/applications/utilities/mesh/advanced/PDRMesh/PDRMesh.C b/applications/utilities/mesh/advanced/PDRMesh/PDRMesh.C
index bb55c6990e0827edb5e671426ba9b5c011773091..58b2e3468e7f0e4fa0c6c64aa27089f9988bb37b 100644
--- a/applications/utilities/mesh/advanced/PDRMesh/PDRMesh.C
+++ b/applications/utilities/mesh/advanced/PDRMesh/PDRMesh.C
@@ -81,7 +81,7 @@ void modifyOrAddFace
     const label zoneID,
     const bool zoneFlip,
 
-    PackedBoolList& modifiedFace
+    bitSet& modifiedFace
 )
 {
     if (modifiedFace.set(facei))
@@ -338,7 +338,7 @@ void subsetTopoSets
         Info<< "Subsetting " << set.type() << " " << set.name() << endl;
 
         // Map the data
-        PackedBoolList isSet(set.maxSize(mesh));
+        bitSet isSet(set.maxSize(mesh));
         forAllConstIter(labelHashSet, set, iter)
         {
             isSet.set(iter.key());
@@ -374,7 +374,7 @@ void createCoupledBaffles
     fvMesh& mesh,
     const labelList& coupledWantedPatch,
     polyTopoChange& meshMod,
-    PackedBoolList& modifiedFace
+    bitSet& modifiedFace
 )
 {
     const faceZoneMesh& faceZones = mesh.faceZones();
@@ -442,7 +442,7 @@ void createCyclicCoupledBaffles
     const labelList& cyclicMasterPatch,
     const labelList& cyclicSlavePatch,
     polyTopoChange& meshMod,
-    PackedBoolList& modifiedFace
+    bitSet& modifiedFace
 )
 {
     const faceZoneMesh& faceZones = mesh.faceZones();
@@ -1119,7 +1119,7 @@ int main(int argc, char *argv[])
 
 
     // Whether first use of face (modify) or consecutive (add)
-    PackedBoolList modifiedFace(mesh.nFaces());
+    bitSet modifiedFace(mesh.nFaces());
 
     // Create coupled wall-side baffles
     createCoupledBaffles
diff --git a/applications/utilities/mesh/advanced/modifyMesh/cellSplitter.C b/applications/utilities/mesh/advanced/modifyMesh/cellSplitter.C
index d6a7cffa96e13d9c10f82a371040312e85d45f91..280c8b1f3b58e3d125b362a5ea363acf21cf244f 100644
--- a/applications/utilities/mesh/advanced/modifyMesh/cellSplitter.C
+++ b/applications/utilities/mesh/advanced/modifyMesh/cellSplitter.C
@@ -366,7 +366,7 @@ void Foam::cellSplitter::setRefinement
 
 
     // Mark off affected face.
-    boolList faceUpToDate(mesh_.nFaces(), true);
+    bitSet faceUpToDate(mesh_.nFaces(), true);
 
     forAllConstIter(Map<point>, cellToMidPoint, iter)
     {
@@ -374,18 +374,15 @@ void Foam::cellSplitter::setRefinement
 
         const cell& cFaces = mesh_.cells()[celli];
 
-        forAll(cFaces, i)
-        {
-            label facei = cFaces[i];
-
-            faceUpToDate[facei] = false;
-        }
+        faceUpToDate.unsetMany(cFaces);
     }
 
     forAll(faceUpToDate, facei)
     {
-        if (!faceUpToDate[facei])
+        if (!faceUpToDate.test(facei))
         {
+            faceUpToDate.set(facei);
+
             const face& f = mesh_.faces()[facei];
 
             if (mesh_.isInternalFace(facei))
@@ -454,8 +451,6 @@ void Foam::cellSplitter::setRefinement
                     )
                 );
             }
-
-            faceUpToDate[facei] = true;
         }
     }
 }
diff --git a/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C b/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
index 01dbfd1ce82e8f5242406bd32e63b794659f765c..e2471832425b888c0dabb81ee526ce8ff97121bf 100644
--- a/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
+++ b/applications/utilities/mesh/advanced/modifyMesh/modifyMesh.C
@@ -579,7 +579,7 @@ int main(int argc, char *argv[])
 
         pointField newPoints(points);
 
-        PackedBoolList collapseEdge(mesh.nEdges());
+        bitSet collapseEdge(mesh.nEdges());
         Map<point> collapsePointToLocation(mesh.nPoints());
 
         // Get new positions and construct collapse network
diff --git a/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C b/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C
index f01fa003e44158b4c3553c4fef8e527a965e744c..30efaf9ecc130a900a034f3b468d88c42db288a3 100644
--- a/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C
+++ b/applications/utilities/mesh/advanced/refineWallLayer/refineWallLayer.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -97,10 +97,10 @@ int main(int argc, char *argv[])
     label nPatchFaces = 0;
     label nPatchEdges = 0;
 
-    forAllConstIter(labelHashSet, patchSet, iter)
+    for (const label patchi : patchSet)
     {
-        nPatchFaces += mesh.boundaryMesh()[iter.key()].size();
-        nPatchEdges += mesh.boundaryMesh()[iter.key()].nEdges();
+        nPatchFaces += mesh.boundaryMesh()[patchi].size();
+        nPatchEdges += mesh.boundaryMesh()[patchi].nEdges();
     }
 
     // Construct from estimate for the number of cells to refine
@@ -111,15 +111,13 @@ int main(int argc, char *argv[])
     DynamicList<scalar> allCutEdgeWeights(nPatchEdges);
 
     // Find cells to refine
-    forAllConstIter(labelHashSet, patchSet, iter)
+    for (const label patchi : patchSet)
     {
-        const polyPatch& pp = mesh.boundaryMesh()[iter.key()];
+        const polyPatch& pp = mesh.boundaryMesh()[patchi];
         const labelList& meshPoints = pp.meshPoints();
 
-        forAll(meshPoints, pointi)
+        for (const label meshPointi : meshPoints)
         {
-            label meshPointi = meshPoints[pointi];
-
             const labelList& pCells = mesh.pointCells()[meshPointi];
 
             cutCells.insertMany(pCells);
@@ -139,49 +137,43 @@ int main(int argc, char *argv[])
             << cells.instance()/cells.local()/cells.name()
             << nl << endl;
 
-        forAllConstIter(cellSet, cells, iter)
+        for (const label celli : cells)
         {
-            cutCells.erase(iter.key());
+            cutCells.erase(celli);
         }
         Info<< "Removed from cells to cut all the ones not in set "
             << setName << nl << endl;
     }
 
     // Mark all mesh points on patch
-    boolList vertOnPatch(mesh.nPoints(), false);
+    bitSet vertOnPatch(mesh.nPoints());
 
-    forAllConstIter(labelHashSet, patchSet, iter)
+    for (const label patchi : patchSet)
     {
-        const polyPatch& pp = mesh.boundaryMesh()[iter.key()];
+        const polyPatch& pp = mesh.boundaryMesh()[patchi];
         const labelList& meshPoints = pp.meshPoints();
 
-        forAll(meshPoints, pointi)
-        {
-            vertOnPatch[meshPoints[pointi]] = true;
-        }
+        vertOnPatch.setMany(meshPoints);
     }
 
-    forAllConstIter(labelHashSet, patchSet, iter)
+    for (const label patchi : patchSet)
     {
-        const polyPatch& pp = mesh.boundaryMesh()[iter.key()];
+        const polyPatch& pp = mesh.boundaryMesh()[patchi];
         const labelList& meshPoints = pp.meshPoints();
 
-        forAll(meshPoints, pointi)
+        for (const label meshPointi : meshPoints)
         {
-            label meshPointi = meshPoints[pointi];
-
             const labelList& pEdges = mesh.pointEdges()[meshPointi];
 
-            forAll(pEdges, pEdgeI)
+            for (const label edgei : pEdges)
             {
-                const label edgeI = pEdges[pEdgeI];
-                const edge& e = mesh.edges()[edgeI];
+                const edge& e = mesh.edges()[edgei];
 
                 label otherPointi = e.otherVertex(meshPointi);
 
-                if (!vertOnPatch[otherPointi])
+                if (!vertOnPatch.test(otherPointi))
                 {
-                    allCutEdges.append(edgeI);
+                    allCutEdges.append(edgei);
 
                     if (e.start() == meshPointi)
                     {
@@ -214,7 +206,7 @@ int main(int argc, char *argv[])
     (
         mesh,
         cutCells.toc(),     // cells candidate for cutting
-        labelList(0),       // cut vertices
+        labelList(),        // cut vertices
         allCutEdges,        // cut edges
         cutEdgeWeights      // weight on cut edges
     );
diff --git a/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L b/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L
index 0f1f12933f74889b06d506086b04f08a134f4c20..c123305d471728ad4227245cbe809634d4075cd9 100644
--- a/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L
+++ b/applications/utilities/mesh/conversion/fluent3DMeshToFoam/fluent3DMeshToFoam.L
@@ -869,7 +869,7 @@ int main(int argc, char *argv[])
     // Pre-filtering: flip "owner" boundary or wrong oriented internal
     // faces and move to neighbour
 
-    boolList fm(faces.size(), false);
+    bitSet fm(faces.size(), false);
     forAll(faces, facei)
     {
         if
@@ -878,7 +878,7 @@ int main(int argc, char *argv[])
          || (neighbour[facei] != -1 && owner[facei] > neighbour[facei])
         )
         {
-            fm[facei] = true;
+            fm.set(facei);
             if (!cubitFile)
             {
                 faces[facei].flip();
@@ -1279,7 +1279,7 @@ int main(int argc, char *argv[])
                     false,              // flipFaceFlux
                     -1,                 // patchID
                     faceZonei,          // zoneID
-                    fm[facei]           // zoneFlip
+                    fm.test(facei)      // zoneFlip
                 );
             }
 
diff --git a/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L b/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L
index 424a447e69837693ebf73823acc89cfadf5cd7ac..f01a59ffe96776c5fbe94ce9909cfcb2d68aa8bc 100644
--- a/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L
+++ b/applications/utilities/mesh/conversion/fluentMeshToFoam/fluentMeshToFoam.L
@@ -1620,14 +1620,14 @@ int main(int argc, char *argv[])
             labelList cls(end() - start() + 1);
 
             // Mark zone cells, used for finding faces
-            boolList zoneCell(pShapeMesh.nCells(), false);
+            bitSet zoneCell(pShapeMesh.nCells(), false);
 
             // shift cell indizes by 1
             label nr=0;
             for (label celli = (start() - 1); celli < end(); celli++)
             {
                 cls[nr]=celli;
-                zoneCell[celli] = true;
+                zoneCell.set(celli);
                 nr++;
             }
 
@@ -1646,7 +1646,7 @@ int main(int argc, char *argv[])
                 label own = pShapeMesh.faceOwner()[facei];
                 if (nei != -1)
                 {
-                    if (zoneCell[nei] && zoneCell[own])
+                    if (zoneCell.test(nei) && zoneCell.test(own))
                     {
                         zoneFaces.append(facei);
                     }
@@ -1669,7 +1669,7 @@ int main(int argc, char *argv[])
                 const labelList& faceCells = bPatches[pI].faceCells();
                 forAll(faceCells, fcI)
                 {
-                    if (zoneCell[faceCells[fcI] ])
+                    if (zoneCell.test(faceCells[fcI]))
                     {
                         boundaryZones[pI].append(name);
                         break;
diff --git a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
index 1c0d36af43967567cdc8963ca6b85bac9cc7acb4..5b11187ee7c6c1c178e5ea2d81c36d1992472497 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
+++ b/applications/utilities/mesh/generation/extrude/extrudeMesh/extrudeMesh.C
@@ -890,7 +890,7 @@ int main(int argc, char *argv[])
         const edgeList& edges = mesh.edges();
         const pointField& points = mesh.points();
 
-        PackedBoolList collapseEdge(mesh.nEdges());
+        bitSet collapseEdge(mesh.nEdges());
         Map<point> collapsePointToLocation(mesh.nPoints());
 
         forAll(edges, edgeI)
diff --git a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
index 36ea269ebda0187c205fa5b317c644259bf06c30..c22514d248e56b979e150aacd18dd04c7923fb2e 100644
--- a/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
+++ b/applications/utilities/mesh/generation/extrude/extrudeToRegionMesh/extrudeToRegionMesh.C
@@ -1268,7 +1268,7 @@ void extrudeGeometricProperties
     // Determine edge normals on original patch
     labelList patchEdges;
     labelList coupledEdges;
-    PackedBoolList sameEdgeOrientation;
+    bitSet sameEdgeOrientation;
     PatchTools::matchEdges
     (
         extrudePatch,
@@ -2160,7 +2160,7 @@ int main(int argc, char *argv[])
     labelListList extrudeEdgePatches(extrudePatch.nEdges());
 
     // Is edge a non-manifold edge
-    PackedBoolList nonManifoldEdge(extrudePatch.nEdges());
+    bitSet nonManifoldEdge(extrudePatch.nEdges());
 
     // Note: logic has to be same as in countExtrudePatches.
     forAll(edgeFaces, edgeI)
diff --git a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C
index b855bbbe1ab9ab2180ca9318cb8a6fd891af9a2c..a54e1beb508ff5d51c8084e9bb9dbb73b9cf8467 100644
--- a/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C
+++ b/applications/utilities/mesh/generation/extrude2DMesh/extrude2DMeshApp.C
@@ -256,7 +256,7 @@ int main(int argc, char *argv[])
         const boundBox& bb = mesh().bounds();
         const scalar mergeDim = 1e-4 * bb.minDim();
 
-        PackedBoolList collapseEdge(mesh().nEdges());
+        bitSet collapseEdge(mesh().nEdges());
         Map<point> collapsePointToLocation(mesh().nPoints());
 
         forAll(edges, edgeI)
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
index b208e2a4b2a66afeae676308ddcca2203d3f7314..214992d792c52a892764fcdc5ef632f1b6bc853a 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/cellShapeControl/controlMeshRefinement/controlMeshRefinement.C
@@ -321,7 +321,7 @@ void Foam::controlMeshRefinement::initialMeshPopulation
         sizes.clear();
         alignments.clear();
 
-        PackedBoolList keepVertex(vertices.size(), true);
+        bitSet keepVertex(vertices.size(), true);
 
         forAll(vertices, vI)
         {
@@ -496,7 +496,7 @@ void Foam::controlMeshRefinement::initialMeshPopulation
             }
         }
 
-        PackedBoolList keepVertex(vertices.size(), true);
+        bitSet keepVertex(vertices.size(), true);
 
         forAll(vertices, vI)
         {
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
index 7700aac5c1d1e2b7e163c69daafb088e56d04b73..8437a92e6f3df10749c3e0389fbe1ef0da6a9795 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.C
@@ -1081,7 +1081,7 @@ void Foam::conformalVoronoiMesh::move()
         Zero
     );
 
-    PackedBoolList pointToBeRetained(number_of_vertices(), true);
+    bitSet pointToBeRetained(number_of_vertices(), true);
 
     DynamicList<Point> pointsToInsert(number_of_vertices());
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
index 165011c907dcf6ccb517dac002fff474d0c013fd..497d64796bf3f229dd8e88c3fbd2ecbf81f252e3 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMesh.H
@@ -47,7 +47,7 @@ SourceFiles
 #include "cellShapeControl.H"
 #include "cvControls.H"
 #include "DynamicList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "Time.H"
 #include "polyMesh.H"
 #include "plane.H"
@@ -606,7 +606,7 @@ private:
             pointField& cellCentres,
             labelList& cellToDelaunayVertex,
             labelListList& patchToDelaunayVertex,
-            PackedBoolList& boundaryFacesToRemove
+            bitSet& boundaryFacesToRemove
         );
 
         void calcNeighbourCellCentres
@@ -760,7 +760,7 @@ private:
             wordList& patchNames,
             PtrList<dictionary>& patchDicts,
             labelListList& patchPointPairSlaves,
-            PackedBoolList& boundaryFacesToRemove,
+            bitSet& boundaryFacesToRemove,
             bool includeEmptyPatches = false
         ) const;
 
@@ -791,7 +791,7 @@ private:
             faceList& faces,
             labelList& owner,
             PtrList<dictionary>& patchDicts,
-            PackedBoolList& boundaryFacesToRemove,
+            bitSet& boundaryFacesToRemove,
             const List<DynamicList<face>>& patchFaces,
             const List<DynamicList<label>>& patchOwners,
             const List<DynamicList<bool>>& indirectPatchFace
@@ -997,7 +997,7 @@ public:
                 const wordList& patchNames,
                 const PtrList<dictionary>& patchDicts,
                 const pointField& cellCentres,
-                PackedBoolList& boundaryFacesToRemove
+                bitSet& boundaryFacesToRemove
             ) const;
 
             //- Calculate and write a field of the target cell size,
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
index bc7cd7f7ad3e7e2fdae987a25d021eda8e81593f..ea9d7602883bf204af7d5bd2b105f685fda6e161 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshCalcDualMesh.C
@@ -47,7 +47,7 @@ void Foam::conformalVoronoiMesh::calcDualMesh
     pointField& cellCentres,
     labelList& cellToDelaunayVertex,
     labelListList& patchToDelaunayVertex,
-    PackedBoolList& boundaryFacesToRemove
+    bitSet& boundaryFacesToRemove
 )
 {
     timeCheck("Start calcDualMesh");
@@ -277,7 +277,7 @@ void Foam::conformalVoronoiMesh::calcTetMesh
 
     sortFaces(faces, owner, neighbour);
 
-//    PackedBoolList boundaryFacesToRemove;
+//    bitSet boundaryFacesToRemove;
 //    List<DynamicList<bool>> indirectPatchFace;
 //
 //    addPatches
@@ -703,7 +703,7 @@ Foam::conformalVoronoiMesh::createPolyMeshFromPoints
     PtrList<dictionary> patchDicts;
     pointField cellCentres;
     labelListList patchToDelaunayVertex;
-    PackedBoolList boundaryFacesToRemove;
+    bitSet boundaryFacesToRemove;
 
     timeCheck("Start of checkPolyMeshQuality");
 
@@ -1103,7 +1103,7 @@ Foam::labelHashSet Foam::conformalVoronoiMesh::checkPolyMeshQuality
     }
 
 
-    PackedBoolList ptToBeLimited(pts.size(), false);
+    bitSet ptToBeLimited(pts.size(), false);
 
     forAllConstIter(labelHashSet, wrongFaces, iter)
     {
@@ -1704,7 +1704,7 @@ void Foam::conformalVoronoiMesh::createFacesOwnerNeighbourAndPatches
     wordList& patchNames,
     PtrList<dictionary>& patchDicts,
     labelListList& patchPointPairSlaves,
-    PackedBoolList& boundaryFacesToRemove,
+    bitSet& boundaryFacesToRemove,
     bool includeEmptyPatches
 ) const
 {
@@ -2486,7 +2486,7 @@ void Foam::conformalVoronoiMesh::addPatches
     faceList& faces,
     labelList& owner,
     PtrList<dictionary>& patchDicts,
-    PackedBoolList& boundaryFacesToRemove,
+    bitSet& boundaryFacesToRemove,
     const List<DynamicList<face>>& patchFaces,
     const List<DynamicList<label>>& patchOwners,
     const List<DynamicList<bool>>& indirectPatchFace
@@ -2531,7 +2531,7 @@ void Foam::conformalVoronoiMesh::removeUnusedPoints
 {
     Info<< nl << "Removing unused points" << endl;
 
-    PackedBoolList ptUsed(pts.size(), false);
+    bitSet ptUsed(pts.size(), false);
 
     // Scan all faces to find all of the points that are used
 
@@ -2585,7 +2585,7 @@ Foam::labelList Foam::conformalVoronoiMesh::removeUnusedCells
 {
     Info<< nl << "Removing unused cells" << endl;
 
-    PackedBoolList cellUsed(vertexCount(), false);
+    bitSet cellUsed(vertexCount(), false);
 
     // Scan all faces to find all of the cells that are used
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
index af6f954a5019782e3b17b2ff1ed92d0b384ed60c..26f0e44716d5935c96f9031c208c4a02081119bc 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshConformToSurface.C
@@ -2271,7 +2271,7 @@ void Foam::conformalVoronoiMesh::reinsertSurfaceConformation()
 
     ptPairs_.reIndex(oldToNewIndices);
 
-    PackedBoolList selectedElems(surfaceConformationVertices_.size(), true);
+    bitSet selectedElems(surfaceConformationVertices_.size(), true);
 
     forAll(surfaceConformationVertices_, vI)
     {
@@ -2295,7 +2295,7 @@ void Foam::conformalVoronoiMesh::reinsertSurfaceConformation()
         }
     }
 
-    inplaceSubset<PackedBoolList, List<Vb>>
+    inplaceSubset<bitSet, List<Vb>>
     (
         selectedElems,
         surfaceConformationVertices_
diff --git a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C
index a65d51377257f7db36e1c9bb7829bec2a1e0391d..f8a285717cf16f6bfc3879ca23568e1dca244e98 100644
--- a/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C
+++ b/applications/utilities/mesh/generation/foamyMesh/conformalVoronoiMesh/conformalVoronoiMesh/conformalVoronoiMeshIO.C
@@ -115,7 +115,7 @@ void Foam::conformalVoronoiMesh::writeMesh(const fileName& instance)
         wordList patchNames;
         PtrList<dictionary> patchDicts;
         pointField cellCentres;
-        PackedBoolList boundaryFacesToRemove;
+        bitSet boundaryFacesToRemove;
 
         calcDualMesh
         (
@@ -377,7 +377,7 @@ void Foam::conformalVoronoiMesh::writeMesh(const fileName& instance)
 //
 //        Info<< nl << "Writing tetDualMesh to " << instance << endl;
 //
-//        PackedBoolList boundaryFacesToRemove;
+//        bitSet boundaryFacesToRemove;
 //        writeMesh
 //        (
 //            "tetDualMesh",
@@ -773,7 +773,7 @@ void Foam::conformalVoronoiMesh::writeMesh
     const wordList& patchNames,
     const PtrList<dictionary>& patchDicts,
     const pointField& cellCentres,
-    PackedBoolList& boundaryFacesToRemove
+    bitSet& boundaryFacesToRemove
 ) const
 {
     if (foamyHexMeshControls().objOutput())
@@ -949,7 +949,7 @@ void Foam::conformalVoronoiMesh::writeMesh
         orEqOp<unsigned int>()
     );
 
-    labelList addr(boundaryFacesToRemove.used());
+    labelList addr(boundaryFacesToRemove.toc());
 
     faceSet indirectPatchFaces
     (
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C
index aa31cd391ca37b50cf415d51e17eb1057c247360..8e4543a07d322c26192d6c8cdee964f18f410eb1 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.C
@@ -496,7 +496,7 @@ void Foam::CV2D::newPoints()
     scalar u = 1.0;
     scalar l = 0.7;
 
-    PackedBoolList pointToBeRetained(startOfSurfacePointPairs_, true);
+    bitSet pointToBeRetained(startOfSurfacePointPairs_, true);
 
     std::list<Point> pointsToInsert;
 
diff --git a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.H b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.H
index 1de92b358cb9712d4aee8a775c731e63fe8ce38d..88569485c901c846a4f9d26fac8b1e3a8da738a2 100644
--- a/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.H
+++ b/applications/utilities/mesh/generation/foamyMesh/foamyQuadMesh/CV2D.H
@@ -122,7 +122,7 @@ SourceFiles
 #include "point2DFieldFwd.H"
 #include "dictionary.H"
 #include "Switch.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "EdgeMap.H"
 #include "cv2DControls.H"
 #include "tolerances.H"
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTools.C b/applications/utilities/mesh/manipulation/checkMesh/checkTools.C
index e825b6e23f32ad93fd935a7f44a2e7be1db01dec..27e6ff25f274371e5a40e88c4fc5f05c58fc2ebd 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkTools.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkTools.C
@@ -306,7 +306,7 @@ void Foam::mergeAndWrite
 
 
     // Determine faces on outside of cellSet
-    PackedBoolList isInSet(mesh.nCells());
+    bitSet isInSet(mesh.nCells());
     forAllConstIter(cellSet, set, iter)
     {
         isInSet.set(iter.key());
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C
index 52c91d699fd1b3244fb34b67f025192f2cd43c99..47e164fb229158aa7c41a3e243528ba1b39a5385 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C
@@ -660,7 +660,7 @@ Foam::label Foam::checkTopology
 
             const cellList& cells = mesh.cells();
             const faceList& faces = mesh.faces();
-            PackedBoolList isZonePoint(mesh.nPoints());
+            bitSet isZonePoint(mesh.nPoints());
 
             for (const cellZone& cZone : cellZones)
             {
diff --git a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
index fbda537bdb92a27587c0d0cd0e78c474c02d977b..890f541dd1ddab5551392c4b8a3d5e3bec1ac409 100644
--- a/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
+++ b/applications/utilities/mesh/manipulation/createBaffles/createBaffles.C
@@ -192,7 +192,7 @@ void modifyOrAddFace
     const label zoneID,
     const bool zoneFlip,
 
-    PackedBoolList& modifiedFace
+    bitSet& modifiedFace
 )
 {
     if (modifiedFace.set(facei))
@@ -247,7 +247,7 @@ void createFaces
     const labelList& newMasterPatches,
     const labelList& newSlavePatches,
     polyTopoChange& meshMod,
-    PackedBoolList& modifiedFace,
+    bitSet& modifiedFace,
     label& nModified
 )
 {
@@ -538,15 +538,13 @@ int main(int argc, char *argv[])
         if (mesh.faceZones().findZoneID(name) == -1)
         {
             mesh.faceZones().clearAddressing();
-            label sz = mesh.faceZones().size();
+            const label zoneID = mesh.faceZones().size();
 
-            labelList addr(0);
-            boolList flip(0);
-            mesh.faceZones().setSize(sz+1);
+            mesh.faceZones().setSize(zoneID+1);
             mesh.faceZones().set
             (
-                sz,
-                new faceZone(name, addr, flip, sz, mesh.faceZones())
+                zoneID,
+                new faceZone(name, labelList(), false, zoneID, mesh.faceZones())
             );
         }
     }
@@ -604,7 +602,14 @@ int main(int argc, char *argv[])
         mesh.faceZones().set
         (
             zoneID,
-            new faceZone(name, addr, flip, zoneID, mesh.faceZones())
+            new faceZone
+            (
+                name,
+                std::move(addr),
+                std::move(flip),
+                zoneID,
+                mesh.faceZones()
+            )
         );
     }
 
@@ -751,7 +756,7 @@ int main(int argc, char *argv[])
     //   side come first and faces from the other side next.
 
     // Whether first use of face (modify) or consecutive (add)
-    PackedBoolList modifiedFace(mesh.nFaces());
+    bitSet modifiedFace(mesh.nFaces());
     label nModified = 0;
 
     forAll(selectors, selectorI)
diff --git a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
index 331972671b4d0ffa0a13789f47ee27e1303a6685..7e2b7fe3a2a596cf7ad4a650f1163c875d7228b0 100644
--- a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
+++ b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
@@ -483,7 +483,7 @@ int main(int argc, char *argv[])
             }
             candidates.setCapacity(sz);
 
-            PackedBoolList isCandidate(mesh.nPoints());
+            bitSet isCandidate(mesh.nPoints());
             forAll(splitPatchIDs, i)
             {
                 const labelList& mp = patches[splitPatchIDs[i]].meshPoints();
diff --git a/applications/utilities/mesh/manipulation/orientFaceZone/orientFaceZone.C b/applications/utilities/mesh/manipulation/orientFaceZone/orientFaceZone.C
index 012ec8a4c87a6ff763a1370caf8674d7f9b586a0..947d593625fa0130804ade03d4e71d3a4cdd6abf 100644
--- a/applications/utilities/mesh/manipulation/orientFaceZone/orientFaceZone.C
+++ b/applications/utilities/mesh/manipulation/orientFaceZone/orientFaceZone.C
@@ -87,7 +87,7 @@ int main(int argc, char *argv[])
 
 
 
-    const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
+    const bitSet isMasterFace(syncTools::getMasterFaces(mesh));
 
 
     // Data on all edges and faces
diff --git a/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C b/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C
index 28aa492564b9d90564f0c95c37513c6f469e185c..a586daad681245d698863ca063deb5a014f21cbe 100644
--- a/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C
+++ b/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.C
@@ -146,7 +146,7 @@ Foam::label Foam::meshDualiser::findDualCell
 
 void Foam::meshDualiser::generateDualBoundaryEdges
 (
-    const PackedBoolList& isBoundaryEdge,
+    const bitSet& isBoundaryEdge,
     const label pointi,
     polyTopoChange& meshMod
 )
@@ -374,7 +374,7 @@ Foam::label Foam::meshDualiser::addBoundaryFace
 void Foam::meshDualiser::createFacesAroundEdge
 (
     const bool splitFace,
-    const PackedBoolList& isBoundaryEdge,
+    const bitSet& isBoundaryEdge,
     const label edgeI,
     const label startFacei,
     polyTopoChange& meshMod,
@@ -886,7 +886,7 @@ void Foam::meshDualiser::setRefinement
     // Mark boundary edges and points.
     // (Note: in 1.4.2 we can use the built-in mesh point ordering
     //  facility instead)
-    PackedBoolList isBoundaryEdge(mesh_.nEdges());
+    bitSet isBoundaryEdge(mesh_.nEdges());
     for (label facei = mesh_.nInternalFaces(); facei < mesh_.nFaces(); facei++)
     {
         const labelList& fEdges = mesh_.faceEdges()[facei];
diff --git a/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.H b/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.H
index 0cb7d2b913a0a463c45cd6837f7038f97857511d..ce631f4ad033b05bcfc4fcc58da322c2fd9a7357 100644
--- a/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.H
+++ b/applications/utilities/mesh/manipulation/polyDualMesh/meshDualiser.H
@@ -48,7 +48,7 @@ SourceFiles
 #define meshDualiser_H
 
 #include "DynamicList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "boolList.H"
 #include "typeInfo.H"
 
@@ -100,7 +100,7 @@ class meshDualiser
         //  emanating from (boundary & feature) point
         void generateDualBoundaryEdges
         (
-            const PackedBoolList& isBoundaryEdge,
+            const bitSet& isBoundaryEdge,
             const label pointi,
             polyTopoChange& meshMod
         );
@@ -143,7 +143,7 @@ class meshDualiser
         void createFacesAroundEdge
         (
             const bool splitFace,
-            const PackedBoolList& isBoundaryEdge,
+            const bitSet& isBoundaryEdge,
             const label edgeI,
             const label startFacei,
             polyTopoChange& meshMod,
diff --git a/applications/utilities/mesh/manipulation/polyDualMesh/polyDualMeshApp.C b/applications/utilities/mesh/manipulation/polyDualMesh/polyDualMeshApp.C
index 9b68c7baf796c0debca4508dc63d79881779525c..c8128127a1047a8ce0e88b455a6c487a536b56ce 100644
--- a/applications/utilities/mesh/manipulation/polyDualMesh/polyDualMeshApp.C
+++ b/applications/utilities/mesh/manipulation/polyDualMesh/polyDualMeshApp.C
@@ -67,7 +67,7 @@ Note
 #include "unitConversion.H"
 #include "polyTopoChange.H"
 #include "mapPolyMesh.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "meshTools.H"
 #include "OFstream.H"
 #include "meshDualiser.H"
@@ -87,7 +87,7 @@ using namespace Foam;
 void simpleMarkFeatures
 (
     const polyMesh& mesh,
-    const PackedBoolList& isBoundaryEdge,
+    const bitSet& isBoundaryEdge,
     const scalar featureAngle,
     const bool concaveMultiCells,
     const bool doNotPreserveFaceZones,
@@ -390,7 +390,7 @@ int main(int argc, char *argv[])
     // Mark boundary edges and points.
     // (Note: in 1.4.2 we can use the built-in mesh point ordering
     //  facility instead)
-    PackedBoolList isBoundaryEdge(mesh.nEdges());
+    bitSet isBoundaryEdge(mesh.nEdges());
     for (label facei = mesh.nInternalFaces(); facei < mesh.nFaces(); facei++)
     {
         const labelList& fEdges = mesh.faceEdges()[facei];
diff --git a/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C b/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
index 367e62392a47c687bcea1f9069239c0ccb40e9cb..c4b0c01b6d56464aa73429af568802678910d51a 100644
--- a/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
+++ b/applications/utilities/mesh/manipulation/refineMesh/refineMesh.C
@@ -79,7 +79,7 @@ void printEdgeStats(const polyMesh& mesh)
     scalar minOther = GREAT;
     scalar maxOther = -GREAT;
 
-    PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
+    bitSet isMasterEdge(syncTools::getMasterEdges(mesh));
 
     const edgeList& edges = mesh.edges();
 
diff --git a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C
index 7386075a64c408a7e53545dac696ff30602be36a..b655aceab7238b1d146ac0a7c894a3c8a3e9990f 100644
--- a/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C
+++ b/applications/utilities/mesh/manipulation/subsetMesh/subsetMesh.C
@@ -303,7 +303,7 @@ void subsetTopoSets
         Info<< "Subsetting " << set.type() << " " << set.name() << endl;
 
         // Map the data
-        PackedBoolList isSet(set.maxSize(mesh));
+        bitSet isSet(set.maxSize(mesh));
         forAllConstIters(set, iter)
         {
             isSet.set(iter.key());
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C
index c4bf9d4f70ed6cfb940c0ba27220f044756b66bb..9285d85a073d5dc282b40fb390e81f6d0461a203 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecompositionMesh.C
@@ -32,7 +32,7 @@ Description
 
 #include "domainDecomposition.H"
 #include "IOstreams.H"
-#include "boolList.H"
+#include "bitSet.H"
 #include "cyclicPolyPatch.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -434,7 +434,6 @@ void Foam::domainDecomposition::decomposeMesh()
 //    }
 
 
-
     Info<< "\nDistributing points to processors" << endl;
     // For every processor, loop through the list of faces for the processor.
     // For every face, loop through the list of points and mark the point as
@@ -443,42 +442,19 @@ void Foam::domainDecomposition::decomposeMesh()
 
     forAll(procPointAddressing_, proci)
     {
-        boolList pointLabels(nPoints(), false);
-
-        // Get reference to list of used faces
-        const labelList& procFaceLabels = procFaceAddressing_[proci];
+        bitSet pointsInUse(nPoints(), false);
 
-        forAll(procFaceLabels, facei)
+        // For each of the faces used
+        for (const label facei : procFaceAddressing_[proci])
         {
-            // Because of the turning index, some labels may be negative
-            const labelList& facePoints = fcs[mag(procFaceLabels[facei]) - 1];
-
-            forAll(facePoints, pointi)
-            {
-                // Mark the point as used
-                pointLabels[facePoints[pointi]] = true;
-            }
-        }
-
-        // Collect the used points
-        labelList& procPointLabels = procPointAddressing_[proci];
+            // Because of the turning index, some face labels may be -ve
+            const labelList& facePoints = fcs[mag(facei) - 1];
 
-        procPointLabels.setSize(pointLabels.size());
-
-        label nUsedPoints = 0;
-
-        forAll(pointLabels, pointi)
-        {
-            if (pointLabels[pointi])
-            {
-                procPointLabels[nUsedPoints] = pointi;
-
-                nUsedPoints++;
-            }
+            // Mark the face points as being used
+            pointsInUse.setMany(facePoints);
         }
 
-        // Reset the size of used points
-        procPointLabels.setSize(nUsedPoints);
+        procPointAddressing_[proci] = pointsInUse.sortedToc();
     }
 }
 
diff --git a/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C b/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C
index 30bd9223d5fd83d2bcb6663cf3bad8ed423bca83..a45bb8ffa35607338e697e24c489a1a7c4c2db27 100644
--- a/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C
+++ b/applications/utilities/surface/surfaceHookUp/surfaceHookUp.C
@@ -41,7 +41,7 @@ Usage
 #include "triSurfaceMesh.H"
 #include "indexedOctree.H"
 #include "treeBoundBox.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "unitConversion.H"
 #include "searchableSurfaces.H"
 #include "IOdictionary.H"
@@ -329,7 +329,7 @@ int main(int argc, char *argv[])
 
     List<DynamicList<labelledTri>> newFaces(surfs.size());
     List<DynamicList<point>> newPoints(surfs.size());
-    List<PackedBoolList> visitedFace(surfs.size());
+    List<bitSet> visitedFace(surfs.size());
 
     PtrList<triSurfaceMesh> newSurfaces(surfs.size());
     forAll(surfs, surfI)
@@ -370,7 +370,7 @@ int main(int argc, char *argv[])
 
             newFaces[surfI] = newSurf.localFaces();
             newPoints[surfI] = newSurf.localPoints();
-            visitedFace[surfI] = PackedBoolList(newSurf.size(), false);
+            visitedFace[surfI] = bitSet(newSurf.size(), false);
         }
 
         forAll(newSurfaces, surfI)
diff --git a/applications/utilities/surface/surfaceInflate/surfaceInflate.C b/applications/utilities/surface/surfaceInflate/surfaceInflate.C
index 83f5be06afed4a84e155ad7ae306d6f595d5afc1..039bae91e82a7fbe118b2e7e07e7ba3ffdc08820 100644
--- a/applications/utilities/surface/surfaceInflate/surfaceInflate.C
+++ b/applications/utilities/surface/surfaceInflate/surfaceInflate.C
@@ -54,7 +54,7 @@ Usage
 #include "triSurfaceFields.H"
 #include "triSurfaceMesh.H"
 #include "triSurfaceGeoMesh.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "OBJstream.H"
 #include "surfaceFeatures.H"
 
@@ -131,7 +131,7 @@ tmp<vectorField> calcVertexNormals(const triSurface& surf)
 tmp<vectorField> calcPointNormals
 (
     const triSurface& s,
-    const PackedBoolList& isFeaturePoint,
+    const bitSet& isFeaturePoint,
     const List<surfaceFeatures::edgeStatus>& edgeStat
 )
 {
@@ -215,7 +215,7 @@ tmp<vectorField> calcPointNormals
 void detectSelfIntersections
 (
     const triSurfaceMesh& s,
-    PackedBoolList& isEdgeIntersecting
+    bitSet& isEdgeIntersecting
 )
 {
     const edgeList& edges = s.edges();
@@ -258,9 +258,9 @@ label detectIntersectionPoints
     const vectorField& displacement,
 
     const bool checkSelfIntersect,
-    const PackedBoolList& initialIsEdgeIntersecting,
+    const bitSet& initialIsEdgeIntersecting,
 
-    PackedBoolList& isPointOnHitEdge,
+    bitSet& isPointOnHitEdge,
     scalarField& scale
 )
 {
@@ -307,7 +307,7 @@ label detectIntersectionPoints
     // 2. (new) surface self intersections
     if (checkSelfIntersect)
     {
-        PackedBoolList isEdgeIntersecting;
+        bitSet isEdgeIntersecting;
         detectSelfIntersections(s, isEdgeIntersecting);
 
         const edgeList& edges = s.edges();
@@ -400,7 +400,7 @@ tmp<scalarField> avg
 void minSmooth
 (
     const triSurface& s,
-    const PackedBoolList& isAffectedPoint,
+    const bitSet& isAffectedPoint,
     const scalarField& fld,
     scalarField& newFld
 )
@@ -442,19 +442,19 @@ void lloydsSmoothing
 (
     const label nSmooth,
     triSurface& s,
-    const PackedBoolList& isFeaturePoint,
+    const bitSet& isFeaturePoint,
     const List<surfaceFeatures::edgeStatus>& edgeStat,
-    const PackedBoolList& isAffectedPoint
+    const bitSet& isAffectedPoint
 )
 {
     const labelList& meshPoints = s.meshPoints();
     const edgeList& edges = s.edges();
 
 
-    PackedBoolList isSmoothPoint(isAffectedPoint);
+    bitSet isSmoothPoint(isAffectedPoint);
     // Extend isSmoothPoint
     {
-        PackedBoolList newIsSmoothPoint(isSmoothPoint);
+        bitSet newIsSmoothPoint(isSmoothPoint);
         forAll(edges, edgeI)
         {
             const edge& e = edges[edgeI];
@@ -539,7 +539,7 @@ void lloydsSmoothing
 
         // Extend isSmoothPoint
         {
-            PackedBoolList newIsSmoothPoint(isSmoothPoint);
+            bitSet newIsSmoothPoint(isSmoothPoint);
             forAll(edges, edgeI)
             {
                 const edge& e = edges[edgeI];
@@ -662,7 +662,7 @@ int main(int argc, char *argv[])
         << " out of " << s.nEdges() << nl
         << endl;
 
-    PackedBoolList isFeaturePoint(s.nPoints(), features.featurePoints());
+    bitSet isFeaturePoint(s.nPoints(), features.featurePoints());
 
     const List<surfaceFeatures::edgeStatus> edgeStat(features.toStatus());
 
@@ -723,11 +723,11 @@ int main(int argc, char *argv[])
 
 
     // Any point on any intersected edge in any of the iterations
-    PackedBoolList isScaledPoint(s.nPoints());
+    bitSet isScaledPoint(s.nPoints());
 
 
     // Detect any self intersections on initial mesh
-    PackedBoolList initialIsEdgeIntersecting;
+    bitSet initialIsEdgeIntersecting;
     if (checkSelfIntersect)
     {
         detectSelfIntersections(s, initialIsEdgeIntersecting);
@@ -775,7 +775,7 @@ int main(int argc, char *argv[])
 
 
         // Detect any intersections and scale back
-        PackedBoolList isAffectedPoint;
+        bitSet isAffectedPoint;
         label nIntersections = detectIntersectionPoints
         (
             1e-9,       // intersection tolerance
@@ -818,7 +818,7 @@ int main(int argc, char *argv[])
             minSmooth
             (
                 s,
-                PackedBoolList(s.nPoints(), true),
+                bitSet(s.nPoints(), true),
                 oldScale,
                 scale
             );
diff --git a/applications/utilities/surface/surfaceLambdaMuSmooth/surfaceLambdaMuSmooth.C b/applications/utilities/surface/surfaceLambdaMuSmooth/surfaceLambdaMuSmooth.C
index 7eccb601376627bb5612fbcbd4c4e497e267cc3a..ef6e5c33466f91335301ea155f0e0a3edd17b445 100644
--- a/applications/utilities/surface/surfaceLambdaMuSmooth/surfaceLambdaMuSmooth.C
+++ b/applications/utilities/surface/surfaceLambdaMuSmooth/surfaceLambdaMuSmooth.C
@@ -54,7 +54,7 @@ using namespace Foam;
 tmp<pointField> avg
 (
     const meshedSurface& s,
-    const PackedBoolList& fixedPoints
+    const bitSet& fixedPoints
 )
 {
     const labelListList& pointEdges = s.pointEdges();
@@ -95,7 +95,7 @@ void getFixedPoints
 (
     const edgeMesh& feMesh,
     const pointField& points,
-    PackedBoolList& fixedPoints
+    bitSet& fixedPoints
 )
 {
     scalarList matchDistance(feMesh.points().size(), 1e-1);
@@ -177,7 +177,7 @@ int main(int argc, char *argv[])
         << "Vertices    : " << surf1.nPoints() << nl
         << "Bounding Box: " << boundBox(surf1.localPoints()) << endl;
 
-    PackedBoolList fixedPoints(surf1.localPoints().size(), false);
+    bitSet fixedPoints(surf1.localPoints().size(), false);
 
     if (args.found("featureFile"))
     {
diff --git a/etc/controlDict b/etc/controlDict
index b64ec0ecf16f989afd942e27920e8617ed8d0faf..eae042cad4fe38bb12e07deed17281f807e6aa2b 100644
--- a/etc/controlDict
+++ b/etc/controlDict
@@ -390,6 +390,7 @@ DebugSwitches
     basicMixture        0;
     basicReactingCloud  0;
     basicReactingParcel 0;
+    bitSet              0;
     fluidThermo         0;
     fluidThermoCloud    0;
     fluidThermoParcel   0;
diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files
index 944d0d26abdd8b5ab6bef5b55ddfc86a839890bb..82a1e700e148f248c47cc96ac8f8b59c00cde3c5 100644
--- a/src/OpenFOAM/Make/files
+++ b/src/OpenFOAM/Make/files
@@ -145,11 +145,12 @@ primitives/polynomialEqns/quadraticEqn/quadraticEqn.C
 primitives/Barycentric/barycentric/barycentric.C
 primitives/Barycentric2D/barycentric2D/barycentric2D.C
 
+containers/Bits/bitSet/bitSet.C
+containers/Bits/bitSet/bitSetIO.C
+containers/Bits/PackedList/PackedListCore.C
 containers/HashTables/HashOps/HashOps.C
 containers/HashTables/HashTable/HashTableCore.C
 containers/Lists/SortableList/ParSortableListName.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
diff --git a/src/OpenFOAM/containers/Bits/BitOps/BitOps.H b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H
new file mode 100644
index 0000000000000000000000000000000000000000..e031ac3f8a938bb0521ad71fe1629f54214cad73
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/BitOps/BitOps.H
@@ -0,0 +1,192 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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/>.
+
+Namespace
+    Foam::BitOps
+
+Description
+    Various bit-wise operations, etc.
+
+    The population count uses the Hamming weight
+    (http://en.wikipedia.org/wiki/Hamming_weight).
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef BitOps_H
+#define BitOps_H
+
+#include "label.H"
+#include "Ostream.H"
+#include <limits>
+#include <utility>
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Namespace BitOps Declaration
+\*---------------------------------------------------------------------------*/
+
+namespace BitOps
+{
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//- Count arbitrary number of bits (of an integral type)
+template<class UIntType>
+inline unsigned int bit_count(UIntType x)
+{
+    unsigned int n = 0u;
+
+    for (; x; ++n) { x &= (x-1); }
+
+    return n;
+}
+
+
+//- Count bits in a 32-bit value (Hamming weight method)
+template<>
+inline unsigned int bit_count(uint32_t x)
+{
+    x -= (x >> 1) & 0x55555555;
+    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
+
+    return ((((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24);
+}
+
+
+//- Count bits in a 64-bit value (Hamming weight method)
+template<>
+inline unsigned int bit_count(uint64_t x)
+{
+    x -= (x >> 1) & 0x5555555555555555;
+    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);
+
+    return unsigned
+        ((((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56);
+}
+
+
+//- Repeat a value of the given BitWidth into the destination output type.
+template<class UIntType, unsigned BitWidth>
+inline UIntType repeat_value(unsigned val)
+{
+    static_assert
+    (
+        BitWidth && std::numeric_limits<UIntType>::digits >= BitWidth,
+        "BitWidth too large for target output"
+    );
+
+    // How many fit into the target
+    const unsigned nrepeat = (std::numeric_limits<UIntType>::digits / BitWidth);
+
+    // Max value for a single element
+    const unsigned mask = ((1u << BitWidth) - 1);
+
+    // The first occurance
+    UIntType fillval = ((val >= mask) ? mask : val);
+
+    // Repeated
+    for (unsigned i = 1; i < nrepeat; ++i)
+    {
+        fillval |= (fillval << BitWidth);
+    }
+
+    return fillval;
+}
+
+
+//- Print 0/1 bits in the (unsigned) integral type
+template<class UIntType>
+inline Ostream& print(Ostream& os, UIntType value, char off='0', char on='1')
+{
+    if (os.format() == IOstream::BINARY)
+    {
+        // Perhaps not the most sensible, but the only thing we currently have.
+        os << label(value);
+    }
+    else
+    {
+        // Starting from most significant bit - makes for easy reading.
+        for
+        (
+            unsigned test = (1u << (std::numeric_limits<UIntType>::digits-1));
+            test;
+            test >>= 1u
+        )
+        {
+            os << ((value & test) ? on : off);
+        }
+    }
+
+    return os;
+}
+
+
+//- An (unsigned) integral type adapter, for output of bit values
+template<class UIntType>
+struct bitInfo
+{
+    typedef UIntType value_type;
+
+    value_type value;
+
+    //- Null constructible as zero
+    bitInfo() : value(0) {}
+
+    //- Value construct
+    explicit bitInfo(UIntType val) : value(val) {}
+
+    //- Conversion to base type
+    operator UIntType () const { return value; }
+
+    //- Conversion to base type
+    operator UIntType& () { return value; }
+};
+
+
+} // End namespace BitOps
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+//- Print 0/1 bits of an (unsigned) integral type via an adapter
+template<class UIntType>
+inline Ostream& operator<<(Ostream& os, const BitOps::bitInfo<UIntType>& info)
+{
+    BitOps::print(os, info.value);
+    return os;
+}
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedList.C b/src/OpenFOAM/containers/Bits/PackedList/PackedList.C
new file mode 100644
index 0000000000000000000000000000000000000000..9f636b2c41383f20a9efbed6d8dcf071e86b8caf
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.C
@@ -0,0 +1,120 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 "PackedList.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<unsigned Width>
+bool Foam::PackedList<Width>::uniform() const
+{
+    if (size() < 2)
+    {
+        return false;   // Trivial case
+    }
+
+    // The value of the first element for testing
+    const unsigned int val = get(0);
+
+    const label nblocks = num_blocks(size());
+
+    bool identical = true;
+
+    if (!val)
+    {
+        // Zero value: can just check block content directly
+
+        for (label blocki = 0; identical && blocki < nblocks; ++blocki)
+        {
+            identical = !blocks_[blocki];
+        }
+
+        return identical;
+    }
+    else if (nblocks > 1)
+    {
+        // Check all blocks that are completely occupied: (nblocks-1)
+        const unsigned int blockval =
+            BitOps::repeat_value<block_type,Width>(val);
+
+        for (label blocki = 0; identical && blocki < (nblocks-1); ++blocki)
+        {
+            identical = (blocks_[blocki] == blockval);
+        }
+    }
+
+    // Partial block: check manually
+    for
+    (
+        label elemi = elem_per_block*(nblocks-1);
+        identical && elemi < size();
+        ++elemi
+    )
+    {
+        identical = (val == get(elemi));
+    }
+
+    return identical;
+}
+
+
+template<unsigned Width>
+Foam::labelList Foam::PackedList<Width>::values() const
+{
+    if (size() < 2 || uniform())
+    {
+        const label val = (size() ? get(0) : 0);
+
+        return labelList(size(), val);
+    }
+
+    labelList output(size());
+    label outi = 0;
+
+    // Process n-1 complete blocks
+    const label nblocks = num_blocks(size());
+
+    for (label blocki=0; blocki < nblocks-1; ++blocki)
+    {
+        unsigned int blockval = blocks_[blocki];
+
+        for (unsigned nget = elem_per_block; nget; --nget, ++outi)
+        {
+            output[outi] = label(blockval & max_value);
+            blockval >>= Width;
+        }
+    }
+
+    // Any partial blocks
+    for (/*nil*/; outi < size(); ++outi)
+    {
+        output[outi] = get(outi);
+    }
+
+    return output;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
similarity index 51%
rename from src/OpenFOAM/containers/Lists/PackedList/PackedList.H
rename to src/OpenFOAM/containers/Bits/PackedList/PackedList.H
index 18b1b6d7bcb7a2b46067d36326eb5dda3514b1aa..017d7f8e1b1b3f8d722ea19380a59c01b8c2f4ea 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.H
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedList.H
@@ -25,11 +25,11 @@ Class
     Foam::PackedList
 
 Description
-    A dynamically list of packed unsigned integers, with the number of bits
-    per item specified by the \<nBits\> template parameter.
+    A dynamic list of packed unsigned integers, with the number of bits
+    per item specified by the \<Width\> template parameter.
 
     Resizing is similar to DynamicList so that clear() and resize() affect
-    the addessed size, but not the allocated size. The reserve() and
+    the addressed size, but not the allocated size. The reserve() and
     setCapacity() methods can be used to influence the allocation.
 
 Note
@@ -37,13 +37,20 @@ Note
     with out-of-range elements returned as zero.
 
     In a non-const context, the '[]' operator returns a reference to an
-    existing value. Some caution with out-of-range elements to ensure
-    that the const version of the [] operator is being called.
-    The get() method is functionally identical to the '[]' operator, but
+    existing value. When accessing out-of-range elements, some caution
+    is required to ensure that the const version of the [] operator is actually
+    being called.
+    The get() method is functionally identical the the '[]' operator, but
     is always const access.
 
     The set() and unset() methods return a bool if the value changed.
-    This can be useful for branching on changed values.
+
+    With const access, the get() method and 'operator[]' are identical.
+    With non-const access, the 'operator[]' may be marginally slower get().
+
+    The set() method may be marginally faster than using the 'operator[]'
+    supports auto-vivification and also returns a bool if the value changed,
+    which can be useful for branching on changed values.
 
     \code
         list.set(5, 4);
@@ -56,27 +63,38 @@ Note
     For example,
     \code
         list.resize(4);
-        Info<< list.get(10) << "\n";  // print zero, but doesn't adjust list
+        Info<< list.get(10) << "\n";    // print zero, but doesn't adjust list
+        list.set(8);                    // auto-vivify
     \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.
 
+Note
+    Iterators for this class have been intentionally removed, for performance
+    reasons.
+
 See also
+    Foam::BitOps
     Foam::DynamicList
 
 SourceFiles
     PackedListI.H
     PackedList.C
+    PackedListIO.C
 
 \*---------------------------------------------------------------------------*/
 
 #ifndef PackedList_H
 #define PackedList_H
 
+#include "BitOps.H"
 #include "labelList.H"
 #include "UIndirectList.H"
+#include "InfoProxy.H"
+#include "PackedListCore.H"
+
 #include <type_traits>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -85,86 +103,117 @@ namespace Foam
 {
 
 // Forward declarations
-template<unsigned nBits> class PackedList;
+template<unsigned Width> class PackedList;
 class Istream;
 class Ostream;
 
-template<unsigned nBits>
-Istream& operator>>(Istream& is, PackedList<nBits>& lst);
-template<unsigned nBits>
-Ostream& operator<<(Ostream& os, const PackedList<nBits>& lst);
+template<unsigned Width>
+Istream& operator>>(Istream& is, PackedList<Width>& list);
 
+template<unsigned Width>
+Ostream& operator<<(Ostream& os, const PackedList<Width>& list);
 
-/*---------------------------------------------------------------------------*\
-                       Class PackedListCore Declaration
-\*---------------------------------------------------------------------------*/
-
-//- Template-invariant bits for PackedList
-struct PackedListCore
-{
-    //- Construct null
-    PackedListCore()
-    {}
-
-    //- Define template name and debug
-    ClassName("PackedList");
-};
+template<unsigned Width>
+Ostream& operator<<(Ostream& os, const InfoProxy<PackedList<Width>>& info);
 
 
 /*---------------------------------------------------------------------------*\
                          Class PackedList Declaration
 \*---------------------------------------------------------------------------*/
 
-template<unsigned nBits=1>
+template<unsigned Width>
 class PackedList
 :
-    public PackedListCore,
-    private List<unsigned int>
+    public Detail::PackedListCore
 {
-protected:
+public:
 
-    typedef unsigned int      StorageType;
-    typedef List<StorageType> StorageList;
+    // Types and dimension information
 
-    // Protected Member Functions
+        //- The storage block type for bit elements
+        typedef unsigned int block_type;
 
-        //- Calculate the list length when packed
-        inline static constexpr label packedLength(const label nElem);
+        //- The number of bits in a single block
+        static constexpr unsigned bits_per_block
+            = (std::numeric_limits<block_type>::digits);
 
-        //- Read a list entry (allows for specialization)
-        inline static unsigned int readValue(Istream& is);
+        //- The width of an individual element (in bits).
+        static constexpr unsigned element_width = (Width);
+
+        //- The number of elements stored per data block.
+        static constexpr unsigned elem_per_block = (bits_per_block / Width);
+
+        //- The max value for an element which is also the bit-mask of the
+        //- individual element.
+        //  Eg, for Width=2: ((1 << 2) - 1) == 0b0011
+        static constexpr block_type max_value = ((1u << Width) - 1);
+
+        //- Calculate the number of blocks required to _address_ the
+        //- requested number of elements.
+        //
+        // We calculate this:
+        // \code
+        //     (numElem / elem_per_block)
+        //   + (numElem % elem_per_block) ? 1 : 0
+        // \code
+        // But avoiding the modulus operation
+        static constexpr label num_blocks(label numElem)
+        {
+            return ((numElem - 1 + elem_per_block) / elem_per_block);
+        }
+
+        //- Masking for all bits below the element offset.
+        //  Ill-defined when elementOffset is out of range.
+        static constexpr block_type mask_lower(unsigned elementOffset)
+        {
+            return (~0u >> (bits_per_block - Width * elementOffset));
+        }
 
-        //- Read an index/value pair and set accordingly.
-        //  For bool specialization, read a single index value
-        inline void setPair(Istream& is);
 
+protected:
 
-private:
+    // Protected Data
 
-    //- 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.
-    static_assert
-    (
-        nBits && nBits <= (sizeof(StorageType) << 2),
-        "nBits must be positive (non-zero) and fit within the storage"
-    );
+        //- The internal container for storing the blocks
+        typedef List<block_type> block_container;
 
-    // Private data
+        //- The blocks of raw data
+        block_container blocks_;
 
-        //- Number of nBits entries
+        //- Number of entries used
         label size_;
 
+        //- Enforce non-zero Width to fit within the block storage and require
+        //- at least 2 items per storage block for general efficiency.
+        //
+        //  Thus 1/2 of the base storage size is (sizeof(block_type)*8/2),
+        //  or (sizeof(block_type) << 2)
+        static_assert
+        (
+            Width && Width <= (sizeof(block_type) << 2),
+            "Width must be > 0 and minimum of two items per data block"
+        );
 
-protected:
 
     // Protected Member Functions
 
+        //- A fill value for complete blocks
+        inline static unsigned int repeated_value(unsigned val);
+
+        //- Read a list entry (allows for specialization)
+        inline static unsigned int readValue(Istream& is);
+
+        //- Read an index/value pair and set accordingly.
+        //  For bool specialization, read a single index value
+        inline void setPair(Istream& is);
+
         //- Write as a dictionary entry
         void writeEntry(Ostream& os) const;
 
+        //- Clear any partial rubbish in the last addressable block
+        //  This \a rubbish may have arisen from block-wise operations etc.
+        inline void clear_trailing_bits();
+
 
 public:
 
@@ -174,129 +223,93 @@ public:
         typedef unsigned int const_reference;
 
 
-    // Public data
-
-        //- The max. number of bits that can be templated.
-        //  Might someday be useful for a template assert.
-        inline static constexpr unsigned int max_bits();
-
-        //- The max. value for an entry, which simultaneously the bit-mask
-        //  eg, ((1 << 2) - 1) yields 0b0011
-        inline static constexpr unsigned int max_value();
-
-        //- The number of entries per packed storage element
-        inline static constexpr unsigned int packing();
-
-        //- Masking for all bits below the offset
-        inline static constexpr unsigned int maskLower(unsigned offset);
-
-
     // Constructors
 
         //- Null constructor
-        inline PackedList();
+        inline constexpr PackedList() noexcept;
 
-        //- Construct with given size, initializes list to 0
-        explicit inline PackedList(const label size);
+        //- Construct for given number of elements, initializes values to 0
+        explicit inline PackedList(const label numElem);
 
-        //- Construct with given size and value for all elements
-        inline PackedList(const label size, const unsigned val);
+        //- Construct for given number of elements, and the specified
+        //- value for each element
+        inline PackedList(const label numElem, const unsigned int val);
 
         //- Construct from Istream
         inline PackedList(Istream& is);
 
         //- Copy construct
-        inline PackedList(const PackedList<nBits>& lst);
+        inline PackedList(const PackedList<Width>& rhs);
 
         //- Move construct
-        inline PackedList(PackedList<nBits>&& lst);
+        inline PackedList(PackedList<Width>&& rhs);
 
-        //- Construct from a list of labels
-        explicit inline PackedList(const labelUList& lst);
+        //- Construct from a list of values
+        explicit inline PackedList(const labelUList& values);
 
-        //- Construct from an indirect list of labels
-        explicit inline PackedList(const labelUIndList& lst);
+        //- Construct from a list of values
+        explicit inline PackedList(const labelUIndList& values);
 
         //- Clone
-        inline autoPtr<PackedList<nBits>> clone() const;
+        inline autoPtr<PackedList<Width>> clone() const;
 
 
     // Member Functions
 
-    // Access
+    // Query
 
-        //- The number of elements that can be stored before reallocating
-        inline label capacity() const;
+        //- Check index is within valid range [0,size)
+        inline void checkIndex(const label i) const;
 
         //- Number of entries.
-        inline label size() const;
+        inline label size() const noexcept;
 
         //- Return true if the list is empty (ie, size() is zero).
-        inline bool empty() const;
+        inline bool empty() const noexcept;
+
+        //- The number of elements that can be stored with reallocating
+        inline label capacity() const;
 
-        //- Get value at index I.
+        //- True if there are two or more entries and all entries have
+        //- identical values.
+        bool uniform() const;
+
+
+    // Access
+
+        //- Get value at index i or 0 for out-of-range.
         //  Never auto-vivify entries.
         inline unsigned int get(const label i) const;
 
-        //- Set value at index I, default value set is the max_value.
+        //- Set value at index i, default value set is the max_value.
         //  Does auto-vivify for non-existent, non-zero entries.
         //  \return true if value changed.
-        inline bool set(const label i, const unsigned int val = ~0u);
+        inline bool set(const label i, unsigned int val = ~0u);
 
-        //- Unset the entry at index I.
+        //- Unset the entry at index i.
         //  Never auto-vivify entries.
-        //  \return true if value changed.
+        //  \return true if the value changed.
         inline bool unset(const label i);
 
-        //- 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;
-
-        //- The number of bytes used in the underlying storage
-        inline std::streamsize 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 list of labels
         labelList values() const;
 
-        //- Print bit patterns, optionally output unused elements
-        //
-        // addressable bits:
-        //   on: '1', off: '-'
-        //
-        // non-addressable bits:
-        //   on: '!', off: '.'
-        //
-        Ostream& printBits(Ostream& os, const bool fullOutput=false) const;
-
-        //- Print information and bit patterns (with printBits)
-        Ostream& printInfo(Ostream& os, const bool fullOutput=false) const;
-
-    // Check
-
-        //- Check index is within valid range [0,size)
-        inline void checkIndex(const label i) const;
-
 
     // Edit
 
-        //- Trim any trailing zero elements
-        bool trim();
+        //- Assign all entries to the given value. Takes linear time.
+        inline void assign(const unsigned int val);
 
-        //- Invert the bits in the addressable region
-        void flip();
+        //- Copy assignment.
+        inline void assign(const PackedList<Width>& rhs);
 
-        //- Clear all bits
+        //- Trim any trailing zero elements, optionally specifying a
+        //- a minimum position, below which trimming will not occur.
+        //
+        //  \return true if trimming changed the size.
+        inline bool trim(label minpos=-1);
+
+        //- Clear all bits but do not adjust the addressable size.
         inline void reset();
 
         //- Alter the size of the underlying storage.
@@ -327,13 +340,36 @@ public:
         //- Shrink the allocated space to what is actually used.
         inline void shrink();
 
+        //- Swap contents with argument
+        inline void swap(PackedList<Width>& rhs);
+
         //- Transfer the contents of the argument list into this list
         //  and annul the argument list.
-        inline void transfer(PackedList<nBits>& lst);
+        inline void transfer(PackedList<Width>& rhs);
+
+
+    // Low-level access
+
+        //- The number of bytes used in the underlying storage
+        //- including any unused padding.
+        inline std::streamsize byteSize() const;
+
+        //- The number of internal storage blocks
+        inline label nBlocks() const;
+
+        //- Return the underlying storage blocks
+        inline const List<unsigned int>& storage() const;
+
+        //- Return the underlying storage blocks
+        //  Manipulate with utmost caution
+        inline List<unsigned int>& storage();
 
 
     // IO
 
+        //- Print bit patterns, optionally with extra debug
+        Ostream& printBits(Ostream& os, bool debugOutput=false) const;
+
         //- Clear list and read from stream
         Istream& read(Istream& is);
 
@@ -349,7 +385,7 @@ public:
     // Member Operators
 
         //- Append a value at the end of the list
-        inline PackedList<nBits>& append(const unsigned int val);
+        inline PackedList<Width>& append(const unsigned int val);
 
         //- Remove and return the last element
         inline unsigned int remove();
@@ -366,32 +402,30 @@ public:
         inline void operator=(const unsigned int val);
 
         //- Copy assignment.
-        void operator=(const PackedList<nBits>& lst);
+        inline void operator=(const PackedList<Width>& lst);
 
         //- Move assignment.
-        void operator=(PackedList<nBits>&& lst);
-
-        //- Assignment operator.
-        void operator=(const labelUList& lst);
-
-        //- Assignment operator.
-        void operator=(const labelUIndList& lst);
+        inline void operator=(PackedList<Width>&& lst);
 
 
-    // Iterators and helpers
+    // Access helpers
 
-        //- A reference for read/write access to an entry
+        //- A reference supporting read/write access to an entry
         class reference
         {
-            friend class PackedList;    // Access for PackedList
+        protected:
+            friend class PackedList;    // Access for parent
             void operator&() = delete;  // Refuse to provide its address
 
-            unsigned int& ref_;   //!< Reference to underlying block value
-            unsigned int shift_;  //!< The bit shift for the sub-portion
+            //- Reference to the block
+            block_type& ref_;
 
-            //- Construct by taking reference of block from within the list
-            //- at the specified index.
-            inline reference(PackedList* lst, const label index);
+            //- The bit shift to access the given sub-portion
+            unsigned shift_;
+
+            //- Construct by taking reference of block from within
+            //- the list and the specified index.
+            inline reference(PackedList* parent, const label index);
 
             //- Get value as unsigned, no range-checking
             inline unsigned int get() const;
@@ -404,27 +438,40 @@ public:
             //- Value assignment
             inline void operator=(const reference& other);
 
-            //- Value assignment
+            //- Value assignment.
             inline void operator=(const unsigned int val);
 
-            //- Conversion operator
+            //- Conversion operator.
             inline operator unsigned int () const;
         };
 
 
     // IOstream Operators
 
-        friend Istream& operator>> <nBits>
+        //- Return info proxy.
+        InfoProxy<PackedList<Width>> info() const
+        {
+            return *this;
+        }
+
+        friend Ostream& operator<< <Width>
+        (
+            Ostream& os,
+            const InfoProxy<PackedList<Width>>& info
+        );
+
+        friend Istream& operator>> <Width>
         (
             Istream& is,
-            PackedList<nBits>& lst
+            PackedList<Width>& list
         );
 
-        friend Ostream& operator<< <nBits>
+        friend Ostream& operator<< <Width>
         (
             Ostream& os,
-            const PackedList<nBits>& lst
+            const PackedList<Width>& list
         );
+
 };
 
 
@@ -440,6 +487,7 @@ public:
 
 #ifdef NoRepository
     #include "PackedList.C"
+    #include "PackedListIO.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C b/src/OpenFOAM/containers/Bits/PackedList/PackedListCore.C
similarity index 89%
rename from src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
rename to src/OpenFOAM/containers/Bits/PackedList/PackedListCore.C
index 92f3b3603d187e189af9b0091c3059d14f0aeee8..f3f68bba64ada78e0e3bc64bad70d53df0484027 100644
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedListCore.C
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListCore.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -23,14 +23,16 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "PackedList.H"
+#include "PackedListCore.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 namespace Foam
 {
-defineTypeNameAndDebug(PackedListCore, 0);
+namespace Detail
+{
+    defineTypeName(PackedListCore);
+}
 }
-
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedListCore.H b/src/OpenFOAM/containers/Bits/PackedList/PackedListCore.H
new file mode 100644
index 0000000000000000000000000000000000000000..3cb640d7f8a28c6e3a276c5beb66f6c422b4fdbe
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListCore.H
@@ -0,0 +1,67 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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::Detail::PackedListCore
+
+Description
+    Implementation of template-invariant details for Foam::PackedList
+
+SourceFiles
+    PackedListCore.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PackedListCore_H
+#define PackedListCore_H
+
+#include "className.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace Detail
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class Detail::PackedListCore Declaration
+\*---------------------------------------------------------------------------*/
+
+//- Template-invariant parts for PackedList
+struct PackedListCore
+{
+    //- Define template name
+    ClassNameNoDebug("PackedList");
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Detail
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
new file mode 100644
index 0000000000000000000000000000000000000000..eb768a8a518504ed2d972af462898f7ab5c712fa
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListI.H
@@ -0,0 +1,753 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
+     \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
+-------------------------------------------------------------------------------
+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 "error.H"
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<unsigned Width>
+inline unsigned int Foam::PackedList<Width>::repeated_value(unsigned val)
+{
+    std::cout << "call repeated_value" << nl;
+    return BitOps::repeat_value<block_type,Width>(val);
+}
+
+
+template<unsigned Width>
+inline unsigned int Foam::PackedList<Width>::readValue(Istream& is)
+{
+    const unsigned int val = readLabel(is);
+
+    if (val > max_value)
+    {
+        FatalIOErrorInFunction(is)
+            << "Out-of-range value " << val << " for PackedList<" << Width
+            << ">. Maximum permitted value is " << max_value << "."
+            << exit(FatalIOError);
+    }
+
+    return val;
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::setPair(Istream& is)
+{
+    is.readBegin("Tuple2<label,uint32>");
+
+    const label ind = readLabel(is);
+    const unsigned int val = readLabel(is);
+
+    is.readEnd("Tuple2<label,uint32>");
+
+    if (val > max_value)
+    {
+        FatalIOErrorInFunction(is)
+            << "Out-of-range value " << val << " for PackedList<" << Width
+            << "> at index " << ind
+            << ". Maximum permitted value is " << max_value << "."
+            << exit(FatalIOError);
+    }
+
+    set(ind, val);
+
+    is.check(FUNCTION_NAME);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::clear_trailing_bits()
+{
+    // Mask off any partial rubbish in final block
+    const unsigned int blk = size() / elem_per_block;
+    const unsigned int off = size() % elem_per_block;
+
+    if (off)
+    {
+        blocks_[blk] &= mask_lower(off);
+    }
+}
+
+
+template<unsigned Width>
+inline bool Foam::PackedList<Width>::trim(label minpos)
+{
+    if (empty())
+    {
+        return false;  // Trivial case
+    }
+
+    const label orig = size();
+    if (orig < minpos)
+    {
+        minpos = orig;   // Don't allow allow accidental growth!
+    }
+
+    for (label blocki = num_blocks(size())-1; blocki >= 0; --blocki)
+    {
+        // Truncate to the block begin
+        size_ = blocki * elem_per_block;
+
+        unsigned int blockval = blocks_[blocki];
+
+        // Some bits were found in the block, increment size again
+        if (blockval)
+        {
+            for (; blockval; ++size_)
+            {
+                blockval >>= Width;
+            }
+            break;
+        }
+        else if (size_ < minpos)
+        {
+            break;
+        }
+    }
+
+    if (size_ < minpos)
+    {
+        size_ = minpos;
+    }
+
+    return (size() != orig);
+}
+
+
+// * * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    template<> inline unsigned int PackedList<1>::repeated_value(unsigned val)
+    {
+        return (val ? ~0u : 0u);
+    }
+
+    template<> inline unsigned int PackedList<1>::readValue(Istream& is)
+    {
+        return readBool(is);
+    }
+
+    template<> inline void PackedList<1>::setPair(Istream& is)
+    {
+        set(readLabel(is), true);
+    }
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+template<unsigned Width>
+inline constexpr Foam::PackedList<Width>::PackedList() noexcept
+:
+    blocks_(),
+    size_(0)
+{}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList(const label numElem)
+:
+    blocks_(num_blocks(numElem), 0u),
+    size_(numElem)
+{}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList
+(
+    const label numElem,
+    const unsigned int val
+)
+:
+    blocks_(num_blocks(numElem), 0u),
+    size_(numElem)
+{
+    if (val)
+    {
+        operator=(val);
+    }
+}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList(Istream& is)
+:
+    blocks_(),
+    size_(0)
+{
+    read(is);
+}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList(const PackedList<Width>& rhs)
+:
+    blocks_(rhs.blocks_),
+    size_(rhs.size_)
+{}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList(PackedList<Width>&& rhs)
+:
+    blocks_(std::move(rhs.blocks_)),
+    size_(rhs.size_)
+{
+    rhs.size_ = 0;
+}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList(const labelUList& values)
+:
+    blocks_(num_blocks(values.size()), 0u),
+    size_(values.size())
+{
+    const label len = values.size();
+
+    // Could add more intelligent filling (blockwise), but likely done
+    // fairly infrequently
+
+    for (label i = 0; i < len; ++i)
+    {
+        const unsigned int val(values[i]);
+        if (val) set(i, val);
+    }
+}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::PackedList(const labelUIndList& values)
+:
+    blocks_(num_blocks(values.size()), 0u),
+    size_(values.size())
+{
+    const label len = values.size();
+
+    // Could add more intelligent filling (blockwise), but likely done
+    // fairly infrequently
+
+    for (label i = 0; i < len; ++i)
+    {
+        const unsigned int val(values[i]);
+        if (val) set(i, val);
+    }
+}
+
+
+template<unsigned Width>
+inline Foam::autoPtr<Foam::PackedList<Width>>
+Foam::PackedList<Width>::clone() const
+{
+    return autoPtr<PackedList<Width>>::New(*this);
+}
+
+
+// * * * * * * * * * * * * * * * * References * * * * * * * * * * * * * * * * //
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::reference::reference
+(
+    PackedList<Width>* parent,
+    const label index
+)
+:
+    ref_(parent->blocks_[index / elem_per_block]),
+    shift_(Width * (index % elem_per_block))
+{}
+
+
+template<unsigned Width>
+inline unsigned int Foam::PackedList<Width>::reference::get() const
+{
+    return ((ref_ >> shift_) & max_value);
+}
+
+
+template<unsigned Width>
+inline bool Foam::PackedList<Width>::reference::set(const unsigned int val)
+{
+    const unsigned int mask = (max_value << shift_);
+    const unsigned int prev = ref_;
+
+    if (val >= max_value)
+    {
+        ref_ |= mask;  // Overflow is max_value, so fill entirely
+    }
+    else
+    {
+        ref_ &= ~mask;
+        ref_ |= mask & (val << shift_);
+    }
+
+    return (prev != ref_);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::reference::operator=
+(
+    const reference& other
+)
+{
+    this->set(other.get());
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::reference::operator=
+(
+    const unsigned int val
+)
+{
+    this->set(val);
+}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>::reference::operator unsigned int () const
+{
+    return this->get();
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::checkIndex(const label i) const
+{
+    if (!size_)
+    {
+        FatalErrorInFunction
+            << "attempt to access element " << i << " from zero sized list"
+            << abort(FatalError);
+    }
+    else if (i < 0 || i >= size_)
+    {
+        FatalErrorInFunction
+            << "index " << i << " out of range [0," << size_ << ")"
+            << abort(FatalError);
+    }
+}
+
+
+template<unsigned Width>
+inline Foam::label Foam::PackedList<Width>::size() const noexcept
+{
+    return size_;
+}
+
+
+template<unsigned Width>
+inline bool Foam::PackedList<Width>::empty() const noexcept
+{
+    return !size_;
+}
+
+
+template<unsigned Width>
+inline Foam::label Foam::PackedList<Width>::capacity() const
+{
+    return elem_per_block * blocks_.size();
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::resize
+(
+    const label newSize,
+    const unsigned int val
+)
+{
+    reserve(newSize);
+
+    const label oldSize = size();
+    size_ = newSize;
+
+    if (oldSize < size())
+    {
+        // Fill new elements or newly exposed elements
+        if (val)
+        {
+            // Fill value for complete blocks
+            const unsigned int blockval = repeated_value(val);
+
+            // Fill complete blocks
+            const label oldLen = num_blocks(oldSize);
+            const label newLen = num_blocks(size());
+            for (label blocki = oldLen; blocki < newLen; ++blocki)
+            {
+                blocks_[blocki] = blockval;
+            }
+
+            // Finish previous partial block, preserve existing value
+            {
+                const unsigned int blk = oldSize / elem_per_block;
+                const unsigned int off = oldSize % elem_per_block;
+                if (off)
+                {
+                    const unsigned int mask = mask_lower(off);
+
+                    blocks_[blk] &= mask;
+                    blocks_[blk] |= ~mask & blockval;
+                }
+            }
+
+            clear_trailing_bits();
+        }
+    }
+    else if (size() < oldSize)
+    {
+        // The list is now shorter than before, so we zero assign the unused
+        // blocks and any trailing junk. This costs slightly here, but make
+        // things much simpler elsewhere.
+
+        // Clear complete blocks
+        const label oldLen = num_blocks(oldSize);
+        const label newLen = num_blocks(size());
+        for (label blocki = newLen; blocki < oldLen; ++blocki)
+        {
+            blocks_[blocki] = 0u;
+        }
+
+        clear_trailing_bits();
+    }
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::setSize
+(
+    const label newSize,
+    const unsigned int val
+)
+{
+    resize(newSize, val);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::setCapacity(const label numElem)
+{
+    const label nblocks = num_blocks(numElem);
+
+    blocks_.resize(nblocks, 0u);
+
+    if (numElem < size())
+    {
+        size_ = numElem;
+        clear_trailing_bits();
+    }
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::reserve(const label numElem)
+{
+    const label oldLen = blocks_.size();
+    const label newLen = num_blocks(numElem);
+
+    // Allocate more capacity if necessary
+    if (oldLen < newLen)
+    {
+        blocks_.resize
+        (
+            // SizeMin=16, allocation doubling
+            max(16, max(newLen, 2*oldLen)),
+            0u
+        );
+    }
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::reset()
+{
+    blocks_ = 0u;
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::clear()
+{
+    reset();
+    size_ = 0;
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::clearStorage()
+{
+    blocks_.clear();
+    size_ = 0;
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::shrink()
+{
+    // Any unneeded space allocated?
+    const label nblocks = num_blocks(size());
+    if (nblocks < blocks_.size())
+    {
+        blocks_.resize(nblocks);
+    }
+}
+
+
+template<unsigned Width>
+inline Foam::List<unsigned int>& Foam::PackedList<Width>::storage()
+{
+    return blocks_;
+}
+
+
+template<unsigned Width>
+inline const Foam::List<unsigned int>& Foam::PackedList<Width>::storage() const
+{
+    return blocks_;
+}
+
+
+template<unsigned Width>
+inline Foam::label Foam::PackedList<Width>::nBlocks() const
+{
+    return num_blocks(size());
+}
+
+
+template<unsigned Width>
+inline std::streamsize Foam::PackedList<Width>::byteSize() const
+{
+    return num_blocks(size()) * sizeof(block_type);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::swap(PackedList<Width>& rhs)
+{
+    blocks_.swap(rhs.blocks_);
+    Foam::Swap(size_, rhs.size_);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::transfer(PackedList<Width>& rhs)
+{
+    blocks_.transfer(rhs.blocks_);
+
+    size_ = rhs.size_;
+    rhs.size_ = 0;
+}
+
+
+template<unsigned Width>
+inline unsigned int Foam::PackedList<Width>::get(const label i) const
+{
+    if (i < 0 || i >= size())
+    {
+        #ifdef FULLDEBUG
+        if (i < 0)
+        {
+            WarningInFunction
+                << "Ignoring attempt to get a negative index " << i
+                << " range is [0," << size_ << ")"
+                << endl;
+        }
+        #endif
+
+        // Lazy evaluation - return 0 for out-of-range
+        return 0u;
+    }
+
+    return reference(const_cast<PackedList<Width>*>(this), i).get();
+}
+
+
+template<unsigned Width>
+inline bool Foam::PackedList<Width>::set
+(
+    const label i,
+    const unsigned int val
+)
+{
+    if (i < 0)
+    {
+        #ifdef FULLDEBUG
+        WarningInFunction
+            << "Ignoring attempt to set a negative index " << i
+            << " range is [0," << size_ << ")"
+            << endl;
+        }
+        #endif
+
+        // Lazy evaluation - ignore out-of-bounds
+        return false;
+    }
+    else if (i >= size())
+    {
+        if (!val)
+        {
+            // Same as unset out-of-bounds = noop
+            return false;
+        }
+
+        // Lazy evaluation - increase size on assigment
+        resize(i + 1);
+    }
+
+    return reference(this, i).set(val);
+}
+
+
+template<unsigned Width>
+inline bool Foam::PackedList<Width>::unset(const label i)
+{
+    if (i < 0 || i >= size())
+    {
+        // Unset out-of-bounds = noop
+        return false;
+    }
+
+    return reference(this, i).set(0u);
+}
+
+
+template<unsigned Width>
+inline Foam::PackedList<Width>&
+Foam::PackedList<Width>::append(const unsigned int val)
+{
+    const label idx = size();
+    reserve(idx + 1);
+    ++size_;
+
+    reference(this, idx).set(val);
+    return *this;
+}
+
+
+template<unsigned Width>
+inline unsigned int Foam::PackedList<Width>::remove()
+{
+    // Location of last element and simultaneously the new size
+    const label idx = size()-1;
+
+    if (idx < 0)
+    {
+        FatalErrorInFunction
+            << "List is empty" << abort(FatalError);
+    }
+
+    const unsigned int old = reference(this, idx).get();
+    resize(idx);
+
+    return old;
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::assign(const unsigned int val)
+{
+    const label nblocks = num_blocks(size());
+
+    // Trivial cases first
+    if (!nblocks)
+    {
+        return;
+    }
+    else if (!val)
+    {
+        for (label blocki=0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] = 0u;
+        }
+        return;
+    }
+
+    // Fill value for complete blocks
+    const unsigned int blockval = repeated_value(val);
+
+    for (label blocki=0; blocki < nblocks; ++blocki)
+    {
+        blocks_[blocki] = blockval;
+    }
+
+    clear_trailing_bits();
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::assign(const PackedList<Width>& list)
+{
+    blocks_ = list.blocks_;
+    size_ = list.size_;
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+template<unsigned Width>
+inline unsigned int Foam::PackedList<Width>::operator[](const label i) const
+{
+    return get(i);
+}
+
+
+template<unsigned Width>
+inline typename Foam::PackedList<Width>::reference
+Foam::PackedList<Width>::operator[](const label i)
+{
+    // Leave enabled during testing period (MAR-2018)
+    // #ifdef FULLDEBUG
+    checkIndex(i);
+    // #endif
+    return reference(this, i);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::operator=(const unsigned int val)
+{
+    assign(val);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::operator=(const PackedList<Width>& rhs)
+{
+    assign(rhs);
+}
+
+
+template<unsigned Width>
+inline void Foam::PackedList<Width>::operator=(PackedList<Width>&& rhs)
+{
+    transfer(rhs);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/PackedList/PackedListIO.C b/src/OpenFOAM/containers/Bits/PackedList/PackedListIO.C
new file mode 100644
index 0000000000000000000000000000000000000000..84b529ae2983f4e005ad825c3501883ebed9503c
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/PackedList/PackedListIO.C
@@ -0,0 +1,314 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 "PackedList.H"
+#include "IOstreams.H"
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+template<unsigned Width>
+void Foam::PackedList<Width>::writeEntry(Ostream& os) const
+{
+    os  << *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<unsigned Width>
+Foam::Ostream& Foam::PackedList<Width>::printBits
+(
+    Ostream& os,
+    bool debugOutput
+) const
+{
+    os << token::BEGIN_LIST << nl;
+
+    const label nblocks = debugOutput ? blocks_.size() : num_blocks(size());
+    for (label blocki = 0; blocki < nblocks; ++blocki)
+    {
+        BitOps::print(os, blocks_[blocki], '.') << nl;
+    }
+
+    os << token::END_LIST << nl;
+
+    return os;
+}
+
+
+template<unsigned Width>
+Foam::Istream& Foam::PackedList<Width>::read(Istream& is)
+{
+    PackedList<Width>& list = *this;
+
+    list.clear();
+    is.fatalCheck(FUNCTION_NAME);
+
+    token firstTok(is);
+    is.fatalCheck
+    (
+        "PackedList::read(Istream&) : "
+        "reading first token"
+    );
+
+    if (firstTok.isLabel())
+    {
+        const label len = firstTok.labelToken();
+
+        // Set list length to that read
+        list.resize(len);
+
+        // Read list contents depending on data format
+        if (is.format() == IOstream::ASCII)
+        {
+            // Read beginning of contents
+            const char delimiter = is.readBeginList("PackedList");
+
+            if (len)
+            {
+                if (delimiter == token::BEGIN_LIST)
+                {
+                    for (label i=0; i<len; ++i)
+                    {
+                        list[i] = list.readValue(is);
+
+                        is.fatalCheck
+                        (
+                            "PackedList::read(Istream&) : "
+                            "reading entry"
+                        );
+                    }
+                }
+                else if (delimiter == token::BEGIN_BLOCK)
+                {
+                    // Assign for all entries
+                    list = list.readValue(is);
+
+                    is.fatalCheck
+                    (
+                        "PackedList::read(Istream&) : "
+                        "reading the single entry"
+                    );
+                }
+                else
+                {
+                    FatalIOErrorInFunction(is)
+                        << "incorrect list token, expected '(' or '{', found "
+                        << firstTok.info()
+                        << exit(FatalIOError);
+                }
+            }
+
+            // Read end of contents
+            is.readEndList("PackedList");
+        }
+        else
+        {
+            if (len)
+            {
+                is.read
+                (
+                    reinterpret_cast<char*>(list.storage().data()),
+                    list.byteSize()
+                );
+
+                is.fatalCheck
+                (
+                    "PackedList::read(Istream&) : "
+                    "reading the binary block"
+                );
+            }
+        }
+    }
+    else if (firstTok.isPunctuation())
+    {
+        if (firstTok.pToken() == token::BEGIN_LIST)
+        {
+            token nextTok(is);
+            is.fatalCheck(FUNCTION_NAME);
+
+            while
+            (
+                !(   nextTok.isPunctuation()
+                  && nextTok.pToken() == token::END_LIST
+                 )
+            )
+            {
+                is.putBack(nextTok);
+                list.append(list.readValue(is));
+
+                is  >> nextTok;
+                is.fatalCheck(FUNCTION_NAME);
+            }
+        }
+        else if (firstTok.pToken() == token::BEGIN_BLOCK)
+        {
+            token nextTok(is);
+            is.fatalCheck(FUNCTION_NAME);
+
+            while
+            (
+                !(   nextTok.isPunctuation()
+                  && nextTok.pToken() == token::END_BLOCK
+                 )
+            )
+            {
+                is.putBack(nextTok);
+                list.setPair(is);
+
+                is  >> nextTok;
+                is.fatalCheck(FUNCTION_NAME);
+            }
+        }
+        else
+        {
+            FatalIOErrorInFunction(is)
+                << "incorrect first token, expected '(', found "
+                << firstTok.info()
+                << exit(FatalIOError);
+        }
+    }
+    else
+    {
+        FatalIOErrorInFunction(is)
+            << "incorrect first token, expected <int>, '(' or '{', found "
+            << firstTok.info()
+            << exit(FatalIOError);
+    }
+
+    return is;
+}
+
+
+template<unsigned Width>
+Foam::Ostream& Foam::PackedList<Width>::writeList
+(
+    Ostream& os,
+    const label shortListLen
+) const
+{
+    const PackedList<Width>& list = *this;
+    const label len = list.size();
+
+    // Write list contents depending on data format
+    if (os.format() == IOstream::ASCII)
+    {
+        if (list.uniform())
+        {
+            // Two or more entries, and all entries have identical values.
+            os  << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
+        }
+        else if (!shortListLen || len <= shortListLen)
+        {
+            // Shorter list, or line-breaks suppressed
+            os  << len << token::BEGIN_LIST;
+            for (label i=0; i < len; ++i)
+            {
+                if (i) os << token::SPACE;
+                os  << list[i];
+            }
+            os  << token::END_LIST;
+        }
+        else
+        {
+            // Longer list
+            os << nl << len << nl << token::BEGIN_LIST << nl;
+            for (label i=0; i < len; ++i)
+            {
+                os << list[i] << nl;
+            }
+            os << token::END_LIST << nl;
+        }
+    }
+    else
+    {
+        // Contents are binary and contiguous
+        os  << nl << len << nl;
+
+        if (len)
+        {
+            // write(...) includes surrounding start/end delimiters
+            os.write
+            (
+                reinterpret_cast<const char*>(list.storage().cdata()),
+                list.byteSize()
+            );
+        }
+    }
+
+    return os;
+}
+
+
+template<unsigned Width>
+void Foam::PackedList<Width>::writeEntry
+(
+    const word& keyword,
+    Ostream& os
+) const
+{
+    os.writeKeyword(keyword);
+    writeEntry(os);
+    os  << token::END_STATEMENT << endl;
+}
+
+
+// * * * * * * * * * * * * * *  Friend Operators * * * * * * * * * * * * * * //
+
+template<unsigned Width>
+Foam::Istream& Foam::operator>>(Istream& is, PackedList<Width>& list)
+{
+    return list.read(is);
+}
+
+
+template<unsigned Width>
+Foam::Ostream& Foam::operator<<(Ostream& os, const PackedList<Width>& list)
+{
+    return list.writeList(os, 10);
+}
+
+
+template<unsigned Width>
+Foam::Ostream& Foam::operator<<
+(
+    Ostream& os,
+    const InfoProxy<PackedList<Width>>& iproxy
+)
+{
+    const PackedList<Width>& list = iproxy.t_;
+
+    os  << "PackedList<" << Width
+        << "> size=" << list.size() << "/" << list.capacity()
+        << " (limits: max=" << PackedList<Width>::max_value
+        << ", elem_per_block=" << PackedList<Width>::elem_per_block
+        << ")"
+        << nl;
+
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/PackedBoolList.H b/src/OpenFOAM/containers/Bits/bitSet/PackedBoolList.H
new file mode 100644
index 0000000000000000000000000000000000000000..a62bab00f2dc70e99713208922c7ce8c15d4e5e0
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/bitSet/PackedBoolList.H
@@ -0,0 +1,36 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM, licensed under GNU General Public License
+    <http://www.gnu.org/licenses/>.
+
+Typedef
+    Foam::PackedBoolList
+
+Description
+    Compatibility name. Superseded (MAR-2018) by Foam::bitSet
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef PackedBoolList_H
+#define PackedBoolList_H
+
+#include "bitSet.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+     typedef bitSet PackedBoolList;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSet.C b/src/OpenFOAM/containers/Bits/bitSet/bitSet.C
new file mode 100644
index 0000000000000000000000000000000000000000..e92769cf8a2af8d27d4897990e56dabfdd8728d6
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSet.C
@@ -0,0 +1,569 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 "bitSet.H"
+#include "labelRange.H"
+#include "IOstreams.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(bitSet, 0);
+}
+
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+Foam::bitSet& Foam::bitSet::minusEq(const bitSet& other)
+{
+    if (&other == this)
+    {
+        // Self '-=' : results in clearing all bits
+        if (debug & 2)
+        {
+            InfoInFunction
+                << "Perform -= on self: clears all bits" << nl;
+        }
+
+        reset();
+        return *this;
+    }
+    else if (empty() || other.empty())
+    {
+        return *this;
+    }
+
+
+    // The operation (on overlapping blocks)
+    {
+        const label nblocks = num_blocks(std::min(size(), other.size()));
+        const auto& rhs = other.blocks_;
+
+        for (label blocki = 0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] &= ~rhs[blocki];
+        }
+    }
+
+    return *this;
+}
+
+
+Foam::bitSet& Foam::bitSet::andEq(const bitSet& other)
+{
+    if (&other == this)
+    {
+        // Self '&=' : no-op
+
+        if (debug & 2)
+        {
+            InfoInFunction
+                << "Perform &= on self: ignore" << nl;
+        }
+
+        return *this;
+    }
+    else if (empty())
+    {
+        // empty set : no-op (no overlap possible)
+        return *this;
+    }
+    else if (other.empty())
+    {
+        reset();  // Other is empty - no overlap possible
+        return *this;
+    }
+
+
+    // The operation (on overlapping blocks)
+    {
+        const label nblocks = num_blocks(std::min(size(), other.size()));
+        const auto& rhs = other.blocks_;
+
+        for (label blocki = 0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] &= rhs[blocki];
+        }
+    }
+
+    return *this;
+}
+
+
+Foam::bitSet& Foam::bitSet::orEq(const bitSet& other, const bool strict)
+{
+    if (&other == this)
+    {
+        // Self '|=' : no-op
+
+        if (debug & 2)
+        {
+            InfoInFunction
+                << "Perform |= on self: ignore" << nl;
+        }
+
+        return *this;
+    }
+    else if (other.empty())
+    {
+        if ((debug & 2) && !empty())
+        {
+            // OK if both are empty
+            InfoInFunction
+                << "Perform |= using empty operand: ignore" << nl;
+        }
+
+        // No (normal) overlap: no-op
+        return *this;
+    }
+    else if (empty())
+    {
+        if (debug & 2)
+        {
+            InfoInFunction
+                << "Perform |= on empty bitSet" << nl;
+        }
+
+        if (strict)
+        {
+            // No (normal) overlap: no-op
+            return *this;
+        }
+    }
+    else if ((debug & 2) && (size() != other.size()))
+    {
+        InfoInFunction
+            << "Perform |= on dissimilar sized bitSets: "
+            << size()  << " vs. " << other.size() << nl;
+    }
+    {
+        return *this;
+    }
+
+    label minpos = -1; // Min trim point
+
+    if ((size() < other.size()) && !strict)
+    {
+        // The size (B > A) and we are non-strict (greedy), which means we may
+        // acquire additional bits from B. However, we would like to avoid
+        // spurious changes in the size of A (ie, B is longer but the extra
+        // bits are unset and thus don't affect the logical result).
+
+        minpos = size();
+        resize(other.size());   // Blocks now overlap
+    }
+
+
+    // The operation (on overlapping blocks)
+    {
+        const label nblocks = num_blocks(std::min(size(), other.size()));
+        const auto& rhs = other.blocks_;
+
+        for (label blocki = 0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] |= rhs[blocki];
+        }
+    }
+
+
+    // Cleanup - minpos >= 0 means we need to check/adjust the trim point
+    if (minpos >= 0)
+    {
+        trim(minpos); // Adjust the trim point (size)
+    }
+    else
+    {
+        clear_trailing_bits();
+    }
+
+    return *this;
+}
+
+
+Foam::bitSet& Foam::bitSet::xorEq(const bitSet& other, const bool strict)
+{
+    if (&other == this)
+    {
+        // Self '^=' : results in clearing all bits
+
+        if (debug & 2)
+        {
+            InfoInFunction
+                << "Perform ^= on self: clears all bits" << nl;
+        }
+
+        reset();
+        return *this;
+    }
+    else if (other.empty())
+    {
+        if ((debug & 2) && !empty())
+        {
+            // OK if both are empty
+            InfoInFunction
+                << "Perform ^= using empty operand: ignore" << nl;
+        }
+
+        // No (normal) overlap: no-op
+        return *this;
+    }
+    else if (empty())
+    {
+        if (debug & 2)
+        {
+            InfoInFunction
+                << "Perform ^= on empty bitSet" << nl;
+        }
+
+        if (strict)
+        {
+            // No (normal) overlap: no-op
+            return *this;
+        }
+    }
+    else if ((debug & 2) && (size() != other.size()))
+    {
+        InfoInFunction
+            << "Perform ^= on dissimilar sized bitSets: "
+            << size()  << " vs. " << other.size() << nl;
+    }
+
+    label minpos = -1; // Min trim point
+
+    if ((size() < other.size()) && !strict)
+    {
+        minpos = size();        // This logic is explained in the orEq() method
+        resize(other.size());   // Blocks now overlap
+    }
+
+
+    // The operation (on overlapping blocks)
+    {
+        const label nblocks = num_blocks(std::min(size(), other.size()));
+        const auto& rhs = other.blocks_;
+
+        for (label blocki = 0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] ^= rhs[blocki];
+        }
+    }
+
+
+    // Cleanup - minpos >= 0 means we need to check/adjust the trim point
+    if (minpos >= 0)
+    {
+        trim(minpos); // Adjust the trim point (size)
+    }
+    else
+    {
+        clear_trailing_bits();
+    }
+
+    return *this;
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::bitSet::bitSet(Istream& is)
+:
+    PackedList<1>()
+{
+    is  >> *this;
+}
+
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+void Foam::bitSet::assign(const UList<bool>& bools)
+{
+    const label len = bools.size();
+
+    resize(len);
+    assign(false);
+
+    // Could also handle block-wise (in the future?)
+
+    // Set according to indices that are true.
+    for (label i = 0; i < len; ++i)
+    {
+        if (bools[i])
+        {
+            set(i);
+        }
+    }
+}
+
+
+bool Foam::bitSet::intersects(const bitSet& other) const
+{
+    if (size() && other.size())
+    {
+        const label nblocks = num_blocks(std::min(size(), other.size()));
+        const auto& rhs = other.blocks_;
+
+        for (label blocki = 0; blocki < nblocks; ++blocki)
+        {
+            if (bool(blocks_[blocki] & rhs[blocki]))
+            {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+
+void Foam::bitSet::set(const labelRange& range)
+{
+    labelRange slice(range);
+    slice.adjust();  // No negative start, size adjusted accordingly
+
+    // Range is invalid (zero-sized or entirely negative) - noop
+    if (slice.empty())
+    {
+        return;
+    }
+
+    // Range finishes at or beyond the right side.
+    // - zero fill any gaps that we might create.
+    // - flood-fill the reset, which now correponds to the full range.
+    //
+    // NB: use labelRange after() for the exclusive end-value, which
+    // corresponds to our new set size.
+    if (slice.after() >= size())
+    {
+        resize(slice.start(), false);
+        resize(slice.after(), true);
+        return;
+    }
+
+    // The more difficult case - everything in between.
+    // 1. sequence may begin/end in the same block
+    // 2. Cover more than one block
+    //    a. with partial coverage in the first block
+    //    b. with partial coverage in the end block
+
+    // The begin block/offset
+    unsigned int bblock = slice.first() / elem_per_block;
+    unsigned int bmask  = slice.first() % elem_per_block;
+
+    // The end block/offset
+    unsigned int eblock = slice.after() / elem_per_block;
+    unsigned int emask  = slice.after() % elem_per_block;
+
+    // Transform offsets to lower bit masks
+    if (bmask) bmask = mask_lower(bmask);
+    if (emask) emask = mask_lower(emask);
+
+    if (bblock == eblock)
+    {
+        // Same block - flll between the begin/end bits.
+        // Example:
+        // bmask = 0000000000001111  (lower bits)
+        // emask = 0000111111111111  (lower bits)
+        // -> set  0000111111110000  (xor)
+
+        blocks_[bblock] |= (emask^bmask);
+    }
+    else
+    {
+        if (bmask)
+        {
+            // The first (partial) block
+            // - set everything above the bmask.
+            blocks_[bblock] |= (~bmask);
+            ++bblock;
+        }
+
+        // Fill these blocks
+        for (unsigned blocki = bblock; blocki < eblock; ++blocki)
+        {
+            blocks_[blocki] = (~0u);
+        }
+
+        if (emask)
+        {
+            // The last (partial) block.
+            // - set everything below emask.
+            blocks_[eblock] |= (emask);
+        }
+    }
+}
+
+
+void Foam::bitSet::unset(const labelRange& range)
+{
+    // Require intersection with the current bitset
+    const labelRange slice = range.subset0(size());
+
+    // Range does not intersect (invalid, empty, bitset is empty)
+    if (slice.empty())
+    {
+        return;
+    }
+
+    // Range finishes at or beyond the right side.
+    //
+    // NB: use labelRange after() for the exclusive end-value, which
+    // corresponds to our new set size.
+    if (slice.after() >= size())
+    {
+        // The original size
+        const label orig = size();
+
+        resize(slice.start(), false);
+        resize(orig, false);
+        return;
+    }
+
+
+    // The more difficult case - everything in between.
+    // 1. sequence may begin/end in the same block
+    // 2. Cover more than one block
+    //    a. with partial coverage in the first block
+    //    b. with partial coverage in the end block
+
+    // The begin block/offset
+    unsigned int bblock = slice.first() / elem_per_block;
+    unsigned int bmask  = slice.first() % elem_per_block;
+
+    // The end block/offset
+    unsigned int eblock = slice.after() / elem_per_block;
+    unsigned int emask  = slice.after() % elem_per_block;
+
+    // Transform offsets to lower bit masks
+    if (bmask) bmask = mask_lower(bmask);
+    if (emask) emask = mask_lower(emask);
+
+    if (bblock == eblock)
+    {
+        // Same block - flll between the begin/end bits.
+        // Example:
+        // bmask = 0000000000001111  (lower bits)
+        // emask = 0000111111111111  (lower bits)
+        // -> set  0000111111110000  (xor)
+        // -> ~    1111000000001111
+
+        blocks_[bblock] &= (~(emask^bmask));
+    }
+    else
+    {
+        if (bmask)
+        {
+            // The first (partial) block
+            // - only retain things below bmask.
+            blocks_[bblock] &= (bmask);
+            ++bblock;
+        }
+
+        // Clear these blocks
+        for (unsigned blocki = bblock; blocki < eblock; ++blocki)
+        {
+            blocks_[blocki] = (0u);
+        }
+
+        if (emask)
+        {
+            // The last (partial) block.
+            // - only retain things above bmask.
+            blocks_[eblock] &= (~emask);
+        }
+    }
+}
+
+
+Foam::labelList Foam::bitSet::toc() const
+{
+    // Number of used (set) entries
+    const label total = any() ? count() : 0;
+
+    if (!total)
+    {
+        return labelList();
+    }
+
+    labelList output(total);
+    label nItem = 0;
+
+    // Process block-wise, detecting any '1' bits
+
+    const label nblocks = num_blocks(size());
+    for (label blocki = 0; blocki < nblocks; ++blocki)
+    {
+        unsigned int blockval = blocks_[blocki];
+
+        if (blockval)
+        {
+            for (label pos = (blocki * elem_per_block); blockval; ++pos)
+            {
+                if (blockval & 1u)
+                {
+                    output[nItem] = pos;
+                    ++nItem;
+                }
+                blockval >>= 1u;
+            }
+            if (nItem == total) break;  // Terminate early
+        }
+    }
+
+    return output;
+}
+
+
+Foam::List<bool> Foam::bitSet::values() const
+{
+    List<bool> output(size(), false);
+
+    // Process block-wise, detecting any '1' bits
+
+    const label nblocks = num_blocks(size());
+    for (label blocki = 0; blocki < nblocks; ++blocki)
+    {
+        label pos = (blocki * elem_per_block);
+
+        for
+        (
+            unsigned int blockval = blocks_[blocki];
+            blockval;
+            blockval >>= 1u
+        )
+        {
+            if (blockval & 1u)
+            {
+                output[pos] = true;
+            }
+            ++pos;
+        }
+    }
+
+    return output;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSet.H b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H
new file mode 100644
index 0000000000000000000000000000000000000000..cf516ba8dc43c2d780c2ce7c89b0ab560cf66d7d
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSet.H
@@ -0,0 +1,547 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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::bitSet
+
+Description
+    A bitSet stores bits (elements with only two states) in packed internal
+    format and supports a variety of bit-set operations.
+    Its behaviour is largely list-like, with some HashSet features.
+
+SourceFiles
+    bitSetI.H
+    bitSet.C
+    bitSetIO.C
+    bitSetTemplates.C
+
+See also
+    Foam::BitOps
+    Foam::PackedList
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef bitSet_H
+#define bitSet_H
+
+#include "className.H"
+#include "PackedList.H"
+#include "UIndirectList.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward declarations
+class bitSet;
+class labelRange;
+
+/*---------------------------------------------------------------------------*\
+                           Class bitSet Declaration
+\*---------------------------------------------------------------------------*/
+
+class bitSet
+:
+    public PackedList<1>
+{
+protected:
+
+    // Protected Member Functions
+
+        //- Write as a dictionary entry
+        void writeEntry(Ostream& os) const;
+
+    // Logic/Set Operations
+
+        //- The set difference
+        //  \code
+        //      A = (A - B)
+        //      A = (A & !B)
+        //      A = (A & ~B)
+        //  \endcode
+        //  A and B can have different sizes.
+        //  Does not change the original set size.
+        bitSet& minusEq(const bitSet& other);
+
+        //- The set logical AND
+        //  \code
+        //      A = (A & B)
+        //
+        //  \endcode
+        //  A and B can have different sizes..
+        //  Does not change the original set size.
+        bitSet& andEq(const bitSet& other);
+
+        //- The set logical OR
+        //  \code
+        //      A = (A | B)
+        //  \endcode
+        //  A and B can have different sizes
+        //
+        //  \note
+        //      The default (strict=true) ignores additional length from B,
+        //      whereas (strict=false) permits the set to automatically grow
+        //      to accommodate additional elements arising from B.
+        bitSet& orEq(const bitSet& other, const bool strict=true);
+
+        //- The set logical XOR
+        //  \code
+        //      A = (A ^ B)
+        //  \endcode
+        //  A and B can have different sizes. Sizing behaviour as per orEq.
+        bitSet& xorEq(const bitSet& other, const bool strict=true);
+
+public:
+
+    // Forward declaration of access classes
+
+        class reference;
+        class const_iterator;
+        typedef unsigned int const_reference;
+
+    //- Define class name and debug
+    ClassName("bitSet");
+
+
+    // Constructors
+
+        //- Construct an empty, zero-sized set
+        inline constexpr bitSet() noexcept;
+
+        //- Construct from Istream
+        explicit bitSet(Istream& is);
+
+        //- Construct with given size, with all bits set to 0
+        explicit inline bitSet(const label n);
+
+        //- Construct with given size and value for all elements
+        inline bitSet(const label n, const bool val);
+
+        //- Copy construct
+        inline bitSet(const bitSet& bitset);
+
+        //- Move construct
+        inline bitSet(bitSet&& bitset);
+
+        //- Construct from a list of bools
+        explicit inline bitSet(const UList<bool>& bools);
+
+        //- Construct with given size with all bits set to 0,
+        //- subsequently add specified locations as 1.
+        inline bitSet(const label n, const labelUList& locations);
+
+        //- Construct with given size with all bits set to 0,
+        //- subsequently add specified locations as 1.
+        inline bitSet(const label n, const labelUIndList& locations);
+
+        //- Construct with given size with all bits set to 0,
+        //- subsequently add specified locations as 1.
+        inline bitSet(const label n, std::initializer_list<label> locations);
+
+        //- Construct with automatic sizing (filled with 0),
+        //- and populate with specified locations as 1.
+        explicit inline bitSet(const labelUList& locations);
+
+        //- Construct with automatic sizing (filled with 0),
+        //- and populate with specified locations as 1.
+        explicit inline bitSet(const labelUIndList& locations);
+
+        //- Clone
+        inline autoPtr<bitSet> clone() const;
+
+
+    // Member Functions
+
+    // Query
+
+        //- True if all bits in this bitset are set or if the set is empty.
+        inline bool all() const;
+
+        //- True if any bits in this bitset are set.
+        inline bool any() const;
+
+        //- True if no bits in this bitset are set.
+        inline bool none() const;
+
+        //- True if there are two or more entries and all entries have
+        //- identical values.
+        inline bool uniform() const;
+
+        //- Count number of bits set.
+        inline unsigned int count() const;
+
+        //- True if any bits in the other bitset intersect (are the same).
+        //
+        //  \note Method name compatibility with boost::dynamic_bitset
+        bool intersects(const bitSet& other) const;
+
+        //- Test value at specified position, never auto-vivify entries.
+        //
+        //  \note Method name compatibility with std::bitset
+        inline bool test(const label pos) const;
+
+        //- Locate the first bit set.
+        //  \return the location or -1 if there are no bits set.
+        //
+        //  \note Method name compatibility with boost::dynamic_bitset
+        inline label find_first() const;
+
+        //- Locate the last bit set.
+        //  \return the location or -1 if there are no bits set.
+        //
+        //  \note Provided for symmetry with find_first()
+        inline label find_last() const;
+
+        //- Locate the next bit set, starting one beyond the specified position
+        //  \return the location or -1 if there are no further bits set.
+        //
+        //  \note Method name compatibility with boost::dynamic_bitset
+        inline label find_next(label pos) const;
+
+        //- The indices of the \a on bits as a sorted labelList.
+        //
+        //  \note Method name compatibility with HashSet
+        labelList toc() const;
+
+        //- The indices of the \a on bits as a sorted labelList.
+        //  This is identical to toc(), which is always sorted.
+        //
+        //  \note Method name compatibility with HashSet
+        inline labelList sortedToc() const;
+
+        //- Return the bitset values as a boolList.
+        List<bool> values() const;
+
+
+    // Assignment
+
+        //- Assign all entries to the given value.
+        inline void assign(const bool val);
+
+        //- Copy assign all entries from a list of bools.
+        void assign(const UList<bool>& bools);
+
+
+    // Setting single or multiple values
+
+        //- Single index/value assign
+        using PackedList<1>::set;
+
+        //- Set specified bits from another bitset.
+        //  The current set size may grow to accommodate any new bits
+        //  (auto-vivifies).
+        inline void set(const bitSet& bitset);
+
+        //- Set the specified range of bits specified
+        //  The current set size may grow to accommodate any new bits
+        //  (auto-vivifies).
+        //  \note this operation is generally more efficient than calling
+        //      set(pos) on individual bits.
+        void set(const labelRange& range);
+
+
+    // Unsetting single or multiple values
+
+        //- Unset a single index
+        using PackedList<1>::unset;
+
+        //- Unset (subtract) the bits specified in the other bitset, which is
+        //- a set difference corresponds to the logical operation
+        //  \code
+        //      A = (A & !B)
+        //  \endcode
+        //  The result is comparable to 'operator-='
+        //  \endcode
+        //
+        //  A and B can have different sizes.
+        //  Does not change the original set size.
+        inline bitSet& unset(const bitSet& other);
+
+        //- Unset the specified range of bits specified, never auto-vivifies.
+        //  \note this operation can be more efficient than calling
+        //      unset(pos) on individual bits.
+        void unset(const labelRange& range);
+
+
+    // Edit
+
+        //- Invert all bits in the addressable region
+        inline void flip();
+
+        //- Invert bits at the specified position.
+        //  A no-op if the position is out-of-range
+        inline void flip(const label pos);
+
+        //- Swap contents
+        inline void swap(bitSet& bitset);
+
+        //- Transfer the contents of the argument list into this list
+        //- and annul the argument list.
+        inline void transfer(bitSet& bitset);
+
+
+    // Convenience methods
+
+        //- Ensure the addressable range does not exceed maxSize.
+        //  Either decreases the size of the bitSet or is a no-op.
+        //
+        //  \code
+        //      pointField& pts = mesh.points();
+        //      bitset.bound(pts.size());
+        //
+        //      for (const label pointi : bitset)
+        //      {
+        //          pts[pointi]  ...
+        //      }
+        //  \endcode
+        inline bitSet& bound(const label maxSize);
+
+        //- Ensure the addressable range does not exceed that of other.
+        //  Either decreases the size of the bitSet or is a no-op.
+        inline bitSet& bound(const bitSet& other);
+
+        //- Ensure that minSize is covered by the bitSet.
+        //  Either increases the size of the bitSet or is a no-op.
+        inline bitSet& extend(const label minSize);
+
+        //- Ensure the bitset is addressable throughout the range of other.
+        //  Either increases the size of the bitSet or is a no-op.
+        inline bitSet& extend(const bitSet& other);
+
+        //- Set the listed locations to true.
+        //  Does auto-vivify for non-existent entries.
+        inline void setMany(const labelUList& locations);
+
+        //- Set the listed locations to true.
+        //  Does auto-vivify for non-existent entries.
+        inline void setMany(const labelUIndList& locations);
+
+        //- Set the locations listed by the iterator range,
+        //  auto-vivify entries if needed.
+        template<class InputIter>
+        void setMany(InputIter first, InputIter last);
+
+        //- Unset the listed locations, never auto-vivifies.
+        inline void unsetMany(const labelUList& locations);
+
+        //- Unset the listed locations, never auto-vivifies.
+        inline void unsetMany(const labelUIndList& locations);
+
+        //- Unset the locations listed by the iterator range,
+        //- never auto-vivify entries.
+        template<class InputIter>
+        void unsetMany(InputIter first, InputIter last);
+
+
+    // Access helpers
+
+        //- A reference supporting read/write access to an entry
+        class reference
+        :
+            public PackedList<1>::reference
+        {
+        protected:
+            friend class bitSet;        // Access for parent
+            void operator&() = delete;  // Refuse to provide its address
+
+            //- Construct by taking reference of block from within
+            //- the list and the specified index.
+            inline reference(bitSet* parent, const label index);
+
+        public:
+
+            //- Flip the bit at the position, no range-checking
+            inline void flip();
+
+            //- Value assignment
+            inline void operator=(const reference& other);
+
+            //- Value assignment
+            inline void operator=(const unsigned int val);
+
+            //- Conversion operator
+            inline operator unsigned int () const;
+        };
+
+
+    // Iteration
+
+        //- A const_iterator for iterating across \a on values
+        class const_iterator
+        {
+            friend class bitSet;
+
+            //- The parent being iterated
+            const bitSet* set_;
+
+            //- Global position of the current \a on bit
+            label pos_;
+
+            //- Construct null - an end iterator
+            inline const_iterator() noexcept;
+
+            //- Construct begin iterator
+            inline const_iterator(const bitSet* bitset);
+
+        public:
+
+            //- Return the current \a on position
+            inline label operator*() const noexcept;
+
+            //- Move to the next \a on position
+            inline const_iterator& operator++();
+
+            inline bool operator==(const const_iterator& iter) const noexcept;
+            inline bool operator!=(const const_iterator& iter) const noexcept;
+        };
+
+
+        //- Iterator set to the position of the first \a on bit
+        inline const_iterator begin() const;
+
+        //- Iterator set to the position of the first \a on bit
+        inline const_iterator cbegin() const;
+
+        //- Iterator beyond the end of the bitSet
+        inline const_iterator end() const noexcept;
+
+        //- Iterator beyond the end of the bitSet
+        inline const_iterator cend() const noexcept;
+
+
+    // Member Operators
+
+        //- Identical to get() - get value at index.
+        //  Never auto-vivify entries.
+        inline unsigned int operator[](const label i) const;
+
+        //- Non-const access to value at index.
+        //  Fatal for out-of-range indices
+        inline reference operator[](const label i);
+
+        //- Assignment of all entries to the given value.
+        inline bitSet& operator=(const bool val);
+
+        //- Copy assignment
+        inline bitSet& operator=(const bitSet& bitset);
+
+        //- Move assignment
+        inline bitSet& operator=(bitSet&& bitset);
+
+        //- Complement operator.
+        //  Return a copy of the existing set with all its bits flipped.
+        inline bitSet operator~() const;
+
+        //- Bitwise-AND all the bits in other with the bits in this bitset.
+        //  The operands may have dissimilar sizes without affecting the size
+        //  of the set.
+        inline bitSet& operator&=(const bitSet& other);
+
+        //- Bitwise-OR operator - similar to the set() method.
+        //  The operands may have dissimilar sizes without affecting the size
+        //  of the set.
+        inline bitSet& operator|=(const bitSet& other);
+
+        //- Bitwise-XOR operator - retains unique entries.
+        //  The operands may have dissimilar sizes without affecting the size
+        //  of the set.
+        inline bitSet& operator^=(const bitSet& other);
+
+        //- Remove entries from this list - identical to the unset() method.
+        //  The operands may have dissimilar sizes without affecting the size
+        //  of the set.
+        inline bitSet& operator-=(const bitSet& other);
+
+
+    // IO
+
+        //- Write the bitSet, with line-breaks in ASCII if the size
+        //- exceeds shortListLen.
+        //  Using '0' suppresses line-breaks entirely.
+        Ostream& writeList(Ostream& os, const label shortListLen=0) const;
+
+        //- Write as a dictionary entry with keyword
+        void writeEntry(const word& keyword, Ostream& os) const;
+
+
+    // IOstream Operators
+
+        //- Return info proxy
+        InfoProxy<bitSet> info() const
+        {
+            return *this;
+        }
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const InfoProxy<bitSet>& info
+        );
+
+        friend Ostream& operator<<
+        (
+            Ostream& os,
+            const bitSet& bitset
+        );
+};
+
+
+// Global Operators
+
+//- Bitwise-AND of two bitsets.
+//  See bitSet::operator&= for more details.
+inline bitSet operator&(const bitSet& a, const bitSet& b);
+
+//- Bitwise-OR of two bitsets
+//  See bitSet::operator|= for more details.
+inline bitSet operator|(const bitSet& a, const bitSet& b);
+
+//- Bitwise-XOR of two bitsets to form a unique bit-set
+//  See bitSet::operator^= for more details.
+inline bitSet operator^(const bitSet& a, const bitSet& b);
+
+//- Bitwise difference (subset) of two bitsets to form a unique bit-set
+//  See bitSet::operator-= for more details.
+inline bitSet operator-(const bitSet& a, const bitSet& b);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#include "bitSetI.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+    #include "bitSetTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H b/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H
new file mode 100644
index 0000000000000000000000000000000000000000..4d4bfd16469c7954e15888bce5f51d00eb6392e3
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSetI.H
@@ -0,0 +1,672 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 constexpr Foam::bitSet::bitSet() noexcept
+:
+    PackedList<1>()
+{}
+
+
+inline Foam::bitSet::bitSet(const label n)
+:
+    PackedList<1>(n)
+{}
+
+
+inline Foam::bitSet::bitSet(const label n, const bool val)
+:
+    bitSet(n)
+{
+    if (val) assign(val);
+}
+
+
+inline Foam::bitSet::bitSet(const bitSet& bitset)
+:
+    PackedList<1>(bitset)
+{}
+
+
+inline Foam::bitSet::bitSet(bitSet&& bitset)
+:
+    PackedList<1>(std::move(bitset))
+{}
+
+
+inline Foam::bitSet::bitSet(const UList<bool>& bools)
+:
+    bitSet()
+{
+    assign(bools);
+}
+
+
+inline Foam::bitSet::bitSet(const label n, const labelUList& locations)
+:
+    bitSet(n)
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline Foam::bitSet::bitSet(const label n, const labelUIndList& locations)
+:
+    bitSet(n)
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline Foam::bitSet::bitSet
+(
+    const label n,
+    std::initializer_list<label> locations
+)
+:
+    bitSet(n)
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline Foam::bitSet::bitSet(const labelUList& locations)
+:
+    bitSet()
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline Foam::bitSet::bitSet(const labelUIndList& locations)
+:
+    bitSet()
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline Foam::autoPtr<Foam::bitSet> Foam::bitSet::clone() const
+{
+    return autoPtr<bitSet>::New(*this);
+}
+
+
+// * * * * * * * * * * * * * * * * References * * * * * * * * * * * * * * * * //
+
+inline Foam::bitSet::reference::reference
+(
+    bitSet* parent,
+    const label index
+)
+:
+    PackedList<1>::reference(parent, index)
+{}
+
+
+inline void Foam::bitSet::reference::flip()
+{
+    const unsigned int mask = (max_value << shift_);
+    ref_ ^= mask;
+}
+
+
+inline void Foam::bitSet::reference::operator=
+(
+    const reference& other
+)
+{
+    set(other.get());
+}
+
+
+inline void Foam::bitSet::reference::operator=
+(
+    const unsigned int val
+)
+{
+    set(val);
+}
+
+
+inline Foam::bitSet::reference::operator unsigned int () const
+{
+    return get();
+}
+
+
+// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
+
+inline Foam::bitSet::const_iterator::const_iterator() noexcept
+:
+    set_(nullptr),
+    pos_(-1)
+{}
+
+
+inline Foam::bitSet::const_iterator::const_iterator(const bitSet* parent)
+:
+    set_(parent),
+    pos_(set_->find_first())
+{}
+
+
+inline Foam::label Foam::bitSet::const_iterator::operator*() const noexcept
+{
+    return pos_;
+}
+
+
+inline Foam::bitSet::const_iterator& Foam::bitSet::const_iterator::operator++()
+{
+    pos_ = set_->find_next(pos_);
+    return *this;
+}
+
+
+inline bool Foam::bitSet::const_iterator::operator==
+(
+    const const_iterator& iter
+) const noexcept
+{
+    return (iter.pos_ == pos_);
+}
+
+
+inline bool Foam::bitSet::const_iterator::operator!=
+(
+    const const_iterator& iter
+) const noexcept
+{
+    return (iter.pos_ != pos_);
+}
+
+
+inline Foam::bitSet::const_iterator Foam::bitSet::begin() const
+{
+    return const_iterator(this);
+}
+
+
+inline Foam::bitSet::const_iterator Foam::bitSet::cbegin() const
+{
+    return const_iterator(this);
+}
+
+
+inline Foam::bitSet::const_iterator Foam::bitSet::end() const noexcept
+{
+    return const_iterator();
+}
+
+
+inline Foam::bitSet::const_iterator Foam::bitSet::cend() const noexcept
+{
+    return const_iterator();
+}
+
+
+inline Foam::label Foam::bitSet::find_first() const
+{
+    // Process block-wise, detecting any '1' bits
+
+    const label nblocks = num_blocks(size());
+    for (label blocki = 0; blocki < nblocks; ++blocki)
+    {
+        label pos = (blocki * elem_per_block);
+
+        for
+        (
+            unsigned int blockval = blocks_[blocki];
+            blockval;
+            blockval >>= 1u
+        )
+        {
+            if (blockval & 1u)
+            {
+                return pos;
+            }
+            ++pos;
+        }
+    }
+
+    return -1;
+}
+
+
+inline Foam::label Foam::bitSet::find_last() const
+{
+    // Process block-wise, detecting any '1' bits
+
+    for (label blocki = num_blocks(size())-1; blocki >= 0; --blocki)
+    {
+        unsigned int blockval = blocks_[blocki];
+
+        if (blockval)
+        {
+            label pos = (blocki * elem_per_block) - 1;
+
+            while (blockval)
+            {
+                blockval >>= 1u;
+                ++pos;
+            }
+
+            return pos;
+        }
+    }
+
+    return -1;
+}
+
+
+inline Foam::label Foam::bitSet::find_next(label pos) const
+{
+    ++pos;
+    if (pos < 0 || pos >= size())
+    {
+        return -1;
+    }
+
+    // The corresponding block/offset
+    label blocki = pos / elem_per_block;
+    unsigned int off = pos % elem_per_block;
+
+    for
+    (
+        unsigned int blockval = (blocks_[blocki] >> off);
+        blockval;
+        blockval >>= 1u
+    )
+    {
+        if (blockval & 1u)
+        {
+            return pos;
+        }
+        ++pos;
+    }
+
+    // Normal block-wise search. Starting at the next block
+
+    const label nblocks = num_blocks(size());
+    for (++blocki; blocki < nblocks; ++blocki)
+    {
+        label pos = (blocki * elem_per_block);
+
+        for
+        (
+            unsigned int blockval = blocks_[blocki];
+            blockval;
+            blockval >>= 1u
+        )
+        {
+            if (blockval & 1u)
+            {
+                return pos;
+            }
+            ++pos;
+        }
+    }
+
+    return -1;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+inline bool Foam::bitSet::all() const
+{
+    if (empty())
+    {
+        return true;
+    }
+
+    // Use complement to change 0 <-> 1 and check if any 1's now appear
+
+    const label nblocks = num_blocks(size());
+
+    // Extra bits in the final block?
+    const unsigned int off = size() % elem_per_block;
+
+    if (!off)
+    {
+        for (label blocki=0; blocki < nblocks; ++blocki)
+        {
+            if (~(blocks_[blocki]))
+            {
+                return false;
+            }
+        }
+    }
+    else
+    {
+        for (label blocki=0; blocki < nblocks-1; ++blocki)
+        {
+            if (~(blocks_[blocki]))
+            {
+                return false;
+            }
+        }
+
+        // Verify the final block, with masking
+
+        return (!(~blocks_[nblocks-1] & mask_lower(off)));
+    }
+
+    return true;
+}
+
+
+inline bool Foam::bitSet::any() const
+{
+    if (size())
+    {
+        const label nblocks = num_blocks(size());
+
+        for (label blocki=0; blocki < nblocks; ++blocki)
+        {
+            if (blocks_[blocki]) return true;
+        }
+    }
+
+    return false;
+}
+
+
+inline bool Foam::bitSet::none() const
+{
+    return !any();
+}
+
+
+inline bool Foam::bitSet::uniform() const
+{
+    return (size() > 1 && (test(0) ? all() : none()));
+}
+
+
+inline unsigned int Foam::bitSet::count() const
+{
+    unsigned int total = 0;
+
+    const label nblocks = num_blocks(size());
+
+    for (label blocki = 0; blocki < nblocks; ++blocki)
+    {
+        total += BitOps::bit_count(blocks_[blocki]);
+    }
+
+    return total;
+}
+
+
+inline bool Foam::bitSet::test(const label pos) const
+{
+    return get(pos);
+}
+
+
+inline Foam::labelList Foam::bitSet::sortedToc() const
+{
+    return toc();
+}
+
+
+inline void Foam::bitSet::swap(bitSet& bitset)
+{
+    PackedList<1>::swap(bitset);
+}
+
+
+inline void Foam::bitSet::transfer(bitSet& bitset)
+{
+    PackedList<1>::transfer(bitset);
+}
+
+
+inline void Foam::bitSet::assign(const bool val)
+{
+    if (empty())
+    {
+        return;  // Trivial case
+    }
+
+    const label nblocks = num_blocks(size());
+
+    if (val)
+    {
+        for (label blocki=0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] = (~0u);
+        }
+        clear_trailing_bits();
+    }
+    else
+    {
+        for (label blocki=0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] = (0u);
+        }
+    }
+}
+
+
+inline void Foam::bitSet::set(const bitSet& bitset)
+{
+    orEq(bitset, false);  // Non-strict: Lets the set size grow.
+}
+
+
+inline void Foam::bitSet::setMany(const labelUList& locations)
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline void Foam::bitSet::setMany(const labelUIndList& locations)
+{
+    setMany(locations.begin(), locations.end());
+}
+
+
+inline void Foam::bitSet::unsetMany(const labelUList& locations)
+{
+    unsetMany(locations.begin(), locations.end());
+}
+
+
+inline void Foam::bitSet::unsetMany(const labelUIndList& locations)
+{
+    unsetMany(locations.begin(), locations.end());
+}
+
+
+inline Foam::bitSet& Foam::bitSet::unset(const bitSet& other)
+{
+    return minusEq(other);
+}
+
+
+inline void Foam::bitSet::flip()
+{
+    if (size())
+    {
+        const label nblocks = num_blocks(size());
+
+        for (label blocki=0; blocki < nblocks; ++blocki)
+        {
+            blocks_[blocki] = ~(blocks_[blocki]);
+        }
+        clear_trailing_bits();
+    }
+}
+
+
+inline void Foam::bitSet::flip(const label i)
+{
+    if (i >= 0 && i < size())
+    {
+        reference(this, i).flip();
+    }
+}
+
+
+inline Foam::bitSet& Foam::bitSet::bound(const label maxSize)
+{
+    if (maxSize < size())
+    {
+        resize(maxSize);
+    }
+
+    return *this;
+}
+
+
+inline Foam::bitSet& Foam::bitSet::bound(const bitSet& other)
+{
+    return bound(other.size());
+}
+
+
+inline Foam::bitSet& Foam::bitSet::extend(const label minSize)
+{
+    if (size() < minSize)
+    {
+        resize(minSize);
+    }
+
+    return *this;
+}
+
+
+inline Foam::bitSet& Foam::bitSet::extend(const bitSet& other)
+{
+    return extend(other.size());
+}
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+inline unsigned int Foam::bitSet::operator[](const label i) const
+{
+    return get(i);
+}
+
+
+inline Foam::bitSet::reference Foam::bitSet::operator[](const label i)
+{
+    // Leave enabled during testing period (MAR-2018) ... and perhaps later too
+    // #ifdef FULLDEBUG
+    checkIndex(i);
+    // #endif
+    return reference(this, i);
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator=(const bool val)
+{
+    PackedList<1>::operator=(val);
+    return *this;
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator=(const bitSet& bitset)
+{
+    PackedList<1>::operator=(bitset);
+    return *this;
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator=(bitSet&& bitset)
+{
+    transfer(bitset);
+    return *this;
+}
+
+
+inline Foam::bitSet Foam::bitSet::operator~() const
+{
+    bitSet result(*this);
+    result.flip();
+    return result;
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator&=(const bitSet& other)
+{
+    return andEq(other);
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator|=(const bitSet& other)
+{
+    return orEq(other);
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator^=(const bitSet& other)
+{
+    return xorEq(other);
+}
+
+
+inline Foam::bitSet& Foam::bitSet::operator-=(const bitSet& other)
+{
+    return minusEq(other);
+}
+
+
+// * * * * * * * * * * * * * * * Global Operators  * * * * * * * * * * * * * //
+
+inline Foam::bitSet Foam::operator&(const bitSet& a, const bitSet& b)
+{
+    bitSet result(a);
+    return (result &= b);
+}
+
+
+inline Foam::bitSet Foam::operator|(const bitSet& a, const bitSet& b)
+{
+    bitSet result(a);
+    return (result |= b);
+}
+
+
+inline Foam::bitSet Foam::operator^(const bitSet& a, const bitSet& b)
+{
+    bitSet result(a);
+    return (result ^= b);
+}
+
+
+inline Foam::bitSet Foam::operator-(const bitSet& a, const bitSet& b)
+{
+    bitSet result(a);
+    return (result -= b);
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSetIO.C b/src/OpenFOAM/containers/Bits/bitSet/bitSetIO.C
new file mode 100644
index 0000000000000000000000000000000000000000..f3b03da8f73a440cf1fac4d09bb1a32170b3f69a
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSetIO.C
@@ -0,0 +1,135 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 "bitSet.H"
+#include "IOstreams.H"
+
+// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
+
+void Foam::bitSet::writeEntry(Ostream& os) const
+{
+    os  << *this;
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::bitSet::writeList
+(
+    Ostream& os,
+    const label shortListLen
+) const
+{
+    const bitSet& list = *this;
+    const label len = list.size();
+
+    // Write list contents depending on data format
+    if (os.format() == IOstream::ASCII)
+    {
+        if (list.uniform())
+        {
+            // Two or more entries, and all entries have identical values.
+            os  << len << token::BEGIN_BLOCK << list[0] << token::END_BLOCK;
+        }
+        else if (!shortListLen || len <= shortListLen)
+        {
+            // Shorter list, or line-breaks suppressed
+            os  << len << token::BEGIN_LIST;
+            for (label i=0; i < len; ++i)
+            {
+                if (i) os << token::SPACE;
+                os  << list[i];
+            }
+            os  << token::END_LIST;
+        }
+        else
+        {
+            // Longer list
+            os << nl << len << nl << token::BEGIN_LIST << nl;
+            for (label i=0; i < len; ++i)
+            {
+                os << list[i] << nl;
+            }
+            os << token::END_LIST << nl;
+        }
+    }
+    else
+    {
+        // Contents are binary and contiguous
+        os  << nl << len << nl;
+
+        if (len)
+        {
+            // write(...) includes surrounding start/end delimiters
+            os.write
+            (
+                reinterpret_cast<const char*>(list.storage().cdata()),
+                list.byteSize()
+            );
+        }
+    }
+
+    return os;
+}
+
+
+void Foam::bitSet::writeEntry
+(
+    const word& keyword,
+    Ostream& os
+) const
+{
+    os.writeKeyword(keyword);
+    writeEntry(os);
+    os  << token::END_STATEMENT << endl;
+}
+
+
+// * * * * * * * * * * * * * *  Friend Operators * * * * * * * * * * * * * * //
+
+Foam::Ostream& Foam::operator<<(Ostream& os, const bitSet& bitset)
+{
+    return bitset.writeList(os, 10);
+}
+
+
+Foam::Ostream& Foam::operator<<
+(
+    Ostream& os,
+    const InfoProxy<bitSet>& iproxy
+)
+{
+    const bitSet& bitset = iproxy.t_;
+
+    os  << "bitSet<" << bitSet::elem_per_block
+        << "> size=" << bitset.size() << "/" << bitset.capacity()
+        << " count=" << bitset.count()
+        << nl;
+
+    return os;
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C b/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..a8d5ac325677825c46d171e65ebcee791df1802e
--- /dev/null
+++ b/src/OpenFOAM/containers/Bits/bitSet/bitSetTemplates.C
@@ -0,0 +1,59 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2018 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 <algorithm>
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class InputIter>
+void Foam::bitSet::setMany(InputIter first, InputIter last)
+{
+    // Check the max expected value first
+    const auto max = std::max_element(first, last);
+    const label len = (max != last ? (1 + *max) : 0);
+
+    if (len > 0)
+    {
+        reserve(len);
+
+        for (; first != last; ++first)
+        {
+            set(*first);
+        }
+    }
+}
+
+
+template<class InputIter>
+void Foam::bitSet::unsetMany(InputIter first, InputIter last)
+{
+    for (; first != last; ++first)
+    {
+        unset(*first);
+    }
+}
+
+
+// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/HashTables/HashOps/HashOps.C b/src/OpenFOAM/containers/HashTables/HashOps/HashOps.C
index 494ad5ed4b0c914a4969d5f28dd8ff162a4f80bd..e783ad0e517f4726c2b8f90d2c581895e8c4dfe0 100644
--- a/src/OpenFOAM/containers/HashTables/HashOps/HashOps.C
+++ b/src/OpenFOAM/containers/HashTables/HashOps/HashOps.C
@@ -24,26 +24,23 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "HashOps.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 #include <algorithm>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-Foam::labelHashSet Foam::HashSetOps::used(const PackedBoolList& select)
+Foam::labelHashSet Foam::HashSetOps::used(const bitSet& select)
 {
-    const label count = select.count();
-    const label len = select.size();
-
-    labelHashSet output(2*count);
+    labelHashSet output(0);
 
-    label used = 0;
-    for (label i = 0; i < len && used < count; ++i)
+    if (select.any())
     {
-        if (select[i])
+        output.resize(2*select.count());
+
+        for (label i = select.find_first(); i >= 0; i = select.find_next(i))
         {
             output.insert(i);
-            ++used;
         }
     }
 
@@ -53,11 +50,10 @@ Foam::labelHashSet Foam::HashSetOps::used(const PackedBoolList& select)
 
 Foam::labelHashSet Foam::HashSetOps::used(const UList<bool>& select)
 {
-    // We have no estimate of the size/sparsity, just assume 1/10
-
     const label len = select.size();
 
-    labelHashSet output(len/10);
+    // No idea of the sparseness, just assume 1/8
+    labelHashSet output(len/4);
 
     for (label i = 0; i < len; ++i)
     {
@@ -71,34 +67,19 @@ Foam::labelHashSet Foam::HashSetOps::used(const UList<bool>& select)
 }
 
 
-Foam::PackedBoolList Foam::HashSetOps::bitset(const labelHashSet& labels)
+Foam::bitSet Foam::HashSetOps::bitset(const labelHashSet& locations)
 {
-    auto const max = std::max_element(labels.cbegin(), labels.cend());
-    const label len = (max.found() ? (1 + *max) : 0);
-
-    if (len <= 0)
-    {
-        return PackedBoolList();
-    }
-
-    PackedBoolList output(len);
-
-    for (const label i : labels)
-    {
-        if (i >= 0)
-        {
-            output.set(i);
-        }
-    }
+    bitSet output;
+    output.setMany(locations.begin(), locations.end());
 
     return output;
 }
 
 
-Foam::List<bool> Foam::HashSetOps::bools(const labelHashSet& labels)
+Foam::List<bool> Foam::HashSetOps::bools(const labelHashSet& locations)
 {
-    auto const max = std::max_element(labels.cbegin(), labels.cend());
-    const label len = (max.found() ? (1 + *max) : 0);
+    auto const max = std::max_element(locations.begin(), locations.end());
+    const label len = (max != locations.end() ? (1 + *max) : 0);
 
     if (len <= 0)
     {
@@ -107,7 +88,7 @@ Foam::List<bool> Foam::HashSetOps::bools(const labelHashSet& labels)
 
     List<bool> output(len, false);
 
-    for (const label i : labels)
+    for (const label i : locations)
     {
         if (i >= 0)
         {
diff --git a/src/OpenFOAM/containers/HashTables/HashOps/HashOps.H b/src/OpenFOAM/containers/HashTables/HashOps/HashOps.H
index b19f1aca99e91d7447fab844e97752533c7f3cc0..8a6ae13c262d001c30c9276ac2c75ccc928c6ed7 100644
--- a/src/OpenFOAM/containers/HashTables/HashOps/HashOps.H
+++ b/src/OpenFOAM/containers/HashTables/HashOps/HashOps.H
@@ -49,7 +49,7 @@ namespace Foam
 
 // Forward declarations
 
-class PackedBoolList;
+class bitSet;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -60,7 +60,7 @@ class PackedBoolList;
 namespace HashSetOps
 {
 
-//- Combine HashSet operation. Equivalent to 'a += b'
+//- Combine HashSet operation. Equivalent to 'a |= b'
 template<class Key=word, class Hash=string::hash>
 struct plusEqOp
 {
@@ -68,52 +68,56 @@ struct plusEqOp
 
     void operator()(value_type& a, const value_type& b) const
     {
-        a += b;
+        a |= b;
     }
 };
 
 
-//- Convert a packed list of bits to a labelHashSet of the indices used.
+//- Convert a bitset to a labelHashSet of the indices used.
 //
-//  \param selection the list for which a 'true' entry corresponds
-//       to an index for be added to the labelHashSet
+//  \param select the bitset for which an \a on entry corresponds
+//       to an index in the output labelHashSet
 //
 //  \return a labelHashSet of the selected indices
-labelHashSet used(const PackedBoolList& select);
+//
+//  This is equivalent of the following code, but more efficiently implemented.
+//  \code
+//      bitSet select = ...;
+//      return labelHashSet(select.toc());
+//  \endcode
+labelHashSet used(const bitSet& select);
 
 
 //- Convert a list of bools to a labelHashSet of the indices used.
 //
-//  \param selection the list for which a 'true' entry corresponds
-//       to an index for be added to the labelHashSet
+//  \param select the boolList for which a \a true entry corresponds
+//       to an index in the output labelHashSet
 //
 //  \return a labelHashSet of the selected indices
 labelHashSet used(const UList<bool>& select);
 
 
-//- Convert labels to a packed list of bits, with '1' for each
-//- non-negative value and '0' for all others.
+//- Transform the \a on locations to a bitSet.
 //
-//  \param labels the list of indices.
+//  \param locations the list of positions corresponding to an \a on bit.
 //
-//  \return a packed bit list of the selected indices
+//  \return a bitset
 //
-//  \note The operation discards any negative values since these are
-//     invalid positions in the output list.
-PackedBoolList bitset(const labelHashSet& labels);
+//  \note The operation necessarily discards any negative values since these
+//     are invalid positions in a bitset.
+bitSet bitset(const labelHashSet& locations);
 
 
-//- Convert labels to a list of bools, with 'true' for each
-//- non-negative value and 'false' for all others.
+//- Transform the \a on locations to a boolList, with \a true for each
+//- non-negative location and \a false for all others.
 //
-//  \param labels the list of indices.
+//  \param locations the list of positions corresponding to an \a on bit.
 //
-//  \return a bool List of the selected indices
+//  \return a boolList
 //
-//  \note The operation discards any negative values since these are
-//     invalid positions in the output list.
-List<bool> bools(const labelHashSet& labels);
-
+//  \note The operation necessarily discards any negative values since these
+//     are invalid positions in a boolList.
+List<bool> bools(const labelHashSet& locations);
 
 } // End namespace HashSetOps
 
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
index 72b34de0ca81e15ae7b1560d54a2330d8481d2e8..6b19a60422f7656fc58c04fd05e743406818bd6b 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.C
@@ -115,16 +115,16 @@ Foam::labelList Foam::identity(const label len, const label start)
 }
 
 
-Foam::PackedBoolList Foam::reorder
+Foam::bitSet Foam::reorder
 (
     const labelUList& oldToNew,
-    const PackedBoolList& input,
+    const bitSet& input,
     const bool prune
 )
 {
     const label len = input.size();
 
-    PackedBoolList output(len);
+    bitSet output;
     output.reserve(len);
 
     for (label i=0; i < len; ++i)
@@ -149,10 +149,6 @@ Foam::PackedBoolList Foam::reorder
         output.trim();
     }
 
-    // Verify addresses (for movable refs)
-    // Info<< "reordered in " << long(input.storage().cdata()) << nl
-    //     << "reordered out " << long(output.storage().cdata()) << nl;
-
     return output;
 }
 
@@ -160,14 +156,11 @@ Foam::PackedBoolList Foam::reorder
 void Foam::inplaceReorder
 (
     const labelUList& oldToNew,
-    PackedBoolList& input,
+    bitSet& input,
     const bool prune
 )
 {
     input = reorder(oldToNew, input, prune);
-
-    // Verify address (for movable refs)
-    // Info<< "now have " << long(input.storage().cdata()) << nl;
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
index b4a988542eca6c2c81093f35046b9d48844be8fa..f5e9a8f591b78e3ac6e647353b5c3aa1c11ef111 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
@@ -45,7 +45,7 @@ SourceFiles
 #include "FlatOutput.H"
 #include "labelList.H"
 #include "HashSet.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "ops.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -126,22 +126,20 @@ void inplaceReorder
 
 
 //- Reorder the elements of a list.
-//  Similar to the general templated form, but with auto-vivify
-//  for PackedBoolList.
-PackedBoolList reorder
+//  Similar to the general templated form, but with auto-vivify for Bitset.
+bitSet reorder
 (
     const labelUList& oldToNew,
-    const PackedBoolList& input,
+    const bitSet& input,
     const bool prune = false
 );
 
 //- Inplace reorder the elements of a list.
-//  Similar to the general templated form, but with auto-vivify
-//  for PackedBoolList.
+//  Similar to the general templated form, but with auto-vivify for bitSet.
 void inplaceReorder
 (
     const labelUList& oldToNew,
-    PackedBoolList& input,
+    bitSet& input,
     const bool prune = false
 );
 
@@ -456,7 +454,7 @@ template<class T>
 void setValue
 (
     UList<T>& list,
-    const PackedBoolList& locations,
+    const bitSet& locations,
     const T& val
 );
 
@@ -578,7 +576,7 @@ template<class T>
 List<T> createWithValue
 (
     const label len,
-    const PackedBoolList& locations,
+    const bitSet& locations,
     const T& val,
     const T& deflt = T()
 );
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
index 068d4187bdc6801180a5565c19d8e4e60e030651..cbb95cf7f594ebc13e4f7d05e290f56d5ee1d4c4 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
@@ -128,7 +128,7 @@ void Foam::inplaceReorder
     // the oldToNew map is unique (ie, shuffle)
 
     // Use const reference to ensure we obtain the proper operator[]
-    // on lazy lists (eg, List<bool>, PackedBoolList)
+    // on lazy lists (eg, List<bool>, PackedList)
 
     const ListType& input = inputOutput;
     const label len = input.size();
@@ -439,7 +439,7 @@ ListType Foam::subset
 {
     const label len = input.size();
 
-    // select can have a different size (eg, PackedBoolList, labelHashSet)
+    // select can have a different size (eg, bitSet, labelHashSet)
 
     ListType output(len);
     output.resize(len);   // Consistent sizing (eg, DynamicList)
@@ -468,7 +468,7 @@ void Foam::inplaceSubset
 {
     const label len = input.size();
 
-    // select can have a different size (eg, PackedBoolList, labelHashSet)
+    // select can have a different size (eg, bitSet, labelHashSet)
 
     label count = 0;
     for (label i=0; i < len; ++i)
@@ -979,22 +979,20 @@ template<class T>
 void Foam::ListOps::setValue
 (
     UList<T>& list,
-    const PackedBoolList& locations,
+    const bitSet& locations,
     const T& val
 )
 {
-    // Need improvements in PackedBoolList for more efficiency
-
     const label len = list.size();
-    const label count = locations.count();
 
-    for (label index = 0, used = 0; index < len && used < count; ++index)
+    for
+    (
+        label pos = locations.find_first();
+        pos >= 0 && pos < len;
+        pos = locations.find_next(pos)
+    )
     {
-        if (locations.test(index))
-        {
-            list[index] = val;
-            ++used;
-        }
+        list[pos] = val;
     }
 }
 
@@ -1106,7 +1104,7 @@ template<class T>
 Foam::List<T> Foam::ListOps::createWithValue
 (
     const label len,
-    const PackedBoolList& locations,
+    const bitSet& locations,
     const T& val,
     const T& deflt
 )
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C
deleted file mode 100644
index e47ee6f4f36c524d3d93f55bd06c1575f78400f3..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.C
+++ /dev/null
@@ -1,217 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     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 PackedBoolList& 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>
-void Foam::PackedBoolList::setIndices(const LabelListType& indices)
-{
-    const label len = indices.size();
-
-    // No better information, just guess something from the size
-    reserve(len);
-
-    for (label i = 0; i < len; ++i)
-    {
-        set(indices[i]);
-    }
-}
-
-
-template<class LabelListType>
-void Foam::PackedBoolList::unsetIndices(const LabelListType& indices)
-{
-    const label len = indices.size();
-    for (label i = 0; i < len; ++i)
-    {
-        unset(indices[i]);
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-Foam::PackedBoolList::PackedBoolList(Istream& is)
-:
-    PackedList<1>()
-{
-    is  >> *this;
-}
-
-
-// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
-
-void Foam::PackedBoolList::set(const PackedBoolList& 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();
-    }
-}
-
-
-void Foam::PackedBoolList::unset(const PackedBoolList& 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];
-    }
-}
-
-
-void Foam::PackedBoolList::setMany(const labelUList& indices)
-{
-    setIndices(indices);
-}
-
-
-void Foam::PackedBoolList::setMany(const labelUIndList& indices)
-{
-    setIndices(indices);
-}
-
-
-void Foam::PackedBoolList::unsetMany(const labelUList& indices)
-{
-    unsetIndices(indices);
-}
-
-
-void Foam::PackedBoolList::unsetMany(const labelUIndList& indices)
-{
-    unsetIndices(indices);
-}
-
-
-Foam::labelList Foam::PackedBoolList::used() const
-{
-    // Number of used (set) entries
-    const label cnt = this->count();
-
-    labelList lst(cnt);
-
-    if (cnt)
-    {
-        // The length of the input list
-        const label len = this->size();
-
-        for (label i=0, usedi=0; (i < len && usedi < cnt); ++i)
-        {
-            if (test(i))
-            {
-                lst[usedi++] = i;
-            }
-        }
-    }
-
-    return lst;
-}
-
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H b/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H
deleted file mode 100644
index dd69d6f79f3994195b82cff75e339e0c529c7486..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolList.H
+++ /dev/null
@@ -1,216 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
--------------------------------------------------------------------------------
-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
-
-See also
-    Foam::PackedList
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef PackedBoolList_H
-#define PackedBoolList_H
-
-#include "PackedList.H"
-#include "UIndirectList.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// Forward declaration
-class PackedBoolList;
-
-//- \typedef A List of PackedBoolList
-typedef List<PackedBoolList> PackedBoolListList;
-
-/*---------------------------------------------------------------------------*\
-                       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 PackedBoolList& lst, label& maxPackLen);
-
-        //- Set the listed indices. Return number of elements changed.
-        //  Does auto-vivify for non-existent entries.
-        template<class LabelListType>
-        void setIndices(const LabelListType& indices);
-
-        //- Unset the listed indices. Return number of elements changed.
-        //  Never auto-vivify entries.
-        template<class LabelListType>
-        void unsetIndices(const LabelListType& indices);
-
-public:
-
-    // Constructors
-
-        //- Construct null
-        PackedBoolList() = default;
-
-        //- Construct from Istream
-        PackedBoolList(Istream& is);
-
-        //- Construct with given size, initializes list to 0 (false)
-        explicit inline PackedBoolList(const label size);
-
-        //- Construct with given size and value for all elements
-        inline PackedBoolList(const label size, const bool val);
-
-        //- Copy construct
-        inline PackedBoolList(const PackedBoolList& lst);
-
-        //- Move construct
-        inline PackedBoolList(PackedBoolList&& lst);
-
-        //- Construct with given size and list of labels to set as true.
-        inline PackedBoolList(const label size, const labelUList& indices);
-
-        //- Construct with given size and list of labels to set as true.
-        inline PackedBoolList(const label size, const labelUIndList& indices);
-
-        //- Construct from a list of bools
-        explicit inline PackedBoolList(const UList<bool>& lst);
-
-        //- Construct from a list of labels
-        //- using the labels as indices to indicate which bits are set
-        explicit inline PackedBoolList(const labelUList& indices);
-
-        //- Construct from a list of labels
-        //- using the labels as indices to indicate which bits are set
-        explicit inline PackedBoolList(const labelUIndList& indices);
-
-        //- Clone
-        inline autoPtr<PackedBoolList> clone() const;
-
-
-    // Member Functions
-
-    // Query
-
-        //- Test value at specified position.
-        //  \note Method name compatibility with std::bitset
-        inline bool test(const label pos) const;
-
-
-    // Access
-
-        //- Single index/value assign
-        using PackedList<1>::set;
-
-        //- Single index unassign
-        using PackedList<1>::unset;
-
-        //- Set specified bits.
-        void set(const PackedBoolList& lst);
-
-        //- Unset specified bits.
-        void unset(const PackedBoolList& lst);
-
-        //- Return indices of the used (true) elements as a list of labels
-        labelList used() const;
-
-
-    // Edit
-
-        //- Transfer the contents of the argument list into this list
-        //- and annul the argument list.
-        inline void transfer(PackedBoolList& lst);
-
-
-    // Convenience Methods
-
-        //- Set the listed indices. Return number of elements changed.
-        //  Does auto-vivify for non-existent entries.
-        void setMany(const labelUList& indices);
-
-        //- Set the listed indices. Return number of elements changed.
-        //  Does auto-vivify for non-existent entries.
-        void setMany(const labelUIndList& indices);
-
-        //- Unset the listed indices. Return number of elements changed.
-        //  Never auto-vivify entries.
-        void unsetMany(const labelUList& indices);
-
-        //- Unset the listed indices. Return number of elements changed.
-        //  Never auto-vivify entries.
-        void unsetMany(const labelUIndList& indices);
-
-
-    // Member Operators
-
-        //- Assign all entries to the given value.
-        inline void operator=(const bool val);
-
-        //- Copy assignment
-        inline void operator=(const PackedBoolList& lst);
-
-        //- Move assignment
-        inline void operator=(PackedBoolList&& lst);
-
-
-    // Housekeeping
-
-        //- No assignment from list. Use setMany for that.
-        void operator=(const labelUList&) = delete;
-
-        //- No assignment from list. Use setMany for that.
-        void operator=(const labelUIndList&) = delete;
-
-
-};
-
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // 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
deleted file mode 100644
index da76aff94b51e77d2aa5001af8f8a3f9df445646..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedBoolListI.H
+++ /dev/null
@@ -1,152 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
--------------------------------------------------------------------------------
-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(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(PackedBoolList&& lst)
-:
-    PackedList<1>()
-{
-    transfer(lst);
-}
-
-
-inline Foam::PackedBoolList::PackedBoolList(const UList<bool>& lst)
-:
-    PackedList<1>(lst.size())
-{
-    // Set according to indices that are true
-    const label len = lst.size();
-
-    for (label i = 0; i < len; ++i)
-    {
-        if (lst[i])
-        {
-            this->set(i, 1u);
-        }
-    }
-}
-
-
-inline Foam::PackedBoolList::PackedBoolList(const labelUList& indices)
-:
-    PackedBoolList((indices.size() ? indices.last() : 0), indices)
-{}
-
-
-inline Foam::PackedBoolList::PackedBoolList(const labelUIndList& indices)
-:
-    PackedBoolList((indices.size() ? indices.last() : 0), indices)
-{}
-
-
-inline Foam::PackedBoolList::PackedBoolList
-(
-    const label size,
-    const labelUList& indices
-)
-:
-    PackedList<1>(size)
-{
-    setMany(indices);
-}
-
-
-inline Foam::PackedBoolList::PackedBoolList
-(
-    const label size,
-    const labelUIndList& indices
-)
-:
-    PackedList<1>(size)
-{
-    setMany(indices);
-}
-
-
-inline Foam::autoPtr<Foam::PackedBoolList>
-Foam::PackedBoolList::clone() const
-{
-    return autoPtr<PackedBoolList>::New(*this);
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-inline bool Foam::PackedBoolList::test(const label pos) const
-{
-    return get(pos);
-}
-
-
-inline void Foam::PackedBoolList::transfer(PackedBoolList& lst)
-{
-    PackedList<1>::transfer(static_cast<PackedList<1>&>(lst));
-}
-
-
-// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
-
-inline void Foam::PackedBoolList::operator=(const bool val)
-{
-    PackedList<1>::operator=(val);
-}
-
-
-inline void Foam::PackedBoolList::operator=(const PackedBoolList& lst)
-{
-    PackedList<1>::operator=(lst);
-}
-
-
-inline void Foam::PackedBoolList::operator=(PackedBoolList&& lst)
-{
-    transfer(lst);
-}
-
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C b/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
deleted file mode 100644
index 72def35291e62a5a3e9bf0873d726a3903650168..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedList.C
+++ /dev/null
@@ -1,536 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
--------------------------------------------------------------------------------
-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 "PackedList.H"
-#include "IOstreams.H"
-
-// * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
-
-template<unsigned nBits>
-void Foam::PackedList<nBits>::writeEntry(Ostream& os) const
-{
-    os  << *this;
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-#if (UINT_MAX == 0xFFFFFFFF)
-    // 32-bit counting, Hamming weight method
-    #define COUNT_PACKEDBITS(sum, x)                                           \
-{                                                                              \
-    x -= (x >> 1) & 0x55555555;                                                \
-    x = (x & 0x33333333) + ((x >> 2) & 0x33333333);                            \
-    sum += (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;                 \
-}
-#elif (UINT_MAX == 0xFFFFFFFFFFFFFFFF)
-    // 64-bit counting, Hamming weight method
-    #define COUNT_PACKEDBITS(sum, x)                                           \
-{                                                                              \
-    x -= (x >> 1) & 0x5555555555555555;                                        \
-    x = (x & 0x3333333333333333) + ((x >> 2) & 0x3333333333333333);            \
-    sum += (((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 56; \
-}
-#else
-    // Arbitrary number of bits, Brian Kernighan's method
-    #define COUNT_PACKEDBITS(sum, x)    for (; x; ++sum) { x &= x - 1; }
-#endif
-
-
-template<unsigned nBits>
-unsigned int Foam::PackedList<nBits>::count() const
-{
-    unsigned int c = 0;
-
-    if (size_)
-    {
-        const label packLen = packedLength();
-        for (label i = 0; i < packLen; ++i)
-        {
-            unsigned int bits = StorageList::operator[](i);
-            COUNT_PACKEDBITS(c, bits);
-        }
-    }
-
-    return c;
-}
-
-#undef COUNT_PACKEDBITS
-
-
-template<unsigned nBits>
-bool Foam::PackedList<nBits>::trim()
-{
-    if (!size_)
-    {
-        return false;
-    }
-
-    const label oldSize = size_;
-    for (label storeI = packedLength()-1; storeI >= 0; --storeI)
-    {
-        size_ = storeI * packing();
-        unsigned int bits = StorageList::operator[](storeI);
-
-        // found some bits
-        if (bits)
-        {
-            while (bits)
-            {
-                bits >>= nBits;
-                ++size_;
-            }
-            break;
-        }
-    }
-
-    return (size_ != oldSize);
-}
-
-
-template<unsigned nBits>
-void Foam::PackedList<nBits>::flip()
-{
-    if (!size_)
-    {
-        return;
-    }
-
-    // mask value for complete segments
-    const unsigned int mask = maskLower(packing());
-
-    const label packLen = packedLength();
-    for (label i=0; i < packLen; ++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
-{
-    labelList elems(size_);
-
-    for (label i=0; i < size_; ++i)
-    {
-        elems[i] = get(i);
-    }
-
-    return elems;
-}
-
-
-template<unsigned nBits>
-Foam::Ostream& Foam::PackedList<nBits>::printBits
-(
-    Ostream& os,
-    const bool fullOutput
-) const
-{
-    const label packLen = packedLength();
-
-    // mask value for complete segments
-    unsigned int mask = maskLower(packing());
-    const label outputLen = fullOutput ? StorageList::size() : packLen;
-
-    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 == packLen-1)
-        {
-            const unsigned int off = size_ % packing();
-
-            if (off)
-            {
-                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';
-                }
-                else
-                {
-                    os  << '-';
-                }
-            }
-            else
-            {
-                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(FUNCTION_NAME);
-
-    token firstTok(is);
-    is.fatalCheck
-    (
-        "PackedList::read(Istream&) : "
-        "reading first token"
-    );
-
-    if (firstTok.isLabel())
-    {
-        const label len = firstTok.labelToken();
-
-        // Set list length to that read
-        lst.resize(len);
-
-        // Read list contents depending on data format
-        if (is.format() == IOstream::ASCII)
-        {
-            // Read beginning of contents
-            const char delimiter = is.readBeginList("PackedList");
-
-            if (len)
-            {
-                if (delimiter == token::BEGIN_LIST)
-                {
-                    for (label i=0; i<len; ++i)
-                    {
-                        lst.set(i, lst.readValue(is));
-
-                        is.fatalCheck
-                        (
-                            "PackedList::read(Istream&) : "
-                            "reading entry"
-                        );
-                    }
-                }
-                else if (delimiter == token::BEGIN_BLOCK)
-                {
-                    // assign for all entries
-                    lst = lst.readValue(is);
-
-                    is.fatalCheck
-                    (
-                        "PackedList::read(Istream&) : "
-                        "reading the single entry"
-                    );
-                }
-                else
-                {
-                    FatalIOErrorInFunction(is)
-                        << "incorrect list token, expected '(' or '{', found "
-                        << firstTok.info()
-                        << exit(FatalIOError);
-                }
-            }
-
-            // Read end of contents
-            is.readEndList("PackedList");
-        }
-        else
-        {
-            if (len)
-            {
-                is.read
-                (
-                    reinterpret_cast<char*>(lst.storage().data()),
-                    lst.byteSize()
-                );
-
-                is.fatalCheck
-                (
-                    "PackedList::read(Istream&) : "
-                    "reading the binary block"
-                );
-            }
-        }
-    }
-    else if (firstTok.isPunctuation())
-    {
-        if (firstTok.pToken() == token::BEGIN_LIST)
-        {
-            token nextTok(is);
-            is.fatalCheck(FUNCTION_NAME);
-
-            while
-            (
-                !(   nextTok.isPunctuation()
-                  && nextTok.pToken() == token::END_LIST
-                 )
-            )
-            {
-                is.putBack(nextTok);
-                lst.append(lst.readValue(is));
-
-                is  >> nextTok;
-                is.fatalCheck(FUNCTION_NAME);
-            }
-        }
-        else if (firstTok.pToken() == token::BEGIN_BLOCK)
-        {
-            token nextTok(is);
-            is.fatalCheck(FUNCTION_NAME);
-
-            while
-            (
-                !(   nextTok.isPunctuation()
-                  && nextTok.pToken() == token::END_BLOCK
-                 )
-            )
-            {
-                is.putBack(nextTok);
-                lst.setPair(is);
-
-                is  >> nextTok;
-                is.fatalCheck(FUNCTION_NAME);
-            }
-        }
-        else
-        {
-            FatalIOErrorInFunction(is)
-                << "incorrect first token, expected '(', found "
-                << firstTok.info()
-                << exit(FatalIOError);
-        }
-    }
-    else
-    {
-        FatalIOErrorInFunction(is)
-            << "incorrect first token, expected <int>, '(' or '{', found "
-            << firstTok.info()
-            << exit(FatalIOError);
-    }
-
-    return is;
-}
-
-
-template<unsigned nBits>
-Foam::Ostream& Foam::PackedList<nBits>::writeList
-(
-    Ostream& os,
-    const label shortListLen
-) const
-{
-    const PackedList<nBits>& lst = *this;
-    const label len = lst.size();
-
-    // Write list contents depending on data format
-    if (os.format() == IOstream::ASCII)
-    {
-        // Can the contents be considered 'uniform' (ie, identical)?
-        bool uniform = (len > 1);
-        if (uniform)
-        {
-            forAll(lst, i)
-            {
-                if (lst[i] != lst[0])
-                {
-                    uniform = false;
-                    break;
-                }
-            }
-        }
-
-        if (uniform)
-        {
-            // uniform values:
-            os  << len << token::BEGIN_BLOCK << lst[0] << token::END_BLOCK;
-        }
-        else if (!shortListLen || len <= shortListLen)
-        {
-            // Shorter list, or line-breaks suppressed
-            os  << len << token::BEGIN_LIST;
-            forAll(lst, i)
-            {
-                if (i) os << token::SPACE;
-                os  << lst[i];
-            }
-            os  << token::END_LIST;
-        }
-        else
-        {
-            // Longer list
-            os << nl << len << nl << token::BEGIN_LIST << nl;
-            forAll(lst, i)
-            {
-                os << lst[i] << nl;
-            }
-            os << token::END_LIST << nl;
-        }
-    }
-    else
-    {
-        // Contents are binary and contiguous
-        os  << nl << len << nl;
-
-        if (len)
-        {
-            // write(...) includes surrounding start/end delimiters
-            os.write
-            (
-                reinterpret_cast<const char*>(lst.storage().cdata()),
-                lst.byteSize()
-            );
-        }
-    }
-
-    return os;
-}
-
-
-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)
-{
-    StorageList::operator=(lst);
-    size_ = lst.size();
-}
-
-
-template<unsigned nBits>
-void Foam::PackedList<nBits>::operator=(PackedList<nBits>&& lst)
-{
-    transfer(lst);
-}
-
-
-template<unsigned nBits>
-void Foam::PackedList<nBits>::operator=(const labelUList& lst)
-{
-    setCapacity(lst.size());
-    size_ = lst.size();
-
-    forAll(lst, i)
-    {
-        set(i, lst[i]);
-    }
-}
-
-
-template<unsigned nBits>
-void Foam::PackedList<nBits>::operator=(const labelUIndList& lst)
-{
-    setCapacity(lst.size());
-    size_ = lst.size();
-
-    forAll(lst, i)
-    {
-        set(i, lst[i]);
-    }
-}
-
-
-// * * * * * * * * * * * * * *  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)
-{
-    return lst.writeList(os, 10);
-}
-
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H b/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
deleted file mode 100644
index cfa2b8ca9cb4c6be9e6cb706ce56d4a0f1e6ce80..0000000000000000000000000000000000000000
--- a/src/OpenFOAM/containers/Lists/PackedList/PackedListI.H
+++ /dev/null
@@ -1,730 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2017-2018 OpenCFD Ltd.
--------------------------------------------------------------------------------
-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 <climits>
-#include "error.H"
-
-// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
-
-template<unsigned nBits>
-inline constexpr unsigned int Foam::PackedList<nBits>::max_bits()
-{
-    return sizeof(StorageType)*CHAR_BIT - 1;
-}
-
-
-template<unsigned nBits>
-inline constexpr unsigned int Foam::PackedList<nBits>::max_value()
-{
-    return (1u << nBits) - 1;
-}
-
-
-template<unsigned nBits>
-inline constexpr unsigned int Foam::PackedList<nBits>::packing()
-{
-    return sizeof(StorageType)*CHAR_BIT / nBits;
-}
-
-
-template<unsigned nBits>
-inline constexpr unsigned int Foam::PackedList<nBits>::maskLower
-(
-    unsigned offset
-)
-{
-    // Return (1u << (nBits * offset)) - 1;
-    // The next one works more reliably with overflows
-    // eg, when compiled without optimization
-    return (~0u >> (sizeof(StorageType)*CHAR_BIT - nBits * offset));
-}
-
-
-template<unsigned nBits>
-inline constexpr Foam::label Foam::PackedList<nBits>::packedLength
-(
-    const label nElem
-)
-{
-    return (nElem + packing() - 1) / packing();
-}
-
-
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-namespace Foam
-{
-    // Template specialization for bool entries
-    template<> inline unsigned int PackedList<1>::readValue(Istream& is)
-    {
-        return readBool(is);
-    }
-
-    // Template specialization for bool entries
-    template<> inline void PackedList<1>::setPair(Istream& is)
-    {
-        set(readLabel(is), true);
-    }
-}
-
-
-template<unsigned nBits>
-inline unsigned int Foam::PackedList<nBits>::readValue(Istream& is)
-{
-    const unsigned int val = readLabel(is);
-
-    if (val > max_value())
-    {
-        FatalIOErrorInFunction(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())
-    {
-        FatalIOErrorInFunction(is)
-            << "Out-of-range value " << val << " for PackedList<" << nBits
-            << "> at index " << ind
-            << ". Maximum permitted value is " << max_value() << "."
-            << exit(FatalIOError);
-    }
-
-    set(ind, val);
-
-    is.check(FUNCTION_NAME);
-}
-
-
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>::PackedList()
-:
-    PackedListCore(),
-    StorageList(),
-    size_(0)
-{}
-
-
-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_)
-{}
-
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>::PackedList(PackedList<nBits>&& lst)
-:
-    PackedListCore(),
-    StorageList(),
-    size_(0)
-{
-    transfer(lst);
-}
-
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>::PackedList(const labelUList& lst)
-:
-    PackedListCore(),
-    StorageList(packedLength(lst.size()), 0u),
-    size_(lst.size())
-{
-    const label len = lst.size();
-    for (label i = 0; i < len; ++i)
-    {
-        set(i, lst[i]);
-    }
-}
-
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>::PackedList(const labelUIndList& lst)
-:
-    PackedListCore(),
-    StorageList(packedLength(lst.size()), 0u),
-    size_(lst.size())
-{
-    const label len = lst.size();
-    for (label i = 0; i < len; ++i)
-    {
-        set(i, lst[i]);
-    }
-}
-
-
-template<unsigned nBits>
-inline Foam::autoPtr<Foam::PackedList<nBits>>
-Foam::PackedList<nBits>::clone() const
-{
-    return autoPtr<PackedList<nBits>>::New(*this);
-}
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::checkIndex(const label i) const
-{
-    if (!size_)
-    {
-        FatalErrorInFunction
-            << "attempt to access element " << i << " from zero sized list"
-            << abort(FatalError);
-    }
-    else if (i < 0 || i >= size_)
-    {
-        FatalErrorInFunction
-            << "index " << i << " out of range [0," << size_ << ")"
-            << abort(FatalError);
-    }
-}
-
-
-// * * * * * * * * * * * * * * * * Reference  * * * * * * * * * * * * * * * * //
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>::reference::reference
-(
-    PackedList* list,
-    const label index
-)
-:
-    ref_(list->StorageList::operator[](index / packing())),
-    shift_(nBits * (index % packing()))
-{}
-
-
-template<unsigned nBits>
-inline unsigned int Foam::PackedList<nBits>::reference::get() const
-{
-    return ((ref_ >> shift_) & max_value());
-}
-
-
-template<unsigned nBits>
-inline bool Foam::PackedList<nBits>::reference::set(const unsigned int val)
-{
-    const unsigned int prev = ref_;
-
-    const unsigned int mask = max_value() << shift_;
-
-    if (val >= max_value())
-    {
-        // Overflow is max_value, fill everything
-        ref_ |= mask;
-    }
-    else
-    {
-        ref_ &= ~mask;
-        ref_ |= mask & (val << shift_);
-    }
-
-    return (prev != ref_);
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::reference::operator=
-(
-    const reference& other
-)
-{
-    this->set(other.get());
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::reference::operator=
-(
-    const unsigned int val
-)
-{
-    this->set(val);
-}
-
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>::reference::operator unsigned int () const
-{
-    return this->get();
-}
-
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-template<unsigned nBits>
-inline Foam::label Foam::PackedList<nBits>::size() const
-{
-    return size_;
-}
-
-
-template<unsigned nBits>
-inline bool Foam::PackedList<nBits>::empty() const
-{
-    return !size_;
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::resize
-(
-    const label newSize,
-    const unsigned int val
-)
-{
-    reserve(newSize);
-
-    const label oldSize = size_;
-    size_ = newSize;
-
-    if (size_ > oldSize)
-    {
-        // Fill new elements or newly exposed elements
-        if (val)
-        {
-            // Fill value for complete segments
-            unsigned int fill = val;
-
-            if (val >= max_value())
-            {
-                // Fill everything
-                fill = maskLower(packing());
-            }
-            else
-            {
-                for (unsigned int i = 1; i < packing(); ++i)
-                {
-                    fill |= (fill << nBits);
-                }
-            }
-
-            // Fill in complete segments
-            const label oldLen = packedLength(oldSize);
-            const label newLen = packedLength(size_);
-            for (label i=oldLen; i < newLen; ++i)
-            {
-                StorageList::operator[](i) = 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);
-
-                    StorageList::operator[](seg) &= mask;
-                    StorageList::operator[](seg) |= ~mask & fill;
-                }
-            }
-
-            // Mask off the (new) final partial segment
-            {
-                const unsigned int off = size_ % packing();
-                if (off)
-                {
-                    const unsigned int seg = size_ / packing();
-
-                    StorageList::operator[](seg) &= maskLower(off);
-                }
-            }
-        }
-    }
-    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)
-        {
-            StorageList::operator[](i) = 0u;
-        }
-
-        // 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>::setSize
-(
-    const label newSize,
-    const unsigned int val
-)
-{
-    resize(newSize, val);
-}
-
-
-template<unsigned nBits>
-inline Foam::label Foam::PackedList<nBits>::capacity() const
-{
-    return packing() * StorageList::size();
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::setCapacity(const label nElem)
-{
-    StorageList::setSize(packedLength(nElem), 0u);
-
-    // 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)
-{
-    const label len = packedLength(nElem);
-
-    // Allocate more capacity if necessary
-    if (len > StorageList::size())
-    {
-        StorageList::setSize
-        (
-            max
-            (
-                len,
-                // SizeInc=0, SizeMult=2, SizeDiv=1
-                2 * StorageList::size()
-            ),
-            0u
-        );
-    }
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::reset()
-{
-    StorageList::operator=(0u);
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::clear()
-{
-    reset();
-    size_ = 0;
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::clearStorage()
-{
-    StorageList::clear();
-    size_ = 0;
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::shrink()
-{
-    // Any unneeded space allocated?
-    const label len = packedLength();
-    if (len < StorageList::size())
-    {
-        StorageList::setSize(len);
-    }
-}
-
-
-template<unsigned nBits>
-inline Foam::List<unsigned int>& Foam::PackedList<nBits>::storage()
-{
-    return static_cast<StorageList&>(*this);
-}
-
-
-template<unsigned nBits>
-inline const Foam::List<unsigned int>& Foam::PackedList<nBits>::storage() const
-{
-    return static_cast<const StorageList&>(*this);
-}
-
-
-template<unsigned nBits>
-inline Foam::label Foam::PackedList<nBits>::packedLength() const
-{
-    return packedLength(size_);
-}
-
-
-template<unsigned nBits>
-inline std::streamsize Foam::PackedList<nBits>::byteSize() const
-{
-    return packedLength() * sizeof(StorageType);
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::transfer(PackedList<nBits>& lst)
-{
-    size_ = lst.size_;
-    lst.size_ = 0;
-
-    StorageList::transfer(lst);
-}
-
-
-template<unsigned nBits>
-inline unsigned int Foam::PackedList<nBits>::get(const label i) const
-{
-    // Lazy evaluation - return 0 for out-of-range
-    if (i < 0 || i >= size_)
-    {
-        return 0u;
-    }
-
-    return reference(const_cast<PackedList<nBits>*>(this), i).get();
-}
-
-
-template<unsigned nBits>
-inline bool Foam::PackedList<nBits>::set
-(
-    const label i,
-    const unsigned int val
-)
-{
-    if (i < 0)
-    {
-        // Lazy evaluation - ignore out-of-bounds
-        return false;
-    }
-    else if (i >= size_)
-    {
-        if (!val)
-        {
-            // Same as unset out-of-bounds = noop
-            return false;
-        }
-
-        // Lazy evaluation - increase size on assignment
-        resize(i + 1);
-    }
-
-    return reference(this, i).set(val);
-}
-
-
-template<unsigned nBits>
-inline bool Foam::PackedList<nBits>::unset(const label i)
-{
-    // Unset out-of-bounds = noop
-    if (i < 0 || i >= size_)
-    {
-        return false;
-    }
-
-    return reference(this, i).set(0u);
-}
-
-
-template<unsigned nBits>
-inline Foam::PackedList<nBits>&
-Foam::PackedList<nBits>::append(const unsigned int val)
-{
-    const label idx = size_;
-    reserve(idx + 1);
-    size_++;
-
-    reference(this, idx).set(val);
-    return *this;
-}
-
-
-template<unsigned nBits>
-inline unsigned int Foam::PackedList<nBits>::remove()
-{
-    // Location of last element and simultaneously the new size
-    const label idx = size_ - 1;
-
-    if (idx < 0)
-    {
-        FatalErrorInFunction
-            << "List is empty" << abort(FatalError);
-    }
-
-    const unsigned int val = reference(this, idx).get();
-    resize(idx);
-
-    return val;
-}
-
-
-// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
-
-template<unsigned nBits>
-inline unsigned int Foam::PackedList<nBits>::operator[](const label i) const
-{
-    return get(i);
-}
-
-
-template<unsigned nBits>
-inline typename Foam::PackedList<nBits>::reference
-Foam::PackedList<nBits>::operator[](const label i)
-{
-    // Leave enabled during testing period (MAR-2018)
-    // #ifdef FULLDEBUG
-    checkIndex(i);
-    // #endif
-    return reference(this, i);
-}
-
-
-template<unsigned nBits>
-inline void Foam::PackedList<nBits>::operator=(const unsigned int val)
-{
-    const label packLen = packedLength();
-
-    if (val && size_)
-    {
-        unsigned int fill = val;
-
-        if (val >= max_value())
-        {
-            // Fill everything
-            fill = maskLower(packing());
-        }
-        else
-        {
-            for (unsigned int i = 1; i < packing(); ++i)
-            {
-                fill |= (fill << nBits);
-            }
-        }
-
-        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
-    {
-        for (label i=0; i < packLen; ++i)
-        {
-            StorageList::operator[](i) = 0u;
-        }
-    }
-}
-
-
-// ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/bandCompression/bandCompression.C b/src/OpenFOAM/meshes/bandCompression/bandCompression.C
index ddb25eb6fea06c5935bfcb845d36a84959e7fba2..d144288867fe1647c564afbf6aaa0a2e2ef54c12 100644
--- a/src/OpenFOAM/meshes/bandCompression/bandCompression.C
+++ b/src/OpenFOAM/meshes/bandCompression/bandCompression.C
@@ -35,7 +35,7 @@ Description
 #include "IOstreams.H"
 #include "DynamicList.H"
 #include "ListOps.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -46,7 +46,7 @@ Foam::labelList Foam::bandCompression(const labelListList& cellCellAddressing)
     // the business bit of the renumbering
     SLList<label> nextCell;
 
-    PackedBoolList visited(cellCellAddressing.size());
+    bitSet visited(cellCellAddressing.size());
 
     label cellInOrder = 0;
 
@@ -171,7 +171,7 @@ Foam::labelList Foam::bandCompression
     // the business bit of the renumbering
     SLList<label> nextCell;
 
-    PackedBoolList visited(offsets.size()-1);
+    bitSet visited(offsets.size()-1);
 
     label cellInOrder = 0;
 
diff --git a/src/OpenFOAM/meshes/meshShapes/cell/oppositeCellFace.C b/src/OpenFOAM/meshes/meshShapes/cell/oppositeCellFace.C
index 6dda4b349e24662272fb93031376d4daa9537927..7b4ecd3ee838048d45809b4d988d8c4dc3fe5ddc 100644
--- a/src/OpenFOAM/meshes/meshShapes/cell/oppositeCellFace.C
+++ b/src/OpenFOAM/meshes/meshShapes/cell/oppositeCellFace.C
@@ -29,7 +29,7 @@ Description
 
 #include "cell.H"
 #include "oppositeFace.H"
-#include "boolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -136,7 +136,7 @@ Foam::oppositeFace Foam::cell::opposingFace
 
     // Get cell edges
     const edgeList e = edges(meshFaces);
-    boolList usedEdges(e.size(), false);
+    bitSet usedEdges(e.size());
 
     oppositeFace oppFace
     (
@@ -151,7 +151,7 @@ Foam::oppositeFace Foam::cell::opposingFace
         // to the slave face
         forAll(e, edgeI)
         {
-            if (!usedEdges[edgeI])
+            if (!usedEdges.test(edgeI))
             {
                 // Get the other vertex
                 label otherVertex = e[edgeI].otherVertex(masterFace[pointi]);
@@ -165,7 +165,7 @@ Foam::oppositeFace Foam::cell::opposingFace
                     {
                         if (slaveFace[slavePointi] == otherVertex)
                         {
-                            usedEdges[edgeI] = true;
+                            usedEdges.set(edgeI);
                             oppFace[pointi] = otherVertex;
 
                             break;
diff --git a/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C b/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C
index 3e6518bc38367f777d7d185381417a76523e6dee..5c67f040bd1be99f82fc055ccdbbd80d9ef1f73d 100644
--- a/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C
+++ b/src/OpenFOAM/meshes/pointMesh/pointPatches/facePointPatch/facePointPatch.C
@@ -27,7 +27,6 @@ License
 #include "pointBoundaryMesh.H"
 #include "pointMesh.H"
 #include "demandDrivenData.H"
-#include "boolList.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
index 73f6ab78bd01343b6e8278582fd51d4b42262fbf..ae6d7f28a2f4bedb910973c28c3aec1c47ac8e2c 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.C
@@ -1187,9 +1187,9 @@ void Foam::globalMeshData::calcGlobalEdgeOrientation() const
         // Now check my edges on how they relate to the master's edgeVerts
         globalEdgeOrientationPtr_.reset
         (
-            new PackedBoolList(coupledPatch().nEdges())
+            new bitSet(coupledPatch().nEdges())
         );
-        PackedBoolList& globalEdgeOrientation = globalEdgeOrientationPtr_();
+        bitSet& globalEdgeOrientation = globalEdgeOrientationPtr_();
 
         forAll(coupledPatch().edges(), edgeI)
         {
@@ -2260,7 +2260,7 @@ const
 }
 
 
-const Foam::PackedBoolList& Foam::globalMeshData::globalEdgeOrientation() const
+const Foam::bitSet& Foam::globalMeshData::globalEdgeOrientation() const
 {
     if (!globalEdgeOrientationPtr_.valid())
     {
@@ -2439,7 +2439,7 @@ Foam::autoPtr<Foam::globalIndex> Foam::globalMeshData::mergePoints
 
     // 1. Count number of masters on my processor.
     label nMaster = 0;
-    PackedBoolList isMaster(mesh_.nPoints(), true);
+    bitSet isMaster(mesh_.nPoints(), true);
     forAll(pointSlaves, pointi)
     {
         if (masterGlobalPoint[pointi] == -1)
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H
index 29ca8855a6b4b8fd2935b950859bdc0085b1f748..26b5763d372c4657c3aea20ad2b0e5130a28f7ac 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalMeshData.H
@@ -90,14 +90,13 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of friend functions and operators
-
+// Forward declarations
 class polyMesh;
 class mapDistribute;
 template<class T> class EdgeMap;
 class globalIndex;
 class globalIndexAndTransform;
-class PackedBoolList;
+class bitSet;
 
 /*---------------------------------------------------------------------------*\
                       Class globalMeshData Declaration
@@ -171,7 +170,7 @@ class globalMeshData
             mutable autoPtr<globalIndex> globalEdgeNumberingPtr_;
             mutable autoPtr<labelListList> globalEdgeSlavesPtr_;
             mutable autoPtr<labelListList> globalEdgeTransformedSlavesPtr_;
-            mutable autoPtr<PackedBoolList> globalEdgeOrientationPtr_;
+            mutable autoPtr<bitSet> globalEdgeOrientationPtr_;
             mutable autoPtr<mapDistribute> globalEdgeSlavesMapPtr_;
 
 
@@ -545,7 +544,7 @@ public:
                 const labelListList& globalEdgeTransformedSlaves() const;
                 const mapDistribute& globalEdgeSlavesMap() const;
                 //- Is my edge same orientation as master edge
-                const PackedBoolList& globalEdgeOrientation() const;
+                const bitSet& globalEdgeOrientation() const;
 
             // Collocated point to collocated point
 
diff --git a/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C b/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C
index c5e58e284eaf4b5260727e713a58c69b0fbb7947..e58d8f6c1634515e493e18ec88348539d9ecf196 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyMeshCheck/polyMeshCheck.C
@@ -70,7 +70,7 @@ bool Foam::polyMesh::checkFaceOrthogonality
 
 
     // Statistics only for internal and masters of coupled faces
-    PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(*this));
+    bitSet isMasterFace(syncTools::getInternalOrMasterFaces(*this));
 
     forAll(ortho, facei)
     {
@@ -203,7 +203,7 @@ bool Foam::polyMesh::checkFaceSkewness
     label nWarnSkew = 0;
 
     // Statistics only for all faces except slave coupled faces
-    PackedBoolList isMasterFace(syncTools::getMasterFaces(*this));
+    bitSet isMasterFace(syncTools::getMasterFaces(*this));
 
     forAll(skew, facei)
     {
@@ -518,7 +518,7 @@ bool Foam::polyMesh::checkFaceWeight
     label nSummed = 0;
 
     // Statistics only for internal and masters of coupled faces
-    PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(*this));
+    bitSet isMasterFace(syncTools::getInternalOrMasterFaces(*this));
 
     forAll(faceWght, facei)
     {
@@ -605,7 +605,7 @@ bool Foam::polyMesh::checkVolRatio
     label nSummed = 0;
 
     // Statistics only for internal and masters of coupled faces
-    PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(*this));
+    bitSet isMasterFace(syncTools::getInternalOrMasterFaces(*this));
 
     forAll(volRatio, facei)
     {
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C
index 798db8f12ae2ced0f98580b47773548f31192d0f..49c37aa8775a82df3d637b172a59510b8e23ebaa 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.C
@@ -62,10 +62,10 @@ void Foam::syncTools::swapBoundaryCellPositions
 }
 
 
-Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
+Foam::bitSet Foam::syncTools::getMasterPoints(const polyMesh& mesh)
 {
-    PackedBoolList isMasterPoint(mesh.nPoints());
-    PackedBoolList donePoint(mesh.nPoints());
+    bitSet isMasterPoint(mesh.nPoints());
+    bitSet donePoint(mesh.nPoints());
 
     const globalMeshData& globalData = mesh.globalData();
     const labelList& meshPoints = globalData.coupledPatch().meshPoints();
@@ -96,7 +96,7 @@ Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
 
     forAll(donePoint, pointi)
     {
-        if (!donePoint[pointi])
+        if (!donePoint.test(pointi))
         {
             isMasterPoint.set(pointi);
         }
@@ -106,10 +106,10 @@ Foam::PackedBoolList Foam::syncTools::getMasterPoints(const polyMesh& mesh)
 }
 
 
-Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
+Foam::bitSet Foam::syncTools::getMasterEdges(const polyMesh& mesh)
 {
-    PackedBoolList isMasterEdge(mesh.nEdges());
-    PackedBoolList doneEdge(mesh.nEdges());
+    bitSet isMasterEdge(mesh.nEdges());
+    bitSet doneEdge(mesh.nEdges());
 
     const globalMeshData& globalData = mesh.globalData();
     const labelList& meshEdges = globalData.coupledPatchMeshEdges();
@@ -140,7 +140,7 @@ Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
 
     forAll(doneEdge, edgeI)
     {
-        if (!doneEdge[edgeI])
+        if (!doneEdge.test(edgeI))
         {
             isMasterEdge.set(edgeI);
         }
@@ -150,9 +150,9 @@ Foam::PackedBoolList Foam::syncTools::getMasterEdges(const polyMesh& mesh)
 }
 
 
-Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
+Foam::bitSet Foam::syncTools::getMasterFaces(const polyMesh& mesh)
 {
-    PackedBoolList isMasterFace(mesh.nFaces(), true);
+    bitSet isMasterFace(mesh.nFaces(), true);
 
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
@@ -177,12 +177,12 @@ Foam::PackedBoolList Foam::syncTools::getMasterFaces(const polyMesh& mesh)
 }
 
 
-Foam::PackedBoolList Foam::syncTools::getInternalOrMasterFaces
+Foam::bitSet Foam::syncTools::getInternalOrMasterFaces
 (
     const polyMesh& mesh
 )
 {
-    PackedBoolList isMasterFace(mesh.nFaces(), true);
+    bitSet isMasterFace(mesh.nFaces(), true);
 
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
@@ -213,12 +213,12 @@ Foam::PackedBoolList Foam::syncTools::getInternalOrMasterFaces
 }
 
 
-Foam::PackedBoolList Foam::syncTools::getInternalOrCoupledFaces
+Foam::bitSet Foam::syncTools::getInternalOrCoupledFaces
 (
     const polyMesh& mesh
 )
 {
-    PackedBoolList isMasterFace(mesh.nFaces(), true);
+    bitSet isMasterFace(mesh.nFaces(), true);
 
     const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
diff --git a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
index 55dd19b72c104bf8937f207d799903f9e90a62d5..6c19c323fbff7288060b3b1020dd43ca3db568fe 100644
--- a/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
+++ b/src/OpenFOAM/meshes/polyMesh/syncTools/syncTools.H
@@ -44,7 +44,7 @@ SourceFiles
 
 #include "Pstream.H"
 #include "EdgeMap.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "polyMesh.H"
 #include "coupledPolyPatch.H"
 #include "mapDistribute.H"
@@ -590,22 +590,22 @@ public:
 
             //- Get per point whether it is uncoupled or a master of a
             //  coupled set of points
-            static PackedBoolList getMasterPoints(const polyMesh&);
+            static bitSet getMasterPoints(const polyMesh&);
 
             //- Get per edge whether it is uncoupled or a master of a
             //  coupled set of edges
-            static PackedBoolList getMasterEdges(const polyMesh&);
+            static bitSet getMasterEdges(const polyMesh&);
 
             //- Get per face whether it is uncoupled or a master of a
             //  coupled set of faces
-            static PackedBoolList getMasterFaces(const polyMesh&);
+            static bitSet getMasterFaces(const polyMesh&);
 
             //- Get per face whether it is internal or a master of a
             //  coupled set of faces
-            static PackedBoolList getInternalOrMasterFaces(const polyMesh&);
+            static bitSet getInternalOrMasterFaces(const polyMesh&);
 
             //- Get per face whether it is internal or coupled
-            static PackedBoolList getInternalOrCoupledFaces(const polyMesh&);
+            static bitSet getInternalOrCoupledFaces(const polyMesh&);
 
 };
 
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
index b8635648d4fb64f19226bf72aacdda9e73849675..b4df8fd49da7fe0b945088d1698bcb4d6134c5e5 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.C
@@ -435,12 +435,12 @@ Foam::label Foam::ZoneMesh<ZoneType, MeshType>::findZoneID
 
 
 template<class ZoneType, class MeshType>
-Foam::PackedBoolList Foam::ZoneMesh<ZoneType, MeshType>::findMatching
+Foam::bitSet Foam::ZoneMesh<ZoneType, MeshType>::findMatching
 (
     const keyType& key
 ) const
 {
-    PackedBoolList bitset;
+    bitSet bitset;
 
     const labelList indices = this->findIndices(key);
     forAll(indices, i)
diff --git a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
index bee3ca172fb0d4cfc68e7def3e8926a9d039a98d..0179ae6de6f4de70325232d75e818a7f9c426393 100644
--- a/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/zones/ZoneMesh/ZoneMesh.H
@@ -39,7 +39,7 @@ SourceFiles
 #include "regIOobject.H"
 #include "pointField.H"
 #include "Map.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "wordRes.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -180,7 +180,7 @@ public:
         label findZoneID(const word& zoneName) const;
 
         //- Mark items (cells, faces, points) that match the zone specification
-        PackedBoolList findMatching(const keyType& key) const;
+        bitSet findMatching(const keyType& key) const;
 
         //- Clear addressing
         void clearAddressing();
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
index dee687334cf7cd4122ff0486bb1ed5bfc3151907..a2ef60137df7c1579638952e8714d73c43e7bf97 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchTools.H
@@ -55,8 +55,9 @@ SourceFiles
 namespace Foam
 {
 
+// Forward declarations
 class polyMesh;
-class PackedBoolList;
+class bitSet;
 class boundBox;
 
 /*---------------------------------------------------------------------------*\
@@ -249,7 +250,7 @@ public:
 
         labelList& p1EdgeLabels,
         labelList& p2EdgeLabels,
-        PackedBoolList& sameOrientation
+        bitSet& sameOrientation
     );
 
 
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C
index 718ed443bdbb28e346b97f009149a27797395132..2e22bc25f6fa08508f720f1da7ac1020399201b8 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsMatch.C
@@ -91,7 +91,7 @@ void Foam::PatchTools::matchEdges
 
     labelList& p1EdgeLabels,
     labelList& p2EdgeLabels,
-    PackedBoolList& sameOrientation
+    bitSet& sameOrientation
 )
 {
     p1EdgeLabels.setSize(p1.nEdges());
diff --git a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C
index 967cceae8d6969b609b4cf886138b9af3e425c57..3a8b44523ad09d5ac9934e826b3e875cce5c992b 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/PatchTools/PatchToolsSearch.C
@@ -27,7 +27,7 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "PatchTools.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "boundBox.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -174,7 +174,7 @@ Foam::PatchTools::subsetMap
     faceMap.setSize(localFaces.size());
     pointMap.setSize(p.nPoints());
 
-    boolList pointHad(pointMap.size(), false);
+    bitSet pointHad(pointMap.size(), false);
 
     forAll(p, oldFacei)
     {
@@ -189,9 +189,8 @@ Foam::PatchTools::subsetMap
             forAll(f, fp)
             {
                 const label ptLabel = f[fp];
-                if (!pointHad[ptLabel])
+                if (pointHad.set(ptLabel))
                 {
-                    pointHad[ptLabel]  = true;
                     pointMap[pointi++] = ptLabel;
                 }
             }
@@ -222,7 +221,7 @@ void Foam::PatchTools::calcBounds
     // ourselves
     const PointField& points = p.points();
 
-    PackedBoolList pointIsUsed(points.size());
+    bitSet pointIsUsed(points.size());
 
     nPoints = 0;
     bb = boundBox::invertedBox;
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H
index 7adb2c8a99b4730cd4137827c2228fc9cfd87218..c4d3b34f4646e9f31b4dd030c95f031e6f72cc81 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMesh.H
@@ -66,7 +66,8 @@ SourceFiles
 namespace Foam
 {
 
-class PackedBoolList;
+// Forward declarations
+class bitSet;
 
 /*---------------------------------------------------------------------------*\
                       Class primitiveMesh Declaration
@@ -296,7 +297,7 @@ protected:
             (
                 const vectorField& areas,
                 const bool report,
-                const PackedBoolList& internalOrCoupledFaces
+                const bitSet& internalOrCoupledFaces
             ) const;
 
             //- Check cells for closedness
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C
index ae0bac1f085bfd51e7bb348c3b5f39875020e6d8..e67cfb5cce3258f64bd445731ef9f007b0abb660 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshCheck.C
@@ -46,7 +46,7 @@ bool Foam::primitiveMesh::checkClosedBoundary
 (
     const vectorField& areas,
     const bool report,
-    const PackedBoolList& internalOrCoupledFaces
+    const bitSet& internalOrCoupledFaces
 ) const
 {
     if (debug)
@@ -1684,7 +1684,7 @@ bool Foam::primitiveMesh::checkFaceFaces
 
 bool Foam::primitiveMesh::checkClosedBoundary(const bool report) const
 {
-    return checkClosedBoundary(faceAreas(), report, PackedBoolList());
+    return checkClosedBoundary(faceAreas(), report, bitSet());
 }
 
 
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C
index 020b3fa8ac2bfce376d15dc7ad647e2e91405a22..88394170b68fb76de20981f80c85934d919db29d 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.C
@@ -455,7 +455,7 @@ Foam::tmp<Foam::scalarField> Foam::primitiveMeshTools::cellDeterminant
     const primitiveMesh& mesh,
     const Vector<label>& meshD,
     const vectorField& faceAreas,
-    const PackedBoolList& internalOrCoupledFace
+    const bitSet& internalOrCoupledFace
 )
 {
     // Determine number of dimensions and (for 2D) missing dimension
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H
index 535ead0a19522484001909d64483f6bcb566e7ec..555b24c44699697c7e1f89c522573d55d73a7524 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCheck/primitiveMeshTools.H
@@ -35,7 +35,7 @@ SourceFiles
 #define primitiveMeshTools_H
 
 #include "primitiveMesh.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -125,7 +125,7 @@ public:
         const primitiveMesh& mesh,
         const Vector<label>& directions,
         const vectorField& faceAreas,
-        const PackedBoolList& internalOrCoupledFace
+        const bitSet& internalOrCoupledFace
     );
 
 
diff --git a/src/conversion/ccm/reader/ccmReaderMesh.C b/src/conversion/ccm/reader/ccmReaderMesh.C
index bd3f0f20c178a14dfd7b9b49700bfa28e2eb527b..c1772fed751f470b2ef4b8eee41f1b491fb43092 100644
--- a/src/conversion/ccm/reader/ccmReaderMesh.C
+++ b/src/conversion/ccm/reader/ccmReaderMesh.C
@@ -35,7 +35,7 @@ License
 #include "uindirectPrimitivePatch.H"
 #include "SortableList.H"
 #include "mergePoints.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "ListOps.H"
 
 #include "ccmInternal.H" // include last to avoid any strange interactions
@@ -1099,7 +1099,7 @@ void Foam::ccm::reader::juggleSolids()
     // Identify solid cells
     // ~~~~~~~~~~~~~~~~~~~~
     label nSolids = 0;
-    boolList solidCells(cellTableId_.size(), false);
+    bitSet solidCells(cellTableId_.size(), false);
     {
         Map<word> solidMap = cellTable_.solids();
 
@@ -1107,7 +1107,7 @@ void Foam::ccm::reader::juggleSolids()
         {
             if (solidMap.found(cellTableId_[cellI]))
             {
-                solidCells[cellI] = true;
+                solidCells.set(cellI);
                 ++nSolids;
             }
         }
@@ -1130,7 +1130,7 @@ void Foam::ccm::reader::juggleSolids()
         label faceI = patchStarts[patchIndex] + i;
         label cellI = faceOwner_[faceI];
 
-        if (solidCells[cellI])
+        if (solidCells.test(cellI))
         {
             ++adjustPatch;
         }
@@ -1186,7 +1186,7 @@ void Foam::ccm::reader::juggleSolids()
         label faceI = patchStarts[patchIndex] + i;
         label cellI = faceOwner_[faceI];
 
-        if (solidCells[cellI])
+        if (solidCells.test(cellI))
         {
             oldToNew[faceI] = solidFace++;
         }
@@ -1213,7 +1213,7 @@ void Foam::ccm::reader::removeUnwanted()
     // Identify fluid/porous/solid cells for removal
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     label nRemove = 0;
-    boolList removeCells(cellTableId_.size(), false);
+    bitSet removeCells(cellTableId_.size(), false);
 
     {
         Map<word> fluidMap  = cellTable_.fluids();
@@ -1236,7 +1236,7 @@ void Foam::ccm::reader::removeUnwanted()
               : false
             )
             {
-                removeCells[cellI] = true;
+                removeCells.set(cellI);
                 ++nRemove;
                 removeMap.set(tableId, cellTable_.name(tableId));
             }
@@ -1291,7 +1291,7 @@ void Foam::ccm::reader::removeUnwanted()
     for (label faceI = 0; faceI < nFaces_; ++faceI)
     {
         label cellI = faceOwner_[faceI];
-        if (removeCells[cellI])
+        if (removeCells.test(cellI))
         {
             if (faceI < nInternalFaces_)
             {
@@ -1356,7 +1356,7 @@ void Foam::ccm::reader::removeUnwanted()
     oldToNew.setSize(nCells_, -1);
     for (label cellI = 0; cellI < nCells_; ++cellI)
     {
-        if (!removeCells[cellI])
+        if (!removeCells.test(cellI))
         {
             if (nCell != cellI)
             {
@@ -1886,7 +1886,7 @@ void Foam::ccm::reader::mergeInplaceInterfaces()
     label nMergedTotal = 0;
 
     // Markup points to merge
-    PackedBoolList whichPoints(points_.size());
+    bitSet whichPoints(points_.size());
 
     Info<< "interface merge points (tol="
         << option().mergeTol() << "):" << endl;
@@ -1923,7 +1923,7 @@ void Foam::ccm::reader::mergeInplaceInterfaces()
         }
 
         // The global addresses
-        labelList addr(whichPoints.used());
+        labelList addr(whichPoints.toc());
 
         const UIndirectList<point> pointsToMerge(points_, addr);
 
diff --git a/src/conversion/ensight/mesh/ensightMesh.C b/src/conversion/ensight/mesh/ensightMesh.C
index 9ba6b17fcc044ef5ca8d605d91fd0200caf3c006..c17901fb03a89d1a5a1cb501f2a44d2a99217bdb 100644
--- a/src/conversion/ensight/mesh/ensightMesh.C
+++ b/src/conversion/ensight/mesh/ensightMesh.C
@@ -222,7 +222,7 @@ void Foam::ensightMesh::correct()
     if (option().useFaceZones())
     {
         // Mark boundary faces to be excluded from export
-        PackedBoolList excludeFace(mesh_.nFaces()); // all false
+        bitSet excludeFace(mesh_.nFaces()); // all false
 
         forAll(mesh_.boundaryMesh(), patchi)
         {
diff --git a/src/conversion/polyDualMesh/polyDualMesh.C b/src/conversion/polyDualMesh/polyDualMesh.C
index 15ee6732bca399e48a5c84a650266965dbac0a64..b0c1f2eaead38c3ef52c1e89c6c23aac8d0b7fe9 100644
--- a/src/conversion/polyDualMesh/polyDualMesh.C
+++ b/src/conversion/polyDualMesh/polyDualMesh.C
@@ -32,6 +32,7 @@ InClass
 #include "Time.H"
 #include "SortableList.H"
 #include "pointSet.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -594,7 +595,7 @@ void Foam::polyDualMesh::dualPatch
     // 3 : done both
     labelList doneEdgeSide(meshEdges.size(), 0);
 
-    boolList donePoint(patch.nPoints(), false);
+    bitSet donePoint(patch.nPoints(), false);
 
 
     // Do points on edge of patch
@@ -650,7 +651,7 @@ void Foam::polyDualMesh::dualPatch
                     dualRegion.append(patch.index());
 
                     doneEdgeSide[patchEdgeI] |= bitMask;
-                    donePoint[pointi] = true;
+                    donePoint.set(pointi);
                 }
             }
         }
@@ -663,7 +664,7 @@ void Foam::polyDualMesh::dualPatch
 
     forAll(donePoint, pointi)
     {
-        if (!donePoint[pointi])
+        if (!donePoint.test(pointi))
         {
             labelList dualFace, featEdgeIndices;
 
@@ -1496,7 +1497,7 @@ void Foam::polyDualMesh::calcFeatures
     const vectorField& faceNormals = allBoundary.faceNormals();
     const labelList& meshPoints = allBoundary.meshPoints();
 
-    boolList isFeatureEdge(edgeFaces.size(), false);
+    bitSet isFeatureEdge(edgeFaces.size(), false);
 
     forAll(edgeFaces, edgeI)
     {
@@ -1514,11 +1515,11 @@ void Foam::polyDualMesh::calcFeatures
                 << " has more than 2 faces connected to it:"
                 << eFaces.size() << endl;
 
-            isFeatureEdge[edgeI] = true;
+            isFeatureEdge.set(edgeI);
         }
         else if (allRegion[eFaces[0]] != allRegion[eFaces[1]])
         {
-            isFeatureEdge[edgeI] = true;
+            isFeatureEdge.set(edgeI);
         }
         else if
         (
@@ -1526,7 +1527,7 @@ void Foam::polyDualMesh::calcFeatures
           < featureCos
         )
         {
-            isFeatureEdge[edgeI] = true;
+            isFeatureEdge.set(edgeI);
         }
     }
 
@@ -1546,9 +1547,9 @@ void Foam::polyDualMesh::calcFeatures
 
         forAll(pEdges, i)
         {
-            if (isFeatureEdge[pEdges[i]])
+            if (isFeatureEdge.test(pEdges[i]))
             {
-                nFeatEdges++;
+                ++nFeatEdges;
             }
         }
         if (nFeatEdges > 2)
@@ -1593,7 +1594,7 @@ void Foam::polyDualMesh::calcFeatures
     DynamicList<label> allFeatureEdges(isFeatureEdge.size());
     forAll(isFeatureEdge, edgeI)
     {
-        if (isFeatureEdge[edgeI])
+        if (isFeatureEdge.test(edgeI))
         {
             // Store in mesh edge label.
             allFeatureEdges.append(meshEdges[edgeI]);
diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
index 0f15ba5800f3ce2bd60912083b00cdd193f99d23..699df4733bb7e1ca220c802ffde595c6a000751c 100644
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.C
@@ -46,7 +46,7 @@ namespace Foam
 
 Foam::label Foam::dynamicRefineFvMesh::count
 (
-    const PackedBoolList& l,
+    const bitSet& l,
     const unsigned int val
 )
 {
@@ -72,7 +72,7 @@ Foam::label Foam::dynamicRefineFvMesh::count
 
 void Foam::dynamicRefineFvMesh::calculateProtectedCells
 (
-    PackedBoolList& unrefineableCell
+    bitSet& unrefineableCell
 ) const
 {
     if (protectedCell_.empty())
@@ -426,7 +426,7 @@ Foam::dynamicRefineFvMesh::refine
     // Update numbering of protectedCell_
     if (protectedCell_.size())
     {
-        PackedBoolList newProtectedCell(nCells());
+        bitSet newProtectedCell(nCells());
 
         forAll(newProtectedCell, celli)
         {
@@ -589,7 +589,7 @@ Foam::dynamicRefineFvMesh::unrefine
     // Update numbering of protectedCell_
     if (protectedCell_.size())
     {
-        PackedBoolList newProtectedCell(nCells());
+        bitSet newProtectedCell(nCells());
 
         forAll(newProtectedCell, celli)
         {
@@ -692,7 +692,7 @@ void Foam::dynamicRefineFvMesh::selectRefineCandidates
     const scalar lowerRefineLevel,
     const scalar upperRefineLevel,
     const scalarField& vFld,
-    PackedBoolList& candidateCell
+    bitSet& candidateCell
 ) const
 {
     // Get error per cell. Is -1 (not to be refined) to >0 (to be refined,
@@ -725,7 +725,7 @@ Foam::labelList Foam::dynamicRefineFvMesh::selectRefineCells
 (
     const label maxCells,
     const label maxRefinement,
-    const PackedBoolList& candidateCell
+    const bitSet& candidateCell
 ) const
 {
     // Every refined cell causes 7 extra cells
@@ -735,7 +735,7 @@ Foam::labelList Foam::dynamicRefineFvMesh::selectRefineCells
 
     // Mark cells that cannot be refined since they would trigger refinement
     // of protected cells (since 2:1 cascade)
-    PackedBoolList unrefineableCell;
+    bitSet unrefineableCell;
     calculateProtectedCells(unrefineableCell);
 
     // Count current selection
@@ -806,7 +806,7 @@ Foam::labelList Foam::dynamicRefineFvMesh::selectRefineCells
 Foam::labelList Foam::dynamicRefineFvMesh::selectUnrefinePoints
 (
     const scalar unrefineLevel,
-    const PackedBoolList& markedCell,
+    const bitSet& markedCell,
     const scalarField& pFld
 ) const
 {
@@ -819,7 +819,7 @@ Foam::labelList Foam::dynamicRefineFvMesh::selectUnrefinePoints
     // If we have any protected cells make sure they also are not being
     // unrefined
 
-    PackedBoolList protectedPoint(nPoints());
+    bitSet protectedPoint(nPoints());
 
     if (protectedCell_.size())
     {
@@ -911,7 +911,7 @@ Foam::labelList Foam::dynamicRefineFvMesh::selectUnrefinePoints
 
 void Foam::dynamicRefineFvMesh::extendMarkedCells
 (
-    PackedBoolList& markedCell
+    bitSet& markedCell
 ) const
 {
     // Mark faces using any marked cell
@@ -953,7 +953,7 @@ void Foam::dynamicRefineFvMesh::extendMarkedCells
 
 void Foam::dynamicRefineFvMesh::checkEightAnchorPoints
 (
-    PackedBoolList& protectedCell,
+    bitSet& protectedCell,
     label& nProtected
 ) const
 {
@@ -1277,7 +1277,7 @@ bool Foam::dynamicRefineFvMesh::update()
             readLabel(refineDict.lookup("nBufferLayers"));
 
         // Cells marked for refinement or otherwise protected from unrefinement.
-        PackedBoolList refineCell(nCells());
+        bitSet refineCell(nCells());
 
         // Determine candidates for refinement (looking at field only)
         selectRefineCandidates
@@ -1318,7 +1318,7 @@ bool Foam::dynamicRefineFvMesh::update()
                     const labelList& cellMap = map().cellMap();
                     const labelList& reverseCellMap = map().reverseCellMap();
 
-                    PackedBoolList newRefineCell(cellMap.size());
+                    bitSet newRefineCell(cellMap.size());
 
                     forAll(cellMap, celli)
                     {
diff --git a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
index 048e996ca7c26732fcb798ff1b23a7f0b87ec379..8010b57bd1d2129950967bbe2335751cf3e908d2 100644
--- a/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
+++ b/src/dynamicFvMesh/dynamicRefineFvMesh/dynamicRefineFvMesh.H
@@ -70,7 +70,7 @@ SourceFiles
 
 #include "dynamicFvMesh.H"
 #include "hexRef8.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "Switch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -101,17 +101,17 @@ protected:
         label nRefinementIterations_;
 
         //- Protected cells (usually since not hexes)
-        PackedBoolList protectedCell_;
+        bitSet protectedCell_;
 
 
     // Protected Member Functions
 
         //- Count set/unset elements in packedlist.
-        static label count(const PackedBoolList&, const unsigned int);
+        static label count(const bitSet&, const unsigned int);
 
         //- Calculate cells that cannot be refined since would trigger
         //  refinement of protectedCell_ (since 2:1 refinement cascade)
-        void calculateProtectedCells(PackedBoolList& unrefineableCell) const;
+        void calculateProtectedCells(bitSet& unrefineableCell) const;
 
         //- Read the projection parameters from dictionary
         void readDict();
@@ -157,7 +157,7 @@ protected:
                 const scalar lowerRefineLevel,
                 const scalar upperRefineLevel,
                 const scalarField& vFld,
-                PackedBoolList& candidateCell
+                bitSet& candidateCell
             ) const;
 
             //- Subset candidate cells for refinement
@@ -165,24 +165,24 @@ protected:
             (
                 const label maxCells,
                 const label maxRefinement,
-                const PackedBoolList& candidateCell
+                const bitSet& candidateCell
             ) const;
 
             //- Select points that can be unrefined.
             virtual labelList selectUnrefinePoints
             (
                 const scalar unrefineLevel,
-                const PackedBoolList& markedCell,
+                const bitSet& markedCell,
                 const scalarField& pFld
             ) const;
 
             //- Extend markedCell with cell-face-cell.
-            void extendMarkedCells(PackedBoolList& markedCell) const;
+            void extendMarkedCells(bitSet& markedCell) const;
 
             //- Check all cells have 8 anchor points
             void checkEightAnchorPoints
             (
-                PackedBoolList& protectedCell,
+                bitSet& protectedCell,
                 label& nProtected
             ) const;
 
@@ -219,13 +219,13 @@ public:
         }
 
         //- Cells which should not be refined/unrefined
-        const PackedBoolList& protectedCell() const
+        const bitSet& protectedCell() const
         {
             return protectedCell_;
         }
 
         //- Cells which should not be refined/unrefined
-        PackedBoolList& protectedCell()
+        bitSet& protectedCell()
         {
             return protectedCell_;
         }
diff --git a/src/dynamicMesh/createShellMesh/createShellMesh.C b/src/dynamicMesh/createShellMesh/createShellMesh.C
index e49c9aabbdae7972547bb507e3114414bacfe7c2..c453fd6c29398617d667e5fded71b52ceacdc421 100644
--- a/src/dynamicMesh/createShellMesh/createShellMesh.C
+++ b/src/dynamicMesh/createShellMesh/createShellMesh.C
@@ -66,16 +66,16 @@ void Foam::createShellMesh::syncEdges
 
     const labelList& patchEdges,
     const labelList& coupledEdges,
-    const PackedBoolList& sameEdgeOrientation,
+    const bitSet& sameEdgeOrientation,
     const bool syncNonCollocated,
 
-    PackedBoolList& isChangedEdge,
+    bitSet& isChangedEdge,
     DynamicList<label>& changedEdges,
     labelPairList& allEdgeData
 )
 {
     const mapDistribute& map = globalData.globalEdgeSlavesMap();
-    const PackedBoolList& cppOrientation = globalData.globalEdgeOrientation();
+    const bitSet& cppOrientation = globalData.globalEdgeOrientation();
 
     // Convert patch-edge data into cpp-edge data
     labelPairList cppEdgeData
@@ -154,7 +154,7 @@ void Foam::createShellMesh::calcPointRegions
 (
     const globalMeshData& globalData,
     const primitiveFacePatch& patch,
-    const PackedBoolList& nonManifoldEdge,
+    const bitSet& nonManifoldEdge,
     const bool syncNonCollocated,
 
     faceList& pointGlobalRegions,
@@ -167,7 +167,7 @@ void Foam::createShellMesh::calcPointRegions
     // Calculate correspondence between patch and globalData.coupledPatch.
     labelList patchEdges;
     labelList coupledEdges;
-    PackedBoolList sameEdgeOrientation;
+    bitSet sameEdgeOrientation;
     PatchTools::matchEdges
     (
         cpp,
@@ -211,7 +211,7 @@ void Foam::createShellMesh::calcPointRegions
 
     DynamicList<label> changedEdges(patch.nEdges());
     labelPairList allEdgeData(patch.nEdges(), labelPair(labelMax, labelMax));
-    PackedBoolList isChangedEdge(patch.nEdges());
+    bitSet isChangedEdge(patch.nEdges());
 
 
     // Fill initial seed
@@ -267,7 +267,7 @@ void Foam::createShellMesh::calcPointRegions
         // ~~~~~~~~~~~~~~~~~
 
         DynamicList<label> changedFaces(patch.size());
-        PackedBoolList isChangedFace(patch.size());
+        bitSet isChangedFace(patch.size());
 
         forAll(changedEdges, changedI)
         {
diff --git a/src/dynamicMesh/createShellMesh/createShellMesh.H b/src/dynamicMesh/createShellMesh/createShellMesh.H
index 8a4fe7a95c47a2d87bdf6564363cff366c23d0c7..ab6b4cbefc0e29504a1bd7d9a56d66c0d9f1e62c 100644
--- a/src/dynamicMesh/createShellMesh/createShellMesh.H
+++ b/src/dynamicMesh/createShellMesh/createShellMesh.H
@@ -40,7 +40,7 @@ SourceFiles
 #define createShellMesh_H
 
 #include "primitiveFacePatch.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "labelPair.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -87,10 +87,10 @@ class createShellMesh
             const globalMeshData&,
             const labelList&,
             const labelList&,
-            const PackedBoolList& sameEdgeOrientation,
+            const bitSet& sameEdgeOrientation,
             const bool syncNonCollocated,
 
-            PackedBoolList& isChangedEdge,
+            bitSet& isChangedEdge,
             DynamicList<label>& changedEdges,
             labelPairList& allEdgeData
         );
@@ -172,7 +172,7 @@ public:
             (
                 const globalMeshData& globalData,
                 const primitiveFacePatch& patch,
-                const PackedBoolList& nonManifoldEdge,
+                const bitSet& nonManifoldEdge,
                 const bool syncNonCollocated,
                 faceList& pointGlobalRegions,
                 faceList& pointLocalRegions,
diff --git a/src/dynamicMesh/extrudePatchMesh/extrudePatchMesh.C b/src/dynamicMesh/extrudePatchMesh/extrudePatchMesh.C
index 345f88a034dbc191604d23af05b145d4c7c4dcd3..2790c62e5224f00a5634fb9d99c80ef3f30a6fc8 100644
--- a/src/dynamicMesh/extrudePatchMesh/extrudePatchMesh.C
+++ b/src/dynamicMesh/extrudePatchMesh/extrudePatchMesh.C
@@ -147,7 +147,7 @@ void extrudePatchMesh::extrudeMesh(const List<polyPatch*>& regionPatches)
     {
         bool columnCells = readBool(dict_.lookup("columnCells"));
 
-        PackedBoolList nonManifoldEdge(extrudedPatch_.nEdges());
+        bitSet nonManifoldEdge(extrudedPatch_.nEdges());
         for (label edgeI = 0; edgeI < extrudedPatch_.nInternalEdges(); edgeI++)
         {
             if (columnCells)
diff --git a/src/dynamicMesh/motionSmoother/badQualityToCell/badQualityToCell.H b/src/dynamicMesh/motionSmoother/badQualityToCell/badQualityToCell.H
index 4b52b0ff1708821124a407fbfccd49a4f64c9000..98f6be7a193585ab272e5b16fc8f5f34b4157605 100644
--- a/src/dynamicMesh/motionSmoother/badQualityToCell/badQualityToCell.H
+++ b/src/dynamicMesh/motionSmoother/badQualityToCell/badQualityToCell.H
@@ -36,7 +36,7 @@ SourceFiles
 #define badQualityToCell_H
 
 #include "topoSetSource.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/dynamicMesh/motionSmoother/badQualityToFace/badQualityToFace.H b/src/dynamicMesh/motionSmoother/badQualityToFace/badQualityToFace.H
index d59964bad82751fe82d5c84db9946b4814d579da..e48fe2e030a586746bde2e3532c49da2d906d8e0 100644
--- a/src/dynamicMesh/motionSmoother/badQualityToFace/badQualityToFace.H
+++ b/src/dynamicMesh/motionSmoother/badQualityToFace/badQualityToFace.H
@@ -36,7 +36,7 @@ SourceFiles
 #define badQualityToFace_H
 
 #include "topoSetSource.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/dynamicMesh/motionSmoother/motionSmootherAlgo.C b/src/dynamicMesh/motionSmoother/motionSmootherAlgo.C
index 9d2e584ef5f8dd54d60616c6d57722d838b86cf0..61032b10c1d382302a7de4e713a3f72646e58e49 100644
--- a/src/dynamicMesh/motionSmoother/motionSmootherAlgo.C
+++ b/src/dynamicMesh/motionSmoother/motionSmootherAlgo.C
@@ -144,7 +144,7 @@ Foam::tmp<Foam::scalarField> Foam::motionSmootherAlgo::calcEdgeWeights
 void Foam::motionSmootherAlgo::minSmooth
 (
     const scalarField& edgeWeights,
-    const PackedBoolList& isAffectedPoint,
+    const bitSet& isAffectedPoint,
     const labelList& meshPoints,
     const pointScalarField& fld,
     pointScalarField& newFld
@@ -179,7 +179,7 @@ void Foam::motionSmootherAlgo::minSmooth
 void Foam::motionSmootherAlgo::minSmooth
 (
     const scalarField& edgeWeights,
-    const PackedBoolList& isAffectedPoint,
+    const bitSet& isAffectedPoint,
     const pointScalarField& fld,
     pointScalarField& newFld
 ) const
@@ -303,7 +303,7 @@ void Foam::motionSmootherAlgo::getAffectedFacesAndPoints
     const faceSet& wrongFaces,
 
     labelList& affectedFaces,
-    PackedBoolList& isAffectedPoint
+    bitSet& isAffectedPoint
 ) const
 {
     isAffectedPoint.setSize(mesh_.nPoints());
@@ -517,7 +517,7 @@ void Foam::motionSmootherAlgo::setDisplacement
     // to them since we want 'proper' values from displacement to take
     // precedence.
     {
-        PackedBoolList isPatchPoint(mesh.nPoints(), ppMeshPoints);
+        bitSet isPatchPoint(mesh.nPoints(), ppMeshPoints);
         syncTools::syncPointList
         (
             mesh,
@@ -970,7 +970,7 @@ bool Foam::motionSmootherAlgo::scaleMesh
         // Grow a few layers to determine
         // - points to be smoothed
         // - faces to be checked in next iteration
-        PackedBoolList isAffectedPoint(mesh_.nPoints());
+        bitSet isAffectedPoint(mesh_.nPoints());
         getAffectedFacesAndPoints
         (
             nSmoothScale,       // smoothing iterations
diff --git a/src/dynamicMesh/motionSmoother/motionSmootherAlgo.H b/src/dynamicMesh/motionSmoother/motionSmootherAlgo.H
index c5081a632ef68aeb79c740ad30c5e814f920b618..b979ba08db75e42f0a32309620624a033f3d7767 100644
--- a/src/dynamicMesh/motionSmoother/motionSmootherAlgo.H
+++ b/src/dynamicMesh/motionSmoother/motionSmootherAlgo.H
@@ -79,7 +79,7 @@ SourceFiles
 
 #include "pointFields.H"
 #include "HashSet.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "indirectPrimitivePatch.H"
 #include "className.H"
 
@@ -161,11 +161,11 @@ class motionSmootherAlgo
             dictionary paramDict_;
 
             //- Is mesh point on boundary or not
-            PackedBoolList isInternalPoint_;
+            bitSet isInternalPoint_;
 
             //- Is edge master (always except if on coupled boundary and on
             //  lower processor)
-            PackedBoolList isMasterEdge_;
+            bitSet isMasterEdge_;
 
 
     // Private Member Functions
@@ -221,7 +221,7 @@ class motionSmootherAlgo
         void minSmooth
         (
             const scalarField& edgeWeights,
-            const PackedBoolList& isAffectedPoint,
+            const bitSet& isAffectedPoint,
             const pointScalarField& fld,
             pointScalarField& newFld
         ) const;
@@ -230,7 +230,7 @@ class motionSmootherAlgo
         void minSmooth
         (
             const scalarField& edgeWeights,
-            const PackedBoolList& isAffectedPoint,
+            const bitSet& isAffectedPoint,
             const labelList& meshPoints,
             const pointScalarField& fld,
             pointScalarField& newFld
@@ -284,7 +284,7 @@ class motionSmootherAlgo
             const faceSet& wrongFaces,
 
             labelList& affectedFaces,
-            PackedBoolList& isAffectedPoint
+            bitSet& isAffectedPoint
         ) const;
 
         //- Disallow default bitwise copy construct
diff --git a/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C b/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
index 85b987ac21e1cb5f37f90888126068941eb4297c..8a6d6a6ec083a96a9307308ba3f732fde657b00d 100644
--- a/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
+++ b/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.C
@@ -60,8 +60,8 @@ namespace Foam
 void Foam::displacementLayeredMotionMotionSolver::calcZoneMask
 (
     const label cellZoneI,
-    PackedBoolList& isZonePoint,
-    PackedBoolList& isZoneEdge
+    bitSet& isZonePoint,
+    bitSet& isZoneEdge
 ) const
 {
     if (cellZoneI == -1)
@@ -133,8 +133,8 @@ void Foam::displacementLayeredMotionMotionSolver::calcZoneMask
 void Foam::displacementLayeredMotionMotionSolver::walkStructured
 (
     const label cellZoneI,
-    const PackedBoolList& isZonePoint,
-    const PackedBoolList& isZoneEdge,
+    const bitSet& isZonePoint,
+    const bitSet& isZoneEdge,
     const labelList& seedPoints,
     const vectorField& seedData,
     scalarField& distance,
@@ -286,8 +286,8 @@ void Foam::displacementLayeredMotionMotionSolver::cellZoneSolve
     const dictionary& zoneDict
 )
 {
-    PackedBoolList isZonePoint(mesh().nPoints());
-    PackedBoolList isZoneEdge(mesh().nEdges());
+    bitSet isZonePoint(mesh().nPoints());
+    bitSet isZoneEdge(mesh().nEdges());
     calcZoneMask(cellZoneI, isZonePoint, isZoneEdge);
 
     const dictionary& patchesDict = zoneDict.subDict("boundaryField");
diff --git a/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H b/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H
index 4975d8c875a873c7e567132c9acf1ae3906cc32a..99986a19d818bab7d6acfff8b8408b0f7085f35b 100644
--- a/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H
+++ b/src/dynamicMesh/motionSolvers/displacement/layeredSolver/displacementLayeredMotionMotionSolver.H
@@ -61,7 +61,7 @@ SourceFiles
 #define displacementLayeredMotionMotionSolver_H
 
 #include "displacementMotionSolver.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -83,15 +83,15 @@ class displacementLayeredMotionMotionSolver
         void calcZoneMask
         (
             const label cellZoneI,
-            PackedBoolList& isZonePoint,
-            PackedBoolList& isZoneEdge
+            bitSet& isZonePoint,
+            bitSet& isZoneEdge
         ) const;
 
         void walkStructured
         (
             const label cellZoneI,
-            const PackedBoolList& isZonePoint,
-            const PackedBoolList& isZoneEdge,
+            const bitSet& isZonePoint,
+            const bitSet& isZoneEdge,
             const labelList& seedPoints,
             const vectorField& seedData,
             scalarField& distance,
diff --git a/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C b/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C
index 58bc03ff1beff026412135813fb3914d99382036..ed7c4f35f685f06360f681bf037389b0ccdfb62c 100644
--- a/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C
+++ b/src/dynamicMesh/polyMeshFilter/polyMeshFilter.C
@@ -31,7 +31,7 @@ License
 #include "syncTools.H"
 #include "polyTopoChange.H"
 #include "globalIndex.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "pointSet.H"
 #include "faceSet.H"
 #include "cellSet.H"
@@ -110,7 +110,7 @@ Foam::label Foam::polyMeshFilter::filterFacesLoop(const label nOriginalBadFaces)
     // Maintain the number of times a point has been part of a bad face
     labelList pointErrorCount(mesh_.nPoints(), 0);
 
-    PackedBoolList newErrorPoint(mesh_.nPoints());
+    bitSet newErrorPoint(mesh_.nPoints());
     edgeCollapser::checkMeshQuality
     (
         mesh_,
@@ -228,7 +228,7 @@ Foam::label Foam::polyMeshFilter::filterFacesLoop(const label nOriginalBadFaces)
 
         if (controlMeshQuality())
         {
-            PackedBoolList isErrorPoint(newMesh.nPoints());
+            bitSet isErrorPoint(newMesh.nPoints());
             nBadFaces = edgeCollapser::checkMeshQuality
             (
                 newMesh,
@@ -301,7 +301,7 @@ Foam::label Foam::polyMeshFilter::filterFaces
 )
 {
     // Per edge collapse status
-    PackedBoolList collapseEdge(newMesh.nEdges());
+    bitSet collapseEdge(newMesh.nEdges());
 
     Map<point> collapsePointToLocation(newMesh.nPoints());
 
@@ -417,7 +417,7 @@ Foam::label Foam::polyMeshFilter::filterEdges
 )
 {
     // Per edge collapse status
-    PackedBoolList collapseEdge(newMesh.nEdges());
+    bitSet collapseEdge(newMesh.nEdges());
 
     Map<point> collapsePointToLocation(newMesh.nPoints());
 
@@ -528,7 +528,7 @@ Foam::label Foam::polyMeshFilter::filterEdges
 
 void Foam::polyMeshFilter::updatePointErrorCount
 (
-    const PackedBoolList& isErrorPoint,
+    const bitSet& isErrorPoint,
     const labelList& oldToNewMesh,
     labelList& pointErrorCount
 ) const
@@ -547,7 +547,7 @@ void Foam::polyMeshFilter::checkMeshEdgesAndRelaxEdges
 (
     const polyMesh& newMesh,
     const labelList& oldToNewMesh,
-    const PackedBoolList& isErrorPoint,
+    const bitSet& isErrorPoint,
     const labelList& pointErrorCount
 )
 {
@@ -624,7 +624,7 @@ void Foam::polyMeshFilter::checkMeshFacesAndRelaxEdges
 (
     const polyMesh& newMesh,
     const labelList& oldToNewMesh,
-    const PackedBoolList& isErrorPoint,
+    const bitSet& isErrorPoint,
     const labelList& pointErrorCount
 )
 {
@@ -1084,7 +1084,7 @@ Foam::label Foam::polyMeshFilter::filterEdges
 
         if (controlMeshQuality())
         {
-            PackedBoolList isErrorPoint(newMesh.nPoints());
+            bitSet isErrorPoint(newMesh.nPoints());
             nBadFaces = edgeCollapser::checkMeshQuality
             (
                 newMesh,
diff --git a/src/dynamicMesh/polyMeshFilter/polyMeshFilter.H b/src/dynamicMesh/polyMeshFilter/polyMeshFilter.H
index 5e85a1f65ff23043f2014bdc438fdde420fb5e24..862783899494416a5ff7ed7d243739cefb3decfd 100644
--- a/src/dynamicMesh/polyMeshFilter/polyMeshFilter.H
+++ b/src/dynamicMesh/polyMeshFilter/polyMeshFilter.H
@@ -54,7 +54,7 @@ namespace Foam
 class polyMesh;
 class fvMesh;
 class faceSet;
-class PackedBoolList;
+class bitSet;
 
 /*---------------------------------------------------------------------------*\
                        Class polyMeshFilter Declaration
@@ -114,7 +114,7 @@ class polyMeshFilter
         //- Increment pointErrorCount for points attached to a bad face
         void updatePointErrorCount
         (
-            const PackedBoolList& isErrorPoint,
+            const bitSet& isErrorPoint,
             const labelList& oldToNewMesh,
             labelList& pointErrorCount
         ) const;
@@ -126,7 +126,7 @@ class polyMeshFilter
         (
             const polyMesh& newMesh,
             const labelList& oldToNewMesh,
-            const PackedBoolList& isErrorPoint,
+            const bitSet& isErrorPoint,
             const labelList& pointErrorCount
         );
 
@@ -136,7 +136,7 @@ class polyMeshFilter
         (
             const polyMesh& newMesh,
             const labelList& oldToNewMesh,
-            const PackedBoolList& isErrorPoint,
+            const bitSet& isErrorPoint,
             const labelList& pointErrorCount
         );
 
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C
index fafbba3b038fa7391f84a0bb89e6eaf4a6173754..50e10cf9997a891c9d27a1fe85848d22d65b0c18 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/addPatchCellLayer.C
@@ -937,7 +937,7 @@ void Foam::addPatchCellLayer::calcExtrudeInfo
 
         labelList patchEdges;
         labelList coupledEdges;
-        PackedBoolList sameEdgeOrientation;
+        bitSet sameEdgeOrientation;
         PatchTools::matchEdges
         (
             pp,
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C
index 9deff04b19b62cea6e042ea1e974ef74f816d808..e3fce41660e8c264c51eeecfae16f2dc48e8842c 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.C
@@ -82,7 +82,7 @@ Foam::label Foam::edgeCollapser::checkMeshQuality
 (
     const polyMesh& mesh,
     const dictionary& meshQualityDict,
-    PackedBoolList& isErrorPoint
+    bitSet& isErrorPoint
 )
 {
     labelHashSet badFaces = edgeCollapser::checkBadFaces
@@ -93,9 +93,9 @@ Foam::label Foam::edgeCollapser::checkMeshQuality
 
     label nBadFaces = returnReduce(badFaces.size(), sumOp<label>());
 
-    forAllConstIter(labelHashSet, badFaces, iter)
+    for (const label facei : badFaces)
     {
-        const face& f = mesh.faces()[iter.key()];
+        const face& f = mesh.faces()[facei];
 
         isErrorPoint.setMany(f);
     }
@@ -175,7 +175,7 @@ void Foam::edgeCollapser::collapseToEdge
     const scalarList& dNeg,
     const scalarList& dPos,
     const scalar dShift,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation
 ) const
 {
@@ -282,7 +282,7 @@ void Foam::edgeCollapser::collapseToPoint
     const labelList& pointPriority,
     const point& fC,
     const labelList& facePts,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation
 ) const
 {
@@ -552,7 +552,7 @@ Foam::edgeCollapser::collapseType Foam::edgeCollapser::collapseFace
     const face& f,
     const label facei,
     const scalar targetFaceSize,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation,
     const scalarField& faceFilterFactor
 ) const
@@ -841,8 +841,8 @@ void Foam::edgeCollapser::checkBoundaryPointMergeEdges
 
 Foam::label Foam::edgeCollapser::breakStringsAtEdges
 (
-    const PackedBoolList& markedEdges,
-    PackedBoolList& collapseEdge,
+    const bitSet& markedEdges,
+    bitSet& collapseEdge,
     List<pointEdgeCollapse>& allPointInfo
 ) const
 {
@@ -904,7 +904,7 @@ Foam::label Foam::edgeCollapser::breakStringsAtEdges
 void Foam::edgeCollapser::determineDuplicatePointsOnFace
 (
     const face& f,
-    PackedBoolList& markedPoints,
+    bitSet& markedPoints,
     labelHashSet& uniqueCollapses,
     labelHashSet& duplicateCollapses,
     List<pointEdgeCollapse>& allPointInfo
@@ -1003,7 +1003,7 @@ Foam::label Foam::edgeCollapser::syncCollapse
 (
     const globalIndex& globalPoints,
     const labelList& pointPriority,
-    const PackedBoolList& collapseEdge,
+    const bitSet& collapseEdge,
     const Map<point>& collapsePointToLocation,
     List<pointEdgeCollapse>& allPointInfo
 ) const
@@ -1300,7 +1300,7 @@ bool Foam::edgeCollapser::setRefinement
 
     bool meshChanged = false;
 
-    PackedBoolList removedPoints(mesh_.nPoints());
+    bitSet removedPoints(mesh_.nPoints());
 
     // Create strings of edges.
     // Map from collapseIndex(=global master point) to set of points
@@ -1372,7 +1372,7 @@ bool Foam::edgeCollapser::setRefinement
     faceList newFaces(mesh_.faces());
 
     // Current cellCollapse status
-    PackedBoolList cellRemoved(mesh_.nCells(), false);
+    bitSet cellRemoved(mesh_.nCells(), false);
 
     label nUnvisited = 0;
     label nUncollapsed = 0;
@@ -1481,11 +1481,11 @@ bool Foam::edgeCollapser::setRefinement
 
 
     // Keep track of faces that have been done already.
-    PackedBoolList doneFace(mesh_.nFaces(), false);
+    bitSet doneFace(mesh_.nFaces(), false);
 
     {
         // Mark points used.
-        PackedBoolList usedPoint(mesh_.nPoints(), false);
+        bitSet usedPoint(mesh_.nPoints(), false);
 
         forAll(cellRemoved, celli)
         {
@@ -1622,7 +1622,7 @@ void Foam::edgeCollapser::consistentCollapse
     const globalIndex& globalPoints,
     const labelList& pointPriority,
     const Map<point>& collapsePointToLocation,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     List<pointEdgeCollapse>& allPointInfo,
     const bool allowCellCollapse
 ) const
@@ -1664,8 +1664,8 @@ void Foam::edgeCollapser::consistentCollapse
 
         // Get collapsed faces
 
-        PackedBoolList isCollapsedFace(mesh_.nFaces());
-        PackedBoolList markedPoints(mesh_.nPoints());
+        bitSet isCollapsedFace(mesh_.nFaces());
+        bitSet markedPoints(mesh_.nPoints());
 
         forAll(faces, facei)
         {
@@ -1720,7 +1720,7 @@ void Foam::edgeCollapser::consistentCollapse
             }
         }
 
-        PackedBoolList markedEdges(mesh_.nEdges());
+        bitSet markedEdges(mesh_.nEdges());
 
         if (!allowCellCollapse)
         {
@@ -1811,7 +1811,7 @@ Foam::label Foam::edgeCollapser::markSmallEdges
 (
     const scalarField& minEdgeLen,
     const labelList& pointPriority,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation
 ) const
 {
@@ -1862,7 +1862,7 @@ Foam::label Foam::edgeCollapser::markMergeEdges
 (
     const scalar maxCos,
     const labelList& pointPriority,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation
 ) const
 {
@@ -1949,7 +1949,7 @@ Foam::labelPair Foam::edgeCollapser::markSmallSliverFaces
 (
     const scalarField& faceFilterFactor,
     const labelList& pointPriority,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation
 ) const
 {
@@ -2011,7 +2011,7 @@ Foam::labelPair Foam::edgeCollapser::markFaceZoneEdges
     const faceZone& fZone,
     const scalarField& faceFilterFactor,
     const labelList& pointPriority,
-    PackedBoolList& collapseEdge,
+    bitSet& collapseEdge,
     Map<point>& collapsePointToLocation
 ) const
 {
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.H
index e61784c0797b340eb4e42287a03bbfb3956fea61..6bf2faeb305ddf2fb2e4bc60d2c65d875ff6c034 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.H
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/edgeCollapser.H
@@ -52,15 +52,14 @@ SourceFiles
 namespace Foam
 {
 
-// Forward declaration of classes
+// Forward declarations
 class polyMesh;
-class PackedBoolList;
+class bitSet;
 class polyTopoChange;
 class globalIndex;
 class face;
 class edge;
 
-
 /*---------------------------------------------------------------------------*\
                         Class edgeCollapser Declaration
 \*---------------------------------------------------------------------------*/
@@ -124,7 +123,7 @@ private:
             const scalarList& dNeg,
             const scalarList& dPos,
             const scalar dShift,
-            PackedBoolList& collapseEdge,
+            bitSet& collapseEdge,
             Map<point>& collapsePointToLocation
         ) const;
 
@@ -137,7 +136,7 @@ private:
             const labelList& pointPriority,
             const point& fC,
             const labelList& facePts,
-            PackedBoolList& collapseEdge,
+            bitSet& collapseEdge,
             Map<point>& collapsePointToLocation
         ) const;
 
@@ -162,7 +161,7 @@ private:
             const face& f,
             const label facei,
             const scalar targetFaceSize,
-            PackedBoolList& collapseEdge,
+            bitSet& collapseEdge,
             Map<point>& collapsePointToLocation,
             const scalarField& faceFilterFactor
         ) const;
@@ -185,8 +184,8 @@ private:
         //  location
         label breakStringsAtEdges
         (
-            const PackedBoolList& markedEdges,
-            PackedBoolList& collapseEdge,
+            const bitSet& markedEdges,
+            bitSet& collapseEdge,
             List<pointEdgeCollapse>& allPointInfo
         ) const;
 
@@ -196,7 +195,7 @@ private:
         void determineDuplicatePointsOnFace
         (
             const face& f,
-            PackedBoolList& markedPoints,
+            bitSet& markedPoints,
             labelHashSet& uniqueCollapses,
             labelHashSet& duplicateCollapses,
             List<pointEdgeCollapse>& allPointInfo
@@ -224,7 +223,7 @@ private:
         (
             const globalIndex& globalPoints,
             const labelList& boundaryPoint,
-            const PackedBoolList& collapseEdge,
+            const bitSet& collapseEdge,
             const Map<point>& collapsePointToLocation,
             List<pointEdgeCollapse>& allPointInfo
         ) const;
@@ -276,7 +275,7 @@ public:
             (
                 const polyMesh& mesh,
                 const dictionary& meshQualityDict,
-                PackedBoolList& isErrorPoint
+                bitSet& isErrorPoint
             );
 
             //- Ensure that the collapse is parallel consistent and update
@@ -288,7 +287,7 @@ public:
                 const globalIndex& globalPoints,
                 const labelList& pointPriority,
                 const Map<point>& collapsePointToLocation,
-                PackedBoolList& collapseEdge,
+                bitSet& collapseEdge,
                 List<pointEdgeCollapse>& allPointInfo,
                 const bool allowCellCollapse = false
             ) const;
@@ -309,7 +308,7 @@ public:
             (
                 const scalarField& minEdgeLen,
                 const labelList& pointPriority,
-                PackedBoolList& collapseEdge,
+                bitSet& collapseEdge,
                 Map<point>& collapsePointToLocation
             ) const;
 
@@ -318,7 +317,7 @@ public:
             (
                 const scalar maxCos,
                 const labelList& pointPriority,
-                PackedBoolList& collapseEdge,
+                bitSet& collapseEdge,
                 Map<point>& collapsePointToLocation
             ) const;
 
@@ -332,7 +331,7 @@ public:
             (
                 const scalarField& faceFilterFactor,
                 const labelList& pointPriority,
-                PackedBoolList& collapseEdge,
+                bitSet& collapseEdge,
                 Map<point>& collapsePointToLocation
             ) const;
 
@@ -342,7 +341,7 @@ public:
                 const faceZone& fZone,
                 const scalarField& faceFilterFactor,
                 const labelList& pointPriority,
-                PackedBoolList& collapseEdge,
+                bitSet& collapseEdge,
                 Map<point>& collapsePointToLocation
             ) const;
 };
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C
index 488019f7726a4733182c05458e0e11f63e70693a..74dcafca1d1d72fc5c1c566b1f86e40b93aa0c48 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.C
@@ -1564,7 +1564,7 @@ void Foam::hexRef8::walkFaceFromMid
 Foam::label Foam::hexRef8::faceConsistentRefinement
 (
     const bool maxSet,
-    PackedBoolList& refineCell
+    bitSet& refineCell
 ) const
 {
     label nChanged = 0;
@@ -1653,7 +1653,7 @@ void Foam::hexRef8::checkWantedRefinementLevels
     const labelList& cellsToRefine
 ) const
 {
-    PackedBoolList refineCell(mesh_.nCells(), cellsToRefine);
+    bitSet refineCell(mesh_.nCells(), cellsToRefine);
 
     for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
     {
@@ -2260,7 +2260,7 @@ Foam::labelList Foam::hexRef8::consistentRefinement
     // maxSet = false : unselect cells to refine
     // maxSet = true  : select cells to refine
 
-    PackedBoolList refineCell(mesh_.nCells(), cellsToRefine);
+    bitSet refineCell(mesh_.nCells(), cellsToRefine);
 
     while (true)
     {
@@ -2282,7 +2282,7 @@ Foam::labelList Foam::hexRef8::consistentRefinement
     }
 
     // Convert back to labelList.
-    labelList newCellsToRefine(refineCell.used());
+    labelList newCellsToRefine(refineCell.toc());
 
     if (debug)
     {
@@ -3079,7 +3079,7 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement2
     // 2. Extend to 2:1. I don't understand yet why this is not done
     // 2. Extend to 2:1. For non-cube cells the scalar distance does not work
     // so make sure it at least provides 2:1.
-    PackedBoolList refineCell(mesh_.nCells());
+    bitSet refineCell(mesh_.nCells());
     forAll(allCellInfo, celli)
     {
         label wanted = allCellInfo[celli].wantedLevel(cc[celli]);
@@ -3111,7 +3111,7 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement2
     }
 
     // 3. Convert back to labelList.
-    labelList newCellsToRefine(refineCell.used());
+    labelList newCellsToRefine(refineCell.toc());
 
     if (debug)
     {
@@ -3137,9 +3137,9 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement2
         }
 
         // Extend to 2:1
-        PackedBoolList refineCell(mesh_.nCells(), newCellsToRefine);
+        bitSet refineCell(mesh_.nCells(), newCellsToRefine);
 
-        const PackedBoolList savedRefineCell(refineCell);
+        const bitSet savedRefineCell(refineCell);
 
         label nChanged = faceConsistentRefinement(true, refineCell);
 
@@ -3747,7 +3747,7 @@ Foam::labelListList Foam::hexRef8::setRefinement
     }
 
     // Get all affected faces.
-    PackedBoolList affectedFace(mesh_.nFaces());
+    bitSet affectedFace(mesh_.nFaces());
 
     {
         forAll(cellMidPoint, celli)
@@ -5286,14 +5286,14 @@ Foam::labelList Foam::hexRef8::consistentUnrefinement
     // maxSet = true: select points to refine
 
     // Maintain bitset for pointsToUnrefine and cellsToUnrefine
-    PackedBoolList unrefinePoint(mesh_.nPoints(), pointsToUnrefine);
+    bitSet unrefinePoint(mesh_.nPoints(), pointsToUnrefine);
 
     while (true)
     {
         // Construct cells to unrefine
         // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-        PackedBoolList unrefineCell(mesh_.nCells());
+        bitSet unrefineCell(mesh_.nCells());
 
         forAll(unrefinePoint, pointi)
         {
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.H
index 9e5cf7639f79a6bfefb164190cc5b551dcd1ce30..a2388f3b60f56b022a02f1a5f56095a60f72ad22 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.H
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8/hexRef8.H
@@ -42,7 +42,7 @@ SourceFiles
 #include "primitivePatch.H"
 #include "removeFaces.H"
 #include "refinementHistory.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "uniformDimensionedFields.H"
 #include "cellShapeList.H"
 
@@ -300,7 +300,7 @@ class hexRef8
         label faceConsistentRefinement
         (
             const bool maxSet,
-            PackedBoolList& refineCell
+            bitSet& refineCell
         ) const;
 
         //- Check wanted refinement for 2:1 consistency
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
index 5c554a2c17db76ab44aa0983ad3865b16e43c9ac..e075ec59d9bced747c64f26c29f2f7cd51fe1ffc 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
@@ -186,7 +186,7 @@ void Foam::polyTopoChange::countMap
 
 Foam::labelHashSet Foam::polyTopoChange::getSetIndices
 (
-    const PackedBoolList& lst
+    const bitSet& lst
 )
 {
     labelHashSet values(lst.count());
@@ -605,7 +605,7 @@ Foam::label Foam::polyTopoChange::getCellOrder
     SLList<label> nextCell;
 
     // Whether cell has been done already
-    PackedBoolList visited(cellCellAddressing.size());
+    bitSet visited(cellCellAddressing.size());
 
     label cellInOrder = 0;
 
@@ -1222,8 +1222,8 @@ void Foam::polyTopoChange::compact
                         {
                             faces_[facei].flip();
                             Swap(faceOwner_[facei], faceNeighbour_[facei]);
-                            flipFaceFlux_.set(facei, !flipFaceFlux_.test(facei));
-                            faceZoneFlip_.set(facei, !faceZoneFlip_.test(facei));
+                            flipFaceFlux_.flip(facei);
+                            faceZoneFlip_.flip(facei);
                         }
                     }
                 }
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H
index f9d7640583cf5eae7f8028ac3803ee2c9b30863c..dda49fe949b56175ba948ca9687d0068987e758e 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.H
@@ -69,7 +69,7 @@ SourceFiles
 #include "Map.H"
 #include "HashSet.H"
 #include "mapPolyMesh.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -160,13 +160,13 @@ class polyTopoChange
             Map<label> faceFromEdge_;
 
             //- In mapping whether to reverse the flux.
-            PackedBoolList flipFaceFlux_;
+            bitSet flipFaceFlux_;
 
             //- Zone of face
             Map<label> faceZone_;
 
             //- Orientation of face in zone
-            PackedBoolList faceZoneFlip_;
+            bitSet faceZoneFlip_;
 
             //- Active faces
             label nActiveFaces_;
@@ -241,7 +241,7 @@ class polyTopoChange
         );
 
         //- Get all set elements as a labelHashSet
-        static labelHashSet getSetIndices(const PackedBoolList& lst);
+        static labelHashSet getSetIndices(const bitSet& lst);
 
         //- Count number of added and removed quantities from maps.
         static void countMap
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/tetDecomposer.H b/src/dynamicMesh/polyTopoChange/polyTopoChange/tetDecomposer.H
index 4b854fdd124494113f155eb36d74beb99ceff6d1..2de77c48c9343792cc27a5352870af2469fa8956 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/tetDecomposer.H
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/tetDecomposer.H
@@ -36,7 +36,7 @@ SourceFiles
 #define tetDecomposer_H
 
 #include "DynamicList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "boolList.H"
 #include "typeInfo.H"
 #include "Enum.H"
diff --git a/src/fileFormats/ensight/part/ensightFaces.C b/src/fileFormats/ensight/part/ensightFaces.C
index f6e4b9da3f45af94f5a831b75163e9f1626f3de3..21489d7d01f3303cddf01bb99afe8618af4d8bfa 100644
--- a/src/fileFormats/ensight/part/ensightFaces.C
+++ b/src/fileFormats/ensight/part/ensightFaces.C
@@ -251,7 +251,7 @@ void Foam::ensightFaces::classify
     const faceList& faces,
     const labelUList& addressing,
     const boolList& flipMap,
-    const PackedBoolList& exclude
+    const bitSet& exclude
 )
 {
     // Note: Since PackedList::operator[] returns zero (false) for out-of-range
diff --git a/src/fileFormats/ensight/part/ensightFaces.H b/src/fileFormats/ensight/part/ensightFaces.H
index bd7b3e8c40eb8add2d619abba7c6ff05b3db6b27..fc9fb996589156102df998c8feb10cd2ff49282b 100644
--- a/src/fileFormats/ensight/part/ensightFaces.H
+++ b/src/fileFormats/ensight/part/ensightFaces.H
@@ -36,7 +36,7 @@ Description
 #include "labelList.H"
 #include "faceList.H"
 #include "FixedList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -186,7 +186,7 @@ public:
             const faceList& faces,
             const labelUList& addressing,
             const boolList& flipMap = boolList(),
-            const PackedBoolList& exclude = PackedBoolList()
+            const bitSet& exclude = bitSet()
         );
 
 
diff --git a/src/fileFormats/starcd/STARCDCore.C b/src/fileFormats/starcd/STARCDCore.C
index 290a93e67107f48f2942d14f4496e851c9db9844..c98849dd75d980700d1ba1dfaaeae147dea11a8b 100644
--- a/src/fileFormats/starcd/STARCDCore.C
+++ b/src/fileFormats/starcd/STARCDCore.C
@@ -26,7 +26,7 @@ License
 #include "STARCDCore.H"
 #include "ListOps.H"
 #include "clock.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "DynamicList.H"
 #include "StringStream.H"
 #include "OSspecific.H"
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorFieldTemplates.C b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorFieldTemplates.C
index b9d1d591271541bb0851298c263536292083fabc..1ca1c1c31e4692d5c74fa75441c3a2ccde93ace0 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorFieldTemplates.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/pressurePIDControlInletVelocity/pressurePIDControlInletVelocityFvPatchVectorFieldTemplates.C
@@ -39,7 +39,7 @@ void Foam::pressurePIDControlInletVelocityFvPatchVectorField::faceZoneAverage
 {
     const fvMesh& mesh(patch().boundaryMesh().mesh());
 
-    PackedBoolList isMasterFace(syncTools::getInternalOrMasterFaces(mesh));
+    bitSet isMasterFace(syncTools::getInternalOrMasterFaces(mesh));
 
     const faceZone& zone = mesh.faceZones()[name];
 
diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C
index 2af783b1821c5fbe7af218c8bd9109d7e06628ae..824b4c84fb41cf25f86dcbb2c404ce5dc58a188b 100644
--- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C
+++ b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.C
@@ -194,7 +194,7 @@ void Foam::isoAdvection::timeIntegratedFlux()
             // This is a surface cell, increment counter, append and mark cell
             nSurfaceCells++;
             surfCells_.append(celli);
-            checkBounding_[celli] = true;
+            checkBounding_.set(celli);
 
             DebugInfo
                 << "\n------------ Cell " << celli << " with alpha1 = "
@@ -327,7 +327,7 @@ void Foam::isoAdvection::timeIntegratedFlux()
 
                         // We want to check bounding of neighbour cells to
                         // surface cells as well:
-                        checkBounding_[otherCell] = true;
+                        checkBounding_.set(otherCell);
 
                         // Also check neighbours of neighbours.
                         // Note: consider making it a run time selectable
@@ -336,10 +336,7 @@ void Foam::isoAdvection::timeIntegratedFlux()
                         // 1 - neighbours of neighbours
                         // 2 - ...
                         const labelList& nNeighbourCells = cellCells[otherCell];
-                        forAll(nNeighbourCells, ni)
-                        {
-                            checkBounding_[nNeighbourCells[ni]] = true;
-                        }
+                        checkBounding_.setMany(nNeighbourCells);
                     }
                     else
                     {
@@ -711,7 +708,7 @@ void Foam::isoAdvection::boundFromAbove
     // Loop through alpha cell centred field
     forAll(alpha1, celli)
     {
-        if (checkBounding_[celli])
+        if (checkBounding_.test(celli))
         {
             const scalar Vi = meshV[celli];
             scalar alpha1New = alpha1[celli] - netFlux(dVf, celli)/Vi;
@@ -734,7 +731,7 @@ void Foam::isoAdvection::boundFromAbove
                 dVfmax.clear();
                 phi.clear();
 
-                cellIsBounded_[celli] = true;
+                cellIsBounded_.set(celli);
 
                 // Find potential neighbour cells to pass surplus phase to
                 setDownwindFaces(celli, downwindFaces);
@@ -1065,12 +1062,9 @@ void Foam::isoAdvection::writeBoundedCells() const
             )
         );
 
-        forAll(cellIsBounded_, i)
+        for (const label celli : cellIsBounded_)
         {
-            if (cellIsBounded_[i])
-            {
-                cSet.insert(i);
-            }
+            cSet.insert(celli);
         }
 
         cSet.write();
diff --git a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H
index bc2d96ee9318d0903ac20ba69532c853dc67a9a5..e0c6a3e9ae73d430e819c3f6d335887e707be953 100644
--- a/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H
+++ b/src/finiteVolume/fvMatrices/solvers/isoAdvection/isoAdvection/isoAdvection.H
@@ -60,6 +60,7 @@ SourceFiles
 #include "className.H"
 #include "isoCutCell.H"
 #include "isoCutFace.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -146,11 +147,11 @@ class isoAdvection
             //- Face cutting object
             isoCutFace isoCutFace_;
 
-            //- Bool list for cells that have been touched by the bounding step
-            boolList cellIsBounded_;
+            //- Cells that have been touched by the bounding step
+            bitSet cellIsBounded_;
 
             //- True for all surface cells and their neighbours
-            boolList checkBounding_;
+            bitSet checkBounding_;
 
             //- Storage for boundary faces downwind to a surface cell
             DynamicLabelList bsFaces_;
diff --git a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H
index 52f006ca1ceed508e6219930a3bfd41c7aaec20b..84770fb0ab92da62fd8593523f6cffdf746696c7 100644
--- a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H
+++ b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedParticle.H
@@ -78,7 +78,7 @@ public:
 
     public:
 
-        const PackedBoolList& isWallPatch_;
+        const bitSet& isWallPatch_;
 
         // Constructors
 
@@ -86,7 +86,7 @@ public:
             inline trackingData
             (
                 const TrackCloudType& cloud,
-                const PackedBoolList& isWallPatch
+                const bitSet& isWallPatch
             )
             :
                 particle::trackingData(cloud),
diff --git a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C
index 35adfda92d95a141e9d7713ce4406e2068b134bd..3c1230946b71ad4cdf177666b173f5c2a5361016 100644
--- a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C
+++ b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.C
@@ -51,7 +51,7 @@ namespace functionObjects
 
 Foam::tetIndices Foam::functionObjects::wallBoundedStreamLine::findNearestTet
 (
-    const PackedBoolList& isWallPatch,
+    const bitSet& isWallPatch,
     const point& seedPt,
     const label celli
 ) const
@@ -108,7 +108,7 @@ void Foam::functionObjects::wallBoundedStreamLine::track()
     // These are the faces that need to be followed
 
     autoPtr<indirectPrimitivePatch> boundaryPatch(wallPatch());
-    PackedBoolList isWallPatch(mesh_.nFaces(), boundaryPatch().addressing());
+    bitSet isWallPatch(mesh_.nFaces(), boundaryPatch().addressing());
 
 
     // Find nearest wall particle for the seedPoints
diff --git a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H
index 155ddceb297f90d0e113f6ee36d946d2010b8650..dbec1b53e834ab3189fe55b69a2e9dab30a4cbec 100644
--- a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H
+++ b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLine.H
@@ -139,7 +139,7 @@ protected:
         //- Find wall tet on cell
         tetIndices findNearestTet
         (
-            const PackedBoolList& isWallPatch,
+            const bitSet& isWallPatch,
             const point& seedPt,
             const label celli
         ) const;
diff --git a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLineParticle.H b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLineParticle.H
index b8189d6b2430a6dad64ec806a2921ec2db87eee5..8f0c25132f264d9b92853bce9dc9ea927f2cc2be 100644
--- a/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLineParticle.H
+++ b/src/functionObjects/field/wallBoundedStreamLine/wallBoundedStreamLineParticle.H
@@ -99,7 +99,7 @@ public:
                 const label UIndex,
                 const bool trackForward,
                 const scalar trackLength,
-                const PackedBoolList& isWallPatch,
+                const bitSet& isWallPatch,
 
                 DynamicList<List<point>>& allPositions,
                 List<DynamicList<scalarList>>& allScalars,
diff --git a/src/lagrangian/basic/Cloud/Cloud.H b/src/lagrangian/basic/Cloud/Cloud.H
index e1ce3d2ba6e45691b0521fa8b1bdd2eeb4b7f0cf..d5980127de89981db4411aa627a2ef3af967976e 100644
--- a/src/lagrangian/basic/Cloud/Cloud.H
+++ b/src/lagrangian/basic/Cloud/Cloud.H
@@ -41,7 +41,7 @@ SourceFiles
 #include "IOField.H"
 #include "CompactIOField.H"
 #include "polyMesh.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -82,7 +82,7 @@ class Cloud
         mutable DynamicList<label> labels_;
 
         //- Does the cell have wall faces
-        mutable autoPtr<PackedBoolList> cellWallFacesPtr_;
+        mutable autoPtr<bitSet> cellWallFacesPtr_;
 
         //- Temporary storage for the global particle positions
         mutable autoPtr<vectorField> globalPositionsPtr_;
diff --git a/src/lagrangian/basic/InteractionLists/InteractionLists.C b/src/lagrangian/basic/InteractionLists/InteractionLists.C
index 34699b1e44e59eaa4592eac1bccf1673ac1ae4b6..d38bfae3bae085858a90655591744e38a2f4f988 100644
--- a/src/lagrangian/basic/InteractionLists/InteractionLists.C
+++ b/src/lagrangian/basic/InteractionLists/InteractionLists.C
@@ -93,7 +93,7 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
     // Recording which cells are in range of an extended boundBox, as
     // only these cells will need to be tested to determine which
     // referred cells that they interact with.
-    PackedBoolList cellInRangeOfCoupledPatch(mesh_.nCells(), false);
+    bitSet cellInRangeOfCoupledPatch(mesh_.nCells(), false);
 
     // IAndT: index (=local cell index) and transform (from
     // globalIndexAndTransform)
@@ -178,7 +178,7 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
 
     ril_.setSize(cellBbsToExchange.size());
 
-    // This needs to be a boolList, not PackedBoolList if
+    // This needs to be a boolList, not bitSet if
     // reverseDistribute is called.
     boolList cellBbRequiredByAnyCell(cellBbsToExchange.size(), false);
 
@@ -400,7 +400,7 @@ void Foam::InteractionLists<ParticleType>::buildInteractionLists()
 
     rwfil_.setSize(wallFaceBbsToExchange.size());
 
-    // This needs to be a boolList, not PackedBoolList if
+    // This needs to be a boolList, not bitSet if
     // reverseDistribute is called.
     boolList wallFaceBbRequiredByAnyCell(wallFaceBbsToExchange.size(), false);
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C
index aa978877f9781a1241031233b68674525cb544f8..1c4ecefade3cf9b94649ef8f651bdd4d014189a2 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InflationInjection/InflationInjection.C
@@ -25,7 +25,7 @@ License
 
 #include "InflationInjection.H"
 #include "mathematicalConstants.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "cellSet.H"
 #include "ListListOps.H"
 
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleDistributionInjection/InjectedParticleDistributionInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleDistributionInjection/InjectedParticleDistributionInjection.C
index 2ae5e8031b78afcfb0050a1ab0a8cf199dcd2f6e..3947b86519a04b60674c1d355ecfd745d184f503 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleDistributionInjection/InjectedParticleDistributionInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleDistributionInjection/InjectedParticleDistributionInjection.C
@@ -25,7 +25,7 @@ License
 
 #include "InjectedParticleDistributionInjection.H"
 #include "mathematicalConstants.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "injectedParticleCloud.H"
 
 using namespace Foam::constant;
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleInjection/InjectedParticleInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleInjection/InjectedParticleInjection.C
index f49931836388d33263f7797ac88936508a8e1497..47a0102e736819d6bd86f63ed448f4cb34144976 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleInjection/InjectedParticleInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/InjectedParticleInjection/InjectedParticleInjection.C
@@ -25,7 +25,7 @@ License
 
 #include "InjectedParticleInjection.H"
 #include "mathematicalConstants.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "SortableList.H"
 #include "injectedParticleCloud.H"
 
@@ -232,7 +232,7 @@ void Foam::InjectedParticleInjection<CloudType>::updateMesh()
 {
     label nRejected = 0;
 
-    PackedBoolList keep(position_.size(), true);
+    bitSet keep(position_.size(), true);
 
     forAll(position_, particlei)
     {
diff --git a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C
index 6a2480608d92a2d078b6c3ecedf30f0a9ed965f8..15728227b110dfed3c757dc872e154e264bd4f32 100644
--- a/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C
+++ b/src/lagrangian/intermediate/submodels/Kinematic/InjectionModel/ManualInjection/ManualInjection.C
@@ -25,7 +25,7 @@ License
 
 #include "ManualInjection.H"
 #include "mathematicalConstants.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 using namespace Foam::constant::mathematical;
 
@@ -116,7 +116,7 @@ void Foam::ManualInjection<CloudType>::updateMesh()
 {
     label nRejected = 0;
 
-    PackedBoolList keep(positions_.size(), true);
+    bitSet keep(positions_.size(), true);
 
     forAll(positions_, pI)
     {
diff --git a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C
index f58ea3306f14ccdfceb79b5bf07d4ad4d5125dc2..6f3b0bc83a351f0c3b59d6170f66612c501d7279 100644
--- a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C
+++ b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/displacementMotionSolverMeshMover.C
@@ -226,7 +226,7 @@ bool Foam::displacementMotionSolverMeshMover::move
           : mesh().lookupObject<scalarField>(minThicknessName)
         );
 
-        const PackedBoolList isPatchMasterPoint
+        const bitSet isPatchMasterPoint
         (
             meshRefinement::getMasterPoints
             (
@@ -235,7 +235,7 @@ bool Foam::displacementMotionSolverMeshMover::move
             )
         );
 
-        const PackedBoolList isPatchMasterEdge
+        const bitSet isPatchMasterEdge
         (
             meshRefinement::getMasterEdges
             (
diff --git a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.C b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.C
index cdfa8b2464119039194baad83b9e0f52ac601839..9253faac3bca0014a7d472a2cac44e921ee55006 100644
--- a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.C
+++ b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.C
@@ -52,8 +52,8 @@ Foam::fieldSmoother::~fieldSmoother()
 void Foam::fieldSmoother::smoothNormals
 (
     const label nIter,
-    const PackedBoolList& isMeshMasterPoint,
-    const PackedBoolList& isMeshMasterEdge,
+    const bitSet& isMeshMasterPoint,
+    const bitSet& isMeshMasterEdge,
     const labelList& fixedPoints,
     pointVectorField& normals
 ) const
@@ -65,7 +65,7 @@ void Foam::fieldSmoother::smoothNormals
     const edgeList& edges = mesh_.edges();
 
     // Points that do not change.
-    PackedBoolList isFixedPoint(mesh_.nPoints());
+    bitSet isFixedPoint(mesh_.nPoints());
 
     // Internal points that are fixed
     forAll(fixedPoints, i)
@@ -140,8 +140,8 @@ void Foam::fieldSmoother::smoothNormals
 void Foam::fieldSmoother::smoothPatchNormals
 (
     const label nIter,
-    const PackedBoolList& isPatchMasterPoint,
-    const PackedBoolList& isPatchMasterEdge,
+    const bitSet& isPatchMasterPoint,
+    const bitSet& isPatchMasterEdge,
     const indirectPrimitivePatch& adaptPatch,
     pointField& normals
 ) const
@@ -206,9 +206,9 @@ void Foam::fieldSmoother::smoothPatchNormals
 void Foam::fieldSmoother::smoothLambdaMuDisplacement
 (
     const label nIter,
-    const PackedBoolList& isMeshMasterPoint,
-    const PackedBoolList& isMeshMasterEdge,
-    const PackedBoolList& isToBeSmoothed,
+    const bitSet& isMeshMasterPoint,
+    const bitSet& isMeshMasterEdge,
+    const bitSet& isToBeSmoothed,
     vectorField& displacement
 ) const
 {
diff --git a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.H b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.H
index 059c09b05b7f6dd389ffa7bbfdf5f665ace485ec..d5b09e496965c0f4dc9f8ea683086a6bad2e4610 100644
--- a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.H
+++ b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmoother.H
@@ -85,8 +85,8 @@ public:
         void smoothNormals
         (
             const label nIter,
-            const PackedBoolList& isMeshMasterPoint,
-            const PackedBoolList& isMeshMasterEdge,
+            const bitSet& isMeshMasterPoint,
+            const bitSet& isMeshMasterEdge,
             const labelList& fixedPoints,
             pointVectorField& normals
         ) const;
@@ -95,8 +95,8 @@ public:
         void smoothPatchNormals
         (
             const label nIter,
-            const PackedBoolList& isPatchMasterPoint,
-            const PackedBoolList& isPatchMasterEdge,
+            const bitSet& isPatchMasterPoint,
+            const bitSet& isPatchMasterEdge,
             const indirectPrimitivePatch& adaptPatch,
             pointField& normals
         ) const;
@@ -106,8 +106,8 @@ public:
         void minSmoothField
         (
             const label nIter,
-            const PackedBoolList& isPatchMasterPoint,
-            const PackedBoolList& isPatchMasterEdge,
+            const bitSet& isPatchMasterPoint,
+            const bitSet& isPatchMasterEdge,
             const indirectPrimitivePatch& adaptPatch,
             const scalarField& fieldMin,
             Field<Type>& field
@@ -117,9 +117,9 @@ public:
         void smoothLambdaMuDisplacement
         (
             const label nIter,
-            const PackedBoolList& isMeshMasterPoint,
-            const PackedBoolList& isMeshMasterEdge,
-            const PackedBoolList& isSmoothable,
+            const bitSet& isMeshMasterPoint,
+            const bitSet& isMeshMasterEdge,
+            const bitSet& isSmoothable,
             vectorField& displacement
         ) const;
 };
diff --git a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmootherTemplates.C b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmootherTemplates.C
index dc02a27c25c6076b60d71259a5ed9158ef056bf8..5da6d68beca3b64293624d7d873c39ae00c2df00 100644
--- a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmootherTemplates.C
+++ b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/fieldSmoother/fieldSmootherTemplates.C
@@ -29,8 +29,8 @@ template <class Type>
 void Foam::fieldSmoother::minSmoothField
 (
     const label nIter,
-    const PackedBoolList& isPatchMasterPoint,
-    const PackedBoolList& isPatchMasterEdge,
+    const bitSet& isPatchMasterPoint,
+    const bitSet& isPatchMasterEdge,
     const indirectPrimitivePatch& adaptPatch,
     const scalarField& fieldMinMag,
     Field<Type>& field
diff --git a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.C b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.C
index 34a3d62af43bcba50e111347d510bb8c60535073..ef0ee2d85b490af5e5a6d6d42f905f6d6e8091c1 100644
--- a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.C
+++ b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.C
@@ -173,8 +173,8 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
     // ~~~~~~~~~~~~~~~~~~~~~~~
 
     // Precalulate (mesh) master point/edge (only relevant for shared pts/edges)
-    const PackedBoolList isMeshMasterPoint(syncTools::getMasterPoints(mesh()));
-    const PackedBoolList isMeshMasterEdge(syncTools::getMasterEdges(mesh()));
+    const bitSet isMeshMasterPoint(syncTools::getMasterPoints(mesh()));
+    const bitSet isMeshMasterEdge(syncTools::getMasterEdges(mesh()));
     // Precalculate meshEdge per pp edge
     const labelList meshEdges
     (
@@ -186,7 +186,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
     );
 
     // Precalulate (patch) master point/edge
-    const PackedBoolList isPatchMasterPoint
+    const bitSet isPatchMasterPoint
     (
         meshRefinement::getMasterPoints
         (
@@ -194,7 +194,7 @@ void Foam::medialAxisMeshMover::update(const dictionary& coeffDict)
             meshPoints
         )
     );
-    const PackedBoolList isPatchMasterEdge
+    const bitSet isPatchMasterEdge
     (
         meshRefinement::getMasterEdges
         (
@@ -768,7 +768,7 @@ void Foam::medialAxisMeshMover::
 handleFeatureAngleLayerTerminations
 (
     const scalar minCos,
-    const PackedBoolList& isPatchMasterPoint,
+    const bitSet& isPatchMasterPoint,
     const labelList& meshEdges,
     List<snappyLayerDriver::extrudeMode>& extrudeStatus,
     pointField& patchDisp,
@@ -901,8 +901,8 @@ void Foam::medialAxisMeshMover::findIsolatedRegions
 (
     const scalar minCosLayerTermination,
     const bool detectExtrusionIsland,
-    const PackedBoolList& isPatchMasterPoint,
-    const PackedBoolList& isPatchMasterEdge,
+    const bitSet& isPatchMasterPoint,
+    const bitSet& isPatchMasterEdge,
     const labelList& meshEdges,
     const scalarField& minThickness,
     List<snappyLayerDriver::extrudeMode>& extrudeStatus,
@@ -1344,8 +1344,8 @@ void Foam::medialAxisMeshMover::calculateDisplacement
 
 
     // Precalulate master points/edge (only relevant for shared points/edges)
-    const PackedBoolList isMeshMasterPoint(syncTools::getMasterPoints(mesh()));
-    const PackedBoolList isMeshMasterEdge(syncTools::getMasterEdges(mesh()));
+    const bitSet isMeshMasterPoint(syncTools::getMasterPoints(mesh()));
+    const bitSet isMeshMasterEdge(syncTools::getMasterEdges(mesh()));
     // Precalculate meshEdge per pp edge
     const labelList meshEdges
     (
@@ -1357,7 +1357,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
     );
 
     // Precalulate (patch) master point/edge
-    const PackedBoolList isPatchMasterPoint
+    const bitSet isPatchMasterPoint
     (
         meshRefinement::getMasterPoints
         (
@@ -1365,7 +1365,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
             meshPoints
         )
     );
-    const PackedBoolList isPatchMasterEdge
+    const bitSet isPatchMasterEdge
     (
         meshRefinement::getMasterEdges
         (
@@ -1614,7 +1614,7 @@ void Foam::medialAxisMeshMover::calculateDisplacement
     // Smear displacement away from fixed values (medialRatio=0 or 1)
     if (nSmoothDisplacement > 0)
     {
-        PackedBoolList isToBeSmoothed(displacement.size(), false);
+        bitSet isToBeSmoothed(displacement.size(), false);
 
         forAll(displacement, i)
         {
diff --git a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.H b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.H
index c8cc5b677af7fc4b24a14d96efac11761cbcd8cc..4cfbca42c333be5c0eff9960e809829568e85a92 100644
--- a/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.H
+++ b/src/mesh/snappyHexMesh/externalDisplacementMeshMover/medialAxisMeshMover.H
@@ -144,7 +144,7 @@ class medialAxisMeshMover
             void handleFeatureAngleLayerTerminations
             (
                 const scalar minCos,
-                const PackedBoolList& isMasterPoint,
+                const bitSet& isMasterPoint,
                 const labelList& meshEdges,
                 List<snappyLayerDriver::extrudeMode>& extrudeStatus,
                 pointField& patchDisp,
@@ -158,8 +158,8 @@ class medialAxisMeshMover
             (
                 const scalar minCosLayerTermination,
                 const bool detectExtrusionIsland,
-                const PackedBoolList& isMasterPoint,
-                const PackedBoolList& isMasterEdge,
+                const bitSet& isMasterPoint,
+                const bitSet& isMasterEdge,
                 const labelList& meshEdges,
                 const scalarField& minThickness,
                 List<snappyLayerDriver::extrudeMode>& extrudeStatus,
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
index 6a3bb20f6ae5d260ded9ccd17dab581559e6e45f..dc9d2ba85ad3e2612e46353ff4fa25a08fb90d26 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.C
@@ -257,7 +257,7 @@ void Foam::meshRefinement::calcCellCellRays
 void Foam::meshRefinement::updateIntersections(const labelList& changedFaces)
 {
     // Stats on edges to test. Count proc faces only once.
-    PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
+    bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
 
     {
         label nMasterFaces = 0;
@@ -1254,7 +1254,7 @@ Foam::meshRefinement::meshRefinement
 Foam::label Foam::meshRefinement::countHits() const
 {
     // Stats on edges to test. Count proc faces only once.
-    PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
+    bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
 
     label nHits = 0;
 
@@ -1551,7 +1551,7 @@ Foam::labelList Foam::meshRefinement::intersectedPoints() const
     const faceList& faces = mesh_.faces();
 
     // Mark all points on faces that will become baffles
-    PackedBoolList isBoundaryPoint(mesh_.nPoints());
+    bitSet isBoundaryPoint(mesh_.nPoints());
     label nBoundaryPoints = 0;
 
     forAll(surfaceIndex_, facei)
@@ -1800,7 +1800,7 @@ void Foam::meshRefinement::checkCoupledFaceZones(const polyMesh& mesh)
 void Foam::meshRefinement::calculateEdgeWeights
 (
     const polyMesh& mesh,
-    const PackedBoolList& isMasterEdge,
+    const bitSet& isMasterEdge,
     const labelList& meshPoints,
     const edgeList& edges,
     scalarField& edgeWeights,
@@ -2292,7 +2292,7 @@ void Foam::meshRefinement::findRegions
     labelList& cellRegion
 )
 {
-    PackedBoolList insideCell(mesh.nCells());
+    bitSet insideCell(mesh.nCells());
 
     // Mark all cells reachable from locationsInMesh
     labelList insideRegions(locationsInMesh.size());
@@ -2702,7 +2702,7 @@ bool Foam::meshRefinement::write() const
 }
 
 
-Foam::PackedBoolList Foam::meshRefinement::getMasterPoints
+Foam::bitSet Foam::meshRefinement::getMasterPoints
 (
     const polyMesh& mesh,
     const labelList& meshPoints
@@ -2726,7 +2726,7 @@ Foam::PackedBoolList Foam::meshRefinement::getMasterPoints
     );
 
 
-    PackedBoolList isPatchMasterPoint(meshPoints.size());
+    bitSet isPatchMasterPoint(meshPoints.size());
     forAll(meshPoints, pointi)
     {
         if (myPoints[pointi] == globalPoints.toGlobal(pointi))
@@ -2739,7 +2739,7 @@ Foam::PackedBoolList Foam::meshRefinement::getMasterPoints
 }
 
 
-Foam::PackedBoolList Foam::meshRefinement::getMasterEdges
+Foam::bitSet Foam::meshRefinement::getMasterEdges
 (
     const polyMesh& mesh,
     const labelList& meshEdges
@@ -2763,7 +2763,7 @@ Foam::PackedBoolList Foam::meshRefinement::getMasterEdges
     );
 
 
-    PackedBoolList isMasterEdge(meshEdges.size());
+    bitSet isMasterEdge(meshEdges.size());
     forAll(meshEdges, edgei)
     {
         if (myEdges[edgei] == globalEdges.toGlobal(edgei))
@@ -2791,7 +2791,7 @@ const
     }
 
     {
-        PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
+        bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
         label nMasterFaces = 0;
         forAll(isMasterFace, i)
         {
@@ -2801,7 +2801,7 @@ const
             }
         }
 
-        PackedBoolList isMeshMasterPoint(syncTools::getMasterPoints(mesh_));
+        bitSet isMeshMasterPoint(syncTools::getMasterPoints(mesh_));
         label nMasterPoints = 0;
         forAll(isMeshMasterPoint, i)
         {
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H
index a6d233a38ed7862f73fc168189e732303b433db3..3c5c03f74cfa60212f83fe4878f4f72de0deef1f 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinement.H
@@ -505,7 +505,7 @@ private:
                 const labelList& testFaces,
 
                 labelList& namedSurfaceIndex,
-                PackedBoolList& posOrientation
+                bitSet& posOrientation
             ) const;
 
             //- Determine patches for baffles
@@ -707,17 +707,17 @@ private:
                 labelList& unnamedRegion1,
                 labelList& unnamedRegion2,
                 labelList& namedSurfaceIndex,
-                PackedBoolList& posOrientation
+                bitSet& posOrientation
             ) const;
 
             //- Put cells into cellZone, faces into faceZone
             void zonify
             (
-                const PackedBoolList& isMasterFace,
+                const bitSet& isMasterFace,
                 const labelList& cellToZone,
                 const labelList& neiCellZone,
                 const labelList& faceToZone,
-                const PackedBoolList& meshFlipMap,
+                const bitSet& meshFlipMap,
                 polyTopoChange& meshMod
             ) const;
 
@@ -759,7 +759,7 @@ private:
             //  to detect non-manifold situations.
             void calcPatchNumMasterFaces
             (
-                const PackedBoolList& isMasterFace,
+                const bitSet& isMasterFace,
                 const indirectPrimitivePatch& patch,
                 labelList& nMasterFaces
             ) const;
@@ -776,12 +776,12 @@ private:
             //- Make faces consistent.
             void consistentOrientation
             (
-                const PackedBoolList& isMasterFace,
+                const bitSet& isMasterFace,
                 const indirectPrimitivePatch& patch,
                 const labelList& nMasterFaces,
                 const labelList& faceToZone,
                 const Map<label>& zoneToOrientation,
-                PackedBoolList& meshFlipMap
+                bitSet& meshFlipMap
             ) const;
 
 
@@ -950,7 +950,7 @@ public:
             static void calculateEdgeWeights
             (
                 const polyMesh& mesh,
-                const PackedBoolList& isMasterEdge,
+                const bitSet& isMasterEdge,
                 const labelList& meshPoints,
                 const edgeList& edges,
                 scalarField& edgeWeights,
@@ -963,7 +963,7 @@ public:
             static void weightedSum
             (
                 const polyMesh& mesh,
-                const PackedBoolList& isMasterEdge,
+                const bitSet& isMasterEdge,
                 const labelList& meshPoints,
                 const edgeList& edges,
                 const scalarField& edgeWeights,
@@ -1410,7 +1410,7 @@ public:
 
             //- Determine master point for subset of points. If coupled
             //  chooses only one
-            static PackedBoolList getMasterPoints
+            static bitSet getMasterPoints
             (
                 const polyMesh& mesh,
                 const labelList& meshPoints
@@ -1418,7 +1418,7 @@ public:
 
             //- Determine master edge for subset of edges. If coupled
             //  chooses only one
-            static PackedBoolList getMasterEdges
+            static bitSet getMasterEdges
             (
                 const polyMesh& mesh,
                 const labelList& meshEdges
@@ -1458,7 +1458,7 @@ public:
             template<class T>
             static T gAverage
             (
-                const PackedBoolList& isMasterElem,
+                const bitSet& isMasterElem,
                 const UList<T>& values
             );
 
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C
index 53a618a454a9926bb41bd29e89d724ebb5764a13..30dd83ee98e38cf9da5b96c4f25c14f6f51f2ec9 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementBaffles.C
@@ -306,7 +306,7 @@ void Foam::meshRefinement::getBafflePatches
     labelList unnamedRegion2;
     labelList namedSurfaceIndex;
     {
-        PackedBoolList posOrientation;
+        bitSet posOrientation;
         zonify
         (
             true,               // allowFreeStandingZoneFaces
@@ -2252,7 +2252,7 @@ void Foam::meshRefinement::getIntersections
     const labelList& testFaces,
 
     labelList& namedSurfaceIndex,
-    PackedBoolList& posOrientation
+    bitSet& posOrientation
 ) const
 {
     namedSurfaceIndex.setSize(mesh_.nFaces());
@@ -2389,7 +2389,7 @@ void Foam::meshRefinement::zonify
     labelList& unnamedRegion1,
     labelList& unnamedRegion2,
     labelList& namedSurfaceIndex,
-    PackedBoolList& posOrientation
+    bitSet& posOrientation
 ) const
 {
     // Determine zones for cells and faces
@@ -2898,7 +2898,7 @@ Foam::labelList Foam::meshRefinement::freeStandingBaffleFaces
 
 void Foam::meshRefinement::calcPatchNumMasterFaces
 (
-    const PackedBoolList& isMasterFace,
+    const bitSet& isMasterFace,
     const indirectPrimitivePatch& patch,
     labelList& nMasterFacesPerEdge
 ) const
@@ -3089,12 +3089,12 @@ Foam::label Foam::meshRefinement::markPatchZones
 
 void Foam::meshRefinement::consistentOrientation
 (
-    const PackedBoolList& isMasterFace,
+    const bitSet& isMasterFace,
     const indirectPrimitivePatch& patch,
     const labelList& nMasterFacesPerEdge,
     const labelList& faceToZone,
     const Map<label>& zoneToOrientation,
-    PackedBoolList& meshFlipMap
+    bitSet& meshFlipMap
 ) const
 {
     const polyBoundaryMesh& bm = mesh_.boundaryMesh();
@@ -3340,11 +3340,11 @@ void Foam::meshRefinement::consistentOrientation
 void Foam::meshRefinement::zonify
 (
     // Get per face whether is it master (of a coupled set of faces)
-    const PackedBoolList& isMasterFace,
+    const bitSet& isMasterFace,
     const labelList& cellToZone,
     const labelList& neiCellZone,
     const labelList& faceToZone,
-    const PackedBoolList& meshFlipMap,
+    const bitSet& meshFlipMap,
     polyTopoChange& meshMod
 ) const
 {
@@ -4399,7 +4399,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
     // >=0 : index of named surface
     labelList cellToZone;
     labelList namedSurfaceIndex;
-    PackedBoolList posOrientation;
+    bitSet posOrientation;
     {
         labelList unnamedRegion1;
         labelList unnamedRegion2;
@@ -4610,7 +4610,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
 
 
     // Get per face whether is it master (of a coupled set of faces)
-    const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
+    const bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
 
 
     // faceZones
@@ -4623,7 +4623,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::meshRefinement::zonify
     //      - do a consistent orientation
     //      - check number of faces with consistent orientation
     //      - if <0 flip the whole patch
-    PackedBoolList meshFlipMap(mesh_.nFaces(), false);
+    bitSet meshFlipMap(mesh_.nFaces(), false);
     {
         // Collect all data on zone faces without cellZones on either side.
         const indirectPrimitivePatch patch
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementProblemCells.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementProblemCells.C
index cc1351813f84ee791db912033bf549c68fae31c1..69740b95ba6c9022519359b8f50340227d7e1926 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementProblemCells.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementProblemCells.C
@@ -528,7 +528,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
 
     // Count of faces marked for baffling
     label nBaffleFaces = 0;
-    PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
+    bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
 
     // Count of faces not baffled since would not cause a collapse
     label nPrevented = 0;
@@ -711,7 +711,7 @@ Foam::labelList Foam::meshRefinement::markFacesOnProblemCells
 
 
     // Does cell have exactly 7 of its 8 anchor points on the boundary?
-    PackedBoolList hasSevenBoundaryAnchorPoints(mesh_.nCells());
+    bitSet hasSevenBoundaryAnchorPoints(mesh_.nCells());
     // If so what is the remaining non-boundary anchor point?
     labelHashSet nonBoundaryAnchors(mesh_.nCells()/10000);
 
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C
index 7cfb52d337fc4a121ea2a4847ffb49e18f0ccc23..22863c4b803fac382a3a501149d731cfaa3e4c03 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementRefine.C
@@ -125,7 +125,7 @@ Foam::labelList Foam::meshRefinement::getChangedFaces
 
     // For reporting: number of masterFaces changed
     label nMasterChanged = 0;
-    PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
+    bitSet isMasterFace(syncTools::getMasterFaces(mesh));
 
     {
         // Mark any face on a cell which has been added or changed
@@ -142,10 +142,10 @@ Foam::labelList Foam::meshRefinement::getChangedFaces
         const label nInternalFaces = mesh.nInternalFaces();
 
         // Mark refined cells on old mesh
-        PackedBoolList oldRefineCell(map.nOldCells(), oldCellsToRefine);
+        bitSet oldRefineCell(map.nOldCells(), oldCellsToRefine);
 
         // Mark refined faces
-        PackedBoolList refinedInternalFace(nInternalFaces);
+        bitSet refinedInternalFace(nInternalFaces);
 
         // 1. Internal faces
 
@@ -358,7 +358,7 @@ void Foam::meshRefinement::markFeatureCellLevel
                 label nRegions = featureMesh.regions(edgeRegion);
 
 
-                PackedBoolList regionVisited(nRegions);
+                bitSet regionVisited(nRegions);
 
 
                 // 1. Seed all 'knots' in edgeMesh
@@ -446,7 +446,7 @@ void Foam::meshRefinement::markFeatureCellLevel
     maxFeatureLevel = labelList(mesh_.nCells(), -1);
 
     // Whether edge has been visited.
-    List<PackedBoolList> featureEdgeVisited(features_.size());
+    List<bitSet> featureEdgeVisited(features_.size());
 
     forAll(features_, featI)
     {
@@ -1124,7 +1124,7 @@ Foam::label Foam::meshRefinement::markSurfaceCurvatureRefinement
     // on a different surface gets refined (if its current level etc.)
 
 
-    const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh_));
+    const bitSet isMasterFace(syncTools::getMasterFaces(mesh_));
 
 
     // Collect candidate faces (i.e. intersecting any surface and
diff --git a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementTemplates.C b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementTemplates.C
index b492ceca1577ba76c01ecc6c63b5f419f0d11e38..f28db75b4a5b4081f96a16855dbccf4c306f8f0e 100644
--- a/src/mesh/snappyHexMesh/meshRefinement/meshRefinementTemplates.C
+++ b/src/mesh/snappyHexMesh/meshRefinement/meshRefinementTemplates.C
@@ -57,7 +57,7 @@ template<class T> void Foam::meshRefinement::updateList
 template<class T>
 T Foam::meshRefinement::gAverage
 (
-    const PackedBoolList& isMasterElem,
+    const bitSet& isMasterElem,
     const UList<T>& values
 )
 {
@@ -274,7 +274,7 @@ template<class Type>
 void Foam::meshRefinement::weightedSum
 (
     const polyMesh& mesh,
-    const PackedBoolList& isMasterEdge,
+    const bitSet& isMasterEdge,
     const labelList& meshPoints,
     const edgeList& edges,
     const scalarField& edgeWeights,
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C
index 4358fc93a84f132a39871bb93969aab3b1f77d34..c4689ee4e9ae8bc158102150647a96a72e1c3d73 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.C
@@ -613,7 +613,7 @@ void Foam::snappyLayerDriver::handleNonManifolds
 
     // 3. Remote check for end of layer across coupled boundaries
     {
-        PackedBoolList isCoupledEdge(mesh.nEdges());
+        bitSet isCoupledEdge(mesh.nEdges());
 
         const labelList& cpEdges = mesh.globalData().coupledPatchMeshEdges();
         isCoupledEdge.setMany(cpEdges);
@@ -1590,7 +1590,7 @@ void Foam::snappyLayerDriver::calculateLayerThickness
             << setw(0) << " -----    ------ --------- -------" << endl;
 
 
-        const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
+        const bitSet isMasterPoint(syncTools::getMasterPoints(mesh));
 
         forAll(patchIDs, i)
         {
@@ -4317,7 +4317,7 @@ void Foam::snappyLayerDriver::addLayers
             DynamicList<label> candidates(baffles.size()*4);
 
             // Mark whether old face was on baffle
-            PackedBoolList oldBaffleFace(map.nOldFaces());
+            bitSet oldBaffleFace(map.nOldFaces());
             forAll(baffles, i)
             {
                 const labelPair& baffle = baffles[i];
@@ -4648,7 +4648,7 @@ void Foam::snappyLayerDriver::doLayers
             // requires balancing to move them off the processor boundaries.
 
             // Is face on a faceZone
-            PackedBoolList isExtrudedZoneFace(mesh.nFaces());
+            bitSet isExtrudedZoneFace(mesh.nFaces());
             {
                 // Add contributions from faceZones that get layers
                 const faceZoneMesh& fZones = mesh.faceZones();
@@ -4668,7 +4668,7 @@ void Foam::snappyLayerDriver::doLayers
                 }
             }
 
-            PackedBoolList intOrCoupled
+            bitSet intOrCoupled
             (
                 syncTools::getInternalOrCoupledFaces(mesh)
             );
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H
index e7c95c953d12c6815a87626dda61453a8c30a4d9..0dae6abac134cdfd6429fea42376dcbe737d3a18 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriver.H
@@ -472,7 +472,7 @@ private:
                 static void averageNeighbours
                 (
                     const polyMesh& mesh,
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterEdge,
                     const labelList& meshEdges,
                     const labelList& meshPoints,
                     const edgeList& edges,
@@ -484,7 +484,7 @@ private:
                 //- Calculate inverse sum of edge weights (currently always 1.0)
                 void sumWeights
                 (
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterEdge,
                     const labelList& meshEdges,
                     const labelList& meshPoints,
                     const edgeList& edges,
@@ -495,8 +495,8 @@ private:
                 void smoothField
                 (
                     const motionSmoother& meshMover,
-                    const PackedBoolList& isMasterPoint,
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterPoint,
+                    const bitSet& isMasterEdge,
                     const labelList& meshEdges,
                     const scalarField& fieldMin,
                     const label nSmoothDisp,
@@ -507,8 +507,8 @@ private:
                 void smoothPatchNormals
                 (
                     const motionSmoother& meshMover,
-                    const PackedBoolList& isMasterPoint,
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterPoint,
+                    const bitSet& isMasterEdge,
                     const labelList& meshEdges,
                     const label nSmoothDisp,
                     pointField& normals
@@ -518,8 +518,8 @@ private:
                 void smoothNormals
                 (
                     const label nSmoothDisp,
-                    const PackedBoolList& isMasterPoint,
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterPoint,
+                    const bitSet& isMasterEdge,
                     const labelList& fixedPoints,
                     pointVectorField& normals
                 ) const;
@@ -529,7 +529,7 @@ private:
                 void handleFeatureAngleLayerTerminations
                 (
                     const scalar minCos,
-                    const PackedBoolList& isMasterPoint,
+                    const bitSet& isMasterPoint,
                     const indirectPrimitivePatch& pp,
                     const labelList& meshEdges,
 
@@ -545,8 +545,8 @@ private:
                 void findIsolatedRegions
                 (
                     const scalar minCosLayerTermination,
-                    const PackedBoolList& isMasterPoint,
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterPoint,
+                    const bitSet& isMasterEdge,
                     const indirectPrimitivePatch& pp,
                     const labelList& meshEdges,
                     const scalarField& minThickness,
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriverTemplates.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriverTemplates.C
index 7fd7beba902e648c2870c02b91ce8192b318de99..a0915b89a2a209e27bfd3b073abf706e4a7b6ae5 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriverTemplates.C
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappyLayerDriverTemplates.C
@@ -32,7 +32,7 @@ template<class Type>
 void Foam::snappyLayerDriver::averageNeighbours
 (
     const polyMesh& mesh,
-    const PackedBoolList& isMasterEdge,
+    const bitSet& isMasterEdge,
     const labelList& meshEdges,
     const labelList& meshPoints,
     const edgeList& edges,
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.C
index cd511ce190094c999ac53228b6cf27d254e3423b..4a0a76ab9fa1f0e6ffd4a18cd21daf4ff117878a 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.C
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.C
@@ -59,13 +59,13 @@ defineTypeNameAndDebug(snappySnapDriver, 0);
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-// Calculate geometrically collocated points, Requires PackedBoolList to be
+// Calculate geometrically collocated points, Requires bitSet to be
 // sized and initialised!
 Foam::label Foam::snappySnapDriver::getCollocatedPoints
 (
     const scalar tol,
     const pointField& points,
-    PackedBoolList& isCollocatedPoint
+    bitSet& isCollocatedPoint
 )
 {
     labelList pointMap;
@@ -136,13 +136,13 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
 
 
     // Get the faces on the boundary
-    PackedBoolList isFront(mesh.nFaces(), pp.addressing());
+    bitSet isFront(mesh.nFaces(), pp.addressing());
 
     // Walk out from the surface a bit. Poor man's FaceCellWave.
     // Commented out for now - not sure if needed and if so how much
     //for (label iter = 0; iter < 2; iter++)
     //{
-    //    PackedBoolList newIsFront(mesh.nFaces());
+    //    bitSet newIsFront(mesh.nFaces());
     //
     //    forAll(isFront, facei)
     //    {
@@ -174,7 +174,7 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothInternalDisplacement
     // Mark all points on faces
     //  - not on the boundary
     //  - inbetween differing refinement levels
-    PackedBoolList isMovingPoint(mesh.nPoints());
+    bitSet isMovingPoint(mesh.nPoints());
 
     label nInterface = 0;
 
@@ -294,7 +294,7 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
     const indirectPrimitivePatch& pp = meshMover.patch();
 
     // Calculate geometrically non-manifold points on the patch to be moved.
-    PackedBoolList nonManifoldPoint(pp.nPoints());
+    bitSet nonManifoldPoint(pp.nPoints());
     label nNonManifoldPoints = getCollocatedPoints
     (
         SMALL,
@@ -324,7 +324,7 @@ Foam::tmp<Foam::pointField> Foam::snappySnapDriver::smoothPatchDisplacement
     const polyMesh& mesh = meshMover.mesh();
 
     // Get labels of faces to count (master of coupled faces and baffle pairs)
-    PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
+    bitSet isMasterFace(syncTools::getMasterFaces(mesh));
 
     {
         forAll(baffles, i)
@@ -1401,7 +1401,7 @@ void Foam::snappySnapDriver::detectNearSurfaces
     }
 
 
-    const PackedBoolList isPatchMasterPoint
+    const bitSet isPatchMasterPoint
     (
         meshRefinement::getMasterPoints
         (
@@ -2025,7 +2025,7 @@ Foam::vectorField Foam::snappySnapDriver::calcNearestSurface
         }
 
         {
-            const PackedBoolList isPatchMasterPoint
+            const bitSet isPatchMasterPoint
             (
                 meshRefinement::getMasterPoints
                 (
@@ -2245,7 +2245,7 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::snappySnapDriver::repatchToSurface
 
 
     // Faces that do not move
-    PackedBoolList isZonedFace(mesh.nFaces());
+    bitSet isZonedFace(mesh.nFaces());
     {
         // 1. Preserve faces in preserveFaces list
         forAll(preserveFaces, facei)
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.H b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.H
index fc39ea0963e7826608476ebb84a6a7eb6ef40d13..7072ba0683350f599cd90f0e079d9b54b7f5f43e 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.H
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriver.H
@@ -74,12 +74,12 @@ class snappySnapDriver
         // Snapping
 
             //- Calculates (geometric) shared points
-            //  Requires PackedBoolList to be sized and initialised
+            //  Requires bitSet to be sized and initialised
             static label getCollocatedPoints
             (
                 const scalar tol,
                 const pointField&,
-                PackedBoolList&
+                bitSet&
             );
 
             //- Calculate displacement (over all mesh points) to move points
@@ -196,13 +196,13 @@ class snappySnapDriver
                 (
                     const scalar featureCos,
                     const indirectPrimitivePatch& pp,
-                    const PackedBoolList& isFeatureEdge,
+                    const bitSet& isFeatureEdge,
                     const label pointi
                 ) const;
 
                 void smoothAndConstrain
                 (
-                    const PackedBoolList& isMasterEdge,
+                    const bitSet& isMasterEdge,
                     const indirectPrimitivePatch& pp,
                     const labelList& meshEdges,
                     const List<pointConstraint>& constraints,
@@ -401,7 +401,7 @@ class snappySnapDriver
                 void writeStats
                 (
                     const indirectPrimitivePatch& pp,
-                    const PackedBoolList& isMasterPoint,
+                    const bitSet& isMasterPoint,
                     const List<pointConstraint>& patchConstraints
                 ) const;
 
diff --git a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriverFeature.C b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriverFeature.C
index 3c73db529ba21fa238a35ba8972cb62f7d51ea92..b4c2dc996a521e66e490865723ab12a3afb8b33a 100644
--- a/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriverFeature.C
+++ b/src/mesh/snappyHexMesh/snappyHexMeshDriver/snappySnapDriverFeature.C
@@ -69,7 +69,7 @@ bool Foam::snappySnapDriver::isFeaturePoint
 (
     const scalar featureCos,
     const indirectPrimitivePatch& pp,
-    const PackedBoolList& isFeatureEdge,
+    const bitSet& isFeatureEdge,
     const label pointi
 ) const
 {
@@ -128,7 +128,7 @@ bool Foam::snappySnapDriver::isFeaturePoint
 
 void Foam::snappySnapDriver::smoothAndConstrain
 (
-    const PackedBoolList& isPatchMasterEdge,
+    const bitSet& isPatchMasterEdge,
     const indirectPrimitivePatch& pp,
     const labelList& meshEdges,
     const List<pointConstraint>& constraints,
@@ -271,7 +271,7 @@ void Foam::snappySnapDriver::calcNearestFace
                 << exit(FatalError);
         }
         const faceZone& fZone = mesh.faceZones()[zonei];
-        PackedBoolList isZonedFace(mesh.nFaces(), fZone);
+        bitSet isZonedFace(mesh.nFaces(), fZone);
 
         DynamicList<label> ppFaces(fZone.size());
         DynamicList<label> meshFaces(fZone.size());
@@ -456,7 +456,7 @@ void Foam::snappySnapDriver::calcNearestFacePointProperties
 {
     const fvMesh& mesh = meshRefiner_.mesh();
 
-    const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
+    const bitSet isMasterFace(syncTools::getMasterFaces(mesh));
 
 
     // For now just get all surrounding face data. Expensive - should just
@@ -558,7 +558,7 @@ void Foam::snappySnapDriver::calcNearestFacePointProperties
 
 
         // Mark all points on 'boundary' edges
-        PackedBoolList isBoundaryPoint(pp.nPoints());
+        bitSet isBoundaryPoint(pp.nPoints());
 
         const labelListList& edgeFaces = pp.edgeFaces();
         const edgeList& edges = pp.edges();
@@ -861,7 +861,7 @@ Foam::pointIndexHit Foam::snappySnapDriver::findMultiPatchPoint
 void Foam::snappySnapDriver::writeStats
 (
     const indirectPrimitivePatch& pp,
-    const PackedBoolList& isPatchMasterPoint,
+    const bitSet& isPatchMasterPoint,
     const List<pointConstraint>& patchConstraints
 ) const
 {
@@ -1430,7 +1430,7 @@ void Foam::snappySnapDriver::releasePointsNextToMultiPatch
 
 
     // 1. Mark points on multiple patches
-    PackedBoolList isMultiPatchPoint(pp.size());
+    bitSet isMultiPatchPoint(pp.size());
 
     forAll(pointFacePatchID, pointi)
     {
@@ -2855,7 +2855,7 @@ void Foam::snappySnapDriver::determineBaffleFeatures
 
 
     // Is edge on baffle
-    PackedBoolList isBaffleEdge(pp.nEdges());
+    bitSet isBaffleEdge(pp.nEdges());
     label nBaffleEdges = 0;
     // Is point on
     //  0 : baffle-edge (0)
@@ -3395,7 +3395,7 @@ void Foam::snappySnapDriver::featureAttractionUsingFeatureEdges
     const refinementFeatures& features = meshRefiner_.features();
     const fvMesh& mesh = meshRefiner_.mesh();
 
-    const PackedBoolList isPatchMasterPoint
+    const bitSet isPatchMasterPoint
     (
         meshRefinement::getMasterPoints
         (
@@ -3833,8 +3833,8 @@ Foam::vectorField Foam::snappySnapDriver::calcNearestSurfaceFeature
     const fvMesh& mesh = meshRefiner_.mesh();
 
 
-    //const PackedBoolList isMasterPoint(syncTools::getMasterPoints(mesh));
-    const PackedBoolList isPatchMasterPoint
+    //const bitSet isMasterPoint(syncTools::getMasterPoints(mesh));
+    const bitSet isPatchMasterPoint
     (
         meshRefinement::getMasterPoints
         (
@@ -4116,12 +4116,12 @@ Foam::vectorField Foam::snappySnapDriver::calcNearestSurfaceFeature
 
     if (featureAttract < 1-0.001)
     {
-        //const PackedBoolList isMasterEdge(syncTools::getMasterEdges(mesh));
+        //const bitSet isMasterEdge(syncTools::getMasterEdges(mesh));
         const labelList meshEdges
         (
             pp.meshEdges(mesh.edges(), mesh.pointEdges())
         );
-        const PackedBoolList isPatchMasterEdge
+        const bitSet isPatchMasterEdge
         (
             meshRefinement::getMasterEdges
             (
diff --git a/src/mesh/snappyHexMesh/trackedParticle/trackedParticle.H b/src/mesh/snappyHexMesh/trackedParticle/trackedParticle.H
index bb683ac52b7280841d97987cbb936a404d9cf2b9..2a30d95915695df7e0a3ea9137d9c3ca6223c93a 100644
--- a/src/mesh/snappyHexMesh/trackedParticle/trackedParticle.H
+++ b/src/mesh/snappyHexMesh/trackedParticle/trackedParticle.H
@@ -96,7 +96,7 @@ public:
 
         labelList& maxLevel_;
 
-        List<PackedBoolList>& featureEdgeVisited_;
+        List<bitSet>& featureEdgeVisited_;
 
 
         // Constructors
@@ -105,7 +105,7 @@ public:
             (
                 Cloud<trackedParticle>& cloud,
                 labelList& maxLevel,
-                List<PackedBoolList>& featureEdgeVisited
+                List<bitSet>& featureEdgeVisited
             )
             :
                 particle::trackingData(cloud),
diff --git a/src/meshTools/AABBTree/AABBTree.C b/src/meshTools/AABBTree/AABBTree.C
index 3ebd4805d1fc3301a61dc3db0a77eac8e460294b..3a5fbf14575ec458ab92eabda7c6010c25c88b13 100644
--- a/src/meshTools/AABBTree/AABBTree.C
+++ b/src/meshTools/AABBTree/AABBTree.C
@@ -25,7 +25,7 @@ License
 
 #include "AABBTree.H"
 #include "meshTools.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 //#include "OFstream.H"
 
 template<class Type>
@@ -157,7 +157,7 @@ void Foam::AABBTree<Type>::createBoxes
     {
         // Pick up points used by this set of objects
 
-        PackedBoolList isUsedPoint(points.size());
+        bitSet isUsedPoint(points.size());
         DynamicList<scalar> component(points.size());
 
         for (const label objI : objectIDs)
diff --git a/src/meshTools/algorithms/MeshWave/FaceCellWave.H b/src/meshTools/algorithms/MeshWave/FaceCellWave.H
index f86aab57d04a6b7d3d71284a1c02a845a501776e..e803a76aebf646efe61507b58077723c20d97817 100644
--- a/src/meshTools/algorithms/MeshWave/FaceCellWave.H
+++ b/src/meshTools/algorithms/MeshWave/FaceCellWave.H
@@ -47,7 +47,7 @@ SourceFiles
 #ifndef FaceCellWave_H
 #define FaceCellWave_H
 
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "DynamicList.H"
 #include "primitiveFieldsFwd.H"
 #include "labelPair.H"
@@ -106,13 +106,13 @@ protected:
         TrackingData& td_;
 
         //- Has face changed
-        PackedBoolList changedFace_;
+        bitSet changedFace_;
 
         //- List of changed faces
         DynamicList<label> changedFaces_;
 
         //- Has cell changed
-        PackedBoolList changedCell_;
+        bitSet changedCell_;
 
         // Cells that have changed
         DynamicList<label> changedCells_;
diff --git a/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.C b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.C
index 367fbfaa57786c33151c453ccc7e7c4cc3aac321..24a30b6864c3c2653f49bbda5aae01672744d5a7 100644
--- a/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.C
+++ b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.C
@@ -170,7 +170,7 @@ syncEdges()
 {
     const globalMeshData& globalData = mesh_.globalData();
     const mapDistribute& map = globalData.globalEdgeSlavesMap();
-    const PackedBoolList& cppOrientation = globalData.globalEdgeOrientation();
+    const bitSet& cppOrientation = globalData.globalEdgeOrientation();
 
     // Convert patch-edge data into cpp-edge data
     // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.H b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.H
index 7ef575b40205081f9435e5f049e97b343da27545..67ee9362f7113fd095de2505d03bb9accfdb2a25 100644
--- a/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.H
+++ b/src/meshTools/algorithms/PatchEdgeFaceWave/PatchEdgeFaceWave.H
@@ -37,8 +37,8 @@ SourceFiles
 #ifndef PatchEdgeFaceWave_H
 #define PatchEdgeFaceWave_H
 
+#include "bitSet.H"
 #include "scalarField.H"
-#include "PackedBoolList.H"
 #include "PrimitivePatch.H"
 #include "vectorTensorTransform.H"
 
@@ -101,13 +101,13 @@ class PatchEdgeFaceWave
         TrackingData& td_;
 
         //- Has edge changed
-        PackedBoolList changedEdge_;
+        bitSet changedEdge_;
 
         //- List of changed edges
         DynamicList<label> changedEdges_;
 
         //- Has face changed
-        PackedBoolList changedFace_;
+        bitSet changedFace_;
 
         //- List of changed faces
         DynamicList<label> changedFaces_;
@@ -123,7 +123,7 @@ class PatchEdgeFaceWave
         // Addressing between edges of patch_ and globalData.coupledPatch()
         labelList patchEdges_;
         labelList coupledEdges_;
-        PackedBoolList sameEdgeOrientation_;
+        bitSet sameEdgeOrientation_;
 
 
     // Private Member Functions
diff --git a/src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.H b/src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.H
index 6b2170787cca681e20ec5661f69e5650f36c698d..6da80f46e40b65359283947037d868e9e79668c9 100644
--- a/src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.H
+++ b/src/meshTools/algorithms/PointEdgeWave/PointEdgeWave.H
@@ -58,7 +58,7 @@ SourceFiles
 #ifndef PointEdgeWave_H
 #define PointEdgeWave_H
 
-#include "boolList.H"
+#include "bitSet.H"
 #include "scalarField.H"
 #include "tensorField.H"
 
@@ -114,7 +114,7 @@ class PointEdgeWave
         TrackingData& td_;
 
         //- Has point changed
-        boolList changedPoint_;
+        bitSet changedPoint_;
 
         //- List of changed points
         labelList changedPoints_;
@@ -123,7 +123,8 @@ class PointEdgeWave
         label nChangedPoints_;
 
         //- Edges that have changed
-        boolList changedEdge_;
+        bitSet changedEdge_;
+
         labelList changedEdges_;
         label nChangedEdges_;
 
diff --git a/src/meshTools/edgeMesh/edgeMesh.C b/src/meshTools/edgeMesh/edgeMesh.C
index de2a294f7d1f854d913e734a3f3f5027553fb403..8fe1542d6fa72f4e4b613f454b1170f3ad7f186a 100644
--- a/src/meshTools/edgeMesh/edgeMesh.C
+++ b/src/meshTools/edgeMesh/edgeMesh.C
@@ -29,7 +29,7 @@ License
 #include "addToMemberFunctionSelectionTable.H"
 #include "ListOps.H"
 #include "edgeHashes.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -237,7 +237,7 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
 void Foam::edgeMesh::mergeEdges()
 {
     edgeHashSet uniqEdges(2*edges_.size());
-    PackedBoolList pointIsUsed(points_.size());
+    bitSet pointIsUsed(points_.size());
 
     label nUniqEdges = 0;
     label nUniqPoints = 0;
diff --git a/src/meshTools/edgeMesh/edgeMeshFormats/nas/NASedgeFormat.C b/src/meshTools/edgeMesh/edgeMeshFormats/nas/NASedgeFormat.C
index 650db264fd5128f583674da2eb50c67d934712ec..2486581bab647da95c56a5eb84c29acba6cfd483 100644
--- a/src/meshTools/edgeMesh/edgeMeshFormats/nas/NASedgeFormat.C
+++ b/src/meshTools/edgeMesh/edgeMeshFormats/nas/NASedgeFormat.C
@@ -26,7 +26,7 @@ License
 #include "NASedgeFormat.H"
 #include "IFstream.H"
 #include "StringStream.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -173,7 +173,7 @@ bool Foam::fileFormats::NASedgeFormat::read
     }
 
     // note which points were really used and which can be culled
-    PackedBoolList usedPoints(points().size());
+    bitSet usedPoints(points().size());
 
 
     // Pass1: relabel edges
@@ -189,29 +189,25 @@ bool Foam::fileFormats::NASedgeFormat::read
     pointId.clearStorage();
     mapPointId.clear();
 
-    // Not all the points were used, cull them accordingly
-    if (unsigned(points().size()) != usedPoints.count())
+    // Not all points were used, subset/cull them accordingly
+    if (!usedPoints.all())
     {
         label nUsed = 0;
 
         pointField& pts = storedPoints();
-        forAll(pts, pointi)
+        for (const label pointi : usedPoints)
         {
-            if (usedPoints.test(pointi))
+            if (nUsed != pointi)
             {
-                if (nUsed != pointi)
-                {
-                    pts[nUsed] = pts[pointi];
-                }
+                pts[nUsed] = pts[pointi];
+            }
 
-                // map prev -> new id
-                mapPointId[pointi] = nUsed;
+            // map prev -> new id
+            mapPointId.set(pointi, nUsed);
 
-                ++nUsed;
-            }
+            ++nUsed;
         }
-
-        pts.setSize(nUsed);
+        pts.resize(nUsed);
 
         // Renumber edge vertices
         for (edge& e : dynEdges)
@@ -221,8 +217,6 @@ bool Foam::fileFormats::NASedgeFormat::read
         }
     }
 
-
-    // transfer to normal lists
     storedEdges().transfer(dynEdges);
 
     return true;
diff --git a/src/meshTools/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C b/src/meshTools/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C
index e9a7a09b167a7b72744b3de1160b90102ede0f3f..ac2be8188c66c6d4200fe7a0215a29720c85896e 100644
--- a/src/meshTools/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C
+++ b/src/meshTools/edgeMesh/edgeMeshFormats/starcd/STARCDedgeFormat.C
@@ -26,7 +26,7 @@ License
 #include "STARCDedgeFormat.H"
 #include "ListOps.H"
 #include "clock.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "StringStream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -132,7 +132,7 @@ bool Foam::fileFormats::STARCDedgeFormat::read
     pointId.clear();
 
     // note which points were really used and which can be culled
-    PackedBoolList usedPoints(points().size());
+    bitSet usedPoints(points().size());
 
     //
     // read .cel file
@@ -187,31 +187,27 @@ bool Foam::fileFormats::STARCDedgeFormat::read
 
     mapPointId.clear();
 
-    // not all the points were used, cull them accordingly
-    if (unsigned(points().size()) != usedPoints.count())
+    // Not all points were used, subset/cull them accordingly
+    if (!usedPoints.all())
     {
         label nUsed = 0;
 
         pointField& pts = storedPoints();
-        forAll(pts, pointi)
+        for (const label pointi : usedPoints)
         {
-            if (usedPoints.test(pointi))
+            if (nUsed != pointi)
             {
-                if (nUsed != pointi)
-                {
-                    pts[nUsed] = pts[pointi];
-                }
+                pts[nUsed] = pts[pointi];
+            }
 
-                // map prev -> new id
-                mapPointId.set(pointi, nUsed);
+            // map prev -> new id
+            mapPointId.set(pointi, nUsed);
 
-                ++nUsed;
-            }
+            ++nUsed;
         }
+        pts.resize(nUsed);
 
-        pts.setSize(nUsed);
-
-        // renumber edge vertices
+        // Renumber edge vertices
         forAll(dynEdges, edgeI)
         {
             edge& e = dynEdges[edgeI];
@@ -221,7 +217,6 @@ bool Foam::fileFormats::STARCDedgeFormat::read
         }
     }
 
-
     storedEdges().transfer(dynEdges);
 
     return true;
diff --git a/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C b/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C
index 6ae082b0bca2936719f42e4a3800b5913160db7c..f1e4964867628db852941a35c8d765dc294edf3b 100644
--- a/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C
+++ b/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMesh.C
@@ -1481,7 +1481,7 @@ void Foam::extendedEdgeMesh::autoMap
     // Compact region edges
     labelList subRegionEdges;
     {
-        PackedBoolList isRegionEdge(edges().size(), regionEdges());
+        bitSet isRegionEdge(edges().size(), regionEdges());
 
         DynamicList<label> newRegionEdges(regionEdges().size());
         forAll(edgeMap, subEdgeI)
@@ -1525,7 +1525,7 @@ void Foam::extendedEdgeMesh::autoMap
     DynamicList<label> normalMap(normals().size());
 
     {
-        PackedBoolList isSubNormal(normals().size());
+        bitSet isSubNormal(normals().size());
         for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
         {
             label pointI = pointMap[subPointI];
diff --git a/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMeshTemplates.C b/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMeshTemplates.C
index 69dca97cc65de260ad1ec1955369f88db5b03864..201a5c94a03191b01e9ad692b4b0ecb5d078d946 100644
--- a/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMeshTemplates.C
+++ b/src/meshTools/edgeMesh/extendedEdgeMesh/extendedEdgeMeshTemplates.C
@@ -26,7 +26,7 @@ License
 #include "extendedEdgeMesh.H"
 #include "ListListOps.H"
 #include "unitConversion.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "PatchTools.H"
 #include "searchableBox.H"
 
@@ -98,7 +98,7 @@ void Foam::extendedEdgeMesh::sortPointsAndEdges
     // All feature points have been added
     nonFeatureStart_ = tmpPts.size();
 
-    PackedBoolList isRegionFeatureEdge(regionFeatureEdges);
+    bitSet isRegionFeatureEdge(regionFeatureEdges);
 
     forAll(featureEdges, i)
     {
diff --git a/src/meshTools/edgeMesh/extendedEdgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshTemplates.C b/src/meshTools/edgeMesh/extendedEdgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshTemplates.C
index 3edfff99b98ed8f9c3961f2a6281f5f142f031e3..25de27b330ac37a46cdf7785a67d365b94a07d23 100644
--- a/src/meshTools/edgeMesh/extendedEdgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshTemplates.C
+++ b/src/meshTools/edgeMesh/extendedEdgeMesh/extendedFeatureEdgeMesh/extendedFeatureEdgeMeshTemplates.C
@@ -26,7 +26,7 @@ License
 #include "extendedFeatureEdgeMesh.H"
 #include "ListListOps.H"
 #include "unitConversion.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "PatchTools.H"
 #include "searchableBox.H"
 
@@ -98,7 +98,7 @@ void Foam::extendedFeatureEdgeMesh::sortPointsAndEdges
     // All feature points have been added
     nonFeatureStart_ = tmpPts.size();
 
-    PackedBoolList isRegionFeatureEdge(regionFeatureEdges);
+    bitSet isRegionFeatureEdge(regionFeatureEdges);
 
     forAll(featureEdges, i)
     {
diff --git a/src/meshTools/indexedOctree/treeDataFace.H b/src/meshTools/indexedOctree/treeDataFace.H
index 8eba1732bf322ef76c810e00e0ce89226de7b2b9..32bc97d462d1e25c0241461c7d9165819d81260f 100644
--- a/src/meshTools/indexedOctree/treeDataFace.H
+++ b/src/meshTools/indexedOctree/treeDataFace.H
@@ -38,7 +38,7 @@ SourceFiles
 #include "face.H"
 #include "indexedOctree.H"
 #include "treeBoundBoxList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "primitiveMesh.H"
 #include "volumeType.H"
 
@@ -72,7 +72,7 @@ class treeDataFace
         const labelList faceLabels_;
 
         //- Inverse of faceLabels. For every mesh whether face is in faceLabels.
-        PackedBoolList isTreeFace_;
+        bitSet isTreeFace_;
 
         //- Whether to precalculate and store face bounding box
         const bool cacheBb_;
diff --git a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
index 51cbd79966ee85ba8cb1230979b557747aeed650..97fe0ab615c46233e5cbef3a23fa0299a302439b 100644
--- a/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
+++ b/src/meshTools/mappedPatches/mappedPolyPatch/mappedPatchBase.C
@@ -716,7 +716,7 @@ void Foam::mappedPatchBase::calcMapping() const
     if (debug)
     {
         // Check that all elements get a value.
-        PackedBoolList used(patch_.size());
+        bitSet used(patch_.size());
         forAll(constructMap, proci)
         {
             const labelList& map = constructMap[proci];
diff --git a/src/meshTools/regionSplit/regionSplit.C b/src/meshTools/regionSplit/regionSplit.C
index d826a25d1571676e8435ac16c84ac9487fc6c243..a901e8d763b054ddbb7c3dd3bfd6c50929989e81 100644
--- a/src/meshTools/regionSplit/regionSplit.C
+++ b/src/meshTools/regionSplit/regionSplit.C
@@ -67,10 +67,10 @@ void Foam::regionSplit::calcNonCompactRegionSplit
     // Seed all faces on (real) boundaries and cell faces next to blockFace,
     // since regions can only occur because of boundaries (or blocked faces)
 
-    PackedBoolList isSeed(mesh().nFaces());
+    bitSet isSeed(mesh().nFaces());
 
     // Get internal or coupled faces
-    PackedBoolList isConnection(syncTools::getInternalOrCoupledFaces(mesh()));
+    bitSet isConnection(syncTools::getInternalOrCoupledFaces(mesh()));
 
     // 1. Seed (real) boundaries
     for
@@ -145,7 +145,7 @@ void Foam::regionSplit::calcNonCompactRegionSplit
         }
     }
 
-    List<label> seedFaces(isSeed.used());
+    List<label> seedFaces(isSeed.toc());
     List<minData> seedData(seedFaces.size());
 
     // Seed face with globally unique number
diff --git a/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.C b/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.C
index e8cbde14c5c5483d1fe185b3891bcc6afbcda571..b8e633b9f8587d74f940cb2440096619c6e94a59 100644
--- a/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.C
+++ b/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.C
@@ -57,7 +57,7 @@ Foam::topoSetSource::addToUsageTable Foam::targetVolumeToCell::usage_
 
 Foam::scalar Foam::targetVolumeToCell::volumeOfSet
 (
-    const PackedBoolList& selected
+    const bitSet& selected
 ) const
 {
     scalar sumVol = 0.0;
@@ -76,8 +76,8 @@ Foam::scalar Foam::targetVolumeToCell::volumeOfSet
 Foam::label Foam::targetVolumeToCell::selectCells
 (
     const scalar normalComp,
-    const PackedBoolList& maskSet,
-    PackedBoolList& selected
+    const bitSet& maskSet,
+    bitSet& selected
 ) const
 {
     selected.resize(mesh_.nCells());
@@ -89,7 +89,7 @@ Foam::label Foam::targetVolumeToCell::selectCells
     {
         const point& cc = mesh_.cellCentres()[celli];
 
-        if (maskSet[celli] && ((cc&n_) < normalComp))
+        if (maskSet.test(celli) && ((cc&n_) < normalComp))
         {
             selected.set(celli);
             nSelected++;
@@ -108,7 +108,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
     }
 
 
-    PackedBoolList maskSet(mesh_.nCells(), true);
+    bitSet maskSet(mesh_.nCells(), true);
     label nTotCells = mesh_.globalData().nTotalCells();
     if (maskSetName_.size())
     {
@@ -157,7 +157,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
             }
         }
 
-        PackedBoolList maxSelected(mesh_.nCells());
+        bitSet maxSelected(mesh_.nCells());
         maxCells = selectCells(maxComp, maskSet, maxSelected);
         //maxVol = volumeOfSet(maxSelected);
 
@@ -177,7 +177,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
     // Bisection
     // ~~~~~~~~~
 
-    PackedBoolList selected(mesh_.nCells());
+    bitSet selected(mesh_.nCells());
     label nSelected = -1;
     scalar selectedVol = 0.0;
     //scalar selectedComp = 0.0;
@@ -204,7 +204,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
         {
             low = mid;
 
-            PackedBoolList highSelected(mesh_.nCells());
+            bitSet highSelected(mesh_.nCells());
             label nHigh = selectCells(high, maskSet, selected);
             if (nSelected == nHigh)
             {
@@ -215,7 +215,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
         {
             high = mid;
 
-            PackedBoolList lowSelected(mesh_.nCells());
+            bitSet lowSelected(mesh_.nCells());
             label nLow = selectCells(low, maskSet, selected);
             if (nSelected == nLow)
             {
@@ -259,7 +259,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
 
     forAll(selected, celli)
     {
-        if (selected[celli])
+        if (selected.test(celli))
         {
             addOrDelete(set, celli, add);
         }
diff --git a/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.H b/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.H
index 076f15e8aaea719228d510c913fbf287ff695dbd..ee350de5223e3c3a7bba941978781c2f101d2d97 100644
--- a/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.H
+++ b/src/meshTools/sets/cellSources/targetVolumeToCell/targetVolumeToCell.H
@@ -37,7 +37,7 @@ SourceFiles
 #define targetVolumeToCell_H
 
 #include "topoSetSource.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -70,13 +70,13 @@ class targetVolumeToCell
 
     // Private Member Functions
 
-        scalar volumeOfSet(const PackedBoolList&) const;
+        scalar volumeOfSet(const bitSet&) const;
 
         label selectCells
         (
             const scalar normalComp,
-            const PackedBoolList&,
-            PackedBoolList& selected
+            const bitSet&,
+            bitSet& selected
         ) const;
 
         void combine(topoSet& set, const bool add) const;
diff --git a/src/meshTools/sets/faceSources/regionToFace/regionToFace.H b/src/meshTools/sets/faceSources/regionToFace/regionToFace.H
index 7a8bef8482ad06651dd379ac724d5ac5a6265f48..e35f38b1062bdc8cb713c40430f7d100e725a67c 100644
--- a/src/meshTools/sets/faceSources/regionToFace/regionToFace.H
+++ b/src/meshTools/sets/faceSources/regionToFace/regionToFace.H
@@ -37,7 +37,7 @@ SourceFiles
 #define regionToFace_H
 
 #include "topoSetSource.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "indirectPrimitivePatch.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/meshTools/sets/topoSets/faceZoneSet.C b/src/meshTools/sets/topoSets/faceZoneSet.C
index 1f7d2d103913c2416fc9f70e0c462a61e7b43a4d..2227813dd23435f8be65913f8236f125d6bd421e 100644
--- a/src/meshTools/sets/topoSets/faceZoneSet.C
+++ b/src/meshTools/sets/topoSets/faceZoneSet.C
@@ -383,7 +383,7 @@ void Foam::faceZoneSet::sync(const polyMesh& mesh)
     syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
 
 
-    const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
+    const bitSet isMasterFace(syncTools::getMasterFaces(mesh));
 
 
     // Rebuild faceZone addressing and flipMap
diff --git a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C
index 7ed11e09bdb724fcec4f0beb49724976097e9713..c79da8b2d25e5991469adf66babecae719a8638f 100644
--- a/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C
+++ b/src/meshTools/triSurface/booleanOps/surfaceIntersection/surfaceIntersection.C
@@ -27,7 +27,7 @@ License
 #include "triSurfaceSearch.H"
 #include "OBJstream.H"
 #include "labelPairHashes.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "triSurface.H"
 #include "pointIndexHit.H"
 #include "mergePoints.H"
@@ -820,7 +820,7 @@ void Foam::surfaceIntersection::doCutEdges
 
         // Optionally prevent intersection within a single region.
         // Like self-intersect, but only if regions are different
-        PackedBoolList maskRegions(32);
+        bitSet maskRegions(32);
 
         treeDataTriSurface::findAllIntersectOp
             allIntersectOp(searchTree, maskFaces);
diff --git a/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C b/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C
index ed0c88a43e4448c98050d889450940d966860d7e..c2eb7468029627fb87bf4843ff84ffb3703e818b 100644
--- a/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C
+++ b/src/overset/cellCellStencil/cellVolumeWeight/cellVolumeWeightCellCellStencil.C
@@ -61,8 +61,8 @@ void Foam::cellCellStencils::cellVolumeWeight::walkFront
 ) const
 {
     // Current front
-    PackedBoolList isFront(mesh_.nFaces());
-    // unused: PackedBoolList doneCell(mesh_.nCells());
+    bitSet isFront(mesh_.nFaces());
+    // unused: bitSet doneCell(mesh_.nCells());
 
     const fvBoundaryMesh& fvm = mesh_.boundary();
 
@@ -143,7 +143,7 @@ void Foam::cellCellStencils::cellVolumeWeight::walkFront
             << " size:" << returnReduce(isFront.count(), sumOp<label>())
             << endl;
 
-        PackedBoolList newIsFront(mesh_.nFaces());
+        bitSet newIsFront(mesh_.nFaces());
         forAll(isFront, faceI)
         {
             if (isFront.test(faceI))
diff --git a/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C b/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C
index 8288eec83ebeedae13ac5b28225669dfe1d70194..576b269ad682c1110c6c778985d1fff6305463c6 100644
--- a/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C
+++ b/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.C
@@ -1173,7 +1173,7 @@ void Foam::cellCellStencils::inverseDistance::seedCell
 (
     const label cellI,
     const scalar wantedFraction,
-    PackedBoolList& isFront,
+    bitSet& isFront,
     scalarField& fraction
 ) const
 {
@@ -1199,7 +1199,7 @@ void Foam::cellCellStencils::inverseDistance::walkFront
 ) const
 {
     // Current front
-    PackedBoolList isFront(mesh_.nFaces());
+    bitSet isFront(mesh_.nFaces());
 
     const fvBoundaryMesh& fvm = mesh_.boundary();
 
@@ -1286,10 +1286,10 @@ void Foam::cellCellStencils::inverseDistance::walkFront
     }
 
 
-    while (returnReduce(isFront.count(), sumOp<label>()))
+    while (returnReduce(isFront.any(), orOp<bool>()))
     {
         // Interpolate cells on front
-        PackedBoolList newIsFront(mesh_.nFaces());
+        bitSet newIsFront(mesh_.nFaces());
         scalarField newFraction(fraction);
         forAll(isFront, faceI)
         {
@@ -1435,7 +1435,7 @@ void Foam::cellCellStencils::inverseDistance::createStencil
     const vector greatPoint(GREAT, GREAT, GREAT);
 
     // Has acceptor been handled already?
-    PackedBoolList doneAcceptor(interpolationCells_.size());
+    bitSet doneAcceptor(interpolationCells_.size());
 
     while (true)
     {
diff --git a/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.H b/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.H
index 1a57c6034048986a1a4d0dc5be6a4d2c17cbacda..9b140b4ce65d4ee680a4b5c81a6c6a3f1e41eca1 100644
--- a/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.H
+++ b/src/overset/cellCellStencil/inverseDistance/inverseDistanceCellCellStencil.H
@@ -229,7 +229,7 @@ protected:
         (
             const label cellI,
             const scalar wantedFraction,
-            PackedBoolList& isFront,
+            bitSet& isFront,
             scalarField& fraction
         ) const;
 
diff --git a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C
index 8cd1e1733d48554c31a7891c722a3b2385907a19..c78d329a6696fde204a912dedc78ada9dc4484c2 100644
--- a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C
+++ b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C
@@ -36,7 +36,7 @@ License
 #include "decompositionMethod.H"
 #include "geomDecomp.H"
 #include "vectorList.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "PatchTools.H"
 #include "OBJstream.H"
 
diff --git a/src/sampling/sampledSurface/sampledPlane/sampledPlane.C b/src/sampling/sampledSurface/sampledPlane/sampledPlane.C
index ed7babbb0040c28f22422f7e3153ca2d32c9af61..32a1892fd30d5ec4ad08b2e4021cf79b8c05b4d7 100644
--- a/src/sampling/sampledSurface/sampledPlane/sampledPlane.C
+++ b/src/sampling/sampledSurface/sampledPlane/sampledPlane.C
@@ -170,7 +170,7 @@ bool Foam::sampledPlane::update()
             << nl << endl;
     }
 
-    labelList selectedCells = mesh().cellZones().findMatching(zoneKey_).used();
+    labelList selectedCells(mesh().cellZones().findMatching(zoneKey_).toc());
 
     bool fullMesh = returnReduce(selectedCells.empty(), andOp<bool>());
 
diff --git a/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C
index e059bc71a191f2d21bdc8d8a9e4b41f56bf388d8..99f81cc4dffe5a2a801a9efc300d5f3b9da426d4 100644
--- a/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C
+++ b/src/sampling/surfMeshSampler/plane/surfMeshPlaneSampler.C
@@ -184,8 +184,10 @@ bool Foam::surfMeshPlaneSampler::update()
             << nl << endl;
     }
 
-
-    labelList selectedCells = mesh().cellZones().findMatching(zoneKey_).used();
+    labelList selectedCells
+    (
+        mesh().cellZones().findMatching(zoneKey_).sortedToc()
+    );
 
     bool fullMesh = returnReduce(selectedCells.empty(), andOp<bool>());
     if (!bounds_.empty())
diff --git a/src/sampling/surface/isoSurface/isoSurface.C b/src/sampling/surface/isoSurface/isoSurface.C
index 42a5ac377ed038b388dc7d96e5b1b8ac65b2dc08..eee98b35a6d53c942a8f7d655541ddbe1679160c 100644
--- a/src/sampling/surface/isoSurface/isoSurface.C
+++ b/src/sampling/surface/isoSurface/isoSurface.C
@@ -80,13 +80,13 @@ bool Foam::isoSurface::collocatedPatch(const polyPatch& pp)
 }
 
 
-Foam::PackedBoolList Foam::isoSurface::collocatedFaces
+Foam::bitSet Foam::isoSurface::collocatedFaces
 (
     const coupledPolyPatch& pp
 ) const
 {
     // Initialise to false
-    PackedBoolList collocated(pp.size());
+    bitSet collocated(pp.size());
 
     if (isA<processorPolyPatch>(pp))
     {
@@ -671,7 +671,7 @@ void Foam::isoSurface::calcSnappedCc
 
 void Foam::isoSurface::calcSnappedPoint
 (
-    const PackedBoolList& isBoundaryPoint,
+    const bitSet& isBoundaryPoint,
     const labelList& boundaryRegion,
     const volVectorField& meshC,
     const volScalarField& cVals,
@@ -1403,7 +1403,7 @@ Foam::isoSurface::isoSurface
                 meshC.boundaryField()[patchi]
             );
 
-            PackedBoolList isCollocated
+            bitSet isCollocated
             (
                 collocatedFaces(refCast<const coupledPolyPatch>(pp))
             );
@@ -1504,7 +1504,7 @@ Foam::isoSurface::isoSurface
     if (regularise_)
     {
         // Determine if point is on boundary.
-        PackedBoolList isBoundaryPoint(mesh_.nPoints());
+        bitSet isBoundaryPoint(mesh_.nPoints());
 
         forAll(patches, patchi)
         {
@@ -1519,7 +1519,7 @@ Foam::isoSurface::isoSurface
                         patches[patchi]
                     );
 
-                PackedBoolList isCollocated(collocatedFaces(cpp));
+                bitSet isCollocated(collocatedFaces(cpp));
 
                 forAll(isCollocated, i)
                 {
diff --git a/src/sampling/surface/isoSurface/isoSurface.H b/src/sampling/surface/isoSurface/isoSurface.H
index c23044744e9a65586a232c73bb3d4c8f0380e376..70dbd615606c112e38058b60bd90b7dce6fe4207 100644
--- a/src/sampling/surface/isoSurface/isoSurface.H
+++ b/src/sampling/surface/isoSurface/isoSurface.H
@@ -64,7 +64,7 @@ SourceFiles
 #ifndef isoSurface_H
 #define isoSurface_H
 
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "volFields.H"
 #include "slicedVolFields.H"
 #include "MeshedSurface.H"
@@ -165,7 +165,7 @@ class isoSurface
             static bool collocatedPatch(const polyPatch&);
 
             //- Per face whether is collocated
-            PackedBoolList collocatedFaces(const coupledPolyPatch&) const;
+            bitSet collocatedFaces(const coupledPolyPatch&) const;
 
             //- Synchonise points on all non-separated coupled patches
             void syncUnseparatedPoints
@@ -231,7 +231,7 @@ class isoSurface
         //  point.
         void calcSnappedPoint
         (
-            const PackedBoolList& isBoundaryPoint,
+            const bitSet& isBoundaryPoint,
             const labelList& boundaryRegion,
             const volVectorField& meshC,
             const volScalarField& cVals,
diff --git a/src/sampling/surface/isoSurface/isoSurfaceCell.C b/src/sampling/surface/isoSurface/isoSurfaceCell.C
index 7a750e9e04b6fa927fa4924e5d54dc5d9717aa12..8e394b6df6c5b8b150e9772a5c1ec8365921fe16 100644
--- a/src/sampling/surface/isoSurface/isoSurfaceCell.C
+++ b/src/sampling/surface/isoSurface/isoSurfaceCell.C
@@ -81,7 +81,7 @@ bool Foam::isoSurfaceCell::isTriCut
 
 Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
 (
-    const PackedBoolList& isTet,
+    const bitSet& isTet,
     const scalarField& cellValues,
     const scalarField& pointValues,
     const label celli
@@ -192,7 +192,7 @@ Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
 
 void Foam::isoSurfaceCell::calcCutTypes
 (
-    const PackedBoolList& isTet,
+    const bitSet& isTet,
     const scalarField& cVals,
     const scalarField& pVals
 )
@@ -360,7 +360,7 @@ Foam::pointIndexHit Foam::isoSurfaceCell::collapseSurface
 
 void Foam::isoSurfaceCell::calcSnappedCc
 (
-    const PackedBoolList& isTet,
+    const bitSet& isTet,
     const scalarField& cVals,
     const scalarField& pVals,
 
@@ -685,7 +685,7 @@ void Foam::isoSurfaceCell::genPointTris
 
 void Foam::isoSurfaceCell::calcSnappedPoint
 (
-    const PackedBoolList& isTet,
+    const bitSet& isTet,
     const scalarField& cVals,
     const scalarField& pVals,
 
@@ -695,7 +695,7 @@ void Foam::isoSurfaceCell::calcSnappedPoint
 {
     // Determine if point is on boundary. Points on boundaries are never
     // snapped. Coupled boundaries are handled explicitly so not marked here.
-    PackedBoolList isBoundaryPoint(mesh_.nPoints());
+    bitSet isBoundaryPoint(mesh_.nPoints());
     const polyBoundaryMesh& patches = mesh_.boundaryMesh();
     forAll(patches, patchi)
     {
@@ -1319,7 +1319,7 @@ Foam::isoSurfaceCell::isoSurfaceCell
     }
 
     // Determine if cell is tet
-    PackedBoolList isTet(mesh_.nCells());
+    bitSet isTet(mesh_.nCells());
     {
         tetMatcher tet;
 
diff --git a/src/sampling/surface/isoSurface/isoSurfaceCell.H b/src/sampling/surface/isoSurface/isoSurfaceCell.H
index 1332102c6c0ed50ba037c9509389fde709a4c88d..9917ce23d5d3ad91e44cec2b94444e123dbb515f 100644
--- a/src/sampling/surface/isoSurface/isoSurfaceCell.H
+++ b/src/sampling/surface/isoSurface/isoSurfaceCell.H
@@ -47,7 +47,7 @@ SourceFiles
 
 #include "labelPair.H"
 #include "pointIndexHit.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "boundBox.H"
 #include "MeshedSurface.H"
 #include "MeshedSurfacesFwd.H"
@@ -146,7 +146,7 @@ class isoSurfaceCell
         //- Determine whether cell is cut
         cellCutType calcCutType
         (
-            const PackedBoolList&,
+            const bitSet&,
             const scalarField& cellValues,
             const scalarField& pointValues,
             const label
@@ -154,7 +154,7 @@ class isoSurfaceCell
 
         void calcCutTypes
         (
-            const PackedBoolList&,
+            const bitSet&,
             const scalarField& cellValues,
             const scalarField& pointValues
         );
@@ -182,7 +182,7 @@ class isoSurfaceCell
         //  point.
         void calcSnappedCc
         (
-            const PackedBoolList& isTet,
+            const bitSet& isTet,
             const scalarField& cVals,
             const scalarField& pVals,
             DynamicList<point>& triPoints,
@@ -214,7 +214,7 @@ class isoSurfaceCell
         //  point.
         void calcSnappedPoint
         (
-            const PackedBoolList& isTet,
+            const bitSet& isTet,
             const scalarField& cVals,
             const scalarField& pVals,
             DynamicList<point>& triPoints,
diff --git a/src/sampling/surface/isoSurface/isoSurfaceTemplates.C b/src/sampling/surface/isoSurface/isoSurfaceTemplates.C
index af0de2ef93a721e7f9600f5c3eadf909f7815d3f..c64ce9b34e0a437f989a43d39ed8f8b14aba7732 100644
--- a/src/sampling/surface/isoSurface/isoSurfaceTemplates.C
+++ b/src/sampling/surface/isoSurface/isoSurfaceTemplates.C
@@ -132,7 +132,7 @@ Foam::isoSurface::adaptPatchFields
                 w*pfld.patchInternalField()
               + (1.0-w)*pfld.patchNeighbourField();
 
-            PackedBoolList isCollocated
+            bitSet isCollocated
             (
                 collocatedFaces(refCast<const processorPolyPatch>(pp))
             );
@@ -636,7 +636,7 @@ void Foam::isoSurface::generateTriPoints
             const processorPolyPatch& cpp =
                 refCast<const processorPolyPatch>(pp);
 
-            PackedBoolList isCollocated(collocatedFaces(cpp));
+            bitSet isCollocated(collocatedFaces(cpp));
 
             forAll(isCollocated, i)
             {
diff --git a/src/surfMesh/triSurface/triSurface.C b/src/surfMesh/triSurface/triSurface.C
index d66271b6d9c82ea44b5a1de6e30fec3a4c495689..6cb9a7f120359bfd910a8abd7c2352403e33b431 100644
--- a/src/surfMesh/triSurface/triSurface.C
+++ b/src/surfMesh/triSurface/triSurface.C
@@ -175,8 +175,7 @@ void Foam::triSurface::checkTriangles(const bool verbose)
     // Done to keep numbering constant in phase 1
 
     // List of valid triangles
-    boolList valid(size(), true);
-    bool hasInvalid = false;
+    bitSet valid(size(), true);
 
     forAll(*this, facei)
     {
@@ -185,8 +184,7 @@ void Foam::triSurface::checkTriangles(const bool verbose)
         if ((f[0] == f[1]) || (f[0] == f[2]) || (f[1] == f[2]))
         {
             // 'degenerate' triangle check
-            valid[facei] = false;
-            hasInvalid = true;
+            valid.unset(facei);
 
             if (verbose)
             {
@@ -222,8 +220,7 @@ void Foam::triSurface::checkTriangles(const bool verbose)
                          && ((f[2] == n[0]) || (f[2] == n[1]) || (f[2] == n[2]))
                         )
                         {
-                            valid[facei] = false;
-                            hasInvalid = true;
+                            valid.unset(facei);
 
                             if (verbose)
                             {
@@ -247,17 +244,13 @@ void Foam::triSurface::checkTriangles(const bool verbose)
         }
     }
 
-    if (hasInvalid)
+    if (!valid.all())
     {
-        // Pack
+        // Compact
         label newFacei = 0;
-        forAll(*this, facei)
+        for (const label facei : valid)
         {
-            if (valid[facei])
-            {
-                const labelledTri& f = (*this)[facei];
-                (*this)[newFacei++] = f;
-            }
+            (*this)[newFacei++] = (*this)[facei];
         }
 
         if (verbose)
@@ -789,7 +782,7 @@ void Foam::triSurface::subsetMeshMap
 
     pointMap.setSize(nPoints());
 
-    boolList pointHad(nPoints(), false);
+    bitSet pointHad(nPoints(), false);
 
     forAll(include, oldFacei)
     {
@@ -803,9 +796,8 @@ void Foam::triSurface::subsetMeshMap
 
             for (const label verti : f)
             {
-                if (!pointHad[verti])
+                if (pointHad.set(verti))
                 {
-                    pointHad[verti] = true;
                     pointMap[pointi++] = verti;
                 }
             }
diff --git a/src/surfMesh/triSurface/triSurfaceIO.C b/src/surfMesh/triSurface/triSurfaceIO.C
index c822da2d4d31cecb1d61b98a25e5fe5550a0828e..7d3154f416b10f36bc555f6a4ef572d42b2c25ed 100644
--- a/src/surfMesh/triSurface/triSurfaceIO.C
+++ b/src/surfMesh/triSurface/triSurfaceIO.C
@@ -27,7 +27,7 @@ License
 #include "Fstream.H"
 #include "Time.H"
 #include "boundBox.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 #include "surfZoneList.H"
 #include "surfaceFormatsCore.H"
 #include "MeshedSurfaceProxy.H"
@@ -326,7 +326,7 @@ void Foam::triSurface::writeStats(Ostream& os) const
 {
     // Unfortunately nPoints constructs meshPoints() so do compact version
     // ourselves.
-    PackedBoolList pointIsUsed(points().size());
+    bitSet pointIsUsed(points().size());
 
     label nPoints = 0;
     boundBox bb(boundBox::invertedBox);
diff --git a/src/surfMesh/triSurface/triSurfaceStitch.C b/src/surfMesh/triSurface/triSurfaceStitch.C
index 1a345cac052b0f4a16d62785302b2fd40e78ea4c..47e47f28b2201020eee5711c187eaf35001c1384 100644
--- a/src/surfMesh/triSurface/triSurfaceStitch.C
+++ b/src/surfMesh/triSurface/triSurfaceStitch.C
@@ -25,7 +25,7 @@ License
 
 #include "triSurface.H"
 #include "mergePoints.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
@@ -101,7 +101,7 @@ bool Foam::triSurface::stitchTriangles
             // Done in two passes to save memory (pointField)
 
             // 1. Detect only
-            PackedBoolList pointIsUsed(ps.size());
+            bitSet pointIsUsed(ps.size());
 
             label nPoints = 0;
 
diff --git a/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.C b/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.C
index fdac5fa958c22d175c04c40470a9e08897f01c87..fd8b9d8a34e0d08c98e3470860a62a94d3e264e8 100644
--- a/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.C
+++ b/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.C
@@ -88,7 +88,7 @@ bool Foam::rawTopoChangerFvMesh::update()
         // - patch faces created out of previously internal faces
 
         // Is face mapped in any way?
-        PackedBoolList mappedFace(nFaces());
+        bitSet mappedFace(nFaces());
 
         const label nOldInternal = topoChangeMap().oldPatchStarts()[0];
 
diff --git a/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.H b/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.H
index 7364a4882a53d326e3c3fe5827202defc96640f0..4a81430a7ea5cf03041363b76723c5c9ce367228 100644
--- a/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.H
+++ b/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMesh.H
@@ -39,7 +39,7 @@ SourceFiles
 #define rawTopoChangerFvMesh_H
 
 #include "topoChangerFvMesh.H"
-#include "PackedBoolList.H"
+#include "bitSet.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -63,12 +63,12 @@ class rawTopoChangerFvMesh
         static void setUnmappedValues
         (
             GeometricField<Type, PatchField, GeoMesh>& fld,
-            const PackedBoolList& mappedFace,
+            const bitSet& mappedFace,
             const GeometricField<Type, PatchField, GeoMesh>& baseFld
         );
 
         template<class Type, template<class> class PatchField, class GeoMesh>
-        void zeroUnmappedValues(const PackedBoolList& mappedFace) const;
+        void zeroUnmappedValues(const bitSet& mappedFace) const;
 
         //- Disallow default bitwise copy construct
         rawTopoChangerFvMesh(const rawTopoChangerFvMesh&);
diff --git a/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMeshTemplates.C b/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMeshTemplates.C
index e88c55d8a49a5c534a0574869f12e1c18a93de62..bd52ee04aeb0f79447beaeeb593b2a39fd2f41dd 100644
--- a/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMeshTemplates.C
+++ b/src/topoChangerFvMesh/rawTopoChangerFvMesh/rawTopoChangerFvMeshTemplates.C
@@ -32,7 +32,7 @@ template<class Type, template<class> class PatchField, class GeoMesh>
 void Foam::rawTopoChangerFvMesh::setUnmappedValues
 (
     GeometricField<Type, PatchField, GeoMesh>& fld,
-    const PackedBoolList& mappedFace,
+    const bitSet& mappedFace,
     const GeometricField<Type, PatchField, GeoMesh>& baseFld
 )
 {
@@ -64,7 +64,7 @@ void Foam::rawTopoChangerFvMesh::setUnmappedValues
 template<class Type, template<class> class PatchField, class GeoMesh>
 void Foam::rawTopoChangerFvMesh::zeroUnmappedValues
 (
-    const PackedBoolList& mappedFace
+    const bitSet& mappedFace
 ) const
 {
     typedef GeometricField<Type, PatchField, GeoMesh> FieldType;