diff --git a/applications/test/DLList/Test-DLList.C b/applications/test/DLList/Test-DLList.C
index 8e653c4b20cbee9eb78060e720003139bdee5269..268c8b3ed1e0c89c1291a7862b2ecec511f4e826 100644
--- a/applications/test/DLList/Test-DLList.C
+++ b/applications/test/DLList/Test-DLList.C
@@ -56,7 +56,6 @@ int main(int argc, char *argv[])
         Info<< "element:" << *iter << endl;
     }
 
-
     Info<< nl << "And again using the same STL iterator: " << nl << endl;
 
     forAllIters(myList, iter)
diff --git a/applications/test/HashPtrTable/Test-hashPtrTable.C b/applications/test/HashPtrTable/Test-hashPtrTable.C
index 5133d784b18fd09f134de28a24feda41f7f1623b..e62d59686983631413faa7c1f4d896548af65c1c 100644
--- a/applications/test/HashPtrTable/Test-hashPtrTable.C
+++ b/applications/test/HashPtrTable/Test-hashPtrTable.C
@@ -36,14 +36,9 @@ void printTable(const HashPtrTable<T>& table)
 {
     Info<< table.size() << nl << "(" << nl;
 
-    for
-    (
-        typename HashPtrTable<T>::const_iterator iter = table.cbegin();
-        iter != table.cend();
-        ++iter
-    )
+    forAllConstIters(table, iter)
     {
-        const T* ptr = *iter;
+        const T* ptr = iter.object();
         Info<< iter.key() << " = ";
         if (ptr)
         {
@@ -57,6 +52,22 @@ void printTable(const HashPtrTable<T>& table)
     }
 
     Info<< ")" << endl;
+
+    // Values only, with for-range
+    Info<< "values (";
+    for (auto val : table)
+    {
+        Info<< ' ';
+        if (val)
+        {
+            Info<< *val;
+        }
+        else
+        {
+            Info<< "nullptr";
+        }
+    }
+    Info<< " )" << nl;
 }
 
 
@@ -68,7 +79,9 @@ int main()
     HashPtrTable<double> myTable;
     myTable.insert("abc", new double(42.1));
     myTable.insert("def", nullptr);
-    myTable.insert("ghi", new double(3.14159));
+    myTable.insert("pi", new double(3.14159));
+    myTable.insert("natlog", new double(2.718282));
+    myTable.insert("sqrt2", new double(1.414214));
 
     // Info<< myTable << endl;
     printTable(myTable);
@@ -79,8 +92,20 @@ int main()
     printTable(copy);
     Info<< copy << endl;
 
+    Info<<"\nerase some existing and non-existing entries" << nl;
+
+    auto iter = myTable.find("pi");
+    myTable.erase(iter);
+
+    iter = myTable.find("unknownKey");
+    myTable.erase(iter);
+
+    myTable.erase("abc");
+    myTable.erase("unknownKey");
+
+    printTable(myTable);
+
     return 0;
 }
 
-
 // ************************************************************************* //
diff --git a/applications/test/HashSet/Test-hashSet.C b/applications/test/HashSet/Test-hashSet.C
index 0b219f2e3d1bef47f8d7831043bc6972bb5bbd29..55640829fb2ea0c2aa01630194e5260144253310 100644
--- a/applications/test/HashSet/Test-hashSet.C
+++ b/applications/test/HashSet/Test-hashSet.C
@@ -197,8 +197,12 @@ int main(int argc, char *argv[])
         Info<< "setD has no 11" << endl;
     }
 
+    Info<< "setB : " << flatOutput(setB) << endl;
     Info<< "setD : " << flatOutput(setD) << endl;
 
+    setD -= setB;
+    Info<< "setD -= setB : " << flatOutput(setD) << endl;
+
     // This should not work (yet?)
     // setD[12] = true;
 
diff --git a/applications/test/HashTable/Test-hashTable.C b/applications/test/HashTable/Test-hashTable.C
index 31bff05b0f840435784592f04bf60bc9e99b8ebe..8352a88ae0c05615b0fff10cd6198a7f6fc50b0b 100644
--- a/applications/test/HashTable/Test-hashTable.C
+++ b/applications/test/HashTable/Test-hashTable.C
@@ -25,6 +25,9 @@ License
 
 #include "HashTable.H"
 #include "List.H"
+#include "SortableList.H"
+#include "DynamicList.H"
+#include "FlatOutput.H"
 #include "IOstreams.H"
 #include "IStringStream.H"
 #include "OStringStream.H"
@@ -163,15 +166,15 @@ int main()
         << "\ntable2" << table2 << nl;
 
 
-    Info<< "\ntable3" << table3
-        << "\nclearStorage table3 ... ";
-    table3.clearStorage();
-    Info<< table3 << nl;
+    Info<< "\ntable3" << table2
+        << "\nclearStorage table2 ... ";
+    table2.clearStorage();
+    Info<< table2 << nl;
 
     table1 =
     {
-        {"aca", 3.0},
-        {"aaw", 6.0},
+        {"abc", 3.0},
+        {"def", 6.0},
         {"acr", 8.0},
         {"aec", 10.0}
     };
@@ -193,7 +196,43 @@ int main()
     // These do not yet work. Issues resolving the distance.
     //
     //  List<scalar> table1vals(table1.begin(), table1.end());
-    //  wordList table1keys(table1.begin(), table1.end());
+
+    {
+        Info<<"distance/size: "
+            << std::distance(table1.begin(), table1.end())
+            << "/" << table1.size()
+            << " and "
+            << std::distance(table1.keys().begin(), table1.keys().end())
+            << "/" << table1.keys().size()
+            << nl;
+
+        SortableList<word> sortKeys
+        // DynamicList<word> sortKeys
+        (
+            table1.keys().begin(),
+            table1.keys().end()
+        );
+        Info<<"sortKeys: " << flatOutput(sortKeys) << nl;
+    }
+
+    Info<< "\nFrom table1: " << flatOutput(table1.sortedToc()) << nl
+        << "retain keys: " << flatOutput(table3.sortedToc()) << nl;
+
+    table1.retain(table3);
+    Info<< "-> " << flatOutput(table1.sortedToc()) << nl;
+
+    Info<< "Lookup non-existent" << nl;
+
+    Info<< table1.lookup("missing-const", 1.2345e+6)
+        << "  // const-access" << nl;
+
+    Info<< table1("missing-inadvertent", 3.14159)
+        << "  // (inadvertent?) non-const access"  << nl;
+
+    Info<< table1("missing-autovivify")
+        << "  // Known auto-vivification (non-const access)" << nl;
+
+    Info<<"\ntable1: " << table1 << endl;
 
     Info<< "\nDone\n";
 
diff --git a/applications/test/List/Test-List.C b/applications/test/List/Test-List.C
index 9ab2732c2e68ff4e9bb496aa64d27a11720b421f..d68bc4d7baa108673feab7951d386b3904a09317 100644
--- a/applications/test/List/Test-List.C
+++ b/applications/test/List/Test-List.C
@@ -42,6 +42,7 @@ See also
 #include "vector.H"
 
 #include "labelRange.H"
+#include "scalarList.H"
 #include "ListOps.H"
 #include "SubList.H"
 
@@ -144,6 +145,18 @@ int main(int argc, char *argv[])
 
         labelList longLabelList = identity(15);
 
+        // This does not work:
+        // scalarList slist = identity(15);
+        //
+        // More writing, but does work:
+        scalarList slist
+        (
+            labelRange::null.begin(),
+            labelRange::identity(15).end()
+        );
+
+        Info<<"scalar identity:" << flatOutput(slist) << endl;
+
         Info<< "labels (contiguous=" << contiguous<label>() << ")" << nl;
 
         Info<< "normal: " << longLabelList << nl;
@@ -220,7 +233,32 @@ int main(int argc, char *argv[])
         }
         Info<< "sub-sorted: " << flatOutput(longLabelList) << nl;
 
-        // Info<<"Slice=" << longLabelList[labelRange(23,5)] << nl;
+        // construct from a label-range
+        labelRange range(25,15);
+
+        labelList ident(range.begin(), range.end());
+        Info<<"range-list (label)=" << ident << nl;
+
+        List<scalar> sident(range.begin(), range.end());
+        Info<<"range-list (scalar)=" << sident << nl;
+
+        // Sub-ranges also work
+        List<scalar> sident2(range(3), range(10));
+        Info<<"range-list (scalar)=" << sident2 << nl;
+
+        // VERY BAD IDEA: List<scalar> sident3(range(10), range(3));
+
+        // This doesn't work, and don't know what it should do anyhow
+        // List<vector> vident(range.begin(), range.end());
+        // Info<<"range-list (vector)=" << vident << nl;
+
+        // Even weird things like this
+        List<scalar> sident4
+        (
+            labelRange().begin(),
+            labelRange::identity(8).end()
+        );
+        Info<<"range-list (scalar)=" << sident4 << nl;
     }
 
     wordReList reLst;
diff --git a/applications/test/labelRanges/Test-labelRanges.C b/applications/test/labelRanges/Test-labelRanges.C
index ec2d15233900b2cf6abd25678dfcda3cc474f3d0..5acb0d296c134ed5aa632fe4dceaf98d260715f7 100644
--- a/applications/test/labelRanges/Test-labelRanges.C
+++ b/applications/test/labelRanges/Test-labelRanges.C
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
         Info<<"test sorting" << endl;
         DynamicList<labelRange> list1(10);
         list1.append(labelRange(25, 8));
-        list1.append(labelRange(0, 10));
+        list1.append(labelRange::identity(8));
         list1.append(labelRange(15, 5));
         list1.append(labelRange(50, -10));
 
diff --git a/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C b/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C
index 9239b81a5dba69f9c8a8e3eaed8c17fd2e72a2c8..d66e43344b8f8c93ab94c391531cfebb426300fd 100644
--- a/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C
+++ b/applications/utilities/mesh/conversion/ideasUnvToFoam/ideasUnvToFoam.C
@@ -924,8 +924,8 @@ int main(int argc, char *argv[])
         }
     }
 
-    HashTable<labelList,word> cellZones;
-    HashTable<labelList,word> faceZones;
+    HashTable<labelList> cellZones;
+    HashTable<labelList> faceZones;
     List<bool> isAPatch(patchNames.size(),true);
 
     if (dofVertIndices.size())
diff --git a/applications/utilities/mesh/manipulation/checkMesh/Make/files b/applications/utilities/mesh/manipulation/checkMesh/Make/files
index 21febe27891c62f5fb80e50aa70fb1cb468114d5..08cbcaf088565debd035ac1aa2201a79e129dc3d 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/Make/files
+++ b/applications/utilities/mesh/manipulation/checkMesh/Make/files
@@ -1,3 +1,4 @@
+writeFields.C
 checkTools.C
 checkTopology.C
 checkGeometry.C
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C b/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C
index 246d559c5472a6b2ba5978f244f444219b3d68f9..8de78b1d6bc70e6b13791f9a726d1e2611b69cc9 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkMesh.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkMesh.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) 2015 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -57,12 +57,18 @@ Usage
     Reconstruct all cellSets and faceSets geometry and write to postProcessing/
     directory according to surfaceFormat (e.g. vtk or ensight)
 
+    \param -writeAllFields \n
+    Writes all mesh quality measures as fields.
+
+    \param -writeFields '(\<fieldName\>)' \n
+    Writes selected mesh quality measures as fields.
+
 \*---------------------------------------------------------------------------*/
 
 #include "argList.H"
 #include "timeSelector.H"
 #include "Time.H"
-#include "polyMesh.H"
+#include "fvMesh.H"
 #include "globalMeshData.H"
 #include "surfaceWriter.H"
 #include "vtkSetWriter.H"
@@ -71,6 +77,7 @@ Usage
 #include "checkTopology.H"
 #include "checkGeometry.H"
 #include "checkMeshQuality.H"
+#include "writeFields.H"
 
 using namespace Foam;
 
@@ -96,6 +103,17 @@ int main(int argc, char *argv[])
         "include extra topology checks"
     );
     argList::addBoolOption
+    (
+        "writeAllFields",
+        "write volFields with mesh quality parameters"
+    );
+    argList::addOption
+    (
+        "writeFields",
+        "wordList",
+        "write volFields with selected mesh quality parameters"
+    );
+    argList::addBoolOption
     (
         "meshQuality",
         "read user-defined mesh quality criterions from system/meshQualityDict"
@@ -110,7 +128,7 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
     instantList timeDirs = timeSelector::select0(runTime, args);
-    #include "createNamedPolyMesh.H"
+    #include "createNamedMesh.H"
 
     const bool noTopology  = args.optionFound("noTopology");
     const bool allGeometry = args.optionFound("allGeometry");
@@ -119,6 +137,24 @@ int main(int argc, char *argv[])
 
     word surfaceFormat;
     const bool writeSets = args.optionReadIfPresent("writeSets", surfaceFormat);
+    HashSet<word> selectedFields;
+    bool writeFields = args.optionReadIfPresent
+    (
+        "writeFields",
+        selectedFields
+    );
+    if (!writeFields && args.optionFound("writeAllFields"))
+    {
+        selectedFields.insert("nonOrthoAngle");
+        selectedFields.insert("faceWeight");
+        selectedFields.insert("skewness");
+        selectedFields.insert("cellDeterminant");
+        selectedFields.insert("aspectRatio");
+        selectedFields.insert("cellShapes");
+        selectedFields.insert("cellVolume");
+        selectedFields.insert("cellVolumeRatio");
+    }
+
 
     if (noTopology)
     {
@@ -143,6 +179,11 @@ int main(int argc, char *argv[])
             << " representation"
             << " of all faceSets and cellSets." << nl << endl;
     }
+    if (selectedFields.size())
+    {
+        Info<< "Writing mesh quality as fields " << selectedFields << nl
+            << endl;
+    }
 
 
     autoPtr<IOdictionary> qualDict;
@@ -234,6 +275,10 @@ int main(int argc, char *argv[])
                 Info<< "\nFailed " << nFailedChecks << " mesh checks.\n"
                     << endl;
             }
+
+
+            // Write selected fields
+            Foam::writeFields(mesh, selectedFields);
         }
         else if (state == polyMesh::POINTS_MOVED)
         {
@@ -262,6 +307,10 @@ int main(int argc, char *argv[])
             {
                 Info<< "\nMesh OK.\n" << endl;
             }
+
+
+            // Write selected fields
+            Foam::writeFields(mesh, selectedFields);
         }
     }
 
diff --git a/applications/utilities/mesh/manipulation/checkMesh/writeFields.C b/applications/utilities/mesh/manipulation/checkMesh/writeFields.C
new file mode 100644
index 0000000000000000000000000000000000000000..1cdc3dbe61a75eae6b8d4ca0eef28135a40527c9
--- /dev/null
+++ b/applications/utilities/mesh/manipulation/checkMesh/writeFields.C
@@ -0,0 +1,360 @@
+#include "writeFields.H"
+#include "volFields.H"
+#include "polyMeshTools.H"
+#include "zeroGradientFvPatchFields.H"
+#include "syncTools.H"
+
+using namespace Foam;
+
+void maxFaceToCell
+(
+    const scalarField& faceData,
+    volScalarField& cellData
+)
+{
+    const cellList& cells = cellData.mesh().cells();
+
+    scalarField& cellFld = cellData.ref();
+
+    cellFld = -GREAT;
+    forAll(cells, cellI)
+    {
+        const cell& cFaces = cells[cellI];
+        forAll(cFaces, i)
+        {
+            cellFld[cellI] = max(cellFld[cellI], faceData[cFaces[i]]);
+        }
+    }
+
+    forAll(cellData.boundaryField(), patchI)
+    {
+        fvPatchScalarField& fvp = cellData.boundaryFieldRef()[patchI];
+
+        fvp = fvp.patch().patchSlice(faceData);
+    }
+    cellData.correctBoundaryConditions();
+}
+
+
+void minFaceToCell
+(
+    const scalarField& faceData,
+    volScalarField& cellData
+)
+{
+    const cellList& cells = cellData.mesh().cells();
+
+    scalarField& cellFld = cellData.ref();
+
+    cellFld = GREAT;
+    forAll(cells, cellI)
+    {
+        const cell& cFaces = cells[cellI];
+        forAll(cFaces, i)
+        {
+            cellFld[cellI] = min(cellFld[cellI], faceData[cFaces[i]]);
+        }
+    }
+
+    forAll(cellData.boundaryField(), patchI)
+    {
+        fvPatchScalarField& fvp = cellData.boundaryFieldRef()[patchI];
+
+        fvp = fvp.patch().patchSlice(faceData);
+    }
+    cellData.correctBoundaryConditions();
+}
+
+
+void Foam::writeFields
+(
+    const fvMesh& mesh,
+    const HashSet<word>& selectedFields
+)
+{
+    if (selectedFields.empty())
+    {
+        return;
+    }
+
+    Info<< "Writing fields with mesh quality parameters" << endl;
+
+    if (selectedFields.found("nonOrthoAngle"))
+    {
+        //- Face based orthogonality
+        const scalarField faceOrthogonality
+        (
+            polyMeshTools::faceOrthogonality
+            (
+                mesh,
+                mesh.faceAreas(),
+                mesh.cellCentres()
+            )
+        );
+
+        //- Face based angle
+        const scalarField nonOrthoAngle
+        (
+            radToDeg
+            (
+                Foam::acos(min(1.0, faceOrthogonality))
+            )
+        );
+
+        //- Cell field - max of either face
+        volScalarField cellNonOrthoAngle
+        (
+            IOobject
+            (
+                "nonOrthoAngle",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE
+            ),
+            mesh,
+            dimensionedScalar("angle", dimless, 0),
+            calculatedFvPatchScalarField::typeName
+        );
+        //- Take max
+        maxFaceToCell(nonOrthoAngle, cellNonOrthoAngle);
+        Info<< "    Writing non-orthogonality (angle) to "
+            << cellNonOrthoAngle.name() << endl;
+        cellNonOrthoAngle.write();
+    }
+
+    if (selectedFields.found("faceWeight"))
+    {
+        const scalarField faceWeights
+        (
+            polyMeshTools::faceWeights
+            (
+                mesh,
+                mesh.faceCentres(),
+                mesh.faceAreas(),
+                mesh.cellCentres()
+            )
+        );
+
+        volScalarField cellWeights
+        (
+            IOobject
+            (
+                "faceWeight",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE
+            ),
+            mesh,
+            dimensionedScalar("weight", dimless, 0),
+            calculatedFvPatchScalarField::typeName
+        );
+        //- Take min
+        minFaceToCell(faceWeights, cellWeights);
+        Info<< "    Writing face interpolation weights (0..0.5) to "
+            << cellWeights.name() << endl;
+        cellWeights.write();
+    }
+
+
+    // Skewness
+    // ~~~~~~~~
+
+    if (selectedFields.found("skewness"))
+    {
+        //- Face based skewness
+        const scalarField faceSkewness
+        (
+            polyMeshTools::faceSkewness
+            (
+                mesh,
+                mesh.points(),
+                mesh.faceCentres(),
+                mesh.faceAreas(),
+                mesh.cellCentres()
+            )
+        );
+
+        //- Cell field - max of either face
+        volScalarField cellSkewness
+        (
+            IOobject
+            (
+                "skewness",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE
+            ),
+            mesh,
+            dimensionedScalar("skewness", dimless, 0),
+            calculatedFvPatchScalarField::typeName
+        );
+        //- Take max
+        maxFaceToCell(faceSkewness, cellSkewness);
+        Info<< "    Writing face skewness to " << cellSkewness.name() << endl;
+        cellSkewness.write();
+    }
+
+
+    // cellDeterminant
+    // ~~~~~~~~~~~~~~~
+
+    if (selectedFields.found("cellDeterminant"))
+    {
+        volScalarField cellDeterminant
+        (
+            IOobject
+            (
+                "cellDeterminant",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE,
+                false
+            ),
+            mesh,
+            dimensionedScalar("cellDeterminant", dimless, 0),
+            zeroGradientFvPatchScalarField::typeName
+        );
+        cellDeterminant.primitiveFieldRef() =
+            primitiveMeshTools::cellDeterminant
+            (
+                mesh,
+                mesh.geometricD(),
+                mesh.faceAreas(),
+                syncTools::getInternalOrCoupledFaces(mesh)
+            );
+        cellDeterminant.correctBoundaryConditions();
+        Info<< "    Writing cell determinant to "
+            << cellDeterminant.name() << endl;
+        cellDeterminant.write();
+    }
+
+
+    // Aspect ratio
+    // ~~~~~~~~~~~~
+    if (selectedFields.found("aspectRatio"))
+    {
+        volScalarField aspectRatio
+        (
+            IOobject
+            (
+                "aspectRatio",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE,
+                false
+            ),
+            mesh,
+            dimensionedScalar("aspectRatio", dimless, 0),
+            zeroGradientFvPatchScalarField::typeName
+        );
+
+
+        scalarField cellOpenness;
+        polyMeshTools::cellClosedness
+        (
+            mesh,
+            mesh.geometricD(),
+            mesh.faceAreas(),
+            mesh.cellVolumes(),
+            cellOpenness,
+            aspectRatio.ref()
+        );
+
+        aspectRatio.correctBoundaryConditions();
+        Info<< "    Writing aspect ratio to " << aspectRatio.name() << endl;
+        aspectRatio.write();
+    }
+
+
+    // cell type
+    // ~~~~~~~~~
+    if (selectedFields.found("cellShapes"))
+    {
+        volScalarField shape
+        (
+            IOobject
+            (
+                "cellShapes",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE,
+                false
+            ),
+            mesh,
+            dimensionedScalar("cellShapes", dimless, 0),
+            zeroGradientFvPatchScalarField::typeName
+        );
+        const cellShapeList& cellShapes = mesh.cellShapes();
+        forAll(cellShapes, cellI)
+        {
+            const cellModel& model = cellShapes[cellI].model();
+            shape[cellI] = model.index();
+        }
+        shape.correctBoundaryConditions();
+        Info<< "    Writing cell shape (hex, tet etc.) to " << shape.name()
+            << endl;
+        shape.write();
+    }
+
+    if (selectedFields.found("cellVolume"))
+    {
+        volScalarField V
+        (
+            IOobject
+            (
+                "cellVolume",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE,
+                false
+            ),
+            mesh,
+            dimensionedScalar("cellVolume", dimVolume, 0),
+            calculatedFvPatchScalarField::typeName
+        );
+        V.ref() = mesh.V();
+        Info<< "    Writing cell volume to " << V.name() << endl;
+        V.write();
+    }
+
+    if (selectedFields.found("cellVolumeRatio"))
+    {
+        const scalarField faceVolumeRatio
+        (
+            polyMeshTools::volRatio
+            (
+                mesh,
+                mesh.V()
+            )
+        );
+
+        volScalarField cellVolumeRatio
+        (
+            IOobject
+            (
+                "cellVolumeRatio",
+                mesh.time().timeName(),
+                mesh,
+                IOobject::NO_READ,
+                IOobject::AUTO_WRITE
+            ),
+            mesh,
+            dimensionedScalar("cellVolumeRatio", dimless, 0),
+            calculatedFvPatchScalarField::typeName
+        );
+        //- Take min
+        minFaceToCell(faceVolumeRatio, cellVolumeRatio);
+        Info<< "    Writing cell volume ratio to "
+            << cellVolumeRatio.name() << endl;
+        cellVolumeRatio.write();
+    }
+
+    Info<< endl;
+}
diff --git a/applications/utilities/mesh/manipulation/checkMesh/writeFields.H b/applications/utilities/mesh/manipulation/checkMesh/writeFields.H
new file mode 100644
index 0000000000000000000000000000000000000000..09c31b0e62bf43db1b9a7d5205d9905fb1be8c18
--- /dev/null
+++ b/applications/utilities/mesh/manipulation/checkMesh/writeFields.H
@@ -0,0 +1,10 @@
+#include "fvMesh.H"
+
+namespace Foam
+{
+    void writeFields
+    (
+        const fvMesh&,
+        const HashSet<word>& selectedFields
+    );
+}
diff --git a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C
index 41855ddd7b5d86d6b7e74483653a334a72e45ee0..52030e9c81028cc99803b5967695cb830f5094ab 100644
--- a/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C
+++ b/applications/utilities/postProcessing/graphics/PVReaders/PVFoamReader/vtkPVFoam/vtkPVFoamUpdateInfo.C
@@ -233,21 +233,16 @@ void Foam::vtkPVFoam::updateInfoPatches
     if (meshPtr_)
     {
         const polyBoundaryMesh& patches = meshPtr_->boundaryMesh();
-        const HashTable<labelList, word>& groups = patches.groupPatchIDs();
+        const HashTable<labelList>& groups = patches.groupPatchIDs();
         const wordList allPatchNames = patches.names();
 
         // Add patch groups
         // ~~~~~~~~~~~~~~~~
 
-        for
-        (
-            HashTable<labelList, word>::const_iterator iter = groups.begin();
-            iter != groups.end();
-            ++iter
-        )
+        forAllConstIters(groups, iter)
         {
             const word& groupName = iter.key();
-            const labelList& patchIDs = iter();
+            const labelList& patchIDs = iter.object();
 
             label nFaces = 0;
             forAll(patchIDs, i)
@@ -349,7 +344,7 @@ void Foam::vtkPVFoam::updateInfoPatches
             // Add (non-zero) patch groups to the list of mesh parts
             // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-            HashTable<labelList, word> groups(patchEntries.size());
+            HashTable<labelList> groups(patchEntries.size());
 
             forAll(patchEntries, patchi)
             {
@@ -360,7 +355,7 @@ void Foam::vtkPVFoam::updateInfoPatches
 
                 forAll(groupNames, groupI)
                 {
-                    HashTable<labelList, word>::iterator iter = groups.find
+                    HashTable<labelList>::iterator iter = groups.find
                     (
                         groupNames[groupI]
                     );
@@ -375,16 +370,10 @@ void Foam::vtkPVFoam::updateInfoPatches
                 }
             }
 
-            for
-            (
-                HashTable<labelList, word>::const_iterator iter =
-                    groups.begin();
-                iter != groups.end();
-                ++iter
-            )
+            forAllConstIters(groups, iter)
             {
                 const word& groupName = iter.key();
-                const labelList& patchIDs = iter();
+                const labelList& patchIDs = iter.object();
 
                 label nFaces = 0;
                 forAll(patchIDs, i)
diff --git a/applications/utilities/surface/surfaceMeshTriangulate/surfaceMeshTriangulate.C b/applications/utilities/surface/surfaceMeshTriangulate/surfaceMeshTriangulate.C
index ee4544ee34529b4b397beed5c8a012ef67437fd7..712ed6564e972dfc28a875731472ea045763d527 100644
--- a/applications/utilities/surface/surfaceMeshTriangulate/surfaceMeshTriangulate.C
+++ b/applications/utilities/surface/surfaceMeshTriangulate/surfaceMeshTriangulate.C
@@ -51,6 +51,7 @@ Description
 #include "uindirectPrimitivePatch.H"
 #include "globalMeshData.H"
 #include "globalIndex.H"
+#include "timeSelector.H"
 
 using namespace Foam;
 
@@ -63,6 +64,8 @@ int main(int argc, char *argv[])
     (
         "extract surface from a polyMesh"
     );
+    timeSelector::addOptions();
+
     argList::validArgs.append("output file");
     #include "addRegionOption.H"
     argList::addBoolOption
@@ -86,7 +89,14 @@ int main(int argc, char *argv[])
     #include "setRootCase.H"
     #include "createTime.H"
 
-    const fileName outFileName(args[1]);
+    const fileName userOutFileName(args[1]);
+
+    if (!userOutFileName.hasExt())
+    {
+        FatalErrorInFunction
+            << "Missing extension on output name " << userOutFileName
+            << exit(FatalError);
+    }
 
     Info<< "Extracting surface from boundaryMesh ..."
         << endl << endl;
@@ -106,275 +116,321 @@ int main(int argc, char *argv[])
         Info<< "Excluding all processor patches." << nl << endl;
     }
 
+
     Info<< "Reading mesh from time " << runTime.value() << endl;
 
     #include "createNamedPolyMesh.H"
 
+    // User specified times
+    instantList timeDirs = timeSelector::select0(runTime, args);
 
-    // Create local surface from:
-    // - explicitly named patches only (-patches (at your option)
-    // - all patches (default in sequential mode)
-    // - all non-processor patches (default in parallel mode)
-    // - all non-processor patches (sequential mode, -excludeProcPatches
-    //   (at your option)
-
-    // Construct table of patches to include.
-    const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
-
-    labelHashSet includePatches(bMesh.size());
-
-    if (args.optionFound("patches"))
+    forAll(timeDirs, timeIndex)
     {
-        includePatches = bMesh.patchSet
-        (
-            wordReList(args.optionLookup("patches")())
-        );
-    }
-    else
-    {
-        forAll(bMesh, patchi)
-        {
-            const polyPatch& patch = bMesh[patchi];
+        runTime.setTime(timeDirs[timeIndex], timeIndex);
+        Info<< "Time [" << timeIndex << "] = " << runTime.timeName();
 
-            if (includeProcPatches || !isA<processorPolyPatch>(patch))
-            {
-                includePatches.insert(patchi);
-            }
+        fileName outFileName;
+        if (timeDirs.size() == 1)
+        {
+            outFileName = userOutFileName;
+            Info<< nl;
         }
-    }
-
-
-
-    const faceZoneMesh& fzm = mesh.faceZones();
-    labelHashSet includeFaceZones(fzm.size());
-
-    if (args.optionFound("faceZones"))
-    {
-        wordReList zoneNames(args.optionLookup("faceZones")());
-        const wordList allZoneNames(fzm.names());
-        forAll(zoneNames, i)
+        else
         {
-            const wordRe& zoneName = zoneNames[i];
-
-            labelList zoneIDs = findStrings(zoneName, allZoneNames);
-
-            forAll(zoneIDs, j)
+            polyMesh::readUpdateState meshState = mesh.readUpdate();
+            if (timeIndex && meshState == polyMesh::UNCHANGED)
             {
-                includeFaceZones.insert(zoneIDs[j]);
+                Info<<"  ... no mesh change." << nl;
+                continue;
             }
-
-            if (zoneIDs.empty())
+            else
             {
-                WarningInFunction
-                    << "Cannot find any faceZone name matching "
-                    << zoneName << endl;
+                Info<< nl;
             }
 
+            // The filename based on the original, but with additional
+            // time information. The extension was previously checked that
+            // it exists
+            std::string::size_type dot = userOutFileName.rfind('.');
+
+            outFileName =
+                userOutFileName.substr(0, dot) + "_"
+              + Foam::name(runTime.value()) + "."
+              + userOutFileName.ext();
         }
-        Info<< "Additionally triangulating faceZones "
-            << UIndirectList<word>(allZoneNames, includeFaceZones.sortedToc())
-            << endl;
-    }
 
+        // Create local surface from:
+        // - explicitly named patches only (-patches (at your option)
+        // - all patches (default in sequential mode)
+        // - all non-processor patches (default in parallel mode)
+        // - all non-processor patches (sequential mode, -excludeProcPatches
+        //   (at your option)
 
+        // Construct table of patches to include.
+        const polyBoundaryMesh& bMesh = mesh.boundaryMesh();
 
-    // From (name of) patch to compact 'zone' index
-    HashTable<label> compactZoneID(1000);
-    // Mesh face and compact zone indx
-    DynamicList<label> faceLabels;
-    DynamicList<label> compactZones;
+        labelHashSet includePatches(bMesh.size());
 
-    {
-        // Collect sizes. Hash on names to handle local-only patches (e.g.
-        //  processor patches)
-        HashTable<label> patchSize(1000);
-        label nFaces = 0;
-        forAllConstIter(labelHashSet, includePatches, iter)
+        if (args.optionFound("patches"))
         {
-            const polyPatch& pp = bMesh[iter.key()];
-            patchSize.insert(pp.name(), pp.size());
-            nFaces += pp.size();
+            includePatches = bMesh.patchSet
+            (
+                wordReList(args.optionLookup("patches")())
+            );
         }
-
-        HashTable<label> zoneSize(1000);
-        forAllConstIter(labelHashSet, includeFaceZones, iter)
+        else
         {
-            const faceZone& pp = fzm[iter.key()];
-            zoneSize.insert(pp.name(), pp.size());
-            nFaces += pp.size();
-        }
+            forAll(bMesh, patchi)
+            {
+                const polyPatch& patch = bMesh[patchi];
 
+                if (includeProcPatches || !isA<processorPolyPatch>(patch))
+                {
+                    includePatches.insert(patchi);
+                }
+            }
+        }
 
-        Pstream::mapCombineGather(patchSize, plusEqOp<label>());
-        Pstream::mapCombineGather(zoneSize, plusEqOp<label>());
 
+        const faceZoneMesh& fzm = mesh.faceZones();
+        labelHashSet includeFaceZones(fzm.size());
 
-        // Allocate compact numbering for all patches/faceZones
-        forAllConstIter(HashTable<label>, patchSize, iter)
+        if (args.optionFound("faceZones"))
         {
-            label sz = compactZoneID.size();
-            compactZoneID.insert(iter.key(), sz);
-        }
+            wordReList zoneNames(args.optionLookup("faceZones")());
+            const wordList allZoneNames(fzm.names());
+            forAll(zoneNames, i)
+            {
+                const wordRe& zoneName = zoneNames[i];
 
-        forAllConstIter(HashTable<label>, zoneSize, iter)
-        {
-            label sz = compactZoneID.size();
-            //Info<< "For faceZone " << iter.key() << " allocating zoneID "
-            //    << sz << endl;
-            compactZoneID.insert(iter.key(), sz);
+                labelList zoneIDs = findStrings(zoneName, allZoneNames);
+
+                forAll(zoneIDs, j)
+                {
+                    includeFaceZones.insert(zoneIDs[j]);
+                }
+
+                if (zoneIDs.empty())
+                {
+                    WarningInFunction
+                        << "Cannot find any faceZone name matching "
+                        << zoneName << endl;
+                }
+
+            }
+            Info<< "Additionally triangulating faceZones "
+                << UIndirectList<word>
+                  (
+                      allZoneNames,
+                      includeFaceZones.sortedToc()
+                  )
+                << endl;
         }
 
 
-        Pstream::mapCombineScatter(compactZoneID);
 
+        // From (name of) patch to compact 'zone' index
+        HashTable<label> compactZoneID(1000);
+        // Mesh face and compact zone indx
+        DynamicList<label> faceLabels;
+        DynamicList<label> compactZones;
 
-        // Rework HashTable into labelList just for speed of conversion
-        labelList patchToCompactZone(bMesh.size(), -1);
-        labelList faceZoneToCompactZone(bMesh.size(), -1);
-        forAllConstIter(HashTable<label>, compactZoneID, iter)
         {
-            label patchi = bMesh.findPatchID(iter.key());
-            if (patchi != -1)
+            // Collect sizes. Hash on names to handle local-only patches (e.g.
+            //  processor patches)
+            HashTable<label> patchSize(1000);
+            label nFaces = 0;
+            forAllConstIter(labelHashSet, includePatches, iter)
             {
-                patchToCompactZone[patchi] = iter();
+                const polyPatch& pp = bMesh[iter.key()];
+                patchSize.insert(pp.name(), pp.size());
+                nFaces += pp.size();
             }
-            else
+
+            HashTable<label> zoneSize(1000);
+            forAllConstIter(labelHashSet, includeFaceZones, iter)
             {
-                label zoneI = fzm.findZoneID(iter.key());
-                faceZoneToCompactZone[zoneI] = iter();
+                const faceZone& pp = fzm[iter.key()];
+                zoneSize.insert(pp.name(), pp.size());
+                nFaces += pp.size();
             }
-        }
 
 
-        faceLabels.setCapacity(nFaces);
-        compactZones.setCapacity(nFaces);
+            Pstream::mapCombineGather(patchSize, plusEqOp<label>());
+            Pstream::mapCombineGather(zoneSize, plusEqOp<label>());
 
-        // Collect faces on patches
-        forAllConstIter(labelHashSet, includePatches, iter)
-        {
-            const polyPatch& pp = bMesh[iter.key()];
-            forAll(pp, i)
+
+            // Allocate compact numbering for all patches/faceZones
+            forAllConstIter(HashTable<label>, patchSize, iter)
             {
-                faceLabels.append(pp.start()+i);
-                compactZones.append(patchToCompactZone[pp.index()]);
+                label sz = compactZoneID.size();
+                compactZoneID.insert(iter.key(), sz);
             }
-        }
-        // Collect faces on faceZones
-        forAllConstIter(labelHashSet, includeFaceZones, iter)
-        {
-            const faceZone& pp = fzm[iter.key()];
-            forAll(pp, i)
+
+            forAllConstIter(HashTable<label>, zoneSize, iter)
             {
-                faceLabels.append(pp[i]);
-                compactZones.append(faceZoneToCompactZone[pp.index()]);
+                label sz = compactZoneID.size();
+                //Info<< "For faceZone " << iter.key() << " allocating zoneID "
+                //    << sz << endl;
+                compactZoneID.insert(iter.key(), sz);
             }
-        }
-    }
 
 
-    // Addressing engine for all faces
-    uindirectPrimitivePatch allBoundary
-    (
-        UIndirectList<face>(mesh.faces(), faceLabels),
-        mesh.points()
-    );
+            Pstream::mapCombineScatter(compactZoneID);
 
 
-    // Find correspondence to master points
-    labelList pointToGlobal;
-    labelList uniqueMeshPoints;
-    autoPtr<globalIndex> globalNumbers = mesh.globalData().mergePoints
-    (
-        allBoundary.meshPoints(),
-        allBoundary.meshPointMap(),
-        pointToGlobal,
-        uniqueMeshPoints
-    );
+            // Rework HashTable into labelList just for speed of conversion
+            labelList patchToCompactZone(bMesh.size(), -1);
+            labelList faceZoneToCompactZone(bMesh.size(), -1);
+            forAllConstIter(HashTable<label>, compactZoneID, iter)
+            {
+                label patchi = bMesh.findPatchID(iter.key());
+                if (patchi != -1)
+                {
+                    patchToCompactZone[patchi] = iter();
+                }
+                else
+                {
+                    label zoneI = fzm.findZoneID(iter.key());
+                    faceZoneToCompactZone[zoneI] = iter();
+                }
+            }
 
-    // Gather all unique points on master
-    List<pointField> gatheredPoints(Pstream::nProcs());
-    gatheredPoints[Pstream::myProcNo()] = pointField
-    (
-        mesh.points(),
-        uniqueMeshPoints
-    );
-    Pstream::gatherList(gatheredPoints);
 
-    // Gather all faces
-    List<faceList> gatheredFaces(Pstream::nProcs());
-    gatheredFaces[Pstream::myProcNo()] = allBoundary.localFaces();
-    forAll(gatheredFaces[Pstream::myProcNo()], i)
-    {
-        inplaceRenumber(pointToGlobal, gatheredFaces[Pstream::myProcNo()][i]);
-    }
-    Pstream::gatherList(gatheredFaces);
+            faceLabels.setCapacity(nFaces);
+            compactZones.setCapacity(nFaces);
 
-    // Gather all ZoneIDs
-    List<labelList> gatheredZones(Pstream::nProcs());
-    gatheredZones[Pstream::myProcNo()] = compactZones.xfer();
-    Pstream::gatherList(gatheredZones);
+            // Collect faces on patches
+            forAllConstIter(labelHashSet, includePatches, iter)
+            {
+                const polyPatch& pp = bMesh[iter.key()];
+                forAll(pp, i)
+                {
+                    faceLabels.append(pp.start()+i);
+                    compactZones.append(patchToCompactZone[pp.index()]);
+                }
+            }
+            // Collect faces on faceZones
+            forAllConstIter(labelHashSet, includeFaceZones, iter)
+            {
+                const faceZone& pp = fzm[iter.key()];
+                forAll(pp, i)
+                {
+                    faceLabels.append(pp[i]);
+                    compactZones.append(faceZoneToCompactZone[pp.index()]);
+                }
+            }
+        }
 
-    // On master combine all points, faces, zones
-    if (Pstream::master())
-    {
-        pointField allPoints = ListListOps::combine<pointField>
+
+        // Addressing engine for all faces
+        uindirectPrimitivePatch allBoundary
         (
-            gatheredPoints,
-            accessOp<pointField>()
+            UIndirectList<face>(mesh.faces(), faceLabels),
+            mesh.points()
         );
-        gatheredPoints.clear();
 
-        faceList allFaces = ListListOps::combine<faceList>
+
+        // Find correspondence to master points
+        labelList pointToGlobal;
+        labelList uniqueMeshPoints;
+        autoPtr<globalIndex> globalNumbers = mesh.globalData().mergePoints
         (
-            gatheredFaces,
-            accessOp<faceList>()
+            allBoundary.meshPoints(),
+            allBoundary.meshPointMap(),
+            pointToGlobal,
+            uniqueMeshPoints
         );
-        gatheredFaces.clear();
 
-        labelList allZones = ListListOps::combine<labelList>
+        // Gather all unique points on master
+        List<pointField> gatheredPoints(Pstream::nProcs());
+        gatheredPoints[Pstream::myProcNo()] = pointField
         (
-            gatheredZones,
-            accessOp<labelList>()
+            mesh.points(),
+            uniqueMeshPoints
         );
-        gatheredZones.clear();
-
+        Pstream::gatherList(gatheredPoints);
 
-        // Zones
-        surfZoneIdentifierList surfZones(compactZoneID.size());
-        forAllConstIter(HashTable<label>, compactZoneID, iter)
+        // Gather all faces
+        List<faceList> gatheredFaces(Pstream::nProcs());
+        gatheredFaces[Pstream::myProcNo()] = allBoundary.localFaces();
+        forAll(gatheredFaces[Pstream::myProcNo()], i)
         {
-            surfZones[iter()] = surfZoneIdentifier(iter.key(), iter());
-            Info<< "surfZone " << iter()  <<  " : " << surfZones[iter()].name()
-                << endl;
+            inplaceRenumber
+           (
+                pointToGlobal,
+                gatheredFaces[Pstream::myProcNo()][i]
+           );
         }
+        Pstream::gatherList(gatheredFaces);
 
-        UnsortedMeshedSurface<face> unsortedFace
-        (
-            xferMove(allPoints),
-            xferMove(allFaces),
-            xferMove(allZones),
-            xferMove(surfZones)
-        );
+        // Gather all ZoneIDs
+        List<labelList> gatheredZones(Pstream::nProcs());
+        gatheredZones[Pstream::myProcNo()] = compactZones.xfer();
+        Pstream::gatherList(gatheredZones);
 
+        // On master combine all points, faces, zones
+        if (Pstream::master())
+        {
+            pointField allPoints = ListListOps::combine<pointField>
+            (
+                gatheredPoints,
+                accessOp<pointField>()
+            );
+            gatheredPoints.clear();
+
+            faceList allFaces = ListListOps::combine<faceList>
+            (
+                gatheredFaces,
+                accessOp<faceList>()
+            );
+            gatheredFaces.clear();
+
+            labelList allZones = ListListOps::combine<labelList>
+            (
+                gatheredZones,
+                accessOp<labelList>()
+            );
+            gatheredZones.clear();
+
+
+            // Zones
+            surfZoneIdentifierList surfZones(compactZoneID.size());
+            forAllConstIter(HashTable<label>, compactZoneID, iter)
+            {
+                surfZones[iter()] = surfZoneIdentifier(iter.key(), iter());
+                Info<< "surfZone " << iter()
+                    <<  " : "      << surfZones[iter()].name()
+                    << endl;
+            }
 
-        MeshedSurface<face> sortedFace(unsortedFace);
+            UnsortedMeshedSurface<face> unsortedFace
+            (
+                xferMove(allPoints),
+                xferMove(allFaces),
+                xferMove(allZones),
+                xferMove(surfZones)
+            );
 
-        fileName globalCasePath
-        (
-            outFileName.isAbsolute()
-          ? outFileName
-          : (
-                runTime.processorCase()
-              ? runTime.rootPath()/runTime.globalCaseName()/outFileName
-              : runTime.path()/outFileName
-            )
-        );
 
-        Info<< "Writing merged surface to " << globalCasePath << endl;
+            MeshedSurface<face> sortedFace(unsortedFace);
 
-        sortedFace.write(globalCasePath);
-    }
+            fileName globalCasePath
+            (
+                outFileName.isAbsolute()
+              ? outFileName
+              : (
+                    runTime.processorCase()
+                  ? runTime.rootPath()/runTime.globalCaseName()/outFileName
+                  : runTime.path()/outFileName
+                )
+            );
+
+            Info<< "Writing merged surface to " << globalCasePath << endl;
 
+            sortedFace.write(globalCasePath);
+        }
+    }
     Info<< "End\n" << endl;
 
     return 0;
diff --git a/doc/codingStyleGuide.org b/doc/codingStyleGuide.org
index 3cde03d85da57228690ffb68dfceccb69b0702e3..b8d1b0d98aa89c36cecc401b823e2af02ead82d4 100644
--- a/doc/codingStyleGuide.org
+++ b/doc/codingStyleGuide.org
@@ -22,7 +22,7 @@
     + Stream output
       + =<<= is always four characters after the start of the stream,
         so that the =<<= symbols align, i.e.
-        #+begin_src c++
+        #+begin_src C++
         Info<< ...
         os  << ...
         #+end_src
@@ -215,7 +215,7 @@
 
 *** =for= and =while= Loops
     #+begin_src C++
-    for (i = 0; i < maxI; i++)
+    for (i = 0; i < maxI; ++i)
     {
         code;
     }
@@ -226,7 +226,7 @@
     (
         i = 0;
         i < maxI;
-        i++
+        ++i
     )
     {
         code;
@@ -234,15 +234,22 @@
     #+end_src
     *not* this (no space between =for= and =(= used)
     #+begin_src C++
-    for(i = 0; i < maxI; i++)
+    for(i = 0; i < maxI; ++i)
+    {
+        code;
+    }
+    #+end_src
+    Range-base for should have a space surrounding the ':'
+    #+begin_src C++
+    for (auto i : range)
     {
         code;
     }
     #+end_src
-    Note that when indexing through iterators, it is often slightly more
-    efficient to use the pre-increment form. Eg, =++iter= instead of =iter++=
+    Note that when indexing through iterators, it is often more efficient
+    to use the pre-increment form. Eg, =++iter= instead of =iter++=
 
-*** =forAll=, =forAllIter=, =forAllConstIter=, /etc./ loops
+*** =forAll=, =forAllIters=, =forAllConstIters=, /etc./ loops
     Like =for= loops, but
     #+begin_src C++
     forAll(
@@ -251,15 +258,22 @@
     #+begin_src C++
     forAll (
     #+end_src
-    Using the =forAllIter= and =forAllConstIter= macros is generally
-    advantageous - less typing, easier to find later.  However, since
-    they are macros, they will fail if the iterated object contains
-    any commas /e.g./ following will FAIL!:
+    In many cases, the new =forAllIters= and =forAllConstIters= macros
+    provide a good means of cycling through iterators (when a range-base
+    for doesn't apply). These use the C++11 decltype and work without
+    explicitly specifying the container class:
+    #+begin_src C++
+    forAllIters(myEdgeHash, iter)
+    #+end_src
+    Using the older =forAllIter= and =forAllConstIter= macros will
+    still be seen.  However, since they are macros, they will fail if
+    the iterated object contains any commas /e.g./ following will FAIL!:
     #+begin_src C++
-    forAllIter(HashTable<labelPair, edge, Hash<edge>>, foo, iter)
+    forAllIter(HashTable<labelPair, edge, Hash<edge>>, myEdgeHash, iter)
     #+end_src
     These convenience macros are also generally avoided in other
     container classes and OpenFOAM primitive classes.
+    In certain cases, the range-based for can also be used.
 
 *** Splitting Over Multiple Lines
 ***** Splitting return type and function name
diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C
index 4143d25d85299c2e3ea2510bf1f80d16796a3a50..9370dd26edf59ee2f60dd2182250881d5df471a0 100644
--- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C
+++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.C
@@ -72,30 +72,44 @@ Foam::HashPtrTable<T, Key, Hash>::~HashPtrTable()
 template<class T, class Key, class Hash>
 T* Foam::HashPtrTable<T, Key, Hash>::remove(iterator& iter)
 {
-    T* ptr = iter.object();
-    this->parent_type::erase(iter);
-    return ptr;
+    if (iter.found())
+    {
+        T* ptr = iter.object();
+        this->parent_type::erase(iter);
+        return ptr;
+    }
+
+    return nullptr;
 }
 
 
 template<class T, class Key, class Hash>
 bool Foam::HashPtrTable<T, Key, Hash>::erase(iterator& iter)
 {
-    T* ptr = iter.object();
-
-    if (this->parent_type::erase(iter))
+    if (iter.found())
     {
-        if (ptr)
+        T* ptr = iter.object();
+
+        if (this->parent_type::erase(iter))
         {
-            delete ptr;
-        }
+            if (ptr)
+            {
+                delete ptr;
+            }
 
-        return true;
-    }
-    else
-    {
-        return false;
+            return true;
+        }
     }
+
+    return false;
+}
+
+
+template<class T, class Key, class Hash>
+bool Foam::HashPtrTable<T, Key, Hash>::erase(const Key& key)
+{
+    auto iter = this->find(key);
+    return this->erase(iter);
 }
 
 
diff --git a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H
index 7cdf3743e311b3acd4e63f42b8fa3e753a7368a3..f83c04e313905400600b2f1733ec49732281e6f8 100644
--- a/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H
+++ b/src/OpenFOAM/containers/HashTables/HashPtrTable/HashPtrTable.H
@@ -116,12 +116,17 @@ public:
 
       // Edit
 
-        //- Remove and return the pointer specified by given iterator
+        //- Remove and return the pointer specified by given iterator.
+        //  Includes a safeguard against the end-iterator.
         T* remove(iterator& iter);
 
-        //- Erase an hashedEntry specified by given iterator
+        //- Erase an entry specified by given iterator
+        //  Includes a safeguard against the end-iterator.
         bool erase(iterator& iter);
 
+        //- Erase an entry specified by the given key
+        bool erase(const Key& key);
+
         //- Clear all entries from table
         void clear();
 
diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
index 321b8dd5dfe6bf9092ee0fe09dffbf8aae23e004..77ab200a42c7d72c7a7c16b066a88e263da06e12 100644
--- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
+++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.C
@@ -227,16 +227,9 @@ void Foam::HashSet<Key, Hash>::operator|=(const HashSet<Key, Hash>& rhs)
 
 
 template<class Key, class Hash>
-void Foam::HashSet<Key, Hash>::operator&=(const HashSet<Key, Hash>& rhs)
+inline void Foam::HashSet<Key, Hash>::operator&=(const HashSet<Key, Hash>& rhs)
 {
-    // Remove elements not also found in rhs
-    for (iterator iter = this->begin(); iter != this->end(); ++iter)
-    {
-        if (!rhs.found(iter.key()))
-        {
-            this->erase(iter);
-        }
-    }
+    this->parent_type::retain(rhs);
 }
 
 
@@ -259,13 +252,9 @@ void Foam::HashSet<Key, Hash>::operator^=(const HashSet<Key, Hash>& rhs)
 
 
 template<class Key, class Hash>
-void Foam::HashSet<Key, Hash>::operator-=(const HashSet<Key, Hash>& rhs)
+inline void Foam::HashSet<Key, Hash>::operator-=(const HashSet<Key, Hash>& rhs)
 {
-    // Remove rhs elements from lhs
-    for (const_iterator iter = rhs.cbegin(); iter != rhs.cend(); ++iter)
-    {
-        this->erase(iter.key());
-    }
+    this->parent_type::erase(rhs);
 }
 
 
diff --git a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
index 300fc111325b22d1cd863f9b94dacb5ae1641419..d6171ad585486595217201e44685c404cda8bfd4 100644
--- a/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
+++ b/src/OpenFOAM/containers/HashTables/HashSet/HashSet.H
@@ -277,7 +277,7 @@ public:
         void operator|=(const HashSet<Key, Hash>& rhs);
 
         //- Only retain entries found in both HashSets
-        void operator&=(const HashSet<Key, Hash>& rhs);
+        inline void operator&=(const HashSet<Key, Hash>& rhs);
 
         //- Only retain unique entries (xor)
         void operator^=(const HashSet<Key, Hash>& rhs);
@@ -289,7 +289,7 @@ public:
         }
 
         //- Remove entries listed in the given HashSet from this HashSet
-        void operator-=(const HashSet<Key, Hash>& rhs);
+        inline void operator-=(const HashSet<Key, Hash>& rhs);
 
 
     // IOstream Operator
diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C
index b0b96c5b19aec6d0e56f0678df055a31e59c8556..276f617dba102f5ef1fcc6b2005c0081f2553967 100644
--- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C
+++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.C
@@ -257,7 +257,7 @@ template<class T, class Key, class Hash>
 bool Foam::HashTable<T, Key, Hash>::set
 (
     const Key& key,
-    const T& newEntry,
+    const T& obj,
     const bool protect
 )
 {
@@ -284,7 +284,7 @@ bool Foam::HashTable<T, Key, Hash>::set
     if (!existing)
     {
         // Not found, insert it at the head
-        table_[hashIdx] = new hashedEntry(key, newEntry, table_[hashIdx]);
+        table_[hashIdx] = new hashedEntry(key, obj, table_[hashIdx]);
         nElmts_++;
 
         if (double(nElmts_)/tableSize_ > 0.8 && tableSize_ < maxTableSize)
@@ -316,7 +316,7 @@ bool Foam::HashTable<T, Key, Hash>::set
     {
         // Found - overwrite existing entry
         // this corresponds to the Perl convention
-        hashedEntry* ep = new hashedEntry(key, newEntry, existing->next_);
+        hashedEntry* ep = new hashedEntry(key, obj, existing->next_);
 
         // Replace existing element - within list or insert at the head
         if (prev)
@@ -411,7 +411,8 @@ bool Foam::HashTable<T, Key, Hash>::erase(const iterator& iter)
 template<class T, class Key, class Hash>
 bool Foam::HashTable<T, Key, Hash>::erase(const Key& key)
 {
-    return erase(find(key));
+    auto iter = find(key);
+    return erase(iter);
 }
 
 
@@ -450,15 +451,15 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
     const HashTable<AnyType, Key, AnyHash>& other
 )
 {
-    // Remove other keys from this table
     const label nTotal = this->size();
     label changed = 0;
 
-    if (other.size() < nTotal)
+    using other_iter =
+        typename HashTable<AnyType, Key, AnyHash>::const_iterator;
+
+    if (other.size() <= nTotal)
     {
-        // other is smaller, use its keys for removal
-        using other_iter =
-            typename HashTable<AnyType, Key, AnyHash>::const_iterator;
+        // The other is smaller/same-size, use its keys for removal
 
         for
         (
@@ -475,7 +476,7 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
     }
     else
     {
-        // other is same/larger: iterate ourselves and check for key in other
+        // We are smaller: remove if found in the other hash
         for
         (
             iterator iter = begin();
@@ -494,6 +495,39 @@ Foam::label Foam::HashTable<T, Key, Hash>::erase
 }
 
 
+template<class T, class Key, class Hash>
+template<class AnyType, class AnyHash>
+Foam::label Foam::HashTable<T, Key, Hash>::retain
+(
+    const HashTable<AnyType, Key, AnyHash>& other
+)
+{
+    const label nTotal = this->size();
+    label changed = 0;
+
+    if (other.empty())
+    {
+        // Trivial case
+        changed = nTotal;
+        this->clear();
+    }
+    else
+    {
+        // Inverted logic: remove if *not* found in the other hash
+
+        for (iterator iter = begin(); iter != end(); ++iter)
+        {
+            if (!other.found(iter.key()) && erase(iter))
+            {
+                ++changed;
+            }
+        }
+    }
+
+    return changed;
+}
+
+
 template<class T, class Key, class Hash>
 void Foam::HashTable<T, Key, Hash>::resize(const label sz)
 {
diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H
index bd60050ee443b517b9faaa4cb29caf923076c863..9eef011d10e1b471b8e0d246ed350805758bdeb4 100644
--- a/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H
+++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTable.H
@@ -44,6 +44,7 @@ Note
 SourceFiles
     HashTableI.H
     HashTable.C
+    HashTableCoreI.H
     HashTableCore.C
     HashTableIO.C
 
@@ -60,6 +61,7 @@ SourceFiles
 #include "nullObject.H"
 
 #include <initializer_list>
+#include <iterator>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -178,10 +180,17 @@ public:
         //- Type of values that the HashTable contains.
         typedef T value_type;
 
+        //- The type used for storing into value_type objects.
+        //  This type is usually value_type&.
+        typedef T* pointer;
+
         //- The type used for storing into value_type objects.
         //  This type is usually value_type&.
         typedef T& reference;
 
+        //- The type used for reading from constant value_type objects.
+        typedef const T* const_pointer;
+
         //- The type used for reading from constant value_type objects.
         typedef const T& const_reference;
 
@@ -247,7 +256,7 @@ private:
 
         //- Assign a new hash-entry to a possibly already existing key.
         //  Return true if the new entry was set.
-        bool set(const Key& key, const T& newEntry, const bool protect);
+        bool set(const Key& key, const T& obj, const bool protect);
 
 
 protected:
@@ -307,17 +316,20 @@ public:
         //- Return true if the hash table is empty
         inline bool empty() const;
 
-        //- Return true if hashedEntry is found in table
+        //- Return true if hashed entry is found in table
         bool found(const Key& key) const;
 
-        //- Find and return an iterator set at the hashedEntry
+        //- Find and return an iterator set at the hashed entry
         //  If not found iterator = end()
         iterator find(const Key& key);
 
-        //- Find and return an const_iterator set at the hashedEntry
+        //- Find and return an const_iterator set at the hashed entry
         //  If not found iterator = end()
         const_iterator find(const Key& key) const;
 
+        //- Return hashed entry if it exists, or return the given default
+        inline const T& lookup(const Key& key, const T& deflt) const;
+
         //- Return the table of contents
         List<Key> toc() const;
 
@@ -327,42 +339,58 @@ public:
 
       // Edit
 
-        //- Insert a new hashedEntry
+        //- Insert a new entry
         //  Return true if the entry inserted, which means that it did
         //  not previously exist in the table.
-        inline bool insert(const Key& key, const T& newEntry);
+        inline bool insert(const Key& key, const T& obj);
 
-        //- Assign a new hashedEntry, overwriting existing entries.
+        //- Assign a new entry, overwriting existing entries.
         //  Returns true.
-        inline bool set(const Key& key, const T& newEntry);
-
-        //- Erase a hashedEntry specified by given iterator
-        //  This invalidates the iterator until the next ++ operation
+        inline bool set(const Key& key, const T& obj);
+
+        //- Erase an entry specified by given iterator
+        //  This invalidates the iterator until the next ++ operation.
+        //
+        //  Includes a safeguard against the end-iterator such that the
+        //  following is safe:
+        //  \code
+        //      auto iter = table.find(unknownKey);
+        //      table.erase(iter);
+        //  \endcode
+        //  which is what \code table.erase(unknownKey) \endcode does anyhow
         bool erase(const iterator& iter);
 
-        //- Erase a hashedEntry specified by the given key
+        //- Erase an entry specified by the given key
         bool erase(const Key& key);
 
-        //- Remove entries given by the listed keys from this HashTable
+        //- Remove table entries given by the listed keys
         //  Return the number of elements removed
         label erase(const UList<Key>& keys);
 
-        //- Remove entries given by the listed keys from this HashTable
+        //- Remove table entries given by the listed keys
         //  Return the number of elements removed
         template<unsigned Size>
         label erase(const FixedList<Key, Size>& keys);
 
-        //- Remove entries given by the listed keys from this HashTable
+        //- Remove table entries given by the listed keys
         //  Return the number of elements removed
         label erase(std::initializer_list<Key> keys);
 
-        //- Remove entries given by the given keys from this HashTable
+        //- Remove table entries given by keys of the other hash-table.
         //  Return the number of elements removed.
-        //  The parameter HashTable needs the same type of key, but the
+        //
+        //  The other hash-table must have the same type of key, but the
         //  type of values held and the hashing function are arbitrary.
         template<class AnyType, class AnyHash>
         label erase(const HashTable<AnyType, Key, AnyHash>& other);
 
+        //- Retain table entries given by keys of the other hash-table.
+        //
+        //  The other hash-table must have the same type of key, but the
+        //  type of values held and the hashing function are arbitrary.
+        template<class AnyType, class AnyHash>
+        label retain(const HashTable<AnyType, Key, AnyHash>& other);
+
         //- Resize the hash table for efficiency
         void resize(const label sz);
 
@@ -383,10 +411,10 @@ public:
 
     // Member Operators
 
-        //- Find and return a hashedEntry
+        //- Find and return a hashed entry. FatalError if it does not exist.
         inline T& operator[](const Key& key);
 
-        //- Find and return a hashedEntry
+        //- Find and return a hashed entry. FatalError if it does not exist.
         inline const T& operator[](const Key& key) const;
 
         //- Return existing entry or create a new entry.
@@ -394,6 +422,12 @@ public:
         //  value-initialized. For primitives, this will be zero.
         inline T& operator()(const Key& key);
 
+        //- Return existing entry or insert a new entry.
+        inline T& operator()(const Key& key, const T& deflt);
+
+        //- Return hashed entry if it exists, or return the given default
+        inline const T& operator()(const Key& key, const T& deflt) const;
+
         //- Assignment
         void operator=(const HashTable<T, Key, Hash>& rhs);
 
@@ -423,6 +457,7 @@ protected:
             // Public typedefs
             using table_type = this_type;
             using key_type   = this_type::key_type;
+            using iterator_category = std::forward_iterator_tag;
             using difference_type  = this_type::difference_type;
 
         private:
@@ -500,16 +535,20 @@ public:
             public WrappedIterator
         {
         public:
+            using value_type = this_type::key_type;
+            using pointer    = const Key*;
             using reference  = const Key&;
-            using difference_type = typename WrappedIterator::difference_type;
 
             //- Implicit conversion
             inline key_iterator_base(const WrappedIterator& iter);
 
             //- Return the key
             inline reference operator*() const;
-        };
+            inline reference operator()() const;
 
+            inline key_iterator_base& operator++();
+            inline key_iterator_base operator++(int);
+        };
 
 
     // STL iterator
@@ -526,9 +565,9 @@ public:
 
           // Public typedefs
             using table_type = this_type;
-            using key_type   = this_type::key_type;
+            using value_type = this_type::value_type;
+            using pointer    = this_type::pointer;
             using reference  = this_type::reference;
-            using difference_type = typename iterator_base::difference_type;
 
           // Constructors
 
@@ -574,9 +613,9 @@ public:
 
           // Public typedefs
             using table_type = const this_type;
-            using key_type   = this_type::key_type;
+            using value_type = const this_type::value_type;
+            using pointer    = this_type::const_pointer;
             using reference  = this_type::const_reference;
-            using difference_type = typename iterator_base::difference_type;
 
           // Constructors
 
diff --git a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H
index f8df2437591dfafd274ff86cb9867d29d113767e..4d8028ca139e61ecd8a0d880d156e6888c199471 100644
--- a/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H
+++ b/src/OpenFOAM/containers/HashTables/HashTable/HashTableI.H
@@ -79,10 +79,10 @@ template<class T, class Key, class Hash>
 inline bool Foam::HashTable<T, Key, Hash>::insert
 (
     const Key& key,
-    const T& newEntry
+    const T& obj
 )
 {
-    return this->set(key, newEntry, true);
+    return this->set(key, obj, true);
 }
 
 
@@ -90,10 +90,10 @@ template<class T, class Key, class Hash>
 inline bool Foam::HashTable<T, Key, Hash>::set
 (
     const Key& key,
-    const T& newEntry
+    const T& obj
 )
 {
-    return this->set(key, newEntry, false);
+    return this->set(key, obj, false);
 }
 
 
@@ -105,6 +105,18 @@ Foam::HashTable<T, Key, Hash>::xfer()
 }
 
 
+template<class T, class Key, class Hash>
+inline const T& Foam::HashTable<T, Key, Hash>::lookup
+(
+    const Key& key,
+    const T& deflt
+) const
+{
+    const_iterator iter = this->find(key);
+    return iter.found() ? iter.object() : deflt;
+}
+
+
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 template<class T, class Key, class Hash>
@@ -156,6 +168,36 @@ inline T& Foam::HashTable<T, Key, Hash>::operator()(const Key& key)
 }
 
 
+template<class T, class Key, class Hash>
+inline T& Foam::HashTable<T, Key, Hash>::operator()
+(
+    const Key& key,
+    const T& deflt
+)
+{
+    iterator iter = this->find(key);
+
+    if (iter.found())
+    {
+        return iter.object();
+    }
+
+    this->insert(key, deflt);
+    return find(key).object();
+}
+
+
+template<class T, class Key, class Hash>
+inline const T& Foam::HashTable<T, Key, Hash>::operator()
+(
+    const Key& key,
+    const T& deflt
+) const
+{
+    return this->lookup(key, deflt);
+}
+
+
 // * * * * * * * * * * * * * * * iterator base * * * * * * * * * * * * * * * //
 
 template<class T, class Key, class Hash>
@@ -321,6 +363,39 @@ Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
 }
 
 
+template<class T, class Key, class Hash>
+template<class WrappedIterator>
+inline const Key&
+Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
+::operator()() const
+{
+    return this->key();
+}
+
+
+template<class T, class Key, class Hash>
+template<class WrappedIterator>
+inline Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>&
+Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
+::operator++()
+{
+    this->increment();
+    return *this;
+}
+
+
+template<class T, class Key, class Hash>
+template<class WrappedIterator>
+inline Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
+Foam::HashTable<T, Key, Hash>::key_iterator_base<WrappedIterator>
+::operator++(int)
+{
+    key_iterator_base old = *this;
+    this->increment();
+    return old;
+}
+
+
 // * * * * * * * * * * * * * * * * STL iterator  * * * * * * * * * * * * * * //
 
 template<class T, class Key, class Hash>
diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C
index 948a451d47f6695cf49afa0ce7633cd623e2de39..ec30dfc20a0e71eb4a4a631871adb6c2e0b18b02 100644
--- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C
+++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.C
@@ -203,7 +203,7 @@ template<class T, class Key, class Hash>
 bool Foam::StaticHashTable<T, Key, Hash>::set
 (
     const Key& key,
-    const T& newEntry,
+    const T& obj,
     const bool protect
 )
 {
@@ -229,7 +229,7 @@ bool Foam::StaticHashTable<T, Key, Hash>::set
         localObjects.setSize(existing+1);
 
         localKeys[existing] = key;
-        localObjects[existing] = newEntry;
+        localObjects[existing] = obj;
 
         nElmts_++;
     }
@@ -250,7 +250,7 @@ bool Foam::StaticHashTable<T, Key, Hash>::set
     {
         // Found - overwrite existing entry
         // this corresponds to the Perl convention
-        objects_[hashIdx][existing] = newEntry;
+        objects_[hashIdx][existing] = obj;
     }
 
     return true;
diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H
index 639a434d654dcf3f073e861714e0428e6ba0629c..5b0a3ef8a59fb88c9c94cd22278c46eda6765420 100644
--- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H
+++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTable.H
@@ -121,10 +121,10 @@ class StaticHashTable
 
         //- Return the hash index of the Key within the current table size.
         //  No checks for zero-sized tables.
-        inline label hashKeyIndex(const Key&) const;
+        inline label hashKeyIndex(const Key& key) const;
 
         //- Assign a new hashed entry to a possibly already existing key
-        bool set(const Key&, const T& newElmt, bool protect);
+        bool set(const Key& key, const T& obj, bool protect);
 
 
 public:
diff --git a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H
index cebb3852aa56de015e2067f4b415134b88bed8a0..2e6b5db0ea0e597a30bd6e2fe4481bd41f79b774 100644
--- a/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H
+++ b/src/OpenFOAM/containers/HashTables/StaticHashTable/StaticHashTableI.H
@@ -26,8 +26,6 @@ License
 #include "error.H"
 #include "IOstreams.H"
 
-// * * * * * * * * * * * * * Private Member Classes * * * * * * * * * * * * //
-
 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
 
 template<class T, class Key, class Hash>
@@ -59,10 +57,10 @@ template<class T, class Key, class Hash>
 inline bool Foam::StaticHashTable<T, Key, Hash>::insert
 (
     const Key& key,
-    const T& newEntry
+    const T& obj
 )
 {
-    return set(key, newEntry, true);
+    return set(key, obj, true);
 }
 
 
@@ -70,10 +68,10 @@ template<class T, class Key, class Hash>
 inline bool Foam::StaticHashTable<T, Key, Hash>::set
 (
     const Key& key,
-    const T& newEntry
+    const T& obj
 )
 {
-    return set(key, newEntry, false);
+    return set(key, obj, false);
 }
 
 
diff --git a/src/OpenFOAM/containers/LinkedLists/accessTypes/LList/LList.H b/src/OpenFOAM/containers/LinkedLists/accessTypes/LList/LList.H
index cac481545ebe5cf58d9176fcf80e33b74f4b3d60..eefabca3290bb76b3eece74e20a0b6b984bc709c 100644
--- a/src/OpenFOAM/containers/LinkedLists/accessTypes/LList/LList.H
+++ b/src/OpenFOAM/containers/LinkedLists/accessTypes/LList/LList.H
@@ -254,14 +254,14 @@ public:
 
             // Member operators
 
-                T& operator*()
+                T& operator*() const
                 {
                     return
                         static_cast<link&>
                         (LListBase_iterator::operator*()).obj_;
                 }
 
-                T& operator()()
+                T& operator()() const
                 {
                     return operator*();
                 }
@@ -312,14 +312,14 @@ public:
 
             // Member operators
 
-                const T& operator*()
+                const T& operator*() const
                 {
                     return
                         static_cast<const link&>
                         (LListBase_const_iterator::operator*()).obj_;
                 }
 
-                const T& operator()()
+                const T& operator()() const
                 {
                     return operator*();
                 }
diff --git a/src/OpenFOAM/containers/LinkedLists/accessTypes/LPtrList/LPtrList.H b/src/OpenFOAM/containers/LinkedLists/accessTypes/LPtrList/LPtrList.H
index e2b7e49a5aad4103a7470d553918eebe977378d8..a0e22917f9c7fc1b29a17e653c9ab838cb871497 100644
--- a/src/OpenFOAM/containers/LinkedLists/accessTypes/LPtrList/LPtrList.H
+++ b/src/OpenFOAM/containers/LinkedLists/accessTypes/LPtrList/LPtrList.H
@@ -196,12 +196,12 @@ public:
 
             // Member operators
 
-                T& operator*()
+                T& operator*() const
                 {
                     return *(LList<LListBase, T*>::iterator::operator*());
                 }
 
-                T& operator()()
+                T& operator()() const
                 {
                     return operator*();
                 }
@@ -235,12 +235,12 @@ public:
 
             // Member operators
 
-                const T& operator*()
+                const T& operator*() const
                 {
                     return *(LList<LListBase, T*>::const_iterator::operator*());
                 }
 
-                const T& operator()()
+                const T& operator()() const
                 {
                     return operator*();
                 }
diff --git a/src/OpenFOAM/containers/LinkedLists/accessTypes/UILList/UILList.H b/src/OpenFOAM/containers/LinkedLists/accessTypes/UILList/UILList.H
index 28d1231762f0e0713a2f5c834a9180eaa91a07fe..1f5b01b326424bf317df0a87e20bacc1cb8125c4 100644
--- a/src/OpenFOAM/containers/LinkedLists/accessTypes/UILList/UILList.H
+++ b/src/OpenFOAM/containers/LinkedLists/accessTypes/UILList/UILList.H
@@ -192,12 +192,12 @@ public:
 
             // Member operators
 
-                T& operator*()
+                T& operator*() const
                 {
                     return static_cast<T&>(LListBase_iterator::operator*());
                 }
 
-                T& operator()()
+                T& operator()() const
                 {
                     return operator*();
                 }
@@ -247,14 +247,14 @@ public:
 
             // Member operators
 
-                const T& operator*()
+                const T& operator*() const
                 {
                     return
                         static_cast<const T&>
                         (LListBase_const_iterator::operator*());
                 }
 
-                const T& operator()()
+                const T& operator()() const
                 {
                     return operator*();
                 }
@@ -309,14 +309,14 @@ public:
 
             // Member operators
 
-                const T& operator*()
+                const T& operator*() const
                 {
                     return
                         static_cast<const T&>
                         (LListBase::const_reverse_iterator::operator*());
                 }
 
-                const T& operator()()
+                const T& operator()() const
                 {
                     return operator*();
                 }
diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C
index e8e6b721c3f7f76c3449fa5bdf26de37093c5c96..f428836f43bab04790383273b1d2f8d127124852 100644
--- a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C
+++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.C
@@ -188,7 +188,7 @@ Foam::DLListBase::link* Foam::DLListBase::removeHead()
 
     if (!first_)
     {
-        last_ = 0;
+        last_ = nullptr;
     }
 
     f->deregister();
@@ -204,8 +204,8 @@ Foam::DLListBase::link* Foam::DLListBase::remove(DLListBase::link* l)
 
     if (l == first_ && first_ == last_)
     {
-        first_ = 0;
-        last_ = 0;
+        first_ = nullptr;
+        last_ = nullptr;
     }
     else if (l == first_)
     {
diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H
index 3208c250a964832ba77fbd535328533c98bc7f6b..d65363113eafaa3991bbc35040fda8dc8099e71c 100644
--- a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H
+++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBase.H
@@ -25,9 +25,10 @@ Class
     Foam::DLListBase
 
 Description
-    Base doubly-linked list.
+    Base for doubly-linked lists.
 
 SourceFiles
+    DLListBaseI.H
     DLListBase.C
 
 \*---------------------------------------------------------------------------*/
@@ -84,10 +85,10 @@ private:
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        DLListBase(const DLListBase&);
+        DLListBase(const DLListBase&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const DLListBase&);
+        void operator=(const DLListBase&) = delete;
 
 
 public:
@@ -184,18 +185,14 @@ public:
             friend class DLListBase;
             friend class const_iterator;
 
-            // Private data
+            //- Reference to the list this is an iterator for
+            DLListBase& curList_;
 
-                //- Reference to the list this is an iterator for
-                DLListBase& curList_;
+            //- Current element
+            link* curElmt_;
 
-                //- Current element
-                link* curElmt_;
-
-                //- Copy of the link
-                link curLink_;
-
-            // Private Member Functions
+            //- Copy of the link
+            link curLink_;
 
             //- Construct for a given SLListBase with nullptr element and link.
             //  Only used to create endIter
@@ -206,17 +203,18 @@ public:
             //- Construct for a given DLListBase and link
             inline iterator(DLListBase&, link*);
 
-            // Member operators
+            //- Currently pointing at a valid entry
+            inline bool found() const;
 
-                inline void operator=(const iterator&);
+            inline void operator=(const iterator& iter);
 
-                inline bool operator==(const iterator&) const;
-                inline bool operator!=(const iterator&) const;
+            inline bool operator==(const iterator& iter) const;
+            inline bool operator!=(const iterator& iter) const;
 
-                inline link& operator*();
+            inline link& operator*() const;
 
-                inline iterator& operator++();
-                inline iterator operator++(int);
+            inline iterator& operator++();
+            inline iterator operator++(int);
         };
 
         inline iterator begin();
@@ -228,13 +226,11 @@ public:
         //- An STL-conforming const_iterator
         class const_iterator
         {
-            // Private data
+            //- Reference to the list this is an iterator for
+            const DLListBase& curList_;
 
-                //- Reference to the list this is an iterator for
-                const DLListBase& curList_;
-
-                //- Current element
-                const link* curElmt_;
+            //- Current element
+            const link* curElmt_;
 
         public:
 
@@ -242,19 +238,20 @@ public:
             inline const_iterator(const DLListBase&, const link*);
 
             //- Construct from a non-const iterator
-            inline const_iterator(const iterator&);
+            inline const_iterator(const DLListBase::iterator& iter);
 
-            // Member operators
+            //- Currently pointing at a valid entry
+            inline bool found() const;
 
-                inline void operator=(const const_iterator&);
+            inline void operator=(const const_iterator& iter);
 
-                inline bool operator==(const const_iterator&) const;
-                inline bool operator!=(const const_iterator&) const;
+            inline bool operator==(const const_iterator& iter) const;
+            inline bool operator!=(const const_iterator& iter) const;
 
-                inline const link& operator*();
+            inline const link& operator*() const;
 
-                inline const_iterator& operator++();
-                inline const_iterator operator++(int);
+            inline const_iterator& operator++();
+            inline const_iterator operator++(int);
         };
 
         inline const_iterator cbegin() const;
@@ -269,30 +266,29 @@ public:
         //- An STL-conforming const_reverse_iterator
         class const_reverse_iterator
         {
-            // Private data
-
-                //- Reference to the list this is an reverse_iterator for
-                const DLListBase& curList_;
+            //- Reference to the list this is an reverse_iterator for
+            const DLListBase& curList_;
 
-                //- Current element
-                const link* curElmt_;
+            //- Current element
+            const link* curElmt_;
 
         public:
 
             //- Construct for a given DLListBase and link
-            inline const_reverse_iterator(const DLListBase&, const link*);
+            inline const_reverse_iterator(const DLListBase& lst, const link*);
 
-            // Member operators
+            //- Currently pointing at a valid entry
+            inline bool found() const;
 
-                inline void operator=(const const_reverse_iterator&);
+            inline void operator=(const const_reverse_iterator& iter);
 
-                inline bool operator==(const const_reverse_iterator&) const;
-                inline bool operator!=(const const_reverse_iterator&) const;
+            inline bool operator==(const const_reverse_iterator& iter) const;
+            inline bool operator!=(const const_reverse_iterator& iter) const;
 
-                inline const link& operator*();
+            inline const link& operator*() const;
 
-                inline const_reverse_iterator& operator++();
-                inline const_reverse_iterator operator++(int);
+            inline const_reverse_iterator& operator++();
+            inline const_reverse_iterator operator++(int);
         };
 
         inline const_reverse_iterator crbegin() const;
diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H
index 91c0bc9ddbd2c713c8a54b651b64740c0ff3095a..6dc080777a9b39d4c9a0a9a973023b3d5b9e9de0 100644
--- a/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H
+++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/DLListBase/DLListBaseI.H
@@ -29,15 +29,15 @@ License
 
 inline Foam::DLListBase::link::link()
 :
-    prev_(0),
-    next_(0)
+    prev_(nullptr),
+    next_(nullptr)
 {}
 
 
 inline Foam::DLListBase::DLListBase()
 :
-    first_(0),
-    last_(0),
+    first_(nullptr),
+    last_(nullptr),
     nElmts_(0)
 {}
 
@@ -63,14 +63,14 @@ inline Foam::DLListBase::~DLListBase()
 
 inline bool Foam::DLListBase::link::registered() const
 {
-    return prev_ != 0 && next_ != 0;
+    return prev_ != nullptr && next_ != nullptr;
 }
 
 
 inline void Foam::DLListBase::link::deregister()
 {
-    prev_ = 0;
-    next_ = 0;
+    prev_ = nullptr;
+    next_ = nullptr;
 }
 
 
@@ -140,8 +140,8 @@ Foam::DLListBase::last() const
 
 inline void Foam::DLListBase::clear()
 {
-    first_ = 0;
-    last_  = 0;
+    first_ = nullptr;
+    last_  = nullptr;
     nElmts_ = 0;
 }
 
@@ -195,6 +195,12 @@ inline Foam::DLListBase::iterator::iterator(DLListBase& s)
 {}
 
 
+inline bool Foam::DLListBase::iterator::found() const
+{
+    return (curElmt_ != nullptr);
+}
+
+
 inline void Foam::DLListBase::iterator::operator=(const iterator& iter)
 {
     curElmt_ = iter.curElmt_;
@@ -215,7 +221,7 @@ inline bool Foam::DLListBase::iterator::operator!=(const iterator& iter) const
 
 
 inline Foam::DLListBase::link&
-Foam::DLListBase::iterator::operator*()
+Foam::DLListBase::iterator::operator*() const
 {
     return *curElmt_;
 }
@@ -226,9 +232,9 @@ Foam::DLListBase::iterator::operator++()
 {
     // Check if the curElmt_ is the last element (if it points to itself)
     // or if the list is empty because the last element may have been removed
-    if (curLink_.next_ == curElmt_ || curList_.last_ == 0)
+    if (curLink_.next_ == curElmt_ || curList_.last_ == nullptr)
     {
-        curElmt_ = 0;
+        curElmt_ = nullptr;
     }
     else
     {
@@ -282,13 +288,22 @@ inline Foam::DLListBase::const_iterator::const_iterator
 {}
 
 
-inline Foam::DLListBase::const_iterator::const_iterator(const iterator& iter)
+inline Foam::DLListBase::const_iterator::const_iterator
+(
+    const DLListBase::iterator& iter
+)
 :
     curList_(iter.curList_),
     curElmt_(iter.curElmt_)
 {}
 
 
+inline bool Foam::DLListBase::const_iterator::found() const
+{
+    return (curElmt_ != nullptr);
+}
+
+
 inline void Foam::DLListBase::const_iterator::operator=
 (
     const const_iterator& iter
@@ -317,7 +332,7 @@ inline bool Foam::DLListBase::const_iterator::operator!=
 
 
 inline const Foam::DLListBase::link&
-Foam::DLListBase::const_iterator::operator*()
+Foam::DLListBase::const_iterator::operator*() const
 {
     return *curElmt_;
 }
@@ -328,7 +343,7 @@ Foam::DLListBase::const_iterator::operator++()
 {
     if (curElmt_ == curList_.last_)
     {
-        curElmt_ = 0;
+        curElmt_ = nullptr;
     }
     else
     {
@@ -387,15 +402,21 @@ Foam::DLListBase::end() const
 
 inline Foam::DLListBase::const_reverse_iterator::const_reverse_iterator
 (
-    const DLListBase& s,
+    const DLListBase& lst,
     const link* elmt
 )
 :
-    curList_(s),
+    curList_(lst),
     curElmt_(elmt)
 {}
 
 
+inline bool Foam::DLListBase::const_reverse_iterator::found() const
+{
+    return (curElmt_ != nullptr);
+}
+
+
 inline void Foam::DLListBase::const_reverse_iterator::operator=
 (
     const const_reverse_iterator& iter
@@ -424,7 +445,7 @@ inline bool Foam::DLListBase::const_reverse_iterator::operator!=
 
 
 inline const Foam::DLListBase::link&
-Foam::DLListBase::const_reverse_iterator::operator*()
+Foam::DLListBase::const_reverse_iterator::operator*() const
 {
     return *curElmt_;
 }
@@ -435,7 +456,7 @@ Foam::DLListBase::const_reverse_iterator::operator++()
 {
     if (curElmt_ == curList_.first_)
     {
-        curElmt_ = 0;
+        curElmt_ = nullptr;
     }
     else
     {
@@ -460,7 +481,7 @@ Foam::DLListBase::crbegin() const
 {
     if (size())
     {
-        return const_reverse_iterator(*this, last());
+        return const_reverse_iterator(*this, this->last());
     }
     else
     {
diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.C b/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.C
index c314cdc7528374d4f28607d01c5736f711cab6ca..693530d595a026350b94b87cb71c2f7b066f3ef8 100644
--- a/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.C
+++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.C
@@ -79,7 +79,7 @@ Foam::SLListBase::link* Foam::SLListBase::removeHead()
 {
     nElmts_--;
 
-    if (last_ == 0)
+    if (last_ == nullptr)
     {
         FatalErrorInFunction
             << "remove from empty list"
@@ -90,7 +90,7 @@ Foam::SLListBase::link* Foam::SLListBase::removeHead()
 
     if (f == last_)
     {
-        last_ = 0;
+        last_ = nullptr;
     }
     else
     {
@@ -132,7 +132,7 @@ Foam::SLListBase::link* Foam::SLListBase::remove(SLListBase::link* it)
         prev = p;
     }
 
-    return 0;
+    return nullptr;
 }
 
 
diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.H b/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.H
index add64244557da03a460dcc4e2614a6151ea11809..421922d3b867ff33eb3cd5b8b04bdc2d3bb8f70c 100644
--- a/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.H
+++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBase.H
@@ -25,9 +25,10 @@ Class
     Foam::SLListBase
 
 Description
-    Base singly-linked list.
+    Base for singly-linked lists.
 
 SourceFiles
+    SLListBaseI.H
     SLListBase.C
 
 \*---------------------------------------------------------------------------*/
@@ -81,10 +82,10 @@ private:
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
-        SLListBase(const SLListBase&);
+        SLListBase(const SLListBase&) = delete;
 
         //- Disallow default bitwise assignment
-        void operator=(const SLListBase&);
+        void operator=(const SLListBase&) = delete;
 
 
 public:
@@ -166,18 +167,14 @@ public:
             friend class SLListBase;
             friend class const_iterator;
 
-            // Private data
+            //- Reference to the list this is an iterator for
+            SLListBase& curList_;
 
-                //- Reference to the list this is an iterator for
-                SLListBase& curList_;
+            //- Current element
+            link* curElmt_;
 
-                //- Current element
-                link* curElmt_;
-
-                //- Copy of the link
-                link curLink_;
-
-            // Private Member Functions
+            //- Copy of the link
+            link curLink_;
 
             //- Construct for a given SLListBase with nullptr element and link.
             //  Only used to create endIter
@@ -188,17 +185,18 @@ public:
             //- Construct for a given SLListBase and link
             inline iterator(SLListBase&, link*);
 
-            // Member operators
+            //- Currently pointing at a valid entry
+            inline bool found() const;
 
-                inline void operator=(const iterator&);
+            inline void operator=(const iterator& iter);
 
-                inline bool operator==(const iterator&) const;
-                inline bool operator!=(const iterator&) const;
+            inline bool operator==(const iterator& iter) const;
+            inline bool operator!=(const iterator& iter) const;
 
-                inline link& operator*();
+            inline link& operator*() const;
 
-                inline iterator& operator++();
-                inline iterator operator++(int);
+            inline iterator& operator++();
+            inline iterator operator++(int);
         };
 
         inline iterator begin();
@@ -210,13 +208,11 @@ public:
         //- An STL-conforming const_iterator
         class const_iterator
         {
-            // Private data
+            //- Reference to the list this is an iterator for
+            const SLListBase& curList_;
 
-                //- Reference to the list this is an iterator for
-                const SLListBase& curList_;
-
-                //- Current element
-                const link* curElmt_;
+            //- Current element
+            const link* curElmt_;
 
         public:
 
@@ -224,20 +220,20 @@ public:
             inline const_iterator(const SLListBase&, const link*);
 
             //- Construct from a non-const iterator
-            inline const_iterator(const iterator&);
-
+            inline const_iterator(const SLListBase::iterator& iter);
 
-            // Member operators
+            //- Currently pointing at a valid entry
+            inline bool found() const;
 
-                inline void operator=(const const_iterator&);
+            inline void operator=(const const_iterator& iter);
 
-                inline bool operator==(const const_iterator&) const;
-                inline bool operator!=(const const_iterator&) const;
+            inline bool operator==(const const_iterator& iter) const;
+            inline bool operator!=(const const_iterator& iter) const;
 
-                inline const link& operator*();
+            inline const link& operator*() const;
 
-                inline const_iterator& operator++();
-                inline const_iterator operator++(int);
+            inline const_iterator& operator++();
+            inline const_iterator operator++(int);
         };
 
         inline const_iterator cbegin() const;
diff --git a/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBaseI.H b/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBaseI.H
index fc9b9f007c05336e157a6b2b8388a85414b69a6d..8c4ebdb7c372a2f1b38972123126918c32be2360 100644
--- a/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBaseI.H
+++ b/src/OpenFOAM/containers/LinkedLists/linkTypes/SLListBase/SLListBaseI.H
@@ -21,9 +21,6 @@ License
     You should have received a copy of the GNU General Public License
     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 
-Description
-    Base singly-linked list.
-
 \*---------------------------------------------------------------------------*/
 
 #include "error.H"
@@ -32,7 +29,7 @@ Description
 
 inline Foam::SLListBase::link::link()
 :
-    next_(0)
+    next_(nullptr)
 {}
 
 
@@ -44,16 +41,22 @@ inline Foam::SLListBase::link::link(link* p)
 
 inline Foam::SLListBase::SLListBase()
 :
-    last_(0),
+    last_(nullptr),
     nElmts_(0)
 {}
 
 
 inline Foam::SLListBase::SLListBase(link* a)
 :
-    last_(a->next_ = a),
-    nElmts_(1)
-{}
+    last_(a),
+    nElmts_(0)
+{
+    if (a)  // protect against nullptr
+    {
+        a->next_ = a;
+        nElmts_  = 1;
+    }
+}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
@@ -130,7 +133,7 @@ Foam::SLListBase::last() const
 
 inline void Foam::SLListBase::clear()
 {
-    last_ = 0;
+    last_ = nullptr;
     nElmts_ = 0;
 }
 
@@ -171,6 +174,12 @@ inline Foam::SLListBase::iterator::iterator(SLListBase& s)
 {}
 
 
+inline bool Foam::SLListBase::iterator::found() const
+{
+    return (curElmt_ != nullptr);
+}
+
+
 inline void Foam::SLListBase::iterator::operator=(const iterator& iter)
 {
     curElmt_ = iter.curElmt_;
@@ -190,7 +199,7 @@ inline bool Foam::SLListBase::iterator::operator!=(const iterator& iter) const
 }
 
 
-inline Foam::SLListBase::link& Foam::SLListBase::iterator::operator*()
+inline Foam::SLListBase::link& Foam::SLListBase::iterator::operator*() const
 {
     return *curElmt_;
 }
@@ -198,9 +207,9 @@ inline Foam::SLListBase::link& Foam::SLListBase::iterator::operator*()
 
 inline Foam::SLListBase::iterator& Foam::SLListBase::iterator::operator++()
 {
-    if (curElmt_ == curList_.last_ || curList_.last_ == 0)
+    if (curElmt_ == curList_.last_ || curList_.last_ == nullptr)
     {
-        curElmt_ = 0;
+        curElmt_ = nullptr;
     }
     else
     {
@@ -255,13 +264,22 @@ inline Foam::SLListBase::const_iterator::const_iterator
 {}
 
 
-inline Foam::SLListBase::const_iterator::const_iterator(const iterator& iter)
+inline Foam::SLListBase::const_iterator::const_iterator
+(
+    const SLListBase::iterator& iter
+)
 :
     curList_(iter.curList_),
     curElmt_(iter.curElmt_)
 {}
 
 
+inline bool Foam::SLListBase::const_iterator::found() const
+{
+    return (curElmt_ != nullptr);
+}
+
+
 inline void Foam::SLListBase::const_iterator::operator=
 (
     const const_iterator& iter
@@ -290,7 +308,7 @@ inline bool Foam::SLListBase::const_iterator::operator!=
 
 
 inline const Foam::SLListBase::link&
-Foam::SLListBase::const_iterator::operator*()
+Foam::SLListBase::const_iterator::operator*() const
 {
     return *curElmt_;
 }
@@ -301,7 +319,7 @@ Foam::SLListBase::const_iterator::operator++()
 {
     if (curElmt_ == curList_.last_)
     {
-        curElmt_ = 0;
+        curElmt_ = nullptr;
     }
     else
     {
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
index be198f8ffabd8713e98672d3150afb11c09e2303..6c03173401e8566d01371df78e450a2d664ef060 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
@@ -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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -59,14 +59,14 @@ class DynamicList;
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 Ostream& operator<<
 (
-    Ostream&,
-    const DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+    Ostream& os,
+    const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
 );
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 Istream& operator>>
 (
-    Istream&,
-    DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+    Istream& is,
+    DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
 );
 
 
@@ -105,29 +105,37 @@ public:
         inline DynamicList();
 
         //- Construct given size.
-        explicit inline DynamicList(const label);
+        explicit inline DynamicList(const label nElem);
 
         //- Construct with given size and value for all elements.
-        inline DynamicList(const label, const T&);
+        inline DynamicList(const label nElem, const T& a);
 
         //- Construct copy.
-        inline DynamicList(const DynamicList<T, SizeInc, SizeMult, SizeDiv>&);
+        inline DynamicList
+        (
+            const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
+        );
 
         //- Construct from UList. Size set to UList size.
         //  Also constructs from DynamicList with different sizing parameters.
-        explicit inline DynamicList(const UList<T>&);
+        explicit inline DynamicList(const UList<T>& lst);
+
+        //- Construct given begin/end iterators.
+        //  Uses std::distance to determine the size.
+        template<class InputIterator>
+        inline DynamicList(InputIterator begIter, InputIterator endIter);
 
         //- Construct from an initializer list. Size set to list size.
-        explicit inline DynamicList(std::initializer_list<T>);
+        explicit inline DynamicList(std::initializer_list<T> lst);
 
         //- Construct from UIndirectList. Size set to UIndirectList size.
-        explicit inline DynamicList(const UIndirectList<T>&);
+        explicit inline DynamicList(const UIndirectList<T>& lst);
 
         //- Construct by transferring the parameter contents
-        explicit inline DynamicList(const Xfer<List<T>>&);
+        explicit inline DynamicList(const Xfer<List<T>>& lst);
 
         //- Construct from Istream. Size set to size of list read.
-        explicit DynamicList(Istream&);
+        explicit DynamicList(Istream& is);
 
 
     // Member Functions
@@ -143,31 +151,31 @@ public:
             //  The addressed size will be truncated if needed to fit, but will
             //  remain otherwise untouched.
             //  Use this or reserve() in combination with append().
-            inline void setCapacity(const label);
+            inline void setCapacity(const label nElem);
 
             //- Alter the addressed list size.
             //  New space will be allocated if required.
             //  Use this to resize the list prior to using the operator[] for
             //  setting values (as per List usage).
-            inline void setSize(const label);
+            inline void setSize(const label nElem);
 
             //- Alter the addressed list size and fill new space with a
             //  constant.
-            inline void setSize(const label, const T&);
+            inline void setSize(const label nElem, const T& t);
 
             //- Alter the addressed list size.
             //  New space will be allocated if required.
             //  Use this to resize the list prior to using the operator[] for
             //  setting values (as per List usage).
-            inline void resize(const label);
+            inline void resize(const label nElem);
 
             //- Alter the addressed list size and fill new space with a
             //  constant.
-            inline void resize(const label, const T&);
+            inline void resize(const label nElem, const T& t);
 
             //- Reserve allocation space for at least this size.
             //  Never shrinks the allocated size, use setCapacity() for that.
-            inline void reserve(const label);
+            inline void reserve(const label nElem);
 
             //- Clear the addressed list, i.e. set the size to zero.
             //  Allocated size does not change
@@ -181,10 +189,13 @@ public:
             inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& shrink();
 
             //- Transfer contents of the argument List into this.
-            inline void transfer(List<T>&);
+            inline void transfer(List<T>& lst);
 
             //- Transfer contents of the argument DynamicList into this.
-            inline void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>&);
+            inline void transfer
+            (
+                DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
+            );
 
             //- Transfer contents to the Xfer container as a plain List
             inline Xfer<List<T>> xfer();
@@ -195,25 +206,25 @@ public:
             //- Append an element at the end of the list
             inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
             (
-                const T&
+                const T& t
             );
 
             //- Append a List at the end of this list
             inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
             (
-                const UList<T>&
+                const UList<T>& lst
             );
 
             //- Append an initializer list at the end of this list.
             inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
             (
-                std::initializer_list<T>
+                std::initializer_list<T> lst
             );
 
             //- Append a UIndirectList at the end of this list
             inline DynamicList<T, SizeInc, SizeMult, SizeDiv>& append
             (
-                const UIndirectList<T>&
+                const UIndirectList<T>& lst
             );
 
             //- Remove and return the top element
@@ -221,32 +232,35 @@ public:
 
             //- Return non-const access to an element, resizing list if
             //  necessary
-            inline T& operator()(const label);
+            inline T& operator()(const label elemI);
 
             //- Assignment of all addressed entries to the given value
-            inline void operator=(const T&);
+            inline void operator=(const T& t);
 
             //- Assignment to DynamicList
             inline void operator=
             (
-                const DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+                const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
             );
 
             //- Assignment to UList
-            inline void operator=(const UList<T>&);
+            inline void operator=(const UList<T>& lst);
 
             //- Assignment from initializer list
-            inline void operator=(std::initializer_list<T>);
+            inline void operator=(std::initializer_list<T> lst);
 
             //- Assignment to UIndirectList
-            inline void operator=(const UIndirectList<T>&);
+            inline void operator=(const UIndirectList<T>& lst);
 
 
         // STL member functions
 
             //- Erase an element, move the remaining elements to fill the gap
             //  and resize the List
-            typename UList<T>::iterator erase(typename UList<T>::iterator);
+            typename UList<T>::iterator erase
+            (
+                typename UList<T>::iterator curIter
+            );
 
 
         // IOstream operators
@@ -254,15 +268,15 @@ public:
             // Write DynamicList to Ostream.
             friend Ostream& operator<< <T, SizeInc, SizeMult, SizeDiv>
             (
-                Ostream&,
-                const DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+                Ostream& os,
+                const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
             );
 
             //- Read from Istream, discarding contents of existing DynamicList.
             friend Istream& operator>> <T, SizeInc, SizeMult, SizeDiv>
             (
-                Istream&,
-                DynamicList<T, SizeInc, SizeMult, SizeDiv>&
+                Istream& is,
+                DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
             );
 };
 
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
index 82f28f5cb5552f284db7cf05882ef9dd905e6291..e6ba973b48af96f1b5e83c46215745805f1dc588 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
@@ -80,6 +80,19 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
 {}
 
 
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+template<class InputIterator>
+inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
+(
+    InputIterator begIter,
+    InputIterator endIter
+)
+:
+    List<T>(begIter, endIter),
+    capacity_(this->size())
+{}
+
+
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
 (
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
index bdf75aa40101e8f61511b421a3318a09c0d88179..dce2cad0c63a23bd6c797d67d630fc31702584e6 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedList.H
@@ -128,11 +128,12 @@ public:
         explicit inline FixedList(const T& t);
 
         //- Construct from C-array
-        explicit inline FixedList(const T v[Size]);
+        explicit inline FixedList(const T lst[Size]);
 
-        //- Construct given start and end iterators
+        //- Construct given begin/end iterators
+        //  Uses std::distance when verifying the size.
         template<class InputIterator>
-        inline FixedList(InputIterator first, InputIterator last);
+        inline FixedList(InputIterator begIter, InputIterator endIter);
 
         //- Construct from an initializer list
         inline FixedList(std::initializer_list<T> lst);
diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
index 2f97b931690bcc67f3bc597a635db4faeca3b6d1..1df4fb958a0ba6bf8d3c4c9b813e51072794e946 100644
--- a/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
+++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListI.H
@@ -37,7 +37,7 @@ inline Foam::FixedList<T, Size>::FixedList()
 template<class T, unsigned Size>
 inline Foam::FixedList<T, Size>::FixedList(const T& t)
 {
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = t;
     }
@@ -45,11 +45,11 @@ inline Foam::FixedList<T, Size>::FixedList(const T& t)
 
 
 template<class T, unsigned Size>
-inline Foam::FixedList<T, Size>::FixedList(const T v[Size])
+inline Foam::FixedList<T, Size>::FixedList(const T lst[Size])
 {
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
-        v_[i] = v[i];
+        v_[i] = lst[i];
     }
 }
 
@@ -58,25 +58,33 @@ template<class T, unsigned Size>
 template<class InputIterator>
 Foam::FixedList<T, Size>::FixedList
 (
-    InputIterator first,
-    InputIterator last
+    InputIterator begIter,
+    InputIterator endIter
 )
 {
-    checkSize(std::distance(first, last));
+    checkSize(std::distance(begIter, endIter));
 
-    InputIterator iter = first;
-    for (unsigned i=0; i<Size; i++)
+    InputIterator iter = begIter;
+    for (unsigned i=0; i<Size; ++i)
     {
-        v_[i] = *iter++;
+        v_[i] = *iter;
+        ++iter;
     }
 }
 
 
 template<class T, unsigned Size>
 inline Foam::FixedList<T, Size>::FixedList(std::initializer_list<T> lst)
-:
-    FixedList<T, Size>(lst.begin(), lst.end())
-{}
+{
+    checkSize(lst.size());
+
+    auto iter = lst.begin();
+    for (unsigned i=0; i<Size; ++i)
+    {
+        v_[i] = *iter;
+        ++iter;
+    }
+}
 
 
 template<class T, unsigned Size>
@@ -84,7 +92,7 @@ inline Foam::FixedList<T, Size>::FixedList(const UList<T>& lst)
 {
     checkSize(lst.size());
 
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = lst[i];
     }
@@ -97,9 +105,10 @@ inline Foam::FixedList<T, Size>::FixedList(const SLList<T>& lst)
     checkSize(lst.size());
 
     typename SLList<T>::const_iterator iter = lst.begin();
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
-        v_[i] = *iter++;
+        v_[i] = *iter;
+        ++iter;
     }
 }
 
@@ -107,7 +116,7 @@ inline Foam::FixedList<T, Size>::FixedList(const SLList<T>& lst)
 template<class T, unsigned Size>
 inline Foam::FixedList<T, Size>::FixedList(const FixedList<T, Size>& lst)
 {
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = lst[i];
     }
@@ -200,7 +209,7 @@ inline void Foam::FixedList<T, Size>::setSize(const label s)
 template<class T, unsigned Size>
 inline void Foam::FixedList<T, Size>::transfer(const FixedList<T, Size>& lst)
 {
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = lst[i];
     }
@@ -276,7 +285,7 @@ inline const T& Foam::FixedList<T, Size>::operator[](const label i) const
 template<class T, unsigned Size>
 inline void Foam::FixedList<T, Size>::operator=(const T lst[Size])
 {
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = lst[i];
     }
@@ -287,7 +296,7 @@ inline void Foam::FixedList<T, Size>::operator=(const UList<T>& lst)
 {
     checkSize(lst.size());
 
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = lst[i];
     }
@@ -299,9 +308,10 @@ inline void Foam::FixedList<T, Size>::operator=(const SLList<T>& lst)
     checkSize(lst.size());
 
     typename SLList<T>::const_iterator iter = lst.begin();
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
-        v_[i] = *iter++;
+        v_[i] = *iter;
+        ++iter;
     }
 }
 
@@ -310,17 +320,18 @@ inline void Foam::FixedList<T, Size>::operator=(std::initializer_list<T> lst)
 {
     checkSize(lst.size());
 
-    typename std::initializer_list<T>::iterator iter = lst.begin();
-    for (unsigned i=0; i<Size; i++)
+    auto iter = lst.begin();
+    for (unsigned i=0; i<Size; ++i)
     {
-        v_[i] = *iter++;
+        v_[i] = *iter;
+        ++iter;
     }
 }
 
 template<class T, unsigned Size>
 inline void Foam::FixedList<T, Size>::operator=(const T& t)
 {
-    for (unsigned i=0; i<Size; i++)
+    for (unsigned i=0; i<Size; ++i)
     {
         v_[i] = t;
     }
@@ -464,7 +475,7 @@ inline unsigned Foam::FixedList<T, Size>::Hash<HashT>::operator()
         // Hash incrementally
         unsigned val = seed;
 
-        for (unsigned i=0; i<Size; i++)
+        for (unsigned i=0; i<Size; ++i)
         {
             val = HashT()(lst[i], val);
         }
diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C
index 0e4dee96ac722d7c05d9f0127181dcd3dd8abfb4..6ba01a2edc0033cd7af582c7217e664a41e55141 100644
--- a/src/OpenFOAM/containers/Lists/List/List.C
+++ b/src/OpenFOAM/containers/Lists/List/List.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  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -160,7 +160,7 @@ Foam::List<T>::List(List<T>& a, bool reuse)
     if (reuse)
     {
         this->v_ = a.v_;
-        a.v_ = 0;
+        a.v_ = nullptr;
         a.size_ = 0;
     }
     else if (this->size_)
@@ -186,19 +186,19 @@ Foam::List<T>::List(List<T>& a, bool reuse)
 
 
 template<class T>
-Foam::List<T>::List(const UList<T>& a, const labelUList& map)
+Foam::List<T>::List(const UList<T>& a, const labelUList& mapAddressing)
 :
-    UList<T>(nullptr, map.size())
+    UList<T>(nullptr, mapAddressing.size())
 {
     if (this->size_)
     {
-        // Note:cannot use List_ELEM since third argument has to be index.
+        // Note: cannot use List_ELEM since third argument has to be index.
 
         alloc();
 
         forAll(*this, i)
         {
-            this->operator[](i) = a[map[i]];
+            this->operator[](i) = a[mapAddressing[i]];
         }
     }
 }
@@ -206,9 +206,9 @@ Foam::List<T>::List(const UList<T>& a, const labelUList& map)
 
 template<class T>
 template<class InputIterator>
-Foam::List<T>::List(InputIterator first, InputIterator last)
+Foam::List<T>::List(InputIterator begIter, InputIterator endIter)
 :
-    List<T>(first, last, std::distance(first, last))
+    List<T>(begIter, endIter, std::distance(begIter, endIter))
 {}
 
 
@@ -231,6 +231,8 @@ Foam::List<T>::List(const PtrList<T>& lst)
 }
 
 
+// Note: using first/last is not entirely accurate.
+// But since the list size is correct, last() is actually ignored.
 template<class T>
 Foam::List<T>::List(const SLList<T>& lst)
 :
@@ -259,7 +261,7 @@ Foam::List<T>::List(const BiIndirectList<T>& lst)
 template<class T>
 Foam::List<T>::List(std::initializer_list<T> lst)
 :
-    List<T>(lst.begin(), lst.end())
+    List<T>(lst.begin(), lst.end(), lst.size())
 {}
 
 
@@ -326,7 +328,7 @@ void Foam::List<T>::setSize(const label newSize)
 template<class T>
 void Foam::List<T>::setSize(const label newSize, const T& a)
 {
-    label oldSize = label(this->size_);
+    const label oldSize = label(this->size_);
     this->setSize(newSize);
 
     if (newSize > oldSize)
@@ -346,7 +348,7 @@ void Foam::List<T>::transfer(List<T>& a)
     this->v_ = a.v_;
 
     a.size_ = 0;
-    a.v_ = 0;
+    a.v_ = nullptr;
 }
 
 
@@ -419,14 +421,9 @@ void Foam::List<T>::operator=(const SLList<T>& lst)
     if (this->size_)
     {
         label i = 0;
-        for
-        (
-            typename SLList<T>::const_iterator iter = lst.begin();
-            iter != lst.end();
-            ++iter
-        )
+        for (auto iter = lst.cbegin(); iter != lst.cend(); ++iter)
         {
-            this->operator[](i++) = iter();
+            this->operator[](i++) = *iter;
         }
     }
 }
@@ -453,10 +450,11 @@ void Foam::List<T>::operator=(std::initializer_list<T> lst)
 {
     reAlloc(lst.size());
 
-    typename std::initializer_list<T>::iterator iter = lst.begin();
+    auto iter = lst.begin();
     forAll(*this, i)
     {
-        this->operator[](i) = *iter++;
+        this->operator[](i) = *iter;
+        ++iter;
     }
 }
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H
index fdb4559bf75ec8abed82d79bd914775871290cea..c8e3219d9928ad7eaf106a1bbe3c437b1ccf827f 100644
--- a/src/OpenFOAM/containers/Lists/List/List.H
+++ b/src/OpenFOAM/containers/Lists/List/List.H
@@ -58,7 +58,7 @@ class Ostream;
 // Forward declaration of friend functions and operators
 template<class T> class List;
 
-template<class T> Istream& operator>>(Istream&, List<T>&);
+template<class T> Istream& operator>>(Istream& is, List<T>& L);
 
 template<class T, unsigned Size> class FixedList;
 template<class T> class PtrList;
@@ -95,22 +95,28 @@ class List
 
         //- Copy list of given type
         template<class List2>
-        inline void copyList(const List2&);
+        inline void copyList(const List2& lst);
 
         //- Allocate storage and copy list of given type
         template<class List2>
-        inline void allocCopyList(const List2&);
+        inline void allocCopyList(const List2& lst);
 
-        //- Construct given start and end iterators and number of elements
+        //- Construct given begin/end iterators and number of elements
+        //  Since the size is provided, the end iterator is actually ignored.
         template<class InputIterator>
-        inline List(InputIterator first, InputIterator last, const label s);
+        inline List
+        (
+            InputIterator begIter,
+            InputIterator endIter,
+            const label s
+        );
 
 
 protected:
 
     //- Override size to be inconsistent with allocated storage.
     //  Use with care
-    inline void size(const label);
+    inline void size(const label n);
 
 
 public:
@@ -127,55 +133,56 @@ public:
         inline List();
 
         //- Construct with given size
-        explicit List(const label);
+        explicit List(const label s);
 
         //- Construct with given size and value for all elements
-        List(const label, const T&);
+        List(const label s, const T& a);
 
         //- Construct with given size initializing all elements to zero
-        List(const label, const zero);
+        List(const label s, const zero);
 
         //- Copy constructor
-        List(const List<T>&);
+        List(const List<T>& a);
 
         //- Copy constructor from list containing another type
         template<class T2>
-        explicit List(const List<T2>&);
+        explicit List(const List<T2>& a);
 
         //- Construct by transferring the parameter contents
-        List(const Xfer<List<T>>&);
+        List(const Xfer<List<T>>& lst);
 
         //- Construct as copy or re-use as specified
-        List(List<T>&, bool reuse);
+        List(List<T>& a, bool reuse);
 
         //- Construct as subset
-        List(const UList<T>&, const labelUList& mapAddressing);
+        List(const UList<T>& a, const labelUList& mapAddressing);
 
-        //- Construct given start and end iterators
+        //- Construct given begin/end iterators.
+        //  Uses std::distance to determine the size.
         template<class InputIterator>
-        List(InputIterator first, InputIterator last);
+        List(InputIterator begIter, InputIterator endIter);
 
         //- Construct as copy of FixedList<T, Size>
         template<unsigned Size>
-        explicit List(const FixedList<T, Size>&);
+        explicit List(const FixedList<T, Size>& lst);
 
         //- Construct as copy of PtrList<T>
-        explicit List(const PtrList<T>&);
+        explicit List(const PtrList<T>& lst);
 
         //- Construct as copy of SLList<T>
-        explicit List(const SLList<T>&);
+        explicit List(const SLList<T>& lst);
 
         //- Construct as copy of UIndirectList<T>
-        explicit List(const UIndirectList<T>&);
+        explicit List(const UIndirectList<T>& lst);
 
         //- Construct as copy of BiIndirectList<T>
-        explicit List(const BiIndirectList<T>&);
+        explicit List(const BiIndirectList<T>& lst);
 
         //- Construct from an initializer list
-        List(std::initializer_list<T>);
+        List(std::initializer_list<T> lst);
 
         //- Construct from Istream
-        List(Istream&);
+        List(Istream& is);
 
         //- Clone
         inline autoPtr<List<T>> clone() const;
@@ -200,47 +207,48 @@ public:
         // Edit
 
             //- Alias for setSize(const label)
-            inline void resize(const label);
+            inline void resize(const label newSize);
 
             //- Alias for setSize(const label, const T&)
-            inline void resize(const label, const T&);
+            inline void resize(const label newSize, const T& a);
 
             //- Reset size of List
-            void setSize(const label);
+            void setSize(const label newSize);
 
             //- Reset size of List and value for new elements
-            void setSize(const label, const T&);
+            void setSize(const label newSize, const T& a);
 
             //- Clear the list, i.e. set size to zero
             inline void clear();
 
             //- Append an element at the end of the list
-            inline void append(const T&);
+            inline void append(const T& t);
 
             //- Append a List at the end of this list
-            inline void append(const UList<T>&);
+            inline void append(const UList<T>& lst);
 
             //- Append a UIndirectList at the end of this list
-            inline void append(const UIndirectList<T>&);
+            inline void append(const UIndirectList<T>& lst);
 
             //- Transfer the contents of the argument List into this list
             //  and annul the argument list
-            void transfer(List<T>&);
+            void transfer(List<T>& a);
 
             //- Transfer the contents of the argument List into this list
             //  and annul the argument list
             template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-            void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>&);
+            void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a);
 
             //- Transfer the contents of the argument List into this list
             //  and annul the argument list
-            void transfer(SortableList<T>&);
+            void transfer(SortableList<T>& a);
 
             //- Transfer contents to the Xfer container
             inline Xfer<List<T>> xfer();
 
-            //- Return subscript-checked element of UList
-            inline T& newElmt(const label);
+            //- Return subscript-checked element of UList.
+            //  Resize list if required.
+            inline T& newElmt(const label i);
 
 
         //- Disallow implicit shallowCopy
@@ -250,25 +258,25 @@ public:
     // Member operators
 
         //- Assignment to UList operator. Takes linear time
-        void operator=(const UList<T>&);
+        void operator=(const UList<T>& a);
 
         //- Assignment operator. Takes linear time
-        void operator=(const List<T>&);
+        void operator=(const List<T>& a);
 
         //- Assignment to SLList operator. Takes linear time
-        void operator=(const SLList<T>&);
+        void operator=(const SLList<T>& lst);
 
         //- Assignment to UIndirectList operator. Takes linear time
-        void operator=(const UIndirectList<T>&);
+        void operator=(const UIndirectList<T>& lst);
 
         //- Assignment to BiIndirectList operator. Takes linear time
-        void operator=(const BiIndirectList<T>&);
+        void operator=(const BiIndirectList<T>& lst);
 
         //- Assignment to an initializer list
-        void operator=(std::initializer_list<T>);
+        void operator=(std::initializer_list<T> lst);
 
         //- Assignment of all entries to the given value
-        inline void operator=(const T&);
+        inline void operator=(const T& t);
 
         //- Assignment of all entries to zero
         inline void operator=(const zero);
@@ -278,7 +286,7 @@ public:
 
         //- Read List from Istream, discarding contents of existing List
         friend Istream& operator>> <T>
-        (Istream&, List<T>&);
+        (Istream& is, List<T>& L);
 };
 
 
@@ -290,7 +298,7 @@ public:
 //  \endcode
 //  Mostly useful for handling command-line arguments
 template<class T>
-List<T> readList(Istream&);
+List<T> readList(Istream& is);
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/containers/Lists/List/ListI.H b/src/OpenFOAM/containers/Lists/List/ListI.H
index 5709c258ec7e2642aa1a478d36ab2f17fe8b5627..8aa5bc016aaad44c4cb7f46a2085aab832a2b5b0 100644
--- a/src/OpenFOAM/containers/Lists/List/ListI.H
+++ b/src/OpenFOAM/containers/Lists/List/ListI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -77,8 +77,8 @@ template<class T>
 template<class InputIterator>
 inline Foam::List<T>::List
 (
-    InputIterator first,
-    InputIterator last,
+    InputIterator begIter,
+    InputIterator endIter,
     const label s
 )
 :
@@ -88,10 +88,11 @@ inline Foam::List<T>::List
     {
         alloc();
 
-        InputIterator iter = first;
+        InputIterator iter = begIter;
         forAll(*this, i)
         {
-            this->operator[](i) = *iter++;
+            this->operator[](i) = *iter;
+            ++iter;
         }
     }
 }
@@ -126,7 +127,7 @@ inline void Foam::List<T>::clear()
     if (this->v_)
     {
         delete[] this->v_;
-        this->v_ = 0;
+        this->v_ = nullptr;
     }
 
     this->size_ = 0;
diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
index fbafc9cf0fb4731eb84e193908ed70246f8c9df1..a35334507aa58d979fa3263ea3ef1b4bbc3c0ef8 100644
--- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
+++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
@@ -28,7 +28,7 @@ License
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class T>
-Foam::SortableList<T>::SortableList()
+inline Foam::SortableList<T>::SortableList()
 {}
 
 
@@ -51,14 +51,14 @@ Foam::SortableList<T>::SortableList(const Xfer<List<T>>& values)
 
 
 template<class T>
-Foam::SortableList<T>::SortableList(const label size)
+inline Foam::SortableList<T>::SortableList(const label size)
 :
     List<T>(size)
 {}
 
 
 template<class T>
-Foam::SortableList<T>::SortableList(const label size, const T& val)
+inline Foam::SortableList<T>::SortableList(const label size, const T& val)
 :
     List<T>(size, val)
 {}
@@ -72,6 +72,20 @@ Foam::SortableList<T>::SortableList(const SortableList<T>& lst)
 {}
 
 
+template<class T>
+template<class InputIterator>
+inline Foam::SortableList<T>::SortableList
+(
+    InputIterator begIter,
+    InputIterator endIter
+)
+:
+    List<T>(begIter, endIter)
+{
+    sort();
+}
+
+
 template<class T>
 Foam::SortableList<T>::SortableList(std::initializer_list<T> values)
 :
@@ -140,9 +154,9 @@ Foam::Xfer<Foam::List<T>> Foam::SortableList<T>::xfer()
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 template<class T>
-inline void Foam::SortableList<T>::operator=(const T& t)
+inline void Foam::SortableList<T>::operator=(const T& val)
 {
-    UList<T>::operator=(t);
+    UList<T>::operator=(val);
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
index 65fb6dc7f41e700d6db90b1f542c9afe9242e5de..cd005a09c2f42e2905ab509642627a6de5bd8fab 100644
--- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
+++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
@@ -65,27 +65,32 @@ public:
     // Constructors
 
         //- Null constructor, sort later (eg, after assignment or transfer)
-        SortableList();
+        inline SortableList();
 
         //- Construct from UList, sorting immediately
-        explicit SortableList(const UList<T>&);
+        explicit SortableList(const UList<T>& values);
 
         //- Construct from transferred List, sorting immediately
-        explicit SortableList(const Xfer<List<T>>&);
+        explicit SortableList(const Xfer<List<T>>& values);
 
         //- Construct given size. Sort later on
         //  The indices remain empty until the list is sorted
-        explicit SortableList(const label size);
+        explicit inline SortableList(const label size);
 
         //- Construct given size and initial value. Sort later on
         //  The indices remain empty until the list is sorted
-        SortableList(const label size, const T&);
+        inline SortableList(const label size, const T& val);
+
+        //- Construct given begin/end iterators.
+        //  Uses std::distance to determine the size.
+        template<class InputIterator>
+        inline SortableList(InputIterator begIter, InputIterator endIter);
 
         //- Construct as copy
-        SortableList(const SortableList<T>&);
+        inline SortableList(const SortableList<T>& lst);
 
         //- Construct from an initializer list, sorting immediately
-        SortableList(std::initializer_list<T>);
+        SortableList(std::initializer_list<T> values);
 
 
     // Member Functions
@@ -122,16 +127,16 @@ public:
     // Member Operators
 
         //- Assignment of all entries to the given value
-        inline void operator=(const T&);
+        inline void operator=(const T& val);
 
         //- Assignment to UList operator. Takes linear time
-        inline void operator=(const UList<T>&);
+        inline void operator=(const UList<T>& lst);
 
         //- Assignment operator. Takes linear time
-        inline void operator=(const SortableList<T>&);
+        inline void operator=(const SortableList<T>& lst);
 
         //- Assignment to an initializer list
-        void operator=(std::initializer_list<T>);
+        void operator=(std::initializer_list<T> lst);
 };
 
 
diff --git a/src/OpenFOAM/containers/Lists/UList/UList.C b/src/OpenFOAM/containers/Lists/UList/UList.C
index f3feb5b83526355c5a80105435866d10fad2c02e..f47969874420dee885258c2eaab74473ebc9d146 100644
--- a/src/OpenFOAM/containers/Lists/UList/UList.C
+++ b/src/OpenFOAM/containers/Lists/UList/UList.C
@@ -112,6 +112,7 @@ Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range)
     return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
 }
 
+
 template<class T>
 const Foam::UList<T> Foam::UList<T>::operator[](const labelRange& range) const
 {
@@ -132,6 +133,7 @@ Foam::UList<T> Foam::UList<T>::operator[]
     return UList<T>(&(this->v_[slice.start()]), slice.size()); // SubList
 }
 
+
 template<class T>
 const Foam::UList<T> Foam::UList<T>::operator[]
 (
diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectList.C b/src/OpenFOAM/db/IOobjectList/IOobjectList.C
index f58bab42140d96864c9a0eae8b0e1b2648e547a8..1f96009a528904e7205c13230f7b9831e6eb6349 100644
--- a/src/OpenFOAM/db/IOobjectList/IOobjectList.C
+++ b/src/OpenFOAM/db/IOobjectList/IOobjectList.C
@@ -91,9 +91,9 @@ Foam::IOobjectList::IOobjectList
 }
 
 
-Foam::IOobjectList::IOobjectList(const IOobjectList& ioOL)
+Foam::IOobjectList::IOobjectList(const IOobjectList& iolist)
 :
-    HashPtrTable<IOobject>(ioOL)
+    HashPtrTable<IOobject>(iolist)
 {}
 
 
@@ -113,17 +113,7 @@ bool Foam::IOobjectList::add(IOobject& io)
 
 bool Foam::IOobjectList::remove(IOobject& io)
 {
-    HashPtrTable<IOobject>::iterator iter =
-        HashPtrTable<IOobject>::find(io.name());
-
-    if (iter != end())
-    {
-        return erase(iter);
-    }
-    else
-    {
-        return false;
-    }
+    return erase(io.name());
 }
 
 
@@ -131,7 +121,7 @@ Foam::IOobject* Foam::IOobjectList::lookup(const word& name) const
 {
     HashPtrTable<IOobject>::const_iterator iter = find(name);
 
-    if (iter != end())
+    if (iter.found())
     {
         if (IOobject::debug)
         {
@@ -152,68 +142,80 @@ Foam::IOobject* Foam::IOobjectList::lookup(const word& name) const
 }
 
 
-Foam::IOobjectList Foam::IOobjectList::lookup(const wordRe& name) const
+Foam::IOobjectList Foam::IOobjectList::lookup(const wordRe& matcher) const
 {
-    IOobjectList objectsOfName(size());
+    IOobjectList results(size());
 
-    forAllConstIter(HashPtrTable<IOobject>, *this, iter)
+    forAllConstIters(*this, iter)
     {
-        if (name.match(iter()->name()))
+        if (matcher.match(iter.key()))
         {
             if (IOobject::debug)
             {
                 InfoInFunction << "Found " << iter.key() << endl;
             }
 
-            objectsOfName.insert(iter.key(), new IOobject(*iter()));
+            results.insert
+            (
+                iter.key(),
+                new IOobject(*(iter.object()))
+            );
         }
     }
 
-    return objectsOfName;
+    return results;
 }
 
 
-Foam::IOobjectList Foam::IOobjectList::lookup(const wordReList& patterns) const
+Foam::IOobjectList Foam::IOobjectList::lookup(const wordReList& matcher) const
 {
-    wordReListMatcher names(patterns);
+    wordReListMatcher mat(matcher);
 
-    IOobjectList objectsOfName(size());
+    IOobjectList results(size());
 
-    forAllConstIter(HashPtrTable<IOobject>, *this, iter)
+    forAllConstIters(*this, iter)
     {
-        if (names.match(iter()->name()))
+        if (mat.match(iter.key()))
         {
             if (IOobject::debug)
             {
                 InfoInFunction << "Found " << iter.key() << endl;
             }
 
-            objectsOfName.insert(iter.key(), new IOobject(*iter()));
+            results.insert
+            (
+                iter.key(),
+                new IOobject(*(iter.object()))
+            );
         }
     }
 
-    return objectsOfName;
+    return results;
 }
 
 
-Foam::IOobjectList Foam::IOobjectList::lookupClass(const word& ClassName) const
+Foam::IOobjectList Foam::IOobjectList::lookupClass(const word& clsName) const
 {
-    IOobjectList objectsOfClass(size());
+    IOobjectList results(size());
 
-    forAllConstIter(HashPtrTable<IOobject>, *this, iter)
+    forAllConstIters(*this, iter)
     {
-        if (iter()->headerClassName() == ClassName)
+        if (iter()->headerClassName() == clsName)
         {
             if (IOobject::debug)
             {
                 InfoInFunction << "Found " << iter.key() << endl;
             }
 
-            objectsOfClass.insert(iter.key(), new IOobject(*iter()));
+            results.insert
+            (
+                iter.key(),
+                new IOobject(*(iter.object()))
+            );
         }
     }
 
-    return objectsOfClass;
+    return results;
 }
 
 
@@ -231,33 +233,33 @@ Foam::wordList Foam::IOobjectList::sortedNames() const
 
 Foam::wordList Foam::IOobjectList::names
 (
-    const word& ClassName
+    const word& clsName
 ) const
 {
-    wordList objectNames(size());
+    wordList objNames(size());
 
     label count = 0;
-    forAllConstIter(HashPtrTable<IOobject>, *this, iter)
+    forAllConstIters(*this, iter)
     {
-        if (iter()->headerClassName() == ClassName)
+        if (iter()->headerClassName() == clsName)
         {
-            objectNames[count++] = iter.key();
+            objNames[count++] = iter.key();
         }
     }
 
-    objectNames.setSize(count);
+    objNames.setSize(count);
 
-    return objectNames;
+    return objNames;
 }
 
 
 Foam::wordList Foam::IOobjectList::names
 (
-    const word& ClassName,
+    const word& clsName,
     const wordRe& matcher
 ) const
 {
-    wordList objNames = names(ClassName);
+    wordList objNames = names(clsName);
 
     return wordList(objNames, findStrings(matcher, objNames));
 }
@@ -265,11 +267,11 @@ Foam::wordList Foam::IOobjectList::names
 
 Foam::wordList Foam::IOobjectList::names
 (
-    const word& ClassName,
+    const word& clsName,
     const wordReList& matcher
 ) const
 {
-    wordList objNames = names(ClassName);
+    wordList objNames = names(clsName);
 
     return wordList(objNames, findStrings(matcher, objNames));
 }
@@ -277,10 +279,10 @@ Foam::wordList Foam::IOobjectList::names
 
 Foam::wordList Foam::IOobjectList::sortedNames
 (
-    const word& ClassName
+    const word& clsName
 ) const
 {
-    wordList sortedLst = names(ClassName);
+    wordList sortedLst = names(clsName);
     sort(sortedLst);
 
     return sortedLst;
@@ -289,11 +291,11 @@ Foam::wordList Foam::IOobjectList::sortedNames
 
 Foam::wordList Foam::IOobjectList::sortedNames
 (
-    const word& ClassName,
+    const word& clsName,
     const wordRe& matcher
 ) const
 {
-    wordList sortedLst = names(ClassName, matcher);
+    wordList sortedLst = names(clsName, matcher);
     sort(sortedLst);
 
     return sortedLst;
@@ -302,11 +304,11 @@ Foam::wordList Foam::IOobjectList::sortedNames
 
 Foam::wordList Foam::IOobjectList::sortedNames
 (
-    const word& ClassName,
+    const word& clsName,
     const wordReList& matcher
 ) const
 {
-    wordList sortedLst = names(ClassName, matcher);
+    wordList sortedLst = names(clsName, matcher);
     sort(sortedLst);
 
     return sortedLst;
diff --git a/src/OpenFOAM/db/IOobjectList/IOobjectList.H b/src/OpenFOAM/db/IOobjectList/IOobjectList.H
index 926135222fd8686869c881496c1537da01b13592..17f75233ed38e01385e752c6edbda806477f386f 100644
--- a/src/OpenFOAM/db/IOobjectList/IOobjectList.H
+++ b/src/OpenFOAM/db/IOobjectList/IOobjectList.H
@@ -77,7 +77,7 @@ public:
         );
 
         //- Construct as copy
-        IOobjectList(const IOobjectList&);
+        IOobjectList(const IOobjectList& iolist);
 
 
     //- Destructor
@@ -87,52 +87,56 @@ public:
     // Member functions
 
         //- Add an IOobject to the list
-        bool add(IOobject&);
+        bool add(IOobject& io);
 
         //- Remove an IOobject from the list
-        bool remove(IOobject&);
+        bool remove(IOobject& io);
 
         //- Lookup a given name and return IOobject ptr if found else nullptr
         IOobject* lookup(const word& name) const;
 
-        //- Return the list for all IOobects whose name matches name
-        IOobjectList lookup(const wordRe& name) const;
+        //- The list of all IOobects with matching names
+        IOobjectList lookup(const wordRe& matcher) const;
 
-        //- Return the list for all IOobects whose name matches name
-        IOobjectList lookup(const wordReList& patterns) const;
+        //- The list of all IOobjects with matching names
+        IOobjectList lookup(const wordReList& matcher) const;
 
-        //- Return the list for all IOobjects of a given class
-        IOobjectList lookupClass(const word& className) const;
+        //- The list of all IOobjects with the given class name
+        IOobjectList lookupClass(const word& clsName) const;
 
 
         //- A list of names of the IOobjects
         wordList names() const;
 
-        //- A list of names of IOobjects of the given class
-        wordList names(const word& className) const;
+        //- The names of IOobjects with the given class name
+        wordList names(const word& clsName) const;
 
-        //- A list of names of IOobjects of the given class,
-        //  and that also satisfy the input matcher
-        wordList names(const word& className, const wordRe&) const;
+        //- The names of IOobjects with the given class name that also
+        //  have a name satisfying the input matcher
+        wordList names(const word& clsName, const wordRe& matcher) const;
 
-        //- A list of names of IOobjects of the given class,
-        //  and that also satisfy the input matchers
-        wordList names(const word& className, const wordReList&) const;
+        //- The names of IOobjects with the given class name that also
+        //  have a name satisfying the input matcher
+        wordList names(const word& clsName, const wordReList& matcher) const;
 
 
         //- A sorted list of names of the IOobjects
         wordList sortedNames() const;
 
-        //- A sorted list of names of IOobjects of given class
-        wordList sortedNames(const word& className) const;
+        //- The sorted names of IOobjects with the given class name
+        wordList sortedNames(const word& clsName) const;
 
-        //- A sorted list of names of IOobjects of the given class,
-        //  and that also satisfy the input matcher
-        wordList sortedNames(const word& className, const wordRe&) const;
+        //- The sorted names of IOobjects with the given class name that also
+        //  have a name satisfying the input matcher
+        wordList sortedNames(const word& clsName, const wordRe& matcher) const;
 
-        //- A sorted list of names of IOobjects of the given class,
-        //  and that also satisfy the input matchers
-        wordList sortedNames(const word& className, const wordReList&) const;
+        //- The sorted names of IOobjects with the given class name that also
+        //  have a name satisfying the input matcher
+        wordList sortedNames
+        (
+            const word& clsName,
+            const wordReList& matcher
+        ) const;
 };
 
 
diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C
index 08c702fee3baeb78724778afae6314da0d863ecd..c2ecd2292cba51e9450275939d5834f407ab7497 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.C
+++ b/src/OpenFOAM/db/dictionary/dictionary.C
@@ -161,7 +161,7 @@ const Foam::entry* Foam::dictionary::lookupScopedSubEntryPtr
 bool Foam::dictionary::findInPatterns
 (
     const bool patternMatch,
-    const word& Keyword,
+    const word& keyword,
     DLList<entry*>::const_iterator& wcLink,
     DLList<autoPtr<regExp>>::const_iterator& reLink
 ) const
@@ -173,8 +173,8 @@ bool Foam::dictionary::findInPatterns
             if
             (
                 patternMatch
-              ? reLink()->match(Keyword)
-              : wcLink()->keyword() == Keyword
+              ? reLink()->match(keyword)
+              : wcLink()->keyword() == keyword
             )
             {
                 return true;
@@ -192,7 +192,7 @@ bool Foam::dictionary::findInPatterns
 bool Foam::dictionary::findInPatterns
 (
     const bool patternMatch,
-    const word& Keyword,
+    const word& keyword,
     DLList<entry*>::iterator& wcLink,
     DLList<autoPtr<regExp>>::iterator& reLink
 )
@@ -204,8 +204,8 @@ bool Foam::dictionary::findInPatterns
             if
             (
                 patternMatch
-              ? reLink()->match(Keyword)
-              : wcLink()->keyword() == Keyword
+              ? reLink()->match(keyword)
+              : wcLink()->keyword() == keyword
             )
             {
                 return true;
@@ -743,6 +743,24 @@ Foam::dictionary Foam::dictionary::subOrEmptyDict
 }
 
 
+const Foam::dictionary& Foam::dictionary::optionalSubDict
+(
+    const word& keyword
+) const
+{
+    const entry* entryPtr = lookupEntryPtr(keyword, false, true);
+
+    if (entryPtr)
+    {
+        return entryPtr->dict();
+    }
+    else
+    {
+        return *this;
+    }
+}
+
+
 Foam::wordList Foam::dictionary::toc() const
 {
     wordList keys(size());
@@ -933,11 +951,11 @@ void Foam::dictionary::set(const keyType& k, const dictionary& d)
 }
 
 
-bool Foam::dictionary::remove(const word& Keyword)
+bool Foam::dictionary::remove(const word& keyword)
 {
-    HashTable<entry*>::iterator iter = hashedEntries_.find(Keyword);
+    HashTable<entry*>::iterator iter = hashedEntries_.find(keyword);
 
-    if (iter != hashedEntries_.end())
+    if (iter.found())
     {
         // Delete from patterns first
         DLList<entry*>::iterator wcLink =
@@ -946,7 +964,7 @@ bool Foam::dictionary::remove(const word& Keyword)
             patternRegexps_.begin();
 
         // Find in pattern using exact match only
-        if (findInPatterns(false, Keyword, wcLink, reLink))
+        if (findInPatterns(false, keyword, wcLink, reLink))
         {
             patternEntries_.remove(wcLink);
             patternRegexps_.remove(reLink);
diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H
index a2031ede037c13586c28d658af516bfd43488f62..876be6ebba02dca07c3a0b800276cf7882590336 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.H
+++ b/src/OpenFOAM/db/dictionary/dictionary.H
@@ -204,7 +204,7 @@ class dictionary
         bool findInPatterns
         (
             const bool patternMatch,
-            const word& Keyword,
+            const word& keyword,
             DLList<entry*>::const_iterator& wcLink,
             DLList<autoPtr<regExp>>::const_iterator& reLink
         ) const;
@@ -213,7 +213,7 @@ class dictionary
         bool findInPatterns
         (
             const bool patternMatch,
-            const word& Keyword,
+            const word& keyword,
             DLList<entry*>::iterator& wcLink,
             DLList<autoPtr<regExp>>::iterator& reLink
         );
@@ -436,6 +436,10 @@ public:
                 const bool mustRead = false
             ) const;
 
+            //- Find and return a sub-dictionary if found
+            //  otherwise return this dictionary
+            const dictionary& optionalSubDict(const word& keyword) const;
+
             //- Return the table of contents
             wordList toc() const;
 
@@ -514,7 +518,7 @@ public:
             void set(const keyType& k, const T& t);
 
             //- Remove an entry specified by keyword
-            bool remove(const word& Keyword);
+            bool remove(const word& keyword);
 
             //- Change the keyword for an entry,
             //  optionally forcing overwrite of an existing entry
diff --git a/src/OpenFOAM/db/dictionary/entry/entry.H b/src/OpenFOAM/db/dictionary/entry/entry.H
index c37809927a6509034f4ecc3cda14958441bf20b5..dcbe358f1843a0a3773ab923624d65e1d1b3302c 100644
--- a/src/OpenFOAM/db/dictionary/entry/entry.H
+++ b/src/OpenFOAM/db/dictionary/entry/entry.H
@@ -57,7 +57,7 @@ class dictionary;
 // Forward declaration of friend functions and operators
 
 class entry;
-Ostream& operator<<(Ostream&, const entry&);
+Ostream& operator<<(Ostream& os, const entry& e);
 
 /*---------------------------------------------------------------------------*\
                            Class entry Declaration
@@ -75,11 +75,16 @@ class entry
 
     // Private Member Functions
 
-        //- Get the next valid keyword. Return true if is valid keyType.
-        static bool getKeyword(keyType&, token&, Istream&);
+        //- Get the next valid keyword. Return true if a valid keyType.
+        static bool getKeyword
+        (
+            keyType& keyword,
+            token& keywordToken,
+            Istream& is
+        );
 
         //- Get the next valid keyword otherwise return false
-        static bool getKeyword(keyType&, Istream&);
+        static bool getKeyword(keyType& keyword, Istream& is);
 
 
 public:
@@ -90,10 +95,10 @@ public:
     // Constructors
 
         //- Construct from keyword
-        entry(const keyType&);
+        entry(const keyType& keyword);
 
         //- Construct as copy
-        entry(const entry&);
+        entry(const entry& e);
 
         //- Construct on freestore as copy with reference to the
         //  dictionary the copy belongs to
@@ -107,7 +112,7 @@ public:
         virtual autoPtr<entry> clone() const;
 
         //- Construct from Istream and insert into dictionary
-        static bool New(dictionary& parentDict, Istream&);
+        static bool New(dictionary& parentDict, Istream& is);
 
         //- Construct on freestore from Istream and return
         static autoPtr<entry> New(Istream& is);
@@ -179,7 +184,7 @@ public:
 
     // Ostream operator
 
-        friend Ostream& operator<<(Ostream&, const entry&);
+        friend Ostream& operator<<(Ostream& os, const entry& e);
 };
 
 
diff --git a/src/OpenFOAM/db/dictionary/entry/entryIO.C b/src/OpenFOAM/db/dictionary/entry/entryIO.C
index 4f7b3e4f0fd318d7ecd6697968d93a4fda6ccad6..3d554bd619afa429ec0fdeecdcad83b9504abf66 100644
--- a/src/OpenFOAM/db/dictionary/entry/entryIO.C
+++ b/src/OpenFOAM/db/dictionary/entry/entryIO.C
@@ -106,7 +106,7 @@ bool Foam::entry::getKeyword(keyType& keyword, Istream& is)
 
 bool Foam::entry::New(dictionary& parentDict, Istream& is)
 {
-    is.fatalCheck("entry::New(const dictionary& parentDict, Istream&)");
+    is.fatalCheck(FUNCTION_NAME);
 
     keyType keyword;
     token keyToken;
@@ -324,7 +324,7 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
 
 Foam::autoPtr<Foam::entry> Foam::entry::New(Istream& is)
 {
-    is.fatalCheck("entry::New(Istream&)");
+    is.fatalCheck(FUNCTION_NAME);
 
     keyType keyword;
 
diff --git a/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
index bf01fe7be95df41b848ebf7929faadebe9aeefc8..9b7fc8a548d93335410f3091d10e427fad0d62af 100644
--- a/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
+++ b/src/OpenFOAM/meshes/Identifiers/patch/coupleGroupIdentifier.C
@@ -46,10 +46,10 @@ Foam::label Foam::coupleGroupIdentifier::findOtherPatchID
             << exit(FatalError);
     }
 
-    HashTable<labelList, word>::const_iterator fnd =
+    HashTable<labelList>::const_iterator fnd =
         pbm.groupPatchIDs().find(name());
 
-    if (fnd == pbm.groupPatchIDs().end())
+    if (!fnd.found())
     {
         if (&mesh == &thisPatch.boundaryMesh().mesh())
         {
@@ -65,7 +65,7 @@ Foam::label Foam::coupleGroupIdentifier::findOtherPatchID
     }
 
     // Mesh has patch group
-    const labelList& patchIDs = fnd();
+    const labelList& patchIDs = fnd.object();
 
     if (&mesh == &thisPatch.boundaryMesh().mesh())
     {
diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edge.H b/src/OpenFOAM/meshes/meshShapes/edge/edge.H
index 52bf97cb7cf65cfebbe2e30ca0a26881b808d3d7..aecb9a9c2e416c1acc4b055fcf1c4ff12e162b17 100644
--- a/src/OpenFOAM/meshes/meshShapes/edge/edge.H
+++ b/src/OpenFOAM/meshes/meshShapes/edge/edge.H
@@ -149,7 +149,11 @@ public:
 
         //- Return true if point label is found in edge.
         //  Always false for a negative label.
-        inline bool found(const label index) const;
+        inline bool found(const label pointLabel) const;
+
+        //- Return local index (0,1) of point label in edge -1 on failure
+        //  Always return -1 for a negative label.
+        inline label which(const label pointLabel) const;
 
         //- Do the edges share a common vertex index?
         //  Negative point labels never connect.
diff --git a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
index 75a5ba23655c5dd5fbe1d82cbf5a0ddb06a98bf9..e4ca81e9386f6abb51f0abc14ba2035222656268 100644
--- a/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
+++ b/src/OpenFOAM/meshes/meshShapes/edge/edgeI.H
@@ -206,10 +206,28 @@ inline Foam::label Foam::edge::maxVertex() const
 }
 
 
-inline bool Foam::edge::found(const label index) const
+inline bool Foam::edge::found(const label pointLabel) const
 {
     // -1: always false
-    return (index >= 0 && (index == start() || index == end()));
+    return (pointLabel >= 0 && (pointLabel == start() || pointLabel == end()));
+}
+
+
+inline Foam::label Foam::edge::which(const label pointLabel) const
+{
+    // -1: always false
+    if (pointLabel >= 0)
+    {
+        if (pointLabel == start())
+        {
+            return 0;
+        }
+        if (pointLabel == end())
+        {
+            return 1;
+        }
+    }
+    return -1;
 }
 
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H
index 2d83def92090a598a8b38213dc82f79a0c2b301e..822e3c4f9a6fc3f146480ee1ada390afb311497f 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -202,7 +202,10 @@ public:
 
         //- Navigation through face vertices
 
-            //- Which vertex on face (face index given a global index)
+            //- Return true if the global point label is found in face.
+            inline bool found(const label globalIndex) const;
+
+            //- Which local vertex on face given a global index.
             //  returns -1 if not found
             label which(const label globalIndex) const;
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
index b45193f0e730b3d59ede32f0f443bf62b252046a..ce807528c6598dbbeae7b5489f3f187d6adbeafe 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -116,20 +116,24 @@ inline Foam::edge Foam::face::faceEdge(const label n) const
 }
 
 
-// Next vertex on face
+inline bool Foam::face::found(const label globalIndex) const
+{
+    return which(globalIndex) != -1;
+}
+
+
 inline Foam::label Foam::face::nextLabel(const label i) const
 {
     return operator[](fcIndex(i));
 }
 
 
-// Previous vertex on face
 inline Foam::label Foam::face::prevLabel(const label i) const
 {
     return operator[](rcIndex(i));
 }
 
-// Number of triangles directly known from number of vertices
+
 inline Foam::label Foam::face::nTriangles() const
 {
     return size() - 2;
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceI.H b/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
similarity index 51%
rename from src/surfMesh/MeshedSurface/MeshedSurfaceI.H
rename to src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
index a7415f7b4b69e8ef8a15731bdfc2e4598090c20b..523233a569957ab20c5e1c78cf35f5e4723646a6 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/traits/faceTraits.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -21,83 +21,53 @@ License
     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::faceTraits
+
+Description
+    Traits class for faces
+
 \*---------------------------------------------------------------------------*/
 
+#ifndef faceTraits_H
+#define faceTraits_H
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-// A triFace surface only handles triangulated faces
-template<>
-inline bool MeshedSurface<triFace>::isTri()
-{
-    return true;
-}
+// Forward declarations
+class triFace;
+class labelledTri;
 
+/*---------------------------------------------------------------------------*\
+                         Class faceTraits Declaration
+\*---------------------------------------------------------------------------*/
 
-// A labelledTri surface only handles triangulated faces
-template<>
-inline bool MeshedSurface<labelledTri>::isTri()
+template<class FaceType>
+class faceTraits
 {
-    return true;
-}
+public:
 
+    //- Face-type only handles triangles. Not true in general.
+    inline static bool isTri()  { return false; }
+};
 
-// Number of triangles for a triFace surface
-template<>
-inline label MeshedSurface<triFace>::nTriangles() const
-{
-    return ParentType::size();
-}
 
-// Number of triangles for a labelledTri surface
 template<>
-inline label MeshedSurface<labelledTri>::nTriangles() const
-{
-    return ParentType::size();
-}
+inline bool faceTraits<triFace>::isTri()        { return true; }
 
-
-// Inplace triangulation of triFace surface = no-op
 template<>
-inline label MeshedSurface<triFace>::triangulate()
-{
-    return 0;
-}
+inline bool faceTraits<labelledTri>::isTri()    { return true; }
 
-// Inplace triangulation of labelledTri surface = no-op
-template<>
-inline label MeshedSurface<labelledTri>::triangulate()
-{
-    return 0;
-}
 
-// Inplace triangulation of triFace surface (with face map) = no-op
-template<>
-inline label MeshedSurface<triFace>::triangulate(List<label>& faceMap)
-{
-    if (notNull(faceMap))
-    {
-        faceMap.clear();
-    }
-    return 0;
-}
-
-// Inplace triangulation of labelledTri surface (with face map) = no-op
-template<>
-inline label MeshedSurface<labelledTri>::triangulate(List<label>& faceMap)
-{
-    if (notNull(faceMap))
-    {
-        faceMap.clear();
-    }
-    return 0;
-}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
+#endif
 
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
index e0e586673acd317ba968050ae2d270137d6f2dfd..301b845d112a82499420b4de2eeddd3daf6f4477 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -137,6 +137,13 @@ public:
         //  The starting points of the original and reverse face are identical.
         inline triFace reverseFace() const;
 
+        //- Return true if the global point label is found in face.
+        bool found(const label globalIndex) const;
+
+        //- Which local index (0,1,2) on face given a global index.
+        //  returns -1 if not found
+        label which(const label globalIndex) const;
+
         //- Return swept-volume from old-points to new-points
         inline scalar sweptVol
         (
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
index 69d2a4033b8607c32d13a876b3670a9effb0763c..ae2545a7aa233e8542a9e4e644e1f098bd6b3c09 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2013 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -209,6 +209,21 @@ inline Foam::triFace Foam::triFace::reverseFace() const
 }
 
 
+inline bool Foam::triFace::found(const label globalIndex) const
+{
+    return which(globalIndex) != -1;
+}
+
+
+inline Foam::label Foam::triFace::which(const label globalIndex) const
+{
+    if (operator[](0) == globalIndex) return 0;
+    if (operator[](1) == globalIndex) return 1;
+    if (operator[](2) == globalIndex) return 2;
+    return -1;
+}
+
+
 inline Foam::scalar Foam::triFace::sweptVol
 (
     const UList<point>& opts,
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
index edb37c727bfc5424f691a678221689847f9f4f83..f7068f4249033117ac57d5244b06f8815494816b 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
@@ -32,6 +32,7 @@ License
 #include "lduSchedule.H"
 #include "globalMeshData.H"
 #include "stringListOps.H"
+#include "EdgeMap.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -287,7 +288,7 @@ Foam::polyBoundaryMesh::neighbourEdges() const
 
         // From mesh edge (expressed as a point pair so as not to construct
         // point addressing) to patch + relative edge index.
-        HashTable<labelPair, edge, Hash<edge>> pointsToEdge(nEdgePairs);
+        EdgeMap<labelPair> pointsToEdge(nEdgePairs);
 
         forAll(*this, patchi)
         {
@@ -308,10 +309,9 @@ Foam::polyBoundaryMesh::neighbourEdges() const
                 // Edge in mesh points.
                 edge meshEdge(pp.meshPoints()[e[0]], pp.meshPoints()[e[1]]);
 
-                HashTable<labelPair, edge, Hash<edge>>::iterator fnd =
-                    pointsToEdge.find(meshEdge);
+                EdgeMap<labelPair>::iterator fnd = pointsToEdge.find(meshEdge);
 
-                if (fnd == pointsToEdge.end())
+                if (!fnd.found())
                 {
                     // First occurrence of mesh edge. Store patch and my
                     // local index.
@@ -328,7 +328,7 @@ Foam::polyBoundaryMesh::neighbourEdges() const
                 else
                 {
                     // Second occurrence. Store.
-                    const labelPair& edgeInfo = fnd();
+                    const labelPair& edgeInfo = fnd.object();
 
                     neighbourEdges[patchi][edgei - pp.nInternalEdges()] =
                         edgeInfo;
@@ -413,13 +413,13 @@ const Foam::labelList& Foam::polyBoundaryMesh::patchID() const
 }
 
 
-const Foam::HashTable<Foam::labelList, Foam::word>&
+const Foam::HashTable<Foam::labelList>&
 Foam::polyBoundaryMesh::groupPatchIDs() const
 {
     if (!groupPatchIDsPtr_.valid())
     {
-        groupPatchIDsPtr_.reset(new HashTable<labelList, word>(10));
-        HashTable<labelList, word>& groupPatchIDs = groupPatchIDsPtr_();
+        groupPatchIDsPtr_.reset(new HashTable<labelList>(10));
+        HashTable<labelList>& groupPatchIDs = groupPatchIDsPtr_();
 
         const polyBoundaryMesh& bm = *this;
 
@@ -431,7 +431,7 @@ Foam::polyBoundaryMesh::groupPatchIDs() const
             {
                 const word& name = groups[i];
 
-                HashTable<labelList, word>::iterator iter = groupPatchIDs.find
+                HashTable<labelList>::iterator iter = groupPatchIDs.find
                 (
                     name
                 );
@@ -612,10 +612,10 @@ Foam::labelList Foam::polyBoundaryMesh::findIndices
 
             if (usePatchGroups && groupPatchIDs().size())
             {
-                const HashTable<labelList, word>::const_iterator iter =
+                const HashTable<labelList>::const_iterator iter =
                     groupPatchIDs().find(key);
 
-                if (iter != groupPatchIDs().end())
+                if (iter.found())
                 {
                     labelHashSet indexSet(indices);
 
@@ -815,14 +815,8 @@ void Foam::polyBoundaryMesh::matchGroups
     // Current set of unmatched patches
     nonGroupPatches = labelHashSet(patchIDs);
 
-    const HashTable<labelList, word>& groupPatchIDs = this->groupPatchIDs();
-    for
-    (
-        HashTable<labelList,word>::const_iterator iter =
-            groupPatchIDs.begin();
-        iter != groupPatchIDs.end();
-        ++iter
-    )
+    const HashTable<labelList>& groupPatchIDs = this->groupPatchIDs();
+    forAllConstIters(groupPatchIDs, iter)
     {
         // Store currently unmatched patches so we can restore
         labelHashSet oldNonGroupPatches(nonGroupPatches);
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H
index 114fc231689348e9c249bb61d609f60423be6fb4..6193b98f4505fae884c0444e726510d99d6084b5 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.H
@@ -70,7 +70,7 @@ class polyBoundaryMesh
 
         mutable autoPtr<labelList> patchIDPtr_;
 
-        mutable autoPtr<HashTable<labelList, word>> groupPatchIDsPtr_;
+        mutable autoPtr<HashTable<labelList>> groupPatchIDsPtr_;
 
         //- Edges of neighbouring patches
         mutable autoPtr<List<labelPairList>> neighbourEdgesPtr_;
@@ -183,8 +183,8 @@ public:
         //- Per boundary face label the patch index
         const labelList& patchID() const;
 
-        //- Per patch group the patch indices
-        const HashTable<labelList, word>& groupPatchIDs() const;
+        //- The patch indices per patch group
+        const HashTable<labelList>& groupPatchIDs() const;
 
         //- Set/add group with patches
         void setGroup(const word& groupName, const labelList& patchIDs);
diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/line.H b/src/OpenFOAM/meshes/primitiveShapes/line/line.H
index 74bc680134eb0b4c2873ac4a9c14c0e81924634e..778a843ba75740616ef5922d017b94747f6a839a 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/line/line.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/line/line.H
@@ -98,10 +98,10 @@ public:
 
         // Access
 
-            //- Return first vertex
+            //- Return first point
             inline PointRef start() const;
 
-            //- Return second vertex
+            //- Return second point
             inline PointRef end() const;
 
 
@@ -113,9 +113,12 @@ public:
             //- Return scalar magnitude
             inline scalar mag() const;
 
-            //- Return start-end vector
+            //- Return start-to-end vector
             inline Point vec() const;
 
+            //- Return the unit vector (start-to-end)
+            inline Point unitVec() const;
+
             //- Return nearest distance to line from a given point
             //  If the nearest point is on the line, return a hit
             PointHit<Point> nearestDist(const Point& p) const;
diff --git a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
index 2dfca1e1c2c01c52405a410d9a6636a568016dd6..c4757716cfc9ad71d0fd17e3eaac235a55ee8cbe 100644
--- a/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
+++ b/src/OpenFOAM/meshes/primitiveShapes/line/lineI.H
@@ -90,6 +90,16 @@ inline Point Foam::line<Point, PointRef>::vec() const
 }
 
 
+template<class Point, class PointRef>
+inline Point Foam::line<Point, PointRef>::unitVec() const
+{
+    Point v = b_ - a_;
+    v /= ::Foam::mag(v) + VSMALL;
+
+    return v;
+}
+
+
 template<class Point, class PointRef>
 Foam::PointHit<Point> Foam::line<Point, PointRef>::nearestDist
 (
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C
index b1033ac17279b4bf00810ac80b6ede0fe51e63aa..38349e92b2f0892a9ea65e85d7ecf097666b9a29 100644
--- a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.C
@@ -34,6 +34,8 @@ namespace Foam
 int labelRange::debug(debug::debugSwitch("labelRange", 0));
 }
 
+const Foam::labelRange Foam::labelRange::null;
+
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H
index c4eb8488a62b143cea7ba469ec637804892f35be..dc3483c109618bcf06dde89c95b78912b65eaeff 100644
--- a/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRange.H
@@ -35,6 +35,7 @@ SourceFiles
 #define labelRange_H
 
 #include "label.H"
+#include <iterator>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -63,26 +64,32 @@ class labelRange
 
 public:
 
-    static int debug;
+    // Static Data Members
+
+        static int debug;
+
+        //- An empty range with start=0, size=0.
+        static const labelRange null;
+
 
     // STL type definitions similar to what UList has
 
         //- Type of values the range contains
         typedef label value_type;
 
-        //- The type that can represent the difference between two iterators
-        typedef label difference_type;
-
         //- The type that can represent the size of the range
         typedef label size_type;
 
+        // Forward declaration
+        class const_iterator;
+
 
     // Constructors
 
         //- An empty range with zero for start/size.
         inline labelRange();
 
-        //- Construct a range from start and size, enforcing non-negative size.
+        //- Construct a range from start/size, enforcing non-negative size.
         //  Optionally adjust the start to avoid any negative indices.
         inline labelRange
         (
@@ -95,6 +102,12 @@ public:
         labelRange(Istream& is);
 
 
+    // Static Member Functions
+
+        //- An identity range with range[i] == i.
+        inline static labelRange identity(const label len);
+
+
     // Member Functions
 
         //- Adjust start position
@@ -184,6 +197,9 @@ public:
         //- Return element in the range, no bounds checking
         inline label operator[](const label localIndex) const;
 
+        //- Return const_iterator to element in the range
+        inline const_iterator operator()(const label localIndex) const;
+
         //- Increase the size by 1.
         inline label operator++();
         inline label operator++(int);
@@ -197,21 +213,30 @@ public:
 
         //- Forward iterator with const access
         class const_iterator
+        :
+            public std::iterator
+            <
+                std::input_iterator_tag,
+                label,
+                label,
+                const label*,
+                const label&
+            >
         {
-            //- The current label (not the local index)
-            label index_;
+            //- The current (global) value
+            label value_;
 
         public:
 
           // Constructors
 
             //- Construct from range at given local index.
-            //  A negative index signals the 'end' position
-            inline const_iterator(const labelRange* range, const label i = 0);
+            //  A negative index is invalid and corresponds to the 'end'
+            inline const_iterator(const labelRange* range, const label i=0);
 
           // Member operators
 
-            //- Return the current label
+            //- Return the current (global) value
             inline label operator*() const;
 
             inline const_iterator& operator++();
diff --git a/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H b/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H
index 0563c1cd22f100df318029dbadff834d11e3d406..dc0e90ae85577ebe492a465e45e9622a4c20d3a8 100644
--- a/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H
+++ b/src/OpenFOAM/primitives/ranges/labelRange/labelRangeI.H
@@ -64,7 +64,7 @@ inline Foam::labelRange::const_iterator::const_iterator
     const label i
 )
 :
-    index_
+    value_
     (
         range->start()
       + ((i < 0 || i > range->size()) ? range->size() : i)
@@ -74,14 +74,14 @@ inline Foam::labelRange::const_iterator::const_iterator
 
 inline Foam::label Foam::labelRange::const_iterator::operator*() const
 {
-    return index_;
+    return value_;
 }
 
 
 inline Foam::labelRange::const_iterator&
 Foam::labelRange::const_iterator::operator++()
 {
-    ++index_;
+    ++value_;
     return *this;
 }
 
@@ -90,7 +90,7 @@ inline Foam::labelRange::const_iterator
 Foam::labelRange::const_iterator::operator++(int)
 {
     const_iterator old = *this;
-    ++index_;
+    ++value_;
     return old;
 }
 
@@ -100,7 +100,7 @@ inline bool Foam::labelRange::const_iterator::operator==
     const const_iterator& iter
 ) const
 {
-    return (this->index_ == iter.index_);
+    return (this->value_ == iter.value_);
 }
 
 
@@ -109,7 +109,7 @@ inline bool Foam::labelRange::const_iterator::operator!=
     const const_iterator& iter
 ) const
 {
-    return (this->index_ != iter.index_);
+    return (this->value_ != iter.value_);
 }
 
 
@@ -139,6 +139,12 @@ inline const Foam::labelRange::const_iterator Foam::labelRange::cend() const
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+inline Foam::labelRange Foam::labelRange::identity(const label len)
+{
+    return labelRange(0, len);
+}
+
+
 inline void Foam::labelRange::setStart(const label i)
 {
     start_ = i;
@@ -264,6 +270,13 @@ inline Foam::label Foam::labelRange::operator[](const label localIndex) const
 }
 
 
+inline Foam::labelRange::const_iterator
+Foam::labelRange::operator()(const label localIndex) const
+{
+    return const_iterator(this, localIndex);
+}
+
+
 inline Foam::label Foam::labelRange::operator++()
 {
     return ++size_;
diff --git a/src/OpenFOAM/primitives/strings/lists/hashedWordList.H b/src/OpenFOAM/primitives/strings/lists/hashedWordList.H
index 733d012b92bbc506930ec638f871518fd1fb6f1d..9ecab0f382553b239cdd9caa4ceae20aece676cc 100644
--- a/src/OpenFOAM/primitives/strings/lists/hashedWordList.H
+++ b/src/OpenFOAM/primitives/strings/lists/hashedWordList.H
@@ -62,7 +62,7 @@ class hashedWordList
     // Private data
 
         //- Hash of words/indices
-        mutable HashTable<label,word> indices_;
+        mutable HashTable<label> indices_;
 
 
     // Private Member Functions
@@ -141,7 +141,7 @@ public:
         inline bool contains(const word& name) const;
 
         //- Return the hash of words/indices for inspection
-        inline const HashTable<label,word>& lookup() const;
+        inline const HashTable<label>& lookup() const;
 
         //- Transfer the contents of the argument List into this list
         //  and annul the argument list,
diff --git a/src/OpenFOAM/primitives/strings/lists/hashedWordListI.H b/src/OpenFOAM/primitives/strings/lists/hashedWordListI.H
index b011b26ecd7b4112215d8d011b138f00bf3cf0e9..80f8d28be0841295f8363ce9745fcb42c9fb92b7 100644
--- a/src/OpenFOAM/primitives/strings/lists/hashedWordListI.H
+++ b/src/OpenFOAM/primitives/strings/lists/hashedWordListI.H
@@ -134,7 +134,7 @@ inline void Foam::hashedWordList::append
 }
 
 
-inline const Foam::HashTable<Foam::label,Foam::word>&
+inline const Foam::HashTable<Foam::label>&
 Foam::hashedWordList::lookup() const
 {
     return indices_;
diff --git a/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.C b/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.C
index 0b2da048ddc2bb58bc18f01bee900ca7e911e0f3..8a0f2a16052f016e76c1b20bc1cfb32a99628fda 100644
--- a/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.C
+++ b/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.C
@@ -869,16 +869,9 @@ void Foam::boundaryCutter::updateMesh(const mapPolyMesh& morphMap)
 
     {
         // Create copy since we're deleting entries
-        HashTable<labelList, edge, Hash<edge>>
-            newEdgeAddedPoints(edgeAddedPoints_.size());
+        EdgeMap<labelList> newEdgeAddedPoints(edgeAddedPoints_.size());
 
-        for
-        (
-            HashTable<labelList, edge, Hash<edge>>::const_iterator iter =
-                edgeAddedPoints_.begin();
-            iter != edgeAddedPoints_.end();
-            ++iter
-        )
+        forAllConstIters(edgeAddedPoints_, iter)
         {
             const edge& e = iter.key();
 
@@ -888,7 +881,7 @@ void Foam::boundaryCutter::updateMesh(const mapPolyMesh& morphMap)
 
             if (newStart >= 0 && newEnd >= 0)
             {
-                const labelList& addedPoints = iter();
+                const labelList& addedPoints = iter.object();
 
                 labelList newAddedPoints(addedPoints.size());
                 label newI = 0;
diff --git a/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.H b/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.H
index 9088b04cf927bd11f098ec8a10fe27cc2e63e0e2..e3c75c5511c176afd35bbc3678ed4e8c8c204fa2 100644
--- a/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.H
+++ b/src/dynamicMesh/meshCut/meshModifiers/boundaryCutter/boundaryCutter.H
@@ -44,7 +44,7 @@ SourceFiles
 
 #include "Map.H"
 #include "labelList.H"
-#include "edge.H"
+#include "EdgeMap.H"
 #include "typeInfo.H"
 #include "labelPair.H"
 
@@ -71,7 +71,7 @@ class boundaryCutter
         const polyMesh& mesh_;
 
         //- Per edge sorted (start to end) list of points added.
-        HashTable<labelList, edge, Hash<edge>> edgeAddedPoints_;
+        EdgeMap<labelList> edgeAddedPoints_;
 
         //- Per face the mid point added.
         Map<label> faceAddedPoint_;
@@ -159,8 +159,7 @@ public:
         // Access
 
             //- Per edge a sorted list (start to end) of added points.
-            const HashTable<labelList, edge, Hash<edge>>& edgeAddedPoints()
-             const
+            const EdgeMap<labelList>& edgeAddedPoints() const
             {
                 return edgeAddedPoints_;
             }
diff --git a/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.C b/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.C
index 4ac1f6485a10d85134718b31f7efa6a95a3f6ebe..d169c6e56ab54b174a99de913d9c65f22541a056 100644
--- a/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.C
+++ b/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.C
@@ -479,13 +479,13 @@ Foam::face Foam::meshCutAndRemove::addEdgeCutsToFace(const label facei) const
         // Check if edge has been cut.
         label fp1 = f.fcIndex(fp);
 
-        HashTable<label, edge, Hash<edge>>::const_iterator fnd =
+        EdgeMap<label>::const_iterator fnd =
             addedPoints_.find(edge(f[fp], f[fp1]));
 
-        if (fnd != addedPoints_.end())
+        if (fnd.found())
         {
             // edge has been cut. Introduce new vertex.
-            newFace[newFp++] = fnd();
+            newFace[newFp++] = fnd.object();
         }
     }
 
@@ -541,12 +541,12 @@ Foam::face Foam::meshCutAndRemove::loopToFace
                 if (edgeI != -1)
                 {
                     // Existing edge. Insert split-edge point if any.
-                    HashTable<label, edge, Hash<edge>>::const_iterator fnd =
+                    EdgeMap<label>::const_iterator fnd =
                         addedPoints_.find(mesh().edges()[edgeI]);
 
-                    if (fnd != addedPoints_.end())
+                    if (fnd.found())
                     {
-                        newFace[newFacei++] = fnd();
+                        newFace[newFacei++] = fnd.object();
                     }
                 }
             }
@@ -1302,24 +1302,17 @@ void Foam::meshCutAndRemove::updateMesh(const mapPolyMesh& map)
     }
 
     {
-        HashTable<label, edge, Hash<edge>> newAddedPoints(addedPoints_.size());
+        EdgeMap<label> newAddedPoints(addedPoints_.size());
 
-        for
-        (
-            HashTable<label, edge, Hash<edge>>::const_iterator iter =
-                addedPoints_.begin();
-            iter != addedPoints_.end();
-            ++iter
-        )
+        forAllConstIters(addedPoints_, iter)
         {
             const edge& e = iter.key();
+            const label addedPointi = iter.object();
 
             label newStart = map.reversePointMap()[e.start()];
 
             label newEnd = map.reversePointMap()[e.end()];
 
-            label addedPointi = iter();
-
             label newAddedPointi = map.reversePointMap()[addedPointi];
 
             if ((newStart >= 0) && (newEnd >= 0) && (newAddedPointi >= 0))
diff --git a/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.H b/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.H
index cbd569f146793e19c80797710c59222212bff2ec..a73123c5db2d7e3b46956b0766cbd6123f7f54ed 100644
--- a/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.H
+++ b/src/dynamicMesh/meshCut/meshModifiers/meshCutAndRemove/meshCutAndRemove.H
@@ -40,6 +40,7 @@ SourceFiles
 #include "labelList.H"
 #include "typeInfo.H"
 #include "Map.H"
+#include "EdgeMap.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -70,7 +71,7 @@ class meshCutAndRemove
 
         //- Points added in last setRefinement. Per split edge label of added
         //  point
-        HashTable<label, edge, Hash<edge>> addedPoints_;
+        EdgeMap<label> addedPoints_;
 
 
     // Private Static Functions
@@ -225,7 +226,7 @@ public:
             //- Points added. Per split edge label of added point.
             //  (note: fairly useless across topology changes since one of the
             //  points of the edge will probably disappear)
-            const HashTable<label, edge, Hash<edge>>& addedPoints() const
+            const EdgeMap<label>& addedPoints() const
             {
                 return addedPoints_;
             }
diff --git a/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.C b/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.C
index 903e1c60a9e71f4630ccaac1093b9255309a029f..6486908275751e31c5feacbc9592e0813c653c21 100644
--- a/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.C
+++ b/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.C
@@ -424,13 +424,13 @@ Foam::face Foam::meshCutter::addEdgeCutsToFace(const label facei) const
         // Check if edge has been cut.
         label fp1 = f.fcIndex(fp);
 
-        HashTable<label, edge, Hash<edge>>::const_iterator fnd =
+        EdgeMap<label>::const_iterator fnd =
             addedPoints_.find(edge(f[fp], f[fp1]));
 
-        if (fnd != addedPoints_.end())
+        if (fnd.found())
         {
             // edge has been cut. Introduce new vertex.
-            newFace[newFp++] = fnd();
+            newFace[newFp++] = fnd.object();
         }
     }
 
@@ -483,12 +483,12 @@ Foam::face Foam::meshCutter::loopToFace
                 if (edgeI != -1)
                 {
                     // Existing edge. Insert split-edge point if any.
-                    HashTable<label, edge, Hash<edge>>::const_iterator fnd =
+                    EdgeMap<label>::const_iterator fnd =
                         addedPoints_.find(mesh().edges()[edgeI]);
 
-                    if (fnd != addedPoints_.end())
+                    if (fnd.found())
                     {
-                        newFace[newFacei++] = fnd();
+                        newFace[newFacei++] = fnd.object();
                     }
                 }
             }
@@ -1043,24 +1043,17 @@ void Foam::meshCutter::updateMesh(const mapPolyMesh& morphMap)
     }
 
     {
-        HashTable<label, edge, Hash<edge>> newAddedPoints(addedPoints_.size());
+        EdgeMap<label> newAddedPoints(addedPoints_.size());
 
-        for
-        (
-            HashTable<label, edge, Hash<edge>>::const_iterator iter =
-                addedPoints_.begin();
-            iter != addedPoints_.end();
-            ++iter
-        )
+        forAllConstIters(addedPoints_, iter)
         {
             const edge& e = iter.key();
+            const label addedPointi = iter.object();
 
             label newStart = morphMap.reversePointMap()[e.start()];
 
             label newEnd = morphMap.reversePointMap()[e.end()];
 
-            label addedPointi = iter();
-
             label newAddedPointi = morphMap.reversePointMap()[addedPointi];
 
             if ((newStart >= 0) && (newEnd >= 0) && (newAddedPointi >= 0))
diff --git a/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.H b/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.H
index b244e72367a081deda60e0f9d6a693eb33ffaaf7..b48d57d260299ba4af48fcb40a3e0cf472c484c5 100644
--- a/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.H
+++ b/src/dynamicMesh/meshCut/meshModifiers/meshCutter/meshCutter.H
@@ -115,6 +115,7 @@ SourceFiles
 #include "labelList.H"
 #include "typeInfo.H"
 #include "Map.H"
+#include "EdgeMap.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -148,7 +149,7 @@ class meshCutter
 
         //- Points added in last setRefinement. Per split edge label of added
         //  point
-        HashTable<label, edge, Hash<edge>> addedPoints_;
+        EdgeMap<label> addedPoints_;
 
 
     // Private Static Functions
@@ -307,7 +308,7 @@ public:
             }
 
             //- Points added. Per split edge label of added point
-            const HashTable<label, edge, Hash<edge>>& addedPoints() const
+            const EdgeMap<label>& addedPoints() const
             {
                 return addedPoints_;
             }
diff --git a/src/fileFormats/ensight/part/ensightCells.C b/src/fileFormats/ensight/part/ensightCells.C
index d08996ad85764bfda0c2616a51c0dbc2e2abc01f..3b1161ad984f075691af3a13957ead158889169e 100644
--- a/src/fileFormats/ensight/part/ensightCells.C
+++ b/src/fileFormats/ensight/part/ensightCells.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -27,24 +27,13 @@ License
 #include "error.H"
 #include "polyMesh.H"
 #include "cellModeller.H"
-#include "demandDrivenData.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 const Foam::label Foam::ensightCells::nTypes = 5;
 
-namespace Foam
-{
-    template<>
-    const char* Foam::NamedEnum
-    <
-        Foam::ensightCells::elemType,
-        5
-    >::names[] = { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
-}
-
-const Foam::NamedEnum<Foam::ensightCells::elemType, 5>
-    Foam::ensightCells::elemEnum;
+const char* Foam::ensightCells::elemNames[5] =
+    { "tetra4", "pyramid5", "penta6", "hexa8", "nfaced" };
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -63,9 +52,8 @@ void Foam::ensightCells::resizeAll()
     n = 0;
     forAll(sizes_, typei)
     {
-        deleteDemandDrivenData(lists_[typei]);
-
-        lists_[typei] = new SubList<label>(address_, sizes_[typei], n);
+        slices_[typei].setStart(n);
+        slices_[typei].setSize(sizes_[typei]);
 
         n += sizes_[typei];
     }
@@ -78,16 +66,10 @@ Foam::ensightCells::ensightCells(const label partIndex)
 :
     index_(partIndex),
     address_(),
-    sizes_(Zero),
-    lists_()
+    slices_(),
+    sizes_(Zero)
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 }
 
 
@@ -95,22 +77,16 @@ Foam::ensightCells::ensightCells(const ensightCells& obj)
 :
     index_(obj.index_),
     address_(obj.address_),
-    sizes_(),
-    lists_()
+    slices_(),
+    sizes_()
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    // Total (reduced) sizes
+    // Save the total (reduced) sizes
     FixedList<label, 5> totSizes = obj.sizes_;
 
-    // Local sizes
+    // Need local sizes for the resize operation
     this->sizes_ = obj.sizes();
 
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 
     // Restore total (reduced) sizes
     this->sizes_ = totSizes;
@@ -120,13 +96,7 @@ Foam::ensightCells::ensightCells(const ensightCells& obj)
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightCells::~ensightCells()
-{
-    forAll(lists_, typei)
-    {
-        deleteDemandDrivenData(lists_[typei]);
-    }
-    address_.clear();
-}
+{}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -134,27 +104,15 @@ Foam::ensightCells::~ensightCells()
 Foam::FixedList<Foam::label, 5> Foam::ensightCells::sizes() const
 {
     FixedList<label, 5> count;
-    forAll(lists_, typei)
+    forAll(slices_, typei)
     {
-        count[typei] = lists_[typei]->size();
+        count[typei] = slices_[typei].size();
     }
 
     return count;
 }
 
 
-Foam::label Foam::ensightCells::offset(const enum elemType what) const
-{
-    label n = 0;
-    for (label typei = 0; typei < label(what); ++typei)
-    {
-        n += lists_[typei]->size();
-    }
-
-    return n;
-}
-
-
 Foam::label Foam::ensightCells::total() const
 {
     label n = 0;
@@ -175,9 +133,10 @@ void Foam::ensightCells::clear()
 
 void Foam::ensightCells::reduce()
 {
+    // No listCombineGather, listCombineScatter for FixedList
     forAll(sizes_, typei)
     {
-        sizes_[typei] = lists_[typei]->size();
+        sizes_[typei] = slices_[typei].size();
         Foam::reduce(sizes_[typei], sumOp<label>());
     }
 }
@@ -185,9 +144,13 @@ void Foam::ensightCells::reduce()
 
 void Foam::ensightCells::sort()
 {
-    forAll(lists_, typei)
+    forAll(slices_, typei)
     {
-        Foam::sort(*(lists_[typei]));
+        if (slices_[typei].size())
+        {
+            SubList<label> idLst(address_, slices_[typei]);
+            Foam::sort(idLst);
+        }
     }
 }
 
@@ -240,7 +203,7 @@ void Foam::ensightCells::classify
     }
 
     resizeAll();    // adjust allocation
-    sizes_ = Zero;  // reset sizes
+    sizes_ = Zero;  // reset sizes - use for local indexing here
 
     // Assign cell-id per shape type
     for (label listi = 0; listi < sz; ++listi)
@@ -267,7 +230,10 @@ void Foam::ensightCells::classify
         }
 
         // eg, the processor local cellId
-        lists_[what]->operator[](sizes_[what]++) = id;
+        UList<label> slice = address_[slices_[what]];
+
+        slice[sizes_[what]] = id;
+        sizes_[what]++;
     }
 }
 
diff --git a/src/fileFormats/ensight/part/ensightCells.H b/src/fileFormats/ensight/part/ensightCells.H
index 33bc98a2f4710835ee61e5dba40f3b9107e46f4f..cef7c4b2edd8c7aa3bc482fd661fa32391dfd0f6 100644
--- a/src/fileFormats/ensight/part/ensightCells.H
+++ b/src/fileFormats/ensight/part/ensightCells.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -35,8 +35,6 @@ Description
 
 #include "labelList.H"
 #include "FixedList.H"
-#include "SubList.H"
-#include "NamedEnum.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -58,18 +56,18 @@ public:
         //- Addressable ensight element types
         enum elemType
         {
-            TETRA4,
-            PYRAMID5,
-            PENTA6,
-            HEXA8,
-            NFACED
+            TETRA4,     //!< "tetra4"
+            PYRAMID5,   //!< "pyramid5"
+            PENTA6,     //!< "penta6"
+            HEXA8,      //!< "hexa8"
+            NFACED      //!< "nfaced"
         };
 
         //- Number of element types (5)
         static const label nTypes;
 
-        //- The Ensight names for each element type
-        static const NamedEnum<elemType, 5> elemEnum;
+        //- The ensight element type names
+        static const char* elemNames[5];
 
 
     // Static Member Functions
@@ -86,17 +84,16 @@ private:
         //  The ensight part number is typically this value +1.
         label index_;
 
-        //- Linear list of ids, sub-sectioned per element type via SubLists
+        //- Linear list of ids, sub-sectioned per element type by sub-lists
         labelList address_;
 
+        //- Slices (sub-lists) of the address ids for each element type.
+        FixedList<labelRange, 5> slices_;
+
         //- List of global sizes for each element type.
         //  Used temporarily for local sizes when building the element lists.
         FixedList<label, 5> sizes_;
 
-        //- List of ids for each element type.
-        //  Managed via pointers, since a SubList cannot be relocated/resized.
-        FixedList<SubList<label>*, 5> lists_;
-
 
     // Private Member Functions
 
@@ -115,7 +112,7 @@ public:
         ensightCells(label partIndex = 0);
 
         //- Copy constructor. Needed for lists etc.
-        ensightCells(const ensightCells&);
+        ensightCells(const ensightCells& obj);
 
 
     //- Destructor
@@ -135,6 +132,9 @@ public:
         //- The processor local size of all elements.
         inline label size() const;
 
+        //- The processor local size of the specified element type.
+        inline label size(const enum elemType) const;
+
         //- The global number of the specified element type.
         //  This value is only meaningful after a reduce operation.
         inline label total(const enum elemType) const;
@@ -151,23 +151,23 @@ public:
         FixedList<label, 5> sizes() const;
 
         //- Processor local starting offset of element type.
-        label offset(const enum elemType what) const;
+        inline label offset(const enum elemType what) const;
 
         //- Return the (local) cell ids of the specified element type
-        inline const labelUList& cellIds(const enum elemType) const;
+        inline const labelUList cellIds(const enum elemType) const;
 
         //- Return the cell ids of all elements
         inline const labelUList& cellIds() const;
 
 
-    // Edit
+      // Edit
 
         //- Classify cell types and set the element lists.
         //  The optional indirect addressing can be used when classifying
         //  groups of cells (eg, from a cellZone etc).
         void classify
         (
-            const polyMesh&,
+            const polyMesh& mesh,
             const labelUList& addressing = labelUList::null()
         );
 
diff --git a/src/fileFormats/ensight/part/ensightCellsI.H b/src/fileFormats/ensight/part/ensightCellsI.H
index 88e016832220ff94ee17033a2da7d06be4adc51e..ff03b8fdfdedcee3f43c89c669ce46c019696701 100644
--- a/src/fileFormats/ensight/part/ensightCellsI.H
+++ b/src/fileFormats/ensight/part/ensightCellsI.H
@@ -29,7 +29,7 @@ License
 
 inline const char* Foam::ensightCells::key(const enum elemType what)
 {
-    return elemEnum[what];
+    return elemNames[what];
 }
 
 
@@ -63,20 +63,24 @@ inline Foam::label Foam::ensightCells::total(const enum elemType what) const
 }
 
 
-inline const Foam::labelUList& Foam::ensightCells::cellIds
+inline Foam::label Foam::ensightCells::size(const enum elemType what) const
+{
+    return slices_[what].size();
+}
+
+
+inline Foam::label Foam::ensightCells::offset(const enum elemType what) const
+{
+    return slices_[what].start();
+}
+
+
+inline const Foam::labelUList Foam::ensightCells::cellIds
 (
     const enum elemType what
 ) const
 {
-    if (!lists_[what])
-    {
-        FatalErrorInFunction
-            << "Accessing unallocated sublist for elem-type: "
-            << elemEnum[what]
-            << exit(FatalError);
-    }
-
-    return *(lists_[what]);
+    return address_[slices_[what]];
 }
 
 
diff --git a/src/fileFormats/ensight/part/ensightFaces.C b/src/fileFormats/ensight/part/ensightFaces.C
index 65117d3cd60d56a36de7ed381f49d654778f50cc..db64d85adbc32e5701c9270eaf2948e950069d29 100644
--- a/src/fileFormats/ensight/part/ensightFaces.C
+++ b/src/fileFormats/ensight/part/ensightFaces.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -27,24 +27,13 @@ License
 #include "error.H"
 #include "polyMesh.H"
 #include "ListOps.H"
-#include "demandDrivenData.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
 const Foam::label Foam::ensightFaces::nTypes = 3;
 
-namespace Foam
-{
-    template<>
-    const char* Foam::NamedEnum
-    <
-        Foam::ensightFaces::elemType,
-        3
-    >::names[] = { "tria3", "quad4", "nsided" };
-}
-
-const Foam::NamedEnum<Foam::ensightFaces::elemType, 3>
-    Foam::ensightFaces::elemEnum;
+const char* Foam::ensightFaces::elemNames[3] =
+    { "tria3", "quad4", "nsided" };
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -99,9 +88,8 @@ void Foam::ensightFaces::resizeAll()
     n = 0;
     forAll(sizes_, typei)
     {
-        deleteDemandDrivenData(lists_[typei]);
-
-        lists_[typei] = new SubList<label>(address_, sizes_[typei], n);
+        slices_[typei].setStart(n);
+        slices_[typei].setSize(sizes_[typei]);
 
         n += sizes_[typei];
     }
@@ -118,16 +106,10 @@ Foam::ensightFaces::ensightFaces(label partIndex)
     index_(partIndex),
     address_(),
     flipMap_(),
-    sizes_(Zero),
-    lists_()
+    slices_(),
+    sizes_(Zero)
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 }
 
 
@@ -136,22 +118,16 @@ Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
     index_(obj.index_),
     address_(obj.address_),
     flipMap_(obj.flipMap_),
-    sizes_(),
-    lists_()
+    slices_(),
+    sizes_()
 {
-    // Ensure sub-lists are properly initialized to nullptr
-    forAll(lists_, typei)
-    {
-        lists_[typei] = nullptr;
-    }
-
-    // Total (reduced) sizes
+    // Save the total (reduced) sizes
     FixedList<label, 3> totSizes = obj.sizes_;
 
-    // Local sizes
+    // Need local sizes for the resize operation
     this->sizes_ = obj.sizes();
 
-    resizeAll(); // adjust allocation
+    resizeAll(); // adjust allocation/sizing
 
     // Restore total (reduced) sizes
     this->sizes_ = totSizes;
@@ -161,14 +137,7 @@ Foam::ensightFaces::ensightFaces(const ensightFaces& obj)
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 Foam::ensightFaces::~ensightFaces()
-{
-    forAll(lists_, typei)
-    {
-        deleteDemandDrivenData(lists_[typei]);
-    }
-    address_.clear();
-    flipMap_.clear();
-}
+{}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -176,27 +145,15 @@ Foam::ensightFaces::~ensightFaces()
 Foam::FixedList<Foam::label, 3> Foam::ensightFaces::sizes() const
 {
     FixedList<label, 3> count;
-    forAll(lists_, typei)
+    forAll(slices_, typei)
     {
-        count[typei] = lists_[typei]->size();
+        count[typei] = slices_[typei].size();
     }
 
     return count;
 }
 
 
-Foam::label Foam::ensightFaces::offset(const enum elemType what) const
-{
-    label n = 0;
-    for (label typei = 0; typei < label(what); ++typei)
-    {
-        n += lists_[typei]->size();
-    }
-
-    return n;
-}
-
-
 Foam::label Foam::ensightFaces::total() const
 {
     label n = 0;
@@ -217,9 +174,10 @@ void Foam::ensightFaces::clear()
 
 void Foam::ensightFaces::reduce()
 {
+    // No listCombineGather, listCombineScatter for FixedList
     forAll(sizes_, typei)
     {
-        sizes_[typei] = lists_[typei]->size();
+        sizes_[typei] = slices_[typei].size();
         Foam::reduce(sizes_[typei], sumOp<label>());
     }
 }
@@ -229,20 +187,15 @@ void Foam::ensightFaces::sort()
 {
     if (flipMap_.size() == address_.size())
     {
-        // sort flip map too
-
+        // Must sort flip map as well
         labelList order;
-        label start = 0;
 
-        forAll(lists_, typei)
+        forAll(slices_, typei)
         {
-            SubList<label>& idLst = *(lists_[typei]);
-            const label sz = idLst.size();
-
-            if (sz)
+            if (slices_[typei].size())
             {
-                SubList<bool> flip(flipMap_, sz, start);
-                start += sz; // for next sub-list
+                SubList<label> idLst(address_, slices_[typei]);
+                SubList<bool>  flip(flipMap_, slices_[typei]);
 
                 Foam::sortedOrder(idLst, order);
 
@@ -254,11 +207,16 @@ void Foam::ensightFaces::sort()
     else
     {
         // no flip-maps, simpler to sort
-        forAll(lists_, typei)
+        forAll(slices_, typei)
         {
-            Foam::sort(*(lists_[typei]));
+            if (slices_[typei].size())
+            {
+                SubList<label> idLst(address_, slices_[typei]);
+                Foam::sort(idLst);
+            }
         }
-        flipMap_.clear();  // for safety
+
+        flipMap_.clear();  // for extra safety
     }
 }
 
@@ -278,7 +236,7 @@ void Foam::ensightFaces::classify(const faceList& faces)
     }
 
     resizeAll();    // adjust allocation
-    sizes_ = Zero;  // reset sizes
+    sizes_ = Zero;  // reset sizes - use for local indexing here
 
     // Assign face-id per shape type
     for (label listi = 0; listi < sz; ++listi)
@@ -318,7 +276,7 @@ void Foam::ensightFaces::classify
     }
 
     resizeAll();    // adjust allocation
-    sizes_ = Zero;  // reset sizes
+    sizes_ = Zero;  // reset sizes - use for local indexing here
 
     if (useFlip)
     {
@@ -330,11 +288,11 @@ void Foam::ensightFaces::classify
     for (label listi = 0; listi < sz; ++listi)
     {
         const label faceId = addressing[listi];
-        const bool flip = useFlip && flipMap[listi];
+        const bool  doFlip = useFlip && flipMap[listi];
 
         if (!exclude[faceId])
         {
-            add(faces[faceId], faceId, flip);
+            add(faces[faceId], faceId, doFlip);
         }
     }
 }
diff --git a/src/fileFormats/ensight/part/ensightFaces.H b/src/fileFormats/ensight/part/ensightFaces.H
index 844a03e9b357f874cb297c0f893958d69bac5c5d..bd7b3e8c40eb8add2d619abba7c6ff05b3db6b27 100644
--- a/src/fileFormats/ensight/part/ensightFaces.H
+++ b/src/fileFormats/ensight/part/ensightFaces.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -37,7 +37,6 @@ Description
 #include "faceList.H"
 #include "FixedList.H"
 #include "PackedBoolList.H"
-#include "NamedEnum.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -57,16 +56,16 @@ public:
         //- Addressable ensight element types
         enum elemType
         {
-            TRIA3,
-            QUAD4,
-            NSIDED
+            TRIA3,      //!< "tria3"
+            QUAD4,      //!< "quad4"
+            NSIDED      //!< "nsided"
         };
 
         //- Number of element types (3)
         static const label nTypes;
 
-        //- The Ensight names for each element type
-        static const NamedEnum<elemType, 3> elemEnum;
+        //- The ensight element type names
+        static const char* elemNames[3];
 
 
     // Static Member Functions
@@ -83,28 +82,27 @@ private:
         //  The ensight part number is typically this value +1.
         label index_;
 
-        //- Linear list of ids, sub-sectioned per element type via SubLists
+        //- Linear list of ids, sub-sectioned per element type by sub-lists
         labelList address_;
 
         //- Linear list of face-flips
         boolList flipMap_;
 
+        //- Slices (sub-lists) of the address and flips for each element type.
+        FixedList<labelRange, 3> slices_;
+
         //- List of global sizes for each element type.
         //  Used temporarily for local sizes when building the element lists.
         FixedList<label, 3> sizes_;
 
-        //- SubLists of ids for each element type.
-        //  Managed via pointers, since a SubList cannot be relocated/resized.
-        FixedList<SubList<label>*, 3> lists_;
-
 
     // Private Member Functions
 
         //- Simple classifier
-        inline static elemType whatType(const face&);
+        inline static elemType whatType(const face& f);
 
         //- Low-level internal addition routine
-        inline void add(const face&, const label id, const bool flip = false);
+        inline void add(const face& f, const label id, const bool flip = false);
 
         //- Use temporarily stored sizes to redimension the element lists
         void resizeAll();
@@ -121,7 +119,7 @@ public:
         ensightFaces(label partIndex = 0);
 
         //- Copy constructor. Needed for lists etc.
-        ensightFaces(const ensightFaces&);
+        ensightFaces(const ensightFaces& obj);
 
 
     //- Destructor
@@ -141,14 +139,17 @@ public:
         //- The processor local size of all elements.
         inline label size() const;
 
-        //- The global number of the specified element type.
-        //  This value is only meaningful after a reduce operation.
-        inline label total(const enum elemType) const;
+        //- The processor local size of the specified element type.
+        inline label size(const enum elemType) const;
 
         //- The global number of all element types.
         //  This value is only meaningful after a reduce operation.
         label total() const;
 
+        //- The global number of the specified element type.
+        //  This value is only meaningful after a reduce operation.
+        inline label total(const enum elemType) const;
+
         //- The global numbers per element type.
         //  This value is only meaningful after a reduce operation.
         inline const FixedList<label, 3>& totals() const;
@@ -157,10 +158,10 @@ public:
         FixedList<label, 3> sizes() const;
 
         //- Processor local starting offset of element type.
-        label offset(const enum elemType what) const;
+        inline label offset(const enum elemType what) const;
 
         //- Return the (local) face ids of the specified element type
-        inline const labelUList& faceIds(const enum elemType) const;
+        inline const labelUList faceIds(const enum elemType) const;
 
         //- Return the processor local face ids of all elements
         inline const labelUList& faceIds() const;
diff --git a/src/fileFormats/ensight/part/ensightFacesI.H b/src/fileFormats/ensight/part/ensightFacesI.H
index 4b32a373dbe23082fde720b58a3c6568396fca68..78048c1c90b26e7b37b71c06e2f6138b5cca282d 100644
--- a/src/fileFormats/ensight/part/ensightFacesI.H
+++ b/src/fileFormats/ensight/part/ensightFacesI.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2016 OpenCFD Ltd.
+    \\  /    A nd           | Copyright (C) 2016-2017 OpenCFD Ltd.
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -29,7 +29,7 @@ License
 
 inline const char* Foam::ensightFaces::key(const enum elemType what)
 {
-    return elemEnum[what];
+    return elemNames[what];
 }
 
 
@@ -63,20 +63,24 @@ inline Foam::label Foam::ensightFaces::total(const enum elemType what) const
 }
 
 
-inline const Foam::labelUList& Foam::ensightFaces::faceIds
+inline Foam::label Foam::ensightFaces::size(const enum elemType what) const
+{
+    return slices_[what].size();
+}
+
+
+inline Foam::label Foam::ensightFaces::offset(const enum elemType what) const
+{
+    return slices_[what].start();
+}
+
+
+inline const Foam::labelUList Foam::ensightFaces::faceIds
 (
     const enum elemType what
 ) const
 {
-    if (!lists_[what])
-    {
-        FatalErrorInFunction
-            << "Accessing unallocated sublist for elem-type: "
-            << elemEnum[what]
-            << exit(FatalError);
-    }
-
-    return *(lists_[what]);
+    return address_[slices_[what]];
 }
 
 
diff --git a/src/fileFormats/sampledSetWriters/gnuplot/gnuplotSetWriter.C b/src/fileFormats/sampledSetWriters/gnuplot/gnuplotSetWriter.C
index 4809bb35045d1963849a585c644396b7b1a7b6d5..f6c724275e928645511c4927e28633ece949783b 100644
--- a/src/fileFormats/sampledSetWriters/gnuplot/gnuplotSetWriter.C
+++ b/src/fileFormats/sampledSetWriters/gnuplot/gnuplotSetWriter.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  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -68,8 +68,18 @@ void Foam::gnuplotSetWriter<Type>::write
 ) const
 {
     os  << "set term postscript color" << nl
-        << "set output \"" << points.name() << ".ps\"" << nl
-        << "plot";
+        << "set output \"" << points.name() << ".ps\"" << nl;
+
+    // Set secondary Y axis if using two columns. Falls back to same
+    // values if both on same scale. However, ignore if more columns.
+    if (valueSetNames.size() == 2)
+    {
+        os  << "set ylabel \"" << valueSetNames[0] << "\"" << nl
+            << "set y2label \"" << valueSetNames[1] << "\"" << nl
+            << "set ytics nomirror" << nl << "set y2tics" << nl;
+    }
+
+    os  << "plot";
 
     forAll(valueSets, i)
     {
@@ -79,10 +89,14 @@ void Foam::gnuplotSetWriter<Type>::write
         }
 
         os  << " \"-\" title \"" << valueSetNames[i] << "\" with lines";
+
+        if (valueSetNames.size() == 2)
+        {
+            os  << " axes x1y" << (i+1) ;
+        }
     }
     os  << nl;
 
-
     forAll(valueSets, i)
     {
         this->writeTable(points, *valueSets[i], os);
diff --git a/src/functionObjects/field/histogram/histogram.C b/src/functionObjects/field/histogram/histogram.C
index 064fb9dded1917aae67d973ca1f2f8293f888e4a..39c2649faba40b3eadfd3702446d54e7de6d8f51 100644
--- a/src/functionObjects/field/histogram/histogram.C
+++ b/src/functionObjects/field/histogram/histogram.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -45,23 +45,31 @@ void Foam::functionObjects::histogram::writeGraph
 (
     const coordSet& coords,
     const word& fieldName,
-    const scalarField& values
+    const scalarField& normalizedValues,
+    const scalarField& absoluteValues
 ) const
 {
-    const wordList fieldNames(1, fieldName);
-
     fileName outputPath = baseTimeDir();
     mkDir(outputPath);
     OFstream graphFile
     (
-        outputPath/formatterPtr_().getFileName(coords, fieldNames)
+        outputPath
+       /formatterPtr_().getFileName
+        (
+            coords,
+            wordList(1, fieldName)
+        )
     );
 
     Log << "    Writing histogram of " << fieldName
         << " to " << graphFile.name() << endl;
 
-    List<const scalarField*> yPtrs(1);
-    yPtrs[0] = &values;
+    wordList fieldNames(2);
+    fieldNames[0] = fieldName;
+    fieldNames[1] = fieldName + "Count";
+    List<const scalarField*> yPtrs(2);
+    yPtrs[0] = &normalizedValues;
+    yPtrs[1] = &absoluteValues;
     formatterPtr_().write(coords, fieldNames, yPtrs, graphFile);
 }
 
@@ -76,7 +84,9 @@ Foam::functionObjects::histogram::histogram
 )
 :
     fvMeshFunctionObject(name, runTime, dict),
-    writeFile(obr_, name)
+    writeFile(obr_, name),
+    max_(-GREAT),
+    min_(GREAT)
 {
     read(dict);
 }
@@ -96,8 +106,9 @@ bool Foam::functionObjects::histogram::read(const dictionary& dict)
     writeFile::read(dict);
 
     dict.lookup("field") >> fieldName_;
-    dict.lookup("max") >> max_;
-    min_ = dict.lookupOrDefault<scalar>("min", 0);
+
+    max_ = dict.lookupOrDefault<scalar>("max", -GREAT);
+    min_ = dict.lookupOrDefault<scalar>("min", GREAT);
     dict.lookup("nBins") >> nBins_;
 
     word format(dict.lookup("setFormat"));
@@ -149,38 +160,63 @@ bool Foam::functionObjects::histogram::write()
        : obr_.lookupObject<volScalarField>(fieldName_)
     );
 
+
+    scalar histMax = max_;
+    scalar histMin = min_;
+
+    if (max_ == -GREAT)
+    {
+        // Determine current min and max
+        histMax = max(field).value();
+
+        if (min_ == GREAT)
+        {
+            histMin = min(field).value();
+        }
+        Log << "    Determined histogram bounds from field"
+            << " min/max(" << fieldName_ << ") = "
+            << histMin << ' ' << histMax << endl;
+    }
+    else if (min_ == GREAT)
+    {
+        histMin = 0;
+    }
+
     // Calculate the mid-points of bins for the graph axis
     pointField xBin(nBins_);
-    const scalar delta = (max_- min_)/nBins_;
+    const scalar delta = (histMax- histMin)/nBins_;
 
-    scalar x = min_ + 0.5*delta;
+    scalar x = histMin + 0.5*delta;
     forAll(xBin, i)
     {
         xBin[i] = point(x, 0, 0);
         x += delta;
     }
 
-    scalarField data(nBins_, 0);
+    scalarField dataNormalized(nBins_, 0);
+    labelField dataCount(nBins_, 0);
     const scalarField& V = mesh_.V();
 
     forAll(field, celli)
     {
-        const label bini = (field[celli] - min_)/delta;
+        const label bini = (field[celli] - histMin)/delta;
         if (bini >= 0 && bini < nBins_)
         {
-            data[bini] += V[celli];
+            dataNormalized[bini] += V[celli];
+            dataCount[bini]++;
         }
     }
 
-    Pstream::listCombineGather(data, plusEqOp<scalar>());
+    Pstream::listCombineGather(dataNormalized, plusEqOp<scalar>());
+    Pstream::listCombineGather(dataCount, plusEqOp<label>());
 
     if (Pstream::master())
     {
-        const scalar sumData = sum(data);
+        const scalar sumData = sum(dataNormalized);
 
         if (sumData > SMALL)
         {
-            data /= sumData;
+            dataNormalized /= sumData;
 
             const coordSet coords
             (
@@ -190,7 +226,15 @@ bool Foam::functionObjects::histogram::write()
                 mag(xBin)
             );
 
-            writeGraph(coords, fieldName_, data);
+
+            // Convert count field from labelField to scalarField
+            scalarField count(dataCount.size());
+            forAll(count, i)
+            {
+                count[i] = 1.0*dataCount[i];
+            }
+
+            writeGraph(coords, fieldName_, dataNormalized, count);
         }
     }
 
diff --git a/src/functionObjects/field/histogram/histogram.H b/src/functionObjects/field/histogram/histogram.H
index 4dd2982a487704bcc6df436b642281ef618760fc..f5b9402a44e5e401ac7bd7661f32a00f6ca99142 100644
--- a/src/functionObjects/field/histogram/histogram.H
+++ b/src/functionObjects/field/histogram/histogram.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -53,11 +53,17 @@ Usage
         type         | type name: histogram    | yes         |
         field        | Field to analyse        | yes         |
         nBins        | Number of bins for the histogram | yes|
-        max          | Maximum value sampled   | yes         |
+        max          | Maximum value sampled   | no          | field max
         min          | minimum value sampled   | no          | 0
         setFormat    | Output format           | yes         |
     \endtable
 
+Note
+    If max is not provided it will use the field's min and max as the bin
+    extremes. If max is provided but not min it will use 0. The set written
+    contains two columns, the first the volume averaged values, the second
+    the raw bin count.
+
 See also
     Foam::functionObject
     Foam::functionObjects::fvMeshFunctionObject
@@ -115,7 +121,8 @@ class histogram
         (
             const coordSet& coords,
             const word& valueName,
-            const scalarField& values
+            const scalarField& normalizedValues,
+            const scalarField& absoluteValues
         ) const;
 
         //- Disallow default bitwise copy construct
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index 0606860e64a4da677e4b4c6eeb72c36c9ed5f0dd..41d0418a3b7d38a1935d59c9f87fe3f69a5d2fa4 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -33,24 +33,17 @@ License
 #include "polyMesh.H"
 #include "surfMesh.H"
 #include "primitivePatch.H"
+#include "faceTraits.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-template<class Face>
-inline bool Foam::MeshedSurface<Face>::isTri()
-{
-    return false;
-}
-
-
 template<class Face>
 Foam::wordHashSet Foam::MeshedSurface<Face>::readTypes()
 {
     return wordHashSet(*fileExtensionConstructorTablePtr_);
 }
 
-
 template<class Face>
 Foam::wordHashSet Foam::MeshedSurface<Face>::writeTypes()
 {
@@ -116,25 +109,34 @@ void Foam::MeshedSurface<Face>::write
     const fileName& name,
     const MeshedSurface<Face>& surf
 )
+{
+    write(name, name.ext(), surf);
+}
+
+
+template<class Face>
+void Foam::MeshedSurface<Face>::write
+(
+    const fileName& name,
+    const word& ext,
+    const MeshedSurface<Face>& surf
+)
 {
     if (debug)
     {
         InfoInFunction << "Writing to " << name << endl;
     }
 
-    const word ext = name.ext();
-
-    typename writefileExtensionMemberFunctionTable::iterator mfIter =
-        writefileExtensionMemberFunctionTablePtr_->find(ext);
+    auto mfIter = writefileExtensionMemberFunctionTablePtr_->find(ext);
 
-    if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
+    if (!mfIter.found())
     {
         // No direct writer, delegate to proxy if possible
         const wordHashSet& delegate = ProxyType::writeTypes();
 
         if (delegate.found(ext))
         {
-            MeshedSurfaceProxy<Face>(surf).write(name);
+            MeshedSurfaceProxy<Face>(surf).write(name, ext);
         }
         else
         {
@@ -850,6 +852,11 @@ bool Foam::MeshedSurface<Face>::checkFaces
 template<class Face>
 Foam::label Foam::MeshedSurface<Face>::nTriangles() const
 {
+    if (faceTraits<Face>::isTri())
+    {
+        return ParentType::size();
+    }
+
     return nTriangles
     (
         const_cast<List<label>&>(List<label>::null())
@@ -905,10 +912,18 @@ Foam::label Foam::MeshedSurface<Face>::nTriangles
 template<class Face>
 Foam::label Foam::MeshedSurface<Face>::triangulate()
 {
-    return triangulate
-    (
-        const_cast<List<label>&>(List<label>::null())
-    );
+    if (faceTraits<Face>::isTri())
+    {
+        // Inplace triangulation of triFace/labelledTri surface = no-op
+        return 0;
+    }
+    else
+    {
+        return triangulate
+        (
+            const_cast<List<label>&>(List<label>::null())
+        );
+    }
 }
 
 
@@ -918,6 +933,17 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
     List<label>& faceMapOut
 )
 {
+    if (faceTraits<Face>::isTri())
+    {
+        // Inplace triangulation of triFace/labelledTri surface = no-op
+        if (notNull(faceMapOut))
+        {
+            faceMapOut.clear();
+        }
+
+        return 0;
+    }
+
     label nTri = 0;
     label maxTri = 0;  // the maximum number of triangles for any single face
     List<Face>& faceLst = this->storedFaces();
@@ -966,7 +992,7 @@ Foam::label Foam::MeshedSurface<Face>::triangulate
             {
                 label fp1 = f.fcIndex(fp);
 
-                newFaces[nTri] = triFace(f[0], f[fp], f[fp1]);
+                newFaces[nTri] = Face{f[0], f[fp], f[fp1]};
                 faceMap[nTri] = facei;
                 nTri++;
             }
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index 513a813597ca1fe5de1a174ff751db4680bc4ff5..aca6e18647f2e65174f915ea80dee8e77a5e66c9 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -186,9 +186,6 @@ public:
 
     // Static
 
-        //- Face storage only handles triangulated faces
-        inline static bool isTri();
-
         //- Can we read this file format?
         static bool canRead(const fileName&, const bool verbose=false);
 
@@ -210,36 +207,36 @@ public:
         //- Construct by transferring components (points, faces, zones).
         MeshedSurface
         (
-            const Xfer<pointField>&,
-            const Xfer<List<Face>>&,
-            const Xfer<surfZoneList>&
+            const Xfer<pointField>& pointLst,
+            const Xfer<List<Face>>& faceLst,
+            const Xfer<surfZoneList>& zoneLst
         );
 
         //- Construct by transferring components (points, faces).
         //  Use zone information if available
         MeshedSurface
         (
-            const Xfer<pointField>&,
-            const Xfer<List<Face>>&,
+            const Xfer<pointField>& pointLst,
+            const Xfer<List<Face>>& faceLst,
             const labelUList& zoneSizes = labelUList(),
             const UList<word>& zoneNames = UList<word>()
         );
 
         //- Construct as copy
-        MeshedSurface(const MeshedSurface&);
+        MeshedSurface(const MeshedSurface& surf);
 
         //- Construct from a UnsortedMeshedSurface
-        MeshedSurface(const UnsortedMeshedSurface<Face>&);
+        MeshedSurface(const UnsortedMeshedSurface<Face>& surf);
 
         //- Construct from a boundary mesh with local points/faces
         MeshedSurface
         (
-            const polyBoundaryMesh&,
+            const polyBoundaryMesh& bMesh,
             const bool globalPoints=false
         );
 
         //- Construct from a surfMesh
-        MeshedSurface(const surfMesh&);
+        MeshedSurface(const surfMesh& mesh);
 
         //- Construct by transferring the contents from a UnsortedMeshedSurface
         MeshedSurface(const Xfer<UnsortedMeshedSurface<Face>>&);
@@ -248,18 +245,18 @@ public:
         MeshedSurface(const Xfer<MeshedSurface<Face>>&);
 
         //- Construct from file name (uses extension to determine type)
-        MeshedSurface(const fileName&);
+        MeshedSurface(const fileName& name);
 
         //- Construct from file name (uses extension to determine type)
-        MeshedSurface(const fileName&, const word& ext);
+        MeshedSurface(const fileName& name, const word& ext);
 
         //- Construct from Istream
-        MeshedSurface(Istream&);
+        MeshedSurface(Istream& is);
 
         //- Construct from database
         MeshedSurface
         (
-            const Time&,
+            const Time& t,
             const word& surfName = word::null
         );
 
@@ -283,7 +280,7 @@ public:
         //- Select constructed from filename (explicit extension)
         static autoPtr<MeshedSurface> New
         (
-            const fileName&,
+            const fileName& name,
             const word& ext
         );
 
@@ -310,11 +307,19 @@ public:
             (name, surf)
         );
 
-        //- Write to file
+        //- Write to file, selecting writer based on its extension
         static void write
         (
-            const fileName&,
-            const MeshedSurface<Face>&
+            const fileName& name,
+            const MeshedSurface<Face>& surf
+        );
+
+        //- Write to file, selecting writer based on the given extension
+        static void write
+        (
+            const fileName& name,
+            const word& ext,
+            const MeshedSurface<Face>& surf
         );
 
 
@@ -563,8 +568,6 @@ bool MeshedSurface<labelledTri>::addZonesToFaces();
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "MeshedSurfaceI.H"
-
 #ifdef NoRepository
     #include "MeshedSurface.C"
 #endif
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C b/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
index 8640b6e5aeb0aa571943318c1bc20f016a7b2321..4a9bb6cac1994038b69a1792a8e9599cb8f3fa57 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceCore.C
@@ -50,7 +50,7 @@ namespace Foam
     )
     {
         // First triangulate
-        // - slightly wasteful for space, but manages adjusts the zones too!
+        // - slightly wasteful for space, but adjusts the zones too!
         surf.triangulate();
         this->storedPoints().transfer(surf.storedPoints());
         this->storedZones().transfer(surf.storedZones());
@@ -81,12 +81,12 @@ namespace Foam
     )
     {
         // First triangulate
-        // - slightly wasteful for space, but manages adjusts the zones too!
+        // - slightly wasteful for space, but adjusts the zones too!
         surf.triangulate();
         this->storedPoints().transfer(surf.storedPoints());
         this->storedZones().transfer(surf.storedZones());
 
-        // transcribe from face -> triFace
+        // transcribe from face -> labelledTri (via triFace)
         const List<face>& origFaces = surf.surfFaces();
         List<labelledTri> newFaces(origFaces.size());
         forAll(origFaces, facei)
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
index 9d8c5dd0912b8c9259657d5a936a5d9b225c3330..a8c8e4c7a3291292151ac3b68cc24b644a9cc4f0 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,7 @@ License
 
 #include "MeshedSurface.H"
 #include "boundBox.H"
+#include "faceTraits.H"
 #include "Istream.H"
 #include "Ostream.H"
 
@@ -58,7 +59,7 @@ template<class Face>
 void Foam::MeshedSurface<Face>::writeStats(Ostream& os) const
 {
     os  << "points      : " << this->points().size() << nl;
-    if (MeshedSurface<Face>::isTri())
+    if (faceTraits<Face>::isTri())
     {
         os << "triangles   : " << this->size() << nl;
     }
@@ -82,7 +83,7 @@ void Foam::MeshedSurface<Face>::writeStats(Ostream& os) const
 
         os  << "faces       : " << this->size()
             << "  (tri:" << nTri << " quad:" << nQuad
-            << " poly:" << (this->size() - nTri - nQuad ) << ")" << nl;
+            << " poly:" << (this->size() - nTri - nQuad) << ")" << nl;
     }
 
     os  << "boundingBox : " << boundBox(this->points()) << endl;
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
index a8280451ee8c6e95c383f74bc9128b0dec957fb0..7d345191ff8539fe5590cdb8cd39ee0e28618b6d 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
@@ -38,10 +38,9 @@ Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
         InfoInFunction << "Constructing MeshedSurface" << endl;
     }
 
-    typename fileExtensionConstructorTable::iterator cstrIter =
-        fileExtensionConstructorTablePtr_->find(ext);
+    auto cstrIter = fileExtensionConstructorTablePtr_->find(ext);
 
-    if (cstrIter == fileExtensionConstructorTablePtr_->end())
+    if (!cstrIter.found())
     {
         // No direct reader, delegate to friend if possible
         const wordHashSet& delegate = FriendType::readTypes();
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
index 168155a59716e9fc1e00ec7da637a4fb62384b15..b5dbdb6c99d3a23dda30fbe7177723c4350898c0 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
@@ -29,6 +29,7 @@ License
 #include "ListOps.H"
 #include "surfMesh.H"
 #include "OFstream.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
@@ -59,18 +60,27 @@ void Foam::MeshedSurfaceProxy<Face>::write
     const fileName& name,
     const MeshedSurfaceProxy& surf
 )
+{
+    write(name, name.ext(), surf);
+}
+
+
+template<class Face>
+void Foam::MeshedSurfaceProxy<Face>::write
+(
+    const fileName& name,
+    const word& ext,
+    const MeshedSurfaceProxy& surf
+)
 {
     if (debug)
     {
         InfoInFunction << "Writing to " << name << endl;
     }
 
-    const word ext = name.ext();
+    auto mfIter = writefileExtensionMemberFunctionTablePtr_->find(ext);
 
-    typename writefileExtensionMemberFunctionTable::iterator mfIter =
-        writefileExtensionMemberFunctionTablePtr_->find(ext);
-
-    if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
+    if (!mfIter.found())
     {
         FatalErrorInFunction
             << "Unknown file extension " << ext << nl << nl
@@ -237,38 +247,24 @@ Foam::MeshedSurfaceProxy<Face>::~MeshedSurfaceProxy()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-
-namespace Foam
-{
-
-// Number of triangles for a triFace surface
-template<>
-inline label MeshedSurfaceProxy<triFace>::nTriangles() const
-{
-    return this->size();
-}
-
-// Number of triangles for a labelledTri surface
-template<>
-inline label MeshedSurfaceProxy<labelledTri>::nTriangles() const
-{
-    return this->size();
-}
-
-}
-
-
 template<class Face>
 inline Foam::label Foam::MeshedSurfaceProxy<Face>::nTriangles() const
 {
-    label nTri = 0;
-    const List<Face>& faceLst = this->surfFaces();
-    forAll(faceLst, facei)
+    if (faceTraits<Face>::isTri())
     {
-        nTri += faceLst[facei].nTriangles();
+        return this->size();
     }
+    else
+    {
+        label nTri = 0;
+        const List<Face>& faceLst = this->surfFaces();
+        forAll(faceLst, facei)
+        {
+            nTri += faceLst[facei].nTriangles();
+        }
 
-    return nTri;
+        return nTri;
+    }
 }
 
 
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
index 3bedc3f0767f90fea6c792158c60676764be8469..6c0f3582e577fa2ac8bcbfae373f606f95a16148 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
@@ -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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -100,9 +100,9 @@ public:
         //- Construct from component references
         MeshedSurfaceProxy
         (
-            const pointField&,
-            const List<Face>&,
-            const List<surfZone>& = List<surfZone>(),
+            const pointField& pointLst,
+            const List<Face>& faceLst,
+            const List<surfZone>& zoneLst = List<surfZone>(),
             const List<label>& faceMap = List<label>()
         );
 
@@ -126,11 +126,19 @@ public:
             (name, surf)
         );
 
-        //- Write to file
+        //- Write to file, selected based on its extension
         static void write
         (
-            const fileName&,
-            const MeshedSurfaceProxy<Face>&
+            const fileName& name,
+            const MeshedSurfaceProxy& surf
+        );
+
+        //- Write to file, selected based on given extension
+        static void write
+        (
+            const fileName& name,
+            const word& ext,
+            const MeshedSurfaceProxy& surf
         );
 
 
@@ -188,10 +196,16 @@ public:
                 write(name, *this);
             }
 
+            //- Generic write routine. Chooses writer based on extension.
+            virtual void write(const fileName& name, const word& ext) const
+            {
+                write(name, ext, *this);
+            }
+
             //- Write to database
             virtual void write
             (
-                const Time&,
+                const Time& t,
                 const word& surfName = word::null
             ) const;
 };
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index 42a7d1d9fe1ecc8e4d36466c10f430d536cf7862..7ac9a3e598c536a08433fe787aff92370aaeb6af 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -113,17 +113,16 @@ void Foam::UnsortedMeshedSurface<Face>::write
 
     const word ext = name.ext();
 
-    typename writefileExtensionMemberFunctionTable::iterator mfIter =
-        writefileExtensionMemberFunctionTablePtr_->find(ext);
+    auto mfIter = writefileExtensionMemberFunctionTablePtr_->find(ext);
 
-    if (mfIter == writefileExtensionMemberFunctionTablePtr_->end())
+    if (!mfIter.found())
     {
         // No direct writer, delegate to proxy if possible
         const wordHashSet& delegate = ProxyType::writeTypes();
 
         if (delegate.found(ext))
         {
-            MeshedSurfaceProxy<Face>(surf).write(name);
+            MeshedSurfaceProxy<Face>(surf).write(name, ext);
         }
         else
         {
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
index f6f1431a8353b3eb01814acf26034b6bae87eeb1..6f50b238975201c096eff579cb5da7c54b0340d9 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
@@ -37,10 +37,9 @@ Foam::UnsortedMeshedSurface<Face>::New(const fileName& name, const word& ext)
         InfoInFunction << "Constructing UnsortedMeshedSurface" << endl;
     }
 
-    typename fileExtensionConstructorTable::iterator cstrIter =
-        fileExtensionConstructorTablePtr_->find(ext);
+    auto cstrIter = fileExtensionConstructorTablePtr_->find(ext);
 
-    if (cstrIter == fileExtensionConstructorTablePtr_->end())
+    if (!cstrIter.found())
     {
         // No direct reader, delegate to parent if possible
         const wordHashSet& delegate = ParentType::readTypes();
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
index 0c60b22ede22db7b1b71739a0b67cc76bcbd21fc..daa0e2c1f8acca4b085751892e3b475a68285e8c 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "AC3DsurfaceFormat.H"
 #include "IStringStream.H"
 #include "PrimitivePatch.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -194,9 +195,9 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                         verts[vertI] = parse<int>(line) + vertexOffset;
                     }
 
-                    labelUList& f = static_cast<labelUList&>(verts);
+                    const labelUList& f = static_cast<const labelUList&>(verts);
 
-                    if (MeshedSurface<Face>::isTri() && f.size() > 3)
+                    if (faceTraits<Face>::isTri() && f.size() > 3)
                     {
                         // simple face triangulation about f[0]
                         // points may be incomplete
@@ -204,7 +205,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                         {
                             label fp2 = f.fcIndex(fp1);
 
-                            dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                            dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                             sizes[zoneI]++;
                         }
                     }
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
index 731b2e1b96aa397c06aeeecfb80073ea37721161..f2aa5b22ee3eaf1b1f7fa0d4fb11a20140e5c04b 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,8 +28,8 @@ License
 #include "clock.H"
 #include "IFstream.H"
 #include "IStringStream.H"
-#include "Ostream.H"
 #include "OFstream.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -187,7 +187,7 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
                 << exit(FatalError);
         }
 
-        faceLst[facei] = triFace(e0Far, common01, e1Far);
+        faceLst[facei] = Face{e0Far, common01, e1Far};
         zoneIds[facei] = zoneI;
     }
 
@@ -229,7 +229,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
-    if (!MeshedSurface<Face>::isTri())
+    if (!faceTraits<Face>::isTri())
     {
         label nNonTris = 0;
         forAll(faceLst, facei)
@@ -249,7 +249,6 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-
     OFstream os(filename);
     if (!os.good())
     {
@@ -331,7 +330,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
-    if (!MeshedSurface<Face>::isTri())
+    if (!faceTraits<Face>::isTri())
     {
         label nNonTris = 0;
         forAll(faceLst, facei)
@@ -351,7 +350,6 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-
     OFstream os(filename);
     if (!os.good())
     {
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
index d7b932ec485de4fba41ca5b3efbb1ae4996bc325..55f941bf43fc63bb21060761959e620141c7e72e 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2015 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "NASsurfaceFormat.H"
 #include "IFstream.H"
 #include "IStringStream.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -191,12 +192,10 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
 
         if (cmd == "CTRIA3")
         {
-            triFace fTri;
-
             label groupId = readLabel(IStringStream(line.substr(16,8))());
-            fTri[0] = readLabel(IStringStream(line.substr(24,8))());
-            fTri[1] = readLabel(IStringStream(line.substr(32,8))());
-            fTri[2] = readLabel(IStringStream(line.substr(40,8))());
+            label a = readLabel(IStringStream(line.substr(24,8))());
+            label b = readLabel(IStringStream(line.substr(32,8))());
+            label c = readLabel(IStringStream(line.substr(40,8))());
 
             // Convert groupID into zoneId
             Map<label>::const_iterator fnd = lookup.find(groupId);
@@ -217,20 +216,17 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 // Info<< "zone" << zoneI << " => group " << groupId <<endl;
             }
 
-            dynFaces.append(fTri);
+            dynFaces.append(Face{a, b, c});
             dynZones.append(zoneI);
             dynSizes[zoneI]++;
         }
         else if (cmd == "CQUAD4")
         {
-            face fQuad(4);
-            labelUList& f = static_cast<labelUList&>(fQuad);
-
             label groupId = readLabel(IStringStream(line.substr(16,8))());
-            fQuad[0] = readLabel(IStringStream(line.substr(24,8))());
-            fQuad[1] = readLabel(IStringStream(line.substr(32,8))());
-            fQuad[2] = readLabel(IStringStream(line.substr(40,8))());
-            fQuad[3] = readLabel(IStringStream(line.substr(48,8))());
+            label a = readLabel(IStringStream(line.substr(24,8))());
+            label b = readLabel(IStringStream(line.substr(32,8))());
+            label c = readLabel(IStringStream(line.substr(40,8))());
+            label d = readLabel(IStringStream(line.substr(48,8))());
 
             // Convert groupID into zoneId
             Map<label>::const_iterator fnd = lookup.find(groupId);
@@ -251,18 +247,17 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 // Info<< "zone" << zoneI << " => group " << groupId <<endl;
             }
 
-
-            if (MeshedSurface<Face>::isTri())
+            if (faceTraits<Face>::isTri())
             {
-                dynFaces.append(triFace(f[0], f[1], f[2]));
-                dynFaces.append(triFace(f[0], f[2], f[3]));
+                dynFaces.append(Face{a, b, c});
+                dynFaces.append(Face{c, d, a});
                 dynZones.append(zoneI);
                 dynZones.append(zoneI);
                 dynSizes[zoneI] += 2;
             }
             else
             {
-                dynFaces.append(Face(f));
+                dynFaces.append(Face{a,b,c,d});
                 dynZones.append(zoneI);
                 dynSizes[zoneI]++;
             }
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
index 395e2bacb73f18c19564946eb17cda5bbf9eb625..db2036aa888e5204251393612833f53273b32bfe 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,9 +27,9 @@ License
 #include "clock.H"
 #include "IFstream.H"
 #include "IStringStream.H"
-#include "Ostream.H"
 #include "OFstream.H"
 #include "ListOps.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -172,7 +172,7 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
 
             labelUList& f = static_cast<labelUList&>(dynVertices);
 
-            if (MeshedSurface<Face>::isTri() && f.size() > 3)
+            if (faceTraits<Face>::isTri() && f.size() > 3)
             {
                 // simple face triangulation about f[0]
                 // points may be incomplete
@@ -180,7 +180,7 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
                 {
                     label fp2 = f.fcIndex(fp1);
 
-                    dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                    dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                     dynZones.append(zoneI);
                     dynSizes[zoneI]++;
                 }
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
index fd869a0c5086db67467529aa42bac8d9f282f080..3146f01b990b6f9fcfbbe537433c0ca51f6e736d 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -27,7 +27,7 @@ License
 #include "clock.H"
 #include "IFstream.H"
 #include "IStringStream.H"
-#include "Ostream.H"
+#include "faceTraits.H"
 #include "OFstream.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
@@ -113,9 +113,9 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
                 lineStream >> verts[vertI];
             }
 
-            labelUList& f = static_cast<labelUList&>(verts);
+            const labelUList& f = static_cast<const labelUList&>(verts);
 
-            if (MeshedSurface<Face>::isTri() && f.size() > 3)
+            if (faceTraits<Face>::isTri() && f.size() > 3)
             {
                 // simple face triangulation about f[0]
                 // cannot use face::triangulation (points may be incomplete)
@@ -123,7 +123,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
                 {
                     label fp2 = f.fcIndex(fp1);
 
-                    dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                    dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                 }
             }
             else
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
index 7240ee78245a01aad1371e18d01ccdf1b7233dfe..36e3f2b0a0bc6abe4831c5a4df54aa3f4cb8e7d5 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -25,6 +25,7 @@ License
 
 #include "STARCDsurfaceFormat.H"
 #include "ListOps.H"
+#include "faceTraits.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -193,7 +194,7 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
             }
 
             SubList<label> vertices(vertexLabels, vertexLabels.size());
-            if (MeshedSurface<Face>::isTri() && nLabels > 3)
+            if (faceTraits<Face>::isTri() && nLabels > 3)
             {
                 // face needs triangulation
                 face f(vertices);
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
index ee598a5228e87c559a0d8c32669eb63f7fba65ec..f9e335c39eb8dd7cca3f629b277f68c197e86077 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
@@ -146,7 +146,7 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         forAll(faceLst, facei)
         {
             const label startPt = 3*facei;
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     else
@@ -160,7 +160,7 @@ bool Foam::fileFormats::STLsurfaceFormat<Face>::read
         forAll(faceMap, facei)
         {
             const label startPt = 3*faceMap[facei];
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     zoneIds.clear();
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
index 5b0aba1f8808a1a6885bd5925f2fe08ef9e42c7d..cb2aa80823b8b074fc90c665010a7236b245cd51 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -97,7 +97,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
         forAll(faceLst, facei)
         {
             const label startPt = 3*facei;
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     else
@@ -111,7 +111,7 @@ bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
         forAll(faceMap, facei)
         {
             const label startPt = 3*faceMap[facei];
-            faceLst[facei] = triFace(startPt, startPt+1, startPt+2);
+            faceLst[facei] = Face{startPt, startPt+1, startPt+2};
         }
     }
     zoneIds.clear();
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
index aedd18d6c853b42e048bfd75f514f62b4d8e85aa..b0a5d2711498e694299a1d41c2504fdd83eb5fd6 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.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 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2107 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -26,6 +26,7 @@ License
 #include "VTKsurfaceFormat.H"
 #include "vtkUnstructuredReader.H"
 #include "scalarIOField.H"
+#include "faceTraits.H"
 #include "OFstream.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
@@ -150,7 +151,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
 
     // Check if it needs triangulation
     label nTri = 0;
-    if (MeshedSurface<Face>::isTri())
+    if (faceTraits<Face>::isTri())
     {
         forAll(faces, facei)
         {
@@ -172,7 +173,7 @@ bool Foam::fileFormats::VTKsurfaceFormat<Face>::read
             {
                 label fp2 = f.fcIndex(fp1);
 
-                dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                dynFaces.append(Face{f[0], f[fp1], f[fp2]});
                 dynZones.append(zones[facei]);
             }
         }