diff --git a/applications/solvers/combustion/PDRFoam/PDRModels/XiEqModels/basicXiSubXiEq/basicXiSubXiEq.H b/applications/solvers/combustion/PDRFoam/PDRModels/XiEqModels/basicXiSubXiEq/basicXiSubXiEq.H
index c89d8dc6c9bba726a9eeaa205cad3c10229bbed7..04cc2a83cadcee2acdcf9473a7ef40f3c3def1f3 100644
--- a/applications/solvers/combustion/PDRFoam/PDRModels/XiEqModels/basicXiSubXiEq/basicXiSubXiEq.H
+++ b/applications/solvers/combustion/PDRFoam/PDRModels/XiEqModels/basicXiSubXiEq/basicXiSubXiEq.H
@@ -29,6 +29,36 @@ Description
     Basic sub-grid obstacle flame-wrinking enhancement factor model.
     Details supplied by J Puttock 2/7/06.
 
+    <b> Sub-grid flame area generation </b>
+
+    \f$ n = N - \hat{\dwea{\vec{U}}}.n_{s}.\hat{\dwea{\vec{U}}} \f$
+    \f$ n_{r} = \sqrt{n} \f$
+
+    where:
+
+        \f$ \hat{\dwea{\vec{U}}} = \dwea{\vec{U}} / \vert \dwea{\vec{U}}
+        \vert \f$
+
+        \f$ b = \hat{\dwea{\vec{U}}}.B.\hat{\dwea{\vec{U}}} / n_{r} \f$
+
+    where:
+
+        \f$ B \f$ is the file "B".
+
+        \f$ N \f$ is the file "N".
+
+        \f$  n_{s} \f$ is the file "ns".
+
+    The flame area enhancement factor \f$ \Xi_{sub} \f$ is expected to
+    approach:
+
+    \f[
+        \Xi_{{sub}_{eq}} =
+            1 + max(2.2 \sqrt{b}, min(0.34 \frac{\vert \dwea{\vec{U}}
+            \vert}{{\vec{U}}^{'}}, 1.6)) \times min(\frac{n}{4}, 1)
+    \f]
+
+
 SourceFiles
     basicSubGrid.C
 
diff --git a/applications/solvers/combustion/PDRFoam/PDRModels/XiGModels/basicXiSubG/basicXiSubG.H b/applications/solvers/combustion/PDRFoam/PDRModels/XiGModels/basicXiSubG/basicXiSubG.H
index 01a6d7cb11c98f6936bc446f2f2001da676a5595..a455fd28b4963ce6ad2305230fdfee06dde245b3 100644
--- a/applications/solvers/combustion/PDRFoam/PDRModels/XiGModels/basicXiSubG/basicXiSubG.H
+++ b/applications/solvers/combustion/PDRFoam/PDRModels/XiGModels/basicXiSubG/basicXiSubG.H
@@ -25,10 +25,28 @@ License
 Class
     basicSubGrid
 
+
 Description
+
     Basic sub-grid obstacle flame-wrinking generation rate coefficient model.
     Details supplied by J Puttock 2/7/06.
 
+    \f$ G_{sub} \f$ denotes the generation coefficient and it is given by
+
+    \f[
+        G_{sub} = k_{1} /frac{\vert \dwea{\vec{U}} \vert}{L_{obs}}
+                 \frac{/Xi_{{sub}_{eq}}-1}{/Xi_{sub}}
+    \f]
+
+    and the removal:
+
+    \f[ - k_{1} /frac{\vert \dwea{\vec{U}} \vert}{L_{sub}}
+    \frac{\Xi_{sub}-1}{\Xi_{sub}} \f]
+
+    Finally, \f$ G_{sub} \f$ is added to generation rate \f$ G_{in} \f$
+    due to the turbulence.
+
+
 SourceFiles
     basicSubGrid.C
 
diff --git a/applications/solvers/combustion/PDRFoam/PDRModels/dragModels/basic/basic.H b/applications/solvers/combustion/PDRFoam/PDRModels/dragModels/basic/basic.H
index ceb75ff827cedb06fa61f68e57b861f7d6317618..05ec433919da7a247042a2011aecab79464f7691 100644
--- a/applications/solvers/combustion/PDRFoam/PDRModels/dragModels/basic/basic.H
+++ b/applications/solvers/combustion/PDRFoam/PDRModels/dragModels/basic/basic.H
@@ -29,6 +29,50 @@ Description
     Basic sub-grid obstacle drag model.
     Details supplied by J Puttock 2/7/06.
 
+    <b> Sub-grid drag term </b>
+
+    The resistance term (force per unit of volume) is given by:
+
+    \f[
+        R = -\frac{1}{2} \rho \vert \dwea{\vec{U}} \vert \dwea{\vec{U}}.D
+    \f]
+
+    where:
+
+        \f$ D \f$ is the tensor field "CR" in \f$ m^{-1} \f$
+
+        This is term is treated implicitly in UEqn.H
+
+    <b> Sub-grid turbulence generation </b>
+
+    The turbulence source term \f$ G_{R} \f$ occurring in the
+    \f$ \kappa-\epsilon \f$ equations for the generation of turbulence due
+    to interaction with unresolved obstacles :
+
+    \f$ G_{R} = C_{s}\beta_{\nu}
+    \mu_{eff} A_{w}^{2}(\dwea{\vec{U}}-\dwea{\vec{U}_{s}})^2 + \frac{1}{2}
+    \rho \vert \dwea{\vec{U}} \vert \dwea{\vec{U}}.T.\dwea{\vec{U}} \f$
+
+    where:
+
+        \f$ C_{s} \f$ = 1
+
+        \f$ \beta_{\nu} \f$ is the volume porosity (file "betav").
+
+        \f$ \mu_{eff} \f$ is the effective viscosity.
+
+        \f$ A_{w}^{2}\f$ is the obstacle surface area per unit of volume
+        (file "Aw").
+
+        \f$ \dwea{\vec{U}_{s}} \f$ is the slip velocity and is considered
+        \f$ \frac{1}{2}. \dwea{\vec{U}} \f$.
+
+        \f$ T \f$ is a tensor in the file CT.
+
+    The term \f$ G_{R} \f$ is treated explicitly in the \f$ \kappa-\epsilon
+    \f$ Eqs in the PDRkEpsilon.C file.
+
+
 SourceFiles
     basic.C
 
@@ -40,7 +84,6 @@ SourceFiles
 #include "PDRDragModel.H"
 #include "XiEqModel.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
diff --git a/applications/solvers/combustion/PDRFoam/PDRModels/turbulence/PDRkEpsilon/PDRkEpsilon.H b/applications/solvers/combustion/PDRFoam/PDRModels/turbulence/PDRkEpsilon/PDRkEpsilon.H
index 15d52e72698f9cb20566a9a7d186e1d22784703c..b35ef9151ea1c7fe633475a459d38a6ded55459d 100644
--- a/applications/solvers/combustion/PDRFoam/PDRModels/turbulence/PDRkEpsilon/PDRkEpsilon.H
+++ b/applications/solvers/combustion/PDRFoam/PDRModels/turbulence/PDRkEpsilon/PDRkEpsilon.H
@@ -26,7 +26,17 @@ Class
     PDRkEpsilon
 
 Description
-    Standard k-epsilon turbulence model.
+    Standard k-epsilon turbulence model with additional source terms
+    corresponding to PDR basic drag model (basic.H)
+
+    The turbulence source term \f$ G_{R} \f$ appears in the
+    \f$ \kappa-\epsilon \f$ equation for the generation of turbulence due to
+    interaction with unresolved obstacles.
+
+    In the \f$ \epsilon  \f$ equation \f$ C_{1} G_{R} \f$ is added as a source
+    term.
+
+    In the \f$ \kappa \f$ equation \f$ G_{R} \f$ is added as a source term.
 
 SourceFiles
     PDRkEpsilon.C
diff --git a/applications/solvers/combustion/PDRFoam/XiModels/XiModel/XiModel.H b/applications/solvers/combustion/PDRFoam/XiModels/XiModel/XiModel.H
index 13fa58a53eebdd090fac5ee9b1acf56e3cf15ff8..2b76f9bc92a498028aa3ee9d48061f415f5c130b 100644
--- a/applications/solvers/combustion/PDRFoam/XiModels/XiModel/XiModel.H
+++ b/applications/solvers/combustion/PDRFoam/XiModels/XiModel/XiModel.H
@@ -27,6 +27,57 @@ Class
 
 Description
     Base-class for all Xi models used by the b-Xi combustion model.
+    See Technical Report SH/RE/01R for details on the PDR modelling.
+
+    Xi is given through an algebraic expression (algebraic.H),
+    by solving a transport equation (transport.H) or a fixed value (fixed.H).
+    See report TR/HGW/10 for details on the Weller two equations model.
+
+    In the algebraic and transport methods \f$\Xi_{eq}\f$ is calculated in
+    similar way. In the algebraic approach, \f$\Xi_{eq}\f$ is the value used in
+    the \f$ b \f$ transport equation.
+
+    \f$\Xi_{eq}\f$ is calculated as follows:
+
+    \f$\Xi_{eq} = 1 + (1 + 2\Xi_{coeff}(0.5 - \dwea{b}))(\Xi^* - 1)\f$
+
+    where:
+
+        \f$ \dwea{b} \f$ is the regress variable.
+
+        \f$ \Xi^* \f$ is the total equilibrium wrinkling combining the effects
+        of the flame inestability and turbulence interaction and is given by
+
+        \f[
+            \Xi^* = \frac {R}{R - G_\eta - G_{in}}
+        \f]
+
+    where:
+
+        \f$ G_\eta \f$ is the generation rate of wrinkling due to turbulence
+        interaction.
+
+        \f$ G_{in} = \kappa \rho_{u}/\rho_{b} \f$ is the generation
+         rate due to the flame inestability.
+
+    By adding the removal rates of the two effects:
+
+        \f[
+            R = G_\eta \frac{\Xi_{\eta_{eq}}}{\Xi_{\eta_{eq}} - 1}
+              + G_{in} \frac{\Xi_{{in}_{eq}}}{\Xi_{{in}_{eq}} - 1}
+        \f]
+
+    where:
+
+        \f$ R \f$ is the total removal.
+
+        \f$ G_\eta \f$ is a model constant.
+
+        \f$ \Xi_{\eta_{eq}} \f$ is the flame wrinkling due to turbulence.
+
+        \f$ \Xi_{{in}_{eq}} \f$ is the equilibrium level of the flame wrinkling
+        generated by inestability. It is a constant (default 2.5).
+
 
 SourceFiles
     XiModel.C
@@ -51,6 +102,8 @@ namespace Foam
                           Class XiModel Declaration
 \*---------------------------------------------------------------------------*/
 
+
+
 class XiModel
 {
 
diff --git a/applications/solvers/combustion/PDRFoam/laminarFlameSpeed/SCOPE/SCOPELaminarFlameSpeed.H b/applications/solvers/combustion/PDRFoam/laminarFlameSpeed/SCOPE/SCOPELaminarFlameSpeed.H
index e837fefa8bf94863ceac099a4bff05c49cf818f1..8c65453b946f51b0b0d2810ea334bd1b13848712 100644
--- a/applications/solvers/combustion/PDRFoam/laminarFlameSpeed/SCOPE/SCOPELaminarFlameSpeed.H
+++ b/applications/solvers/combustion/PDRFoam/laminarFlameSpeed/SCOPE/SCOPELaminarFlameSpeed.H
@@ -28,6 +28,33 @@ Class
 Description
     Laminar flame speed obtained from the SCOPE correlation.
 
+    Seven parameters are specified in terms of polynomial functions of
+    stoichiometry. Two polynomials are fitted, covering different parts of the
+    flammable range. If the mixture is outside the fitted range, linear
+    interpolation is used between the extreme of the polynomio and the upper or
+    lower flammable limit with the Markstein number constant.
+
+    Variations of pressure and temperature from the reference values are taken
+    into account through \f$ pexp \f$ and \f$ texp \f$
+
+    The laminar burning velocity fitting polynomial is:
+
+    \f$ Su = a_{0}(1+a_{1}x+K+..a_{i}x^{i}..+a_{6}x^{6}) (p/p_{ref})^{pexp}
+    (T/T_{ref})^{texp} \f$
+
+    where:
+
+        \f$ a_{i} \f$ are the polinomial coefficients.
+
+        \f$ pexp \f$ and \f$ texp \f$ are the pressure and temperature factors
+        respectively.
+
+        \f$ x \f$ is the equivalence ratio.
+
+        \f$ T_{ref} \f$ and \f$ p_{ref} \f$ are the temperature and pressure
+        references for the laminar burning velocity.
+
+
 SourceFiles
     SCOPELaminarFlameSpeed.C
 
@@ -125,7 +152,7 @@ class SCOPE
         //  corrected for temperature and pressure dependence
         inline scalar Su0pTphi(scalar p, scalar Tu, scalar phi) const;
 
-        //- Laminar flame speed evaluated from the given uniform 
+        //- Laminar flame speed evaluated from the given uniform
         //  equivalence ratio corrected for temperature and pressure dependence
         tmp<volScalarField> Su0pTphi
         (
@@ -134,7 +161,7 @@ class SCOPE
             scalar phi
         ) const;
 
-        //- Laminar flame speed evaluated from the given equivalence ratio 
+        //- Laminar flame speed evaluated from the given equivalence ratio
         //  distribution corrected for temperature and pressure dependence
         tmp<volScalarField> Su0pTphi
         (
@@ -144,7 +171,7 @@ class SCOPE
         ) const;
 
         //- Return the Markstein number
-        //  evaluated from the given equivalence ratio 
+        //  evaluated from the given equivalence ratio
         tmp<volScalarField> Ma(const volScalarField& phi) const;
 
         //- Construct as copy (not implemented)
diff --git a/applications/test/DynamicList/DynamicListTest.C b/applications/test/DynamicList/DynamicListTest.C
index 6cdbb84890f895b8ece48b3e998936b668facb31..28960444a25cb721bd596762b6686855cce0fa2c 100644
--- a/applications/test/DynamicList/DynamicListTest.C
+++ b/applications/test/DynamicList/DynamicListTest.C
@@ -43,16 +43,21 @@ int main(int argc, char *argv[])
     ldl[0](3) = 3;
     ldl[0](1) = 1;
 
-    ldl[0].setSize(5);     // increase allocated size
-    ldl[1].setSize(10);    // increase allocated size
-    ldl[1](2) = 2;
+    ldl[0].setCapacity(5);    // increase allocated size
+    ldl[1].setCapacity(10);   // increase allocated size
+    ldl[0].reserve(15);       // should increase allocated size
+    ldl[1].reserve(5);        // should not decrease allocated size
+    ldl[1](3) = 2;            // allocates space and sets value
+
+    // this works without a segfault, but doesn't change the list size
+    ldl[0][4] = 4;
 
     ldl[1] = 3;
 
     Info<< "<ldl>" << ldl << "</ldl>" << nl << "sizes: ";
     forAll(ldl, i)
     {
-        Info<< " " << ldl[i].size() << "/" << ldl[i].allocSize();
+        Info<< " " << ldl[i].size() << "/" << ldl[i].capacity();
     }
     Info<< endl;
 
@@ -63,7 +68,7 @@ int main(int argc, char *argv[])
     Info<< "<ldl>" << ldl << "</ldl>" << nl << "sizes: ";
     forAll(ldl, i)
     {
-        Info<< " " << ldl[i].size() << "/" << ldl[i].allocSize();
+        Info<< " " << ldl[i].size() << "/" << ldl[i].capacity();
     }
     Info<< endl;
 
@@ -78,10 +83,10 @@ int main(int argc, char *argv[])
     {
         dlA.append(i);
     }
-    dlA.setSize(10);
+    dlA.setCapacity(10);
 
     Info<< "<dlA>" << dlA << "</dlA>" << nl << "sizes: "
-        << " " << dlA.size() << "/" << dlA.allocSize() << endl;
+        << " " << dlA.size() << "/" << dlA.capacity() << endl;
 
     dlB.transfer(dlA);
 
@@ -91,10 +96,54 @@ int main(int argc, char *argv[])
 
     Info<< "Transferred to dlB" << endl;
     Info<< "<dlA>" << dlA << "</dlA>" << nl << "sizes: "
-        << " " << dlA.size() << "/" << dlA.allocSize() << endl;
+        << " " << dlA.size() << "/" << dlA.capacity() << endl;
+    Info<< "<dlB>" << dlB << "</dlB>" << nl << "sizes: "
+        << " " << dlB.size() << "/" << dlB.capacity() << endl;
+
+    // try with a normal list:
+    List<label> lstA;
+    lstA.transfer(dlB);
+    Info<< "Transferred to normal list" << endl;
+    Info<< "<lstA>" << lstA << "</lstA>" << nl << "sizes: "
+        << " " << lstA.size() << endl;
+    Info<< "<dlB>" << dlB << "</dlB>" << nl << "sizes: "
+        << " " << dlB.size() << "/" << dlB.capacity() << endl;
+
+    // Copy back and append a few time
+    for (label i=0; i < 3; i++)
+    {
+        dlB.append(lstA);
+    }
+
+    Info<< "appended list a few times" << endl;
+    Info<< "<dlB>" << dlB << "</dlB>" << nl << "sizes: "
+        << " " << dlB.size() << "/" << dlB.capacity() << endl;
+
+    // assign the list (should maintain allocated space)
+    dlB = lstA;
+    Info<< "assigned list" << endl;
     Info<< "<dlB>" << dlB << "</dlB>" << nl << "sizes: "
-        << " " << dlB.size() << "/" << dlB.allocSize() << endl;
+        << " " << dlB.size() << "/" << dlB.capacity() << endl;
+
+
+    // Copy back and append a few time
+    for (label i=0; i < 3; i++)
+    {
+        dlB.append(lstA);
+    }
+
+
+    // check allocation granularity
+    DynamicList<label, 6, 0> dlC;
+
+    Info<< "<dlC>" << dlC << "</dlC>" << nl << "sizes: "
+        << " " << dlC.size() << "/" << dlC.capacity() << endl;
+
+    dlC.reserve(dlB.size());
+    dlC = dlB;
 
+    Info<< "<dlC>" << dlC << "</dlC>" << nl << "sizes: "
+        << " " << dlC.size() << "/" << dlC.capacity() << endl;
 
     return 0;
 }
diff --git a/applications/test/NamedEnum/Make/files b/applications/test/NamedEnum/Make/files
index a06d4ba5a9d9605dcaf133706ec8e7ff5d9003d4..a6601226facc6495efcb7f0c1db09e18346489e6 100644
--- a/applications/test/NamedEnum/Make/files
+++ b/applications/test/NamedEnum/Make/files
@@ -1,4 +1,3 @@
-
 namedEnumTest.C
 
-EXE = $(FOAM_APPBIN)/NamedEnum
+EXE = $(FOAM_USER_APPBIN)/NamedEnum
diff --git a/applications/test/callback/Make/files b/applications/test/callback/Make/files
index 788abb0467427770c15b8416095f0da4e623d918..bd1eab1e8ab1fbd14f99a331a83c9362fdb5d9a8 100644
--- a/applications/test/callback/Make/files
+++ b/applications/test/callback/Make/files
@@ -1,3 +1,3 @@
 callbackTest.C
 
-EXE = $(FOAM_APPBIN)/callbackTest
+EXE = $(FOAM_USER_APPBIN)/callbackTest
diff --git a/applications/test/dataEntry/Make/files b/applications/test/dataEntry/Make/files
index abbd55d3499c65db8c68b8211adf2f94cb93eb67..b32b5bd950a51cac38293e25b1349978d5371d2e 100644
--- a/applications/test/dataEntry/Make/files
+++ b/applications/test/dataEntry/Make/files
@@ -1,3 +1,3 @@
 testDataEntry.C
 
-EXE = $(FOAM_APPBIN)/testDataEntry
+EXE = $(FOAM_USER_APPBIN)/testDataEntry
diff --git a/applications/test/dictionary/dictionaryTest.C b/applications/test/dictionary/dictionaryTest.C
index 6064102781edfcd25fac64794ee54f9e097e3ffb..d8580bdf5429c851e9907b387cfaa4e18080af79 100644
--- a/applications/test/dictionary/dictionaryTest.C
+++ b/applications/test/dictionary/dictionaryTest.C
@@ -30,6 +30,7 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "IOstreams.H"
+#include "IOobject.H"
 #include "IFstream.H"
 #include "dictionary.H"
 
@@ -40,10 +41,37 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-    IFstream dictStream("testDict");
-    dictionary testDict(dictStream);
+    Info<< dictionary(IFstream("testDict")()) << endl;
 
-    Info<< testDict << endl;
+    IOobject::writeDivider(Info);
+
+    {
+        dictionary dict(IFstream("testDictRegex")());
+
+        Info<< "dict:" << dict << endl;
+
+        // Wildcard find.
+        Info<< "Wildcard find \"abc\" in top directory : "
+            << dict.lookup("abc") << endl;
+        Info<< "Wildcard find \"abc\" in sub directory : "
+            << dict.subDict("someDict").lookup("abc")
+            << endl;
+        Info<< "Recursive wildcard find \"def\" in sub directory : "
+            << dict.subDict("someDict").lookup("def", true)
+            << endl;
+        Info<< "Recursive wildcard find \"foo\" in sub directory : "
+            << dict.subDict("someDict").lookup("foo", true)
+            << endl;
+        Info<< "Recursive wildcard find \"fooz\" in sub directory : "
+            << dict.subDict("someDict").lookup("fooz", true)
+            << endl;
+        Info<< "Recursive wildcard find \"bar\" in sub directory : "
+            << dict.subDict("someDict").lookup("bar", true)
+            << endl;
+        Info<< "Recursive wildcard find \"xxx\" in sub directory : "
+            << dict.subDict("someDict").lookup("xxx", true)
+            << endl;
+    }
 
     return 0;
 }
diff --git a/applications/test/dictionary/testDictRegex b/applications/test/dictionary/testDictRegex
new file mode 100644
index 0000000000000000000000000000000000000000..d4252cd3bee069ada8a5ec37a7e8d694670786ec
--- /dev/null
+++ b/applications/test/dictionary/testDictRegex
@@ -0,0 +1,34 @@
+/*-------------------------------*- C++ -*---------------------------------*\
+|    =========                                                              |
+|    \\      /     OpenFOAM                                                 |
+|     \\    /                                                               |
+|      \\  /       The Open Source CFD Toolbox                              |
+|       \\/                                        http://www.OpenFOAM.org  |
+\*-------------------------------------------------------------------------*/
+FoamFile
+{
+    version         2.0;
+    format          ascii;
+    class           dictionary;
+    object          testDictRegex;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+#inputMode  merge
+
+".*"        parentValue1;
+"[n-z].*"   parentValue2;
+"f.*"       parentValue3;
+
+someDict
+{
+    foo         subdictValue0;
+    bar         $f.*;         // should this really match 'foo'?
+
+    // result is dependent on insert order!
+    "a.*c"      subdictValue3;
+    "ab.*"      subdictValue2;
+    "a.*"       subdictValue1;
+    abcd        subdictValue4;
+}
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/test/findTimes/findTimes.C b/applications/test/findTimes/findTimes.C
index db22507b4f0511facbc3a5860714275104bcfac3..2acc6e756c54e0eee38df49eb6ff9d62004744cb 100644
--- a/applications/test/findTimes/findTimes.C
+++ b/applications/test/findTimes/findTimes.C
@@ -28,6 +28,7 @@ Description
 
 #include "argList.H"
 #include "Time.H"
+#include "timeSelector.H"
 
 using namespace Foam;
 
@@ -36,13 +37,19 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
+    argList::noParallel();
+    // timeSelector::addOptions();
+    timeSelector::addOptions(true, true);
 
 #   include "setRootCase.H"
 #   include "createTime.H"
 
-    Info<< runTime.times() << endl;
+    Info<< "Times found:" << runTime.times() << endl;
 
-    Info << "End\n" << endl;
+    instantList timeDirs = timeSelector::select0(runTime, args);
+
+    Info<< "Times selected:" << timeDirs << endl;
+    Info<< "\nEnd\n" << endl;
 
     return 0;
 }
diff --git a/applications/test/regex/Make/files b/applications/test/regex/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..901da54f0744fcd30dc7985f398d8831fb6e750f
--- /dev/null
+++ b/applications/test/regex/Make/files
@@ -0,0 +1,3 @@
+regexTest.C
+
+EXE = $(FOAM_USER_APPBIN)/regexTest
diff --git a/applications/test/regex/Make/options b/applications/test/regex/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..0eb7b642835fcec4c4b72727cdc17c7e7825fe70
--- /dev/null
+++ b/applications/test/regex/Make/options
@@ -0,0 +1,3 @@
+EXE_LIBS = \
+    $(FOAM_LIBBIN)/libOSspecific.o
+
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/polyDualMeshApp.C b/applications/test/regex/regexTest.C
similarity index 60%
rename from applications/utilities/mesh/conversion/polyDualMesh/polyDualMeshApp.C
rename to applications/test/regex/regexTest.C
index ffa83149528d13d447f0179ca5c9997bf99f7611..51c07b9ceecea77332a64730bd12807689bff171 100644
--- a/applications/utilities/mesh/conversion/polyDualMesh/polyDualMeshApp.C
+++ b/applications/test/regex/regexTest.C
@@ -22,55 +22,61 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-Application
-    polyDualMesh
-
 Description
-    Calculate the dual of a polyMesh. Adheres to all the feature&patch edges
 
 \*---------------------------------------------------------------------------*/
 
-#include "argList.H"
-#include "Time.H"
-#include "polyDualMesh.H"
-#include "mathematicalConstants.H"
+#include "IOstreams.H"
+#include "IOobject.H"
+#include "IFstream.H"
+#include "regExp.H"
+#include "List.H"
+#include "Tuple2.H"
 
 using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
 
 int main(int argc, char *argv[])
 {
-    argList::noParallel();
-    argList::validArgs.append("feature angle[0-180]");
-    argList::validOptions.insert("overwrite", "");
-
-#   include "setRootCase.H"
-#   include "createTime.H"
-    runTime.functionObjects().off();
-#   include "createPolyMesh.H"
-
-    scalar featureAngle(readScalar(IStringStream(args.additionalArgs()[0])()));
-    bool overwrite = args.options().found("overwrite");
 
-    scalar minCos = Foam::cos(featureAngle * mathematicalConstant::pi/180.0);
+    List<Tuple2<string, string> > rawList(IFstream("testRegexps")());
+    Info<< "input list:" << rawList << endl;
+    IOobject::writeDivider(Info);
+    Info<< endl;
 
-    Info<< "Feature:" << featureAngle << endl
-        << "minCos :" << minCos << endl
-        << endl;
+    List<string> groups;
 
-    polyDualMesh dualMesh(mesh, minCos);
-
-    if (!overwrite)
+    // report matches:
+    forAll(rawList, elemI)
     {
-        runTime++;
+        const string& pat = rawList[elemI].first();
+        const string& str = rawList[elemI].second();
+        regExp re(pat);
+
+        Info<< str << " =~ m/" << pat.c_str() << "/ == ";
+
+        if (re.match(str, groups))
+        {
+            Info<< "true";
+            if (re.ngroups())
+            {
+                Info<< groups;
+            }
+        }
+        else
+        {
+            Info<< "false";
+            if (re.match(str, true))
+            {
+                Info<< " partial match";
+            }
+        }
+        Info << endl;
     }
 
-    Pout<< "Writing dualMesh to " << runTime.timeName() << endl;
-
-    dualMesh.write();
-
-    Info << "End\n" << endl;
+    Info<< endl;
 
     return 0;
 }
diff --git a/applications/test/regex/testRegexps b/applications/test/regex/testRegexps
new file mode 100644
index 0000000000000000000000000000000000000000..eeae1d865a7006f03a0543e4aece11fe69ee4933
--- /dev/null
+++ b/applications/test/regex/testRegexps
@@ -0,0 +1,20 @@
+/*-------------------------------*- C++ -*---------------------------------*\
+|    =========                                                              |
+|    \\      /     OpenFOAM                                                 |
+|     \\    /                                                               |
+|      \\  /       The Open Source CFD Toolbox                              |
+|       \\/                                        http://www.OpenFOAM.org  |
+\*-------------------------------------------------------------------------*/
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// pattern, string
+(
+    ( "a.*" "abc" )
+    ( "a.*" "bac" )
+    ( "a.*" "abcd" )
+    ( "a.*" "def" )
+    ( "d(.*)f" "def" )
+)
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/test/sort/sortListTest.C b/applications/test/sort/sortListTest.C
index 89252ae1f37c39ce5ba67ee50be7436e3c189e90..06d5b0118632a452496515f45f5952acb18a60da 100644
--- a/applications/test/sort/sortListTest.C
+++ b/applications/test/sort/sortListTest.C
@@ -27,6 +27,7 @@ Description
 \*---------------------------------------------------------------------------*/
 
 #include "SortableList.H"
+#include "ListOps.H"
 
 using namespace Foam;
 
@@ -35,42 +36,101 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-    labelList orig(5);
+    labelList orig(8);
     orig[0] = 7;
-    orig[1] = 4;
+    orig[1] = 9;
     orig[2] = 1;
     orig[3] = 2;
-    orig[4] = 9;
+    orig[4] = 4;
+    orig[5] = 7;
+    orig[6] = 4;
+    orig[7] = 0;
+
+    labelList order;
 
     labelList a(orig);
-    Info << "before: " << a << endl;
+    sortedOrder(a, order);
+
+    Info<< "unsorted: " << a << endl;
     sort(a);
-    Info << "after:  " << a << endl;
+    Info<< "sorted:   " << a << endl;
+    Info<< "indices:  " << order << endl;
 
     SortableList<label> b(orig);
-    Info << "sorted:  " << b << endl;
-    Info << "indices: " << b.indices() << endl;
+    Info<< "unsorted: " << orig << endl;
+    Info<< "sorted:   " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
 
-    Info << "shrunk:  " << b.shrink() << endl;
-    Info << "indices: " << b.indices() << endl;
+    Info<< "shrunk:   " << b.shrink() << endl;
+    Info<< "indices:  " << b.indices() << endl;
 
     // repeat by assignment
     b = orig;
-    Info << "unsorted: " << b << endl;
+    Info<< "unsorted: " << b << endl;
     b.sort();
 
-    Info << "sorted:   " << b << endl;
-    Info << "indices:  " << b.indices() << endl;
+    Info<< "sorted:   " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
+
+    // find unique/duplicate values
+    b = orig;
+
+    Info<< "unsorted: " << b << endl;
+    uniqueOrder(b, order);
+    Info<< "unique:  " << order << endl;
+    duplicateOrder(b, order);
+    Info<< "duplicate:" << order << endl;
+
+    // sort reverse
+    Info<< "unsorted: " << b << endl;
+    b.reverseSort();
+    Info<< "rsort:    " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
 
     // transfer assignment
-    b.transfer(orig);
-    Info << "unsorted: " << b << endl;
+    a = orig;
+    b.transfer(a);
+    Info<< "unsorted: " << b << endl;
+    b.sort();
+
+    Info<< "sorted:   " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
+
+    a.transfer(b);
+
+    Info<< "plain:    " << a << endl;
+    Info<< "sorted:   " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
+
+    // sort/duplicate/unique with identical values
+    b.setSize(8);
+    b = 5;
+
+    Info<< "unsorted: " << b << endl;
+
+    uniqueOrder(b, order);
+    Info<< "unique:  " << order << endl;
+    duplicateOrder(b, order);
+    Info<< "duplicate:" << order << endl;
+    b.sort();
+
+    Info<< "sorted:   " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
+
+    // with a single value
+    b.setSize(1);
+
+    Info<< "unsorted: " << b << endl;
+    uniqueOrder(b, order);
+    Info<< "unique:  " << order << endl;
+    duplicateOrder(b, order);
+    Info<< "duplicate:" << order << endl;
     b.sort();
 
-    Info << "sorted:   " << b << endl;
-    Info << "indices:  " << b.indices() << endl;
+    Info<< "sorted:   " << b << endl;
+    Info<< "indices:  " << b.indices() << endl;
 
-    Info << "End\n" << endl;
+    Info<< "\nEnd\n" << endl;
 
     return 0;
 }
diff --git a/applications/test/stringList/stringListTest.C b/applications/test/stringList/stringListTest.C
index 045ca1fe72afa2697c524cc2a754943355c57e38..2c7da0d5e9d2d6f21ab8b7be610d91a06684c43e 100644
--- a/applications/test/stringList/stringListTest.C
+++ b/applications/test/stringList/stringListTest.C
@@ -26,7 +26,7 @@ Description
 
 \*---------------------------------------------------------------------------*/
 
-#include "stringList.H"
+#include "stringListOps.H"
 #include "IOstreams.H"
 
 using namespace Foam;
diff --git a/applications/test/xfer/Make/files b/applications/test/xfer/Make/files
index 92414c039e1c4213fb72884b447ca821d7a1ec08..d3c1cd8ac2d9e9ca3068acd88f5d079a2bcd82ac 100644
--- a/applications/test/xfer/Make/files
+++ b/applications/test/xfer/Make/files
@@ -1,4 +1,3 @@
 xferListTest.C
 
-/* EXE = $(FOAM_USER_APPBIN)/xferListTest */
-EXE = ./xferListTest
+EXE = $(FOAM_USER_APPBIN)/xferListTest
diff --git a/applications/test/xfer/xferListTest.C b/applications/test/xfer/xferListTest.C
index 6f2af0932adcc94403b833840810f338dd29c857..25d0d9f3db8a896680ff64e7575800aeef97d8b5 100644
--- a/applications/test/xfer/xferListTest.C
+++ b/applications/test/xfer/xferListTest.C
@@ -108,13 +108,13 @@ int main(int argc, char *argv[])
     face f1(dl);
     face f2(xferCopy<labelList>(dl));
 
-    Info<< "dl[" << dl.size() << "/" << dl.allocSize() << "] " << dl << endl;
+    Info<< "dl[" << dl.size() << "/" << dl.capacity() << "] " << dl << endl;
     Info<< "f1: " << f1 << endl;
     Info<< "f2: " << f2 << endl;
 
     // note: using xferMoveTo to ensure the correct transfer() method is called
     face f3( xferMoveTo<labelList>(dl) );
-    Info<< "dl[" << dl.size() << "/" << dl.allocSize() << "] " << dl << endl;
+    Info<< "dl[" << dl.size() << "/" << dl.capacity() << "] " << dl << endl;
     Info<< "f3: " << f3 << endl;
 
     return 0;
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/Make/files b/applications/utilities/mesh/conversion/polyDualMesh/Make/files
index c43f79e8e148201c61e6d3d41f6fff50a540b4d7..752da5cfddb22955af52029c6b36312a2fedfc45 100644
--- a/applications/utilities/mesh/conversion/polyDualMesh/Make/files
+++ b/applications/utilities/mesh/conversion/polyDualMesh/Make/files
@@ -1,3 +1,4 @@
-polyDualMeshApp.C
+meshDualiser.C
+makePolyDualMesh.C
 
 EXE = $(FOAM_APPBIN)/polyDualMesh
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/Make/options b/applications/utilities/mesh/conversion/polyDualMesh/Make/options
index 6dc63a7a989641aba7de693a1920eec74912cb02..dc318df99832515cca0862ee9d04aea77fda2baf 100644
--- a/applications/utilities/mesh/conversion/polyDualMesh/Make/options
+++ b/applications/utilities/mesh/conversion/polyDualMesh/Make/options
@@ -1,6 +1,9 @@
 EXE_INC = \
     -I$(LIB_SRC)/meshTools/lnInclude \
-    -I$(LIB_SRC)/conversion/lnInclude
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/dynamicMesh/lnInclude
 
 EXE_LIBS = \
-    -lmeshTools -lconversion
+    -lfiniteVolume \
+    -ldynamicMesh \
+    -lmeshTools
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C b/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C
new file mode 100644
index 0000000000000000000000000000000000000000..26eb18e26d0f59e3b2a4fa7a1f3aed8169f80d1f
--- /dev/null
+++ b/applications/utilities/mesh/conversion/polyDualMesh/makePolyDualMesh.C
@@ -0,0 +1,515 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Description
+    Calculate the dual of a polyMesh. Adheres to all the feature&patch edges.
+
+    Feature angle:
+    convex features : point becomes single boundary cell with multiple
+                      boundary faces.
+    concave features: point becomes multiple boundary cells.
+
+    -splitAllFaces:
+    Normally only constructs a single face between two cells. This single face
+    might be too distorted. splitAllFaces will create a single face for every
+    original cell the face passes through. The mesh will thus have
+    multiple faces inbetween two cells! (so is not strictly upper-triangular
+    anymore - checkMesh will complain)
+    -doNotPreserveFaceZones:
+    By default all faceZones are preserved by marking all faces, edges and
+    points on them as features. The -doNotPreserveFaceZones disables this
+    behaviour.
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "Time.H"
+#include "fvMesh.H"
+#include "mathematicalConstants.H"
+#include "polyTopoChange.H"
+#include "mapPolyMesh.H"
+#include "PackedList.H"
+#include "meshTools.H"
+#include "OFstream.H"
+#include "meshDualiser.H"
+#include "ReadFields.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Naive feature detection. All boundary edges with angle > featureAngle become
+// feature edges. All points on feature edges become feature points. All
+// boundary faces become feature faces.
+void simpleMarkFeatures
+(
+    const polyMesh& mesh,
+    const PackedList<1>& isBoundaryEdge,
+    const scalar featureAngle,
+    const bool doNotPreserveFaceZones,
+
+    labelList& featureFaces,
+    labelList& featureEdges,
+    labelList& singleCellFeaturePoints,
+    labelList& multiCellFeaturePoints
+)
+{
+    scalar minCos = Foam::cos(featureAngle * mathematicalConstant::pi/180.0);
+
+    const polyBoundaryMesh& patches = mesh.boundaryMesh();
+
+    // Working sets
+    labelHashSet featureEdgeSet;
+    labelHashSet singleCellFeaturePointSet;
+    labelHashSet multiCellFeaturePointSet;
+
+
+    // 1. Mark all edges between patches
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    forAll(patches, patchI)
+    {
+        const polyPatch& pp = patches[patchI];
+        const labelList& meshEdges = pp.meshEdges();
+
+        // All patch corner edges. These need to be feature points & edges!
+        for (label edgeI = pp.nInternalEdges(); edgeI < pp.nEdges(); edgeI++)
+        {
+            label meshEdgeI = meshEdges[edgeI];
+            featureEdgeSet.insert(meshEdgeI);
+            singleCellFeaturePointSet.insert(mesh.edges()[meshEdgeI][0]);
+            singleCellFeaturePointSet.insert(mesh.edges()[meshEdgeI][1]);
+        }
+    }
+
+
+
+    // 2. Mark all geometric feature edges
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    // Make distinction between convex features where the boundary point becomes
+    // a single cell and concave features where the boundary point becomes
+    // multiple 'half' cells.
+
+    // Addressing for all outside faces
+    primitivePatch allBoundary
+    (
+        SubList<face>
+        (
+            mesh.faces(),
+            mesh.nFaces()-mesh.nInternalFaces(),
+            mesh.nInternalFaces()
+        ),
+        mesh.points()
+    );
+
+    // Check for non-manifold points (surface pinched at point)
+    allBoundary.checkPointManifold(false, &singleCellFeaturePointSet);
+
+    // Check for non-manifold edges (surface pinched at edge)
+    const labelListList& edgeFaces = allBoundary.edgeFaces();
+    const labelList& meshPoints = allBoundary.meshPoints();
+
+    forAll(edgeFaces, edgeI)
+    {
+        const labelList& eFaces = edgeFaces[edgeI];
+
+        if (eFaces.size() > 2)
+        {
+            const edge& e = allBoundary.edges()[edgeI];
+
+            //Info<< "Detected non-manifold boundary edge:" << edgeI
+            //    << " coords:"
+            //    << allBoundary.points()[meshPoints[e[0]]]
+            //    << allBoundary.points()[meshPoints[e[1]]] << endl;
+
+            singleCellFeaturePointSet.insert(meshPoints[e[0]]);
+            singleCellFeaturePointSet.insert(meshPoints[e[1]]);
+        }
+    }
+
+    // Check for features.
+    forAll(edgeFaces, edgeI)
+    {
+        const labelList& eFaces = edgeFaces[edgeI];
+
+        if (eFaces.size() == 2)
+        {
+            label f0 = eFaces[0];
+            label f1 = eFaces[1];
+
+            // check angle
+            const vector& n0 = allBoundary.faceNormals()[f0];
+            const vector& n1 = allBoundary.faceNormals()[f1];
+
+            if ((n0 & n1) < minCos)
+            {
+                const edge& e = allBoundary.edges()[edgeI];
+                label v0 = meshPoints[e[0]];
+                label v1 = meshPoints[e[1]];
+
+                label meshEdgeI = meshTools::findEdge(mesh, v0, v1);
+                featureEdgeSet.insert(meshEdgeI);
+
+                // Check if convex or concave by looking at angle
+                // between face centres and normal
+                vector c1c0
+                (
+                    allBoundary[f1].centre(allBoundary.points())
+                  - allBoundary[f0].centre(allBoundary.points())
+                );
+
+                if ((c1c0 & n0) > SMALL)
+                {
+                    // Found concave edge. Make into multiCell features
+                    Info<< "Detected concave feature edge:" << edgeI
+                        << " cos:" << (c1c0 & n0)
+                        << " coords:"
+                        << allBoundary.points()[v0]
+                        << allBoundary.points()[v1]
+                        << endl;
+
+                    singleCellFeaturePointSet.erase(v0);
+                    multiCellFeaturePointSet.insert(v0);
+                    singleCellFeaturePointSet.erase(v1);
+                    multiCellFeaturePointSet.insert(v1);
+                }
+                else
+                {
+                    // Convex. singleCell feature.
+                    if (!multiCellFeaturePointSet.found(v0))
+                    {
+                        singleCellFeaturePointSet.insert(v0);
+                    }
+                    if (!multiCellFeaturePointSet.found(v1))
+                    {
+                        singleCellFeaturePointSet.insert(v1);
+                    }
+                }
+            }
+        }
+    }
+
+
+    // 3. Mark all feature faces
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    // Face centres that need inclusion in the dual mesh
+    labelHashSet featureFaceSet(mesh.nFaces()-mesh.nInternalFaces());
+    // A. boundary faces.
+    for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
+    {
+        featureFaceSet.insert(faceI);
+    }
+
+    // B. face zones.
+    const faceZoneMesh& faceZones = mesh.faceZones();
+
+    if (doNotPreserveFaceZones)
+    {
+        if (faceZones.size() > 0)
+        {
+            WarningIn("simpleMarkFeatures(..)")
+                << "Detected " << faceZones.size()
+                << " faceZones. These will not be preserved."
+                << endl;
+        }
+    }
+    else
+    {
+        if (faceZones.size() > 0)
+        {
+            Info<< "Detected " << faceZones.size()
+                << " faceZones. Preserving these by marking their"
+                << " points, edges and faces as features." << endl;
+        }
+
+        forAll(faceZones, zoneI)
+        {
+            const faceZone& fz = faceZones[zoneI];
+
+            Info<< "Inserting all faces in faceZone " << fz.name()
+                << " as features." << endl;
+
+            forAll(fz, i)
+            {
+                label faceI = fz[i];
+                const face& f = mesh.faces()[faceI];
+                const labelList& fEdges = mesh.faceEdges()[faceI];
+
+                featureFaceSet.insert(faceI);
+                forAll(f, fp)
+                {
+                    // Mark point as multi cell point (since both sides of
+                    // face should have different cells)
+                    singleCellFeaturePointSet.erase(f[fp]);
+                    multiCellFeaturePointSet.insert(f[fp]);
+
+                    // Make sure there are points on the edges.
+                    featureEdgeSet.insert(fEdges[fp]);
+                }
+            }
+        }
+    }
+
+    // Transfer to arguments
+    featureFaces = featureFaceSet.toc();
+    featureEdges = featureEdgeSet.toc();
+    singleCellFeaturePoints = singleCellFeaturePointSet.toc();
+    multiCellFeaturePoints = multiCellFeaturePointSet.toc();
+}
+
+
+// Dump features to .obj files
+void dumpFeatures
+(
+    const polyMesh& mesh,
+    const labelList& featureFaces,
+    const labelList& featureEdges,
+    const labelList& singleCellFeaturePoints,
+    const labelList& multiCellFeaturePoints
+)
+{
+    {
+        OFstream str("featureFaces.obj");
+        Info<< "Dumping centres of featureFaces to obj file " << str.name()
+            << endl;
+        forAll(featureFaces, i)
+        {
+            meshTools::writeOBJ(str, mesh.faceCentres()[featureFaces[i]]);
+        }
+    }
+    {
+        OFstream str("featureEdges.obj");
+        Info<< "Dumping featureEdges to obj file " << str.name() << endl;
+        label vertI = 0;
+
+        forAll(featureEdges, i)
+        {
+            const edge& e = mesh.edges()[featureEdges[i]];
+            meshTools::writeOBJ(str, mesh.points()[e[0]]);
+            vertI++;
+            meshTools::writeOBJ(str, mesh.points()[e[1]]);
+            vertI++;
+            str<< "l " << vertI-1 << ' ' << vertI << nl;
+        }
+    }
+    {
+        OFstream str("singleCellFeaturePoints.obj");
+        Info<< "Dumping featurePoints that become a single cell to obj file "
+            << str.name() << endl;
+        forAll(singleCellFeaturePoints, i)
+        {
+            meshTools::writeOBJ(str, mesh.points()[singleCellFeaturePoints[i]]);
+        }
+    }
+    {
+        OFstream str("multiCellFeaturePoints.obj");
+        Info<< "Dumping featurePoints that become multiple cells to obj file "
+            << str.name() << endl;
+        forAll(multiCellFeaturePoints, i)
+        {
+            meshTools::writeOBJ(str, mesh.points()[multiCellFeaturePoints[i]]);
+        }
+    }
+}
+
+
+int main(int argc, char *argv[])
+{
+    argList::noParallel();
+#   include "addTimeOptions.H"
+    argList::validArgs.append("feature angle[0-180]");
+    argList::validOptions.insert("splitAllFaces", "");
+    argList::validOptions.insert("doNotPreserveFaceZones", "");
+    argList::validOptions.insert("overwrite", "");
+
+#   include "setRootCase.H"
+#   include "createTime.H"
+    // Get times list
+    instantList Times = runTime.times();
+#   include "checkTimeOptions.H"
+    runTime.setTime(Times[startTime], startTime);
+
+#   include "createMesh.H"
+
+    // Mark boundary edges and points.
+    // (Note: in 1.4.2 we can use the built-in mesh point ordering
+    //  facility instead)
+    PackedList<1> isBoundaryEdge(mesh.nEdges());
+    for (label faceI = mesh.nInternalFaces(); faceI < mesh.nFaces(); faceI++)
+    {
+        const labelList& fEdges = mesh.faceEdges()[faceI];
+
+        forAll(fEdges, i)
+        {
+            isBoundaryEdge.set(fEdges[i], 1);
+        }
+    }
+
+    scalar featureAngle(readScalar(IStringStream(args.additionalArgs()[0])()));
+
+    scalar minCos = Foam::cos(featureAngle * mathematicalConstant::pi/180.0);
+
+    Info<< "Feature:" << featureAngle << endl
+        << "minCos :" << minCos << endl
+        << endl;
+
+
+    const bool splitAllFaces = args.options().found("splitAllFaces");
+    const bool overwrite = args.options().found("overwrite");
+    const bool doNotPreserveFaceZones = args.options().found
+    (
+        "doNotPreserveFaceZones"
+    );
+
+    // Face(centre)s that need inclusion in the dual mesh
+    labelList featureFaces;
+    // Edge(centre)s  ,,
+    labelList featureEdges;
+    // Points (that become a single cell) that need inclusion in the dual mesh
+    labelList singleCellFeaturePoints;
+    // Points (that become a mulitple cells)        ,,
+    labelList multiCellFeaturePoints;
+
+    // Sample implementation of feature detection.
+    simpleMarkFeatures
+    (
+        mesh,
+        isBoundaryEdge,
+        featureAngle,
+        doNotPreserveFaceZones,
+
+        featureFaces,
+        featureEdges,
+        singleCellFeaturePoints,
+        multiCellFeaturePoints
+    );
+
+    // If we want to split all polyMesh faces into one dualface per cell
+    // we are passing through we also need a point
+    // at the polyMesh facecentre and edgemid of the faces we want to
+    // split.
+    if (splitAllFaces)
+    {
+        featureEdges = identity(mesh.nEdges());
+        featureFaces = identity(mesh.nFaces());
+    }
+
+    // Write obj files for debugging
+    dumpFeatures
+    (
+        mesh,
+        featureFaces,
+        featureEdges,
+        singleCellFeaturePoints,
+        multiCellFeaturePoints
+    );
+
+
+
+    // Read objects in time directory
+    IOobjectList objects(mesh, runTime.timeName());
+
+    // Read vol fields.
+    PtrList<volScalarField> vsFlds;
+    ReadFields(mesh, objects, vsFlds);
+
+    PtrList<volVectorField> vvFlds;
+    ReadFields(mesh, objects, vvFlds);
+
+    PtrList<volSphericalTensorField> vstFlds;
+    ReadFields(mesh, objects, vstFlds);
+
+    PtrList<volSymmTensorField> vsymtFlds;
+    ReadFields(mesh, objects, vsymtFlds);
+
+    PtrList<volTensorField> vtFlds;
+    ReadFields(mesh, objects, vtFlds);
+
+    // Read surface fields.
+    PtrList<surfaceScalarField> ssFlds;
+    ReadFields(mesh, objects, ssFlds);
+
+    PtrList<surfaceVectorField> svFlds;
+    ReadFields(mesh, objects, svFlds);
+
+    PtrList<surfaceSphericalTensorField> sstFlds;
+    ReadFields(mesh, objects, sstFlds);
+
+    PtrList<surfaceSymmTensorField> ssymtFlds;
+    ReadFields(mesh, objects, ssymtFlds);
+
+    PtrList<surfaceTensorField> stFlds;
+    ReadFields(mesh, objects, stFlds);
+
+
+    // Topo change container
+    polyTopoChange meshMod(mesh.boundaryMesh().size());
+
+    // Mesh dualiser engine
+    meshDualiser dualMaker(mesh);
+
+    // Insert all commands into polyTopoChange to create dual of mesh. This does
+    // all the hard work.
+    dualMaker.setRefinement
+    (
+        splitAllFaces,
+        featureFaces,
+        featureEdges,
+        singleCellFeaturePoints,
+        multiCellFeaturePoints,
+        meshMod
+    );
+
+    // Create mesh, return map from old to new mesh.
+    autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
+
+    // Update fields
+    mesh.updateMesh(map);
+
+    // Optionally inflate mesh
+    if (map().hasMotionPoints())
+    {
+        mesh.movePoints(map().preMotionPoints());
+    }
+
+    if (!overwrite)
+    {
+        runTime++;
+        mesh.setInstance(runTime.timeName());
+    }
+
+    Info<< "Writing dual mesh to " << runTime.timeName() << endl;
+
+    mesh.write();
+ 
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/meshDualiser.C b/applications/utilities/mesh/conversion/polyDualMesh/meshDualiser.C
new file mode 100644
index 0000000000000000000000000000000000000000..4492a6f6b66d911cf96595ed9a5240ad11ff49c5
--- /dev/null
+++ b/applications/utilities/mesh/conversion/polyDualMesh/meshDualiser.C
@@ -0,0 +1,1489 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    meshDualiser
+
+\*---------------------------------------------------------------------------*/
+
+#include "meshDualiser.H"
+#include "meshTools.H"
+#include "polyMesh.H"
+#include "polyTopoChange.H"
+#include "mapPolyMesh.H"
+#include "edgeFaceCirculator.H"
+#include "mergePoints.H"
+#include "OFstream.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    defineTypeNameAndDebug(meshDualiser, 0);
+}
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::meshDualiser::checkPolyTopoChange(const polyTopoChange& meshMod)
+{
+    // Assume no removed points
+    pointField points(meshMod.points().size());
+    forAll(meshMod.points(), i)
+    {
+        points[i] = meshMod.points()[i];
+    }
+
+    labelList oldToNew;
+    pointField newPoints;
+    bool hasMerged = mergePoints
+    (
+        points,
+        1E-6,
+        false,
+        oldToNew,
+        newPoints
+    );
+
+    if (hasMerged)
+    {
+        labelListList newToOld(invertOneToMany(newPoints.size(), oldToNew));
+
+        forAll(newToOld, newI)
+        {
+            if (newToOld[newI].size() != 1)
+            {
+                FatalErrorIn
+                (
+                    "meshDualiser::checkPolyTopoChange(const polyTopoChange&)"
+                )   << "duplicate verts:" << newToOld[newI]
+                    << " coords:"
+                    << IndirectList<point>(points, newToOld[newI])()
+                    << abort(FatalError);
+            }
+        }
+    }
+}
+
+
+// Dump state so far.
+void Foam::meshDualiser::dumpPolyTopoChange
+(
+    const polyTopoChange& meshMod,
+    const fileName& prefix
+)
+{
+    OFstream str1(prefix + "Faces.obj");
+    OFstream str2(prefix + "Edges.obj");
+
+    Info<< "Dumping current polyTopoChange. Faces to " << str1.name()
+        << " , points and edges to " << str2.name() << endl;
+
+    const DynamicList<point>& points = meshMod.points();
+
+    forAll(points, pointI)
+    {
+        meshTools::writeOBJ(str1, points[pointI]);
+        meshTools::writeOBJ(str2, points[pointI]);
+    }
+
+    const DynamicList<face>& faces = meshMod.faces();
+
+    forAll(faces, faceI)
+    {
+        const face& f = faces[faceI];
+
+        str1<< 'f';
+        forAll(f, fp)
+        {
+            str1<< ' ' << f[fp]+1;
+        }
+        str1<< nl;
+
+        str2<< 'l';
+        forAll(f, fp)
+        {
+            str2<< ' ' << f[fp]+1;
+        }
+        str2<< ' ' << f[0]+1 << nl;
+    }
+}
+
+
+//- Given cell and point on mesh finds the corresponding dualCell. Most
+//  points become only one cell but the feature points might be split.
+Foam::label Foam::meshDualiser::findDualCell
+(
+    const label cellI,
+    const label pointI
+) const
+{
+    const labelList& dualCells = pointToDualCells_[pointI];
+
+    if (dualCells.size() == 1)
+    {
+        return dualCells[0];
+    }
+    else
+    {
+        label index = findIndex(mesh_.pointCells()[pointI], cellI);
+
+        return dualCells[index];
+    }
+}
+
+
+// Helper function to generate dualpoints on all boundary edges emanating
+// from (boundary & feature) point
+void Foam::meshDualiser::generateDualBoundaryEdges
+(
+    const PackedList<1>& isBoundaryEdge,
+    const label pointI,
+    polyTopoChange& meshMod
+)
+{
+    const labelList& pEdges = mesh_.pointEdges()[pointI];
+
+    forAll(pEdges, pEdgeI)
+    {
+        label edgeI = pEdges[pEdgeI];
+
+        if (edgeToDualPoint_[edgeI] == -1 && isBoundaryEdge.get(edgeI) == 1)
+        {
+            const edge& e = mesh_.edges()[edgeI];
+
+            edgeToDualPoint_[edgeI] = meshMod.addPoint
+            (
+                e.centre(mesh_.points()),
+                pointI, // masterPoint
+                -1,     // zoneID
+                true    // inCell
+            );
+        }
+    }
+}
+
+
+// Return true if point on face has same dual cells on both owner and neighbour
+// sides.
+bool Foam::meshDualiser::sameDualCell
+(
+    const label faceI,
+    const label pointI
+) const
+{
+    if (!mesh_.isInternalFace(faceI))
+    {
+        FatalErrorIn("sameDualCell(const label, const label)")
+            << "face:" << faceI << " is not internal face."
+            << abort(FatalError);
+    }
+
+    label own = mesh_.faceOwner()[faceI];
+    label nei = mesh_.faceNeighbour()[faceI];
+
+    return findDualCell(own, pointI) == findDualCell(nei, pointI);
+}
+
+
+Foam::label Foam::meshDualiser::addInternalFace
+(
+    const label masterPointI,
+    const label masterEdgeI,
+    const label masterFaceI,
+
+    const bool edgeOrder,
+    const label dualCell0,
+    const label dualCell1,
+    const DynamicList<label>& verts,
+    polyTopoChange& meshMod
+) const
+{
+    face newFace(verts);
+
+    if (edgeOrder != (dualCell0 < dualCell1))
+    {
+        reverse(newFace);
+    }
+
+    if (debug)
+    {
+        pointField facePoints
+        (
+            IndirectList<point>(meshMod.points(), newFace)()
+        );
+
+        labelList oldToNew;
+        pointField newPoints;
+        bool hasMerged = mergePoints
+        (
+            facePoints,
+            1E-6,
+            false,
+            oldToNew,
+            newPoints
+        );
+
+        if (hasMerged)
+        {
+            FatalErrorIn("addInternalFace(..)")
+                << "verts:" << verts << " newFace:" << newFace
+                << " face points:" << facePoints
+                << abort(FatalError);
+        }
+    }
+
+
+    label zoneID = -1;
+    bool zoneFlip = false;
+    if (masterFaceI != -1)
+    {
+        zoneID = mesh_.faceZones().whichZone(masterFaceI);
+
+        if (zoneID != -1)
+        {
+            const faceZone& fZone = mesh_.faceZones()[zoneID];
+
+            zoneFlip = fZone.flipMap()[fZone.whichFace(masterFaceI)];
+        }
+    }
+
+    label dualFaceI;
+
+    if (dualCell0 < dualCell1)
+    {
+        dualFaceI = meshMod.addFace
+        (
+            newFace,
+            dualCell0,      // own
+            dualCell1,      // nei
+            masterPointI,   // masterPointID
+            masterEdgeI,    // masterEdgeID
+            masterFaceI,    // masterFaceID
+            false,          // flipFaceFlux
+            -1,             // patchID
+            zoneID,         // zoneID
+            zoneFlip        // zoneFlip
+        );
+
+        //pointField dualPoints(meshMod.points());
+        //vector n(newFace.normal(dualPoints));
+        //n /= mag(n);
+        //Pout<< "Generated internal dualFace:" << dualFaceI
+        //    << " verts:" << newFace
+        //    << " points:" << IndirectList<point>(meshMod.points(), newFace)()
+        //    << " n:" << n
+        //    << " between dualowner:" << dualCell0
+        //    << " dualneigbour:" << dualCell1
+        //    << endl;
+    }
+    else
+    {
+        dualFaceI = meshMod.addFace
+        (
+            newFace,
+            dualCell1,      // own
+            dualCell0,      // nei
+            masterPointI,   // masterPointID
+            masterEdgeI,    // masterEdgeID
+            masterFaceI,    // masterFaceID
+            false,          // flipFaceFlux
+            -1,             // patchID
+            zoneID,         // zoneID
+            zoneFlip        // zoneFlip
+        );
+
+        //pointField dualPoints(meshMod.points());
+        //vector n(newFace.normal(dualPoints));
+        //n /= mag(n);
+        //Pout<< "Generated internal dualFace:" << dualFaceI
+        //    << " verts:" << newFace
+        //    << " points:" << IndirectList<point>(meshMod.points(), newFace)()
+        //    << " n:" << n
+        //    << " between dualowner:" << dualCell1
+        //    << " dualneigbour:" << dualCell0
+        //    << endl;
+    }
+    return dualFaceI;
+}
+
+
+Foam::label Foam::meshDualiser::addBoundaryFace
+(
+    const label masterPointI,
+    const label masterEdgeI,
+    const label masterFaceI,
+
+    const label dualCellI,
+    const label patchI,
+    const DynamicList<label>& verts,
+    polyTopoChange& meshMod
+) const
+{
+    face newFace(verts);
+
+    label zoneID = -1;
+    bool zoneFlip = false;
+    if (masterFaceI != -1)
+    {
+        zoneID = mesh_.faceZones().whichZone(masterFaceI);
+
+        if (zoneID != -1)
+        {
+            const faceZone& fZone = mesh_.faceZones()[zoneID];
+
+            zoneFlip = fZone.flipMap()[fZone.whichFace(masterFaceI)];
+        }
+    }
+
+    label dualFaceI = meshMod.addFace
+    (
+        newFace,
+        dualCellI,      // own
+        -1,             // nei
+        masterPointI,   // masterPointID
+        masterEdgeI,    // masterEdgeID
+        masterFaceI,    // masterFaceID
+        false,          // flipFaceFlux
+        patchI,         // patchID
+        zoneID,         // zoneID
+        zoneFlip        // zoneFlip
+    );
+
+    //pointField dualPoints(meshMod.points());
+    //vector n(newFace.normal(dualPoints));
+    //n /= mag(n);
+    //Pout<< "Generated boundary dualFace:" << dualFaceI
+    //    << " verts:" << newFace
+    //    << " points:" << IndirectList<point>(meshMod.points(), newFace)()
+    //    << " n:" << n
+    //    << " on dualowner:" << dualCellI
+    //    << endl;
+    return dualFaceI;
+}
+
+
+// Walks around edgeI.
+// splitFace=true : creates multiple faces
+// splitFace=false: creates single face if same dual cells on both sides,
+//                  multiple faces otherwise.
+void Foam::meshDualiser::createFacesAroundEdge
+(
+    const bool splitFace,
+    const PackedList<1>& isBoundaryEdge,
+    const label edgeI,
+    const label startFaceI,
+    polyTopoChange& meshMod,
+    boolList& doneEFaces
+) const
+{
+    const edge& e = mesh_.edges()[edgeI];
+    const labelList& eFaces = mesh_.edgeFaces()[edgeI];
+
+    label fp = edgeFaceCirculator::getMinIndex
+    (
+        mesh_.faces()[startFaceI],
+        e[0],
+        e[1]
+    );
+
+    edgeFaceCirculator ie
+    (
+        mesh_,
+        startFaceI, // face
+        true,       // ownerSide
+        fp,         // fp
+        isBoundaryEdge.get(edgeI) == 1  // isBoundaryEdge
+    );
+    ie.setCanonical();
+
+    bool edgeOrder = ie.sameOrder(e[0], e[1]);
+    label startFaceLabel = ie.faceLabel();
+
+    //Pout<< "At edge:" << edgeI << " verts:" << e
+    //    << " points:" << mesh_.points()[e[0]] << mesh_.points()[e[1]]
+    //    << " started walking at face:" << ie.faceLabel()
+    //    << " verts:" << mesh_.faces()[ie.faceLabel()]
+    //    << " edgeOrder:" << edgeOrder
+    //    << " in direction of cell:" << ie.cellLabel()
+    //    << endl;
+
+    // Walk and collect face.
+    DynamicList<label> verts(100);
+
+    if (edgeToDualPoint_[edgeI] != -1)
+    {
+        verts.append(edgeToDualPoint_[edgeI]);
+    }
+    if (faceToDualPoint_[ie.faceLabel()] != -1)
+    {
+        doneEFaces[findIndex(eFaces, ie.faceLabel())] = true;
+        verts.append(faceToDualPoint_[ie.faceLabel()]);
+    }
+    if (cellToDualPoint_[ie.cellLabel()] != -1)
+    {
+        verts.append(cellToDualPoint_[ie.cellLabel()]);
+    }
+
+    label currentDualCell0 = findDualCell(ie.cellLabel(), e[0]);
+    label currentDualCell1 = findDualCell(ie.cellLabel(), e[1]);
+
+    ++ie;
+
+    while (true)
+    {
+        label faceI = ie.faceLabel();
+
+        // Mark face as visited.
+        doneEFaces[findIndex(eFaces, faceI)] = true;
+
+        if (faceToDualPoint_[faceI] != -1)
+        {
+            verts.append(faceToDualPoint_[faceI]);
+        }
+
+        label cellI = ie.cellLabel();
+
+        if (cellI == -1)
+        {
+            // At ending boundary face. We've stored the face point above
+            // so this is the whole face.
+            break;
+        }
+
+
+        label dualCell0 = findDualCell(cellI, e[0]);
+        label dualCell1 = findDualCell(cellI, e[1]);
+
+        // Generate face. (always if splitFace=true; only if needed to
+        // separate cells otherwise)
+        if
+        (
+            splitFace
+         || (
+                dualCell0 != currentDualCell0
+             || dualCell1 != currentDualCell1
+            )
+        )
+        {
+            // Close current face.
+            addInternalFace
+            (
+                -1,         // masterPointI
+                edgeI,      // masterEdgeI
+                -1,         // masterFaceI
+                edgeOrder,
+                currentDualCell0,
+                currentDualCell1,
+                verts.shrink(),
+                meshMod
+            );
+
+            // Restart
+            currentDualCell0 = dualCell0;
+            currentDualCell1 = dualCell1;
+
+            verts.clear();
+            if (edgeToDualPoint_[edgeI] != -1)
+            {
+                verts.append(edgeToDualPoint_[edgeI]);
+            }
+            if (faceToDualPoint_[faceI] != -1)
+            {
+                verts.append(faceToDualPoint_[faceI]);
+            }
+        }
+
+        if (cellToDualPoint_[cellI] != -1)
+        {
+            verts.append(cellToDualPoint_[cellI]);
+        }
+
+        ++ie;
+
+        if (ie == ie.end())
+        {
+            // Back at start face (for internal edge only). See if this needs
+            // adding.
+            if (isBoundaryEdge.get(edgeI) == 0)
+            {
+                label startDual = faceToDualPoint_[startFaceLabel];
+
+                if (startDual != -1 && findIndex(verts, startDual) == -1)
+                {
+                    verts.append(startDual);
+                }
+            }
+            break;
+        }
+    }
+
+    verts.shrink();
+    addInternalFace
+    (
+        -1,         // masterPointI
+        edgeI,      // masterEdgeI
+        -1,         // masterFaceI
+        edgeOrder,
+        currentDualCell0,
+        currentDualCell1,
+        verts,
+        meshMod
+    );
+}
+
+
+// Walks around circumference of faceI. Creates single face. Gets given
+// starting (feature) edge to start from. Returns ending edge. (all edges
+// in form of index in faceEdges)
+void Foam::meshDualiser::createFaceFromInternalFace
+(
+    const label faceI,
+    label& fp,
+    polyTopoChange& meshMod
+) const
+{
+    const face& f = mesh_.faces()[faceI];
+    const labelList& fEdges = mesh_.faceEdges()[faceI];
+    label own = mesh_.faceOwner()[faceI];
+    label nei = mesh_.faceNeighbour()[faceI];
+
+    //Pout<< "createFaceFromInternalFace : At face:" << faceI
+    //    << " verts:" << f
+    //    << " points:" << IndirectList<point>(mesh_.points(), f)()
+    //    << " started walking at edge:" << fEdges[fp]
+    //    << " verts:" << mesh_.edges()[fEdges[fp]]
+    //    << endl;
+
+
+    // Walk and collect face.
+    DynamicList<label> verts(100);
+
+    verts.append(faceToDualPoint_[faceI]);
+    verts.append(edgeToDualPoint_[fEdges[fp]]);
+
+    // Step to vertex after edge mid
+    fp = f.fcIndex(fp);
+
+    // Get cells on either side of face at that point
+    label currentDualCell0 = findDualCell(own, f[fp]);
+    label currentDualCell1 = findDualCell(nei, f[fp]);
+
+    forAll(f, i)
+    {
+        // Check vertex
+        if (pointToDualPoint_[f[fp]] != -1)
+        {
+            verts.append(pointToDualPoint_[f[fp]]);
+        }
+
+        // Edge between fp and fp+1
+        label edgeI = fEdges[fp];
+
+        if (edgeToDualPoint_[edgeI] != -1)
+        {
+            verts.append(edgeToDualPoint_[edgeI]);
+        }
+
+        // Next vertex on edge
+        label nextFp = f.fcIndex(fp);
+
+        // Get dual cells on nextFp to check whether face needs closing.
+        label dualCell0 = findDualCell(own, f[nextFp]);
+        label dualCell1 = findDualCell(nei, f[nextFp]);
+
+        if (dualCell0 != currentDualCell0 || dualCell1 != currentDualCell1)
+        {
+            // Check: make sure that there is a midpoint on the edge.
+            if (edgeToDualPoint_[edgeI] == -1)
+            {
+                FatalErrorIn("createFacesFromInternalFace(..)")
+                    << "face:" << faceI << " verts:" << f
+                    << " points:" << IndirectList<point>(mesh_.points(), f)()
+                    << " no feature edge between " << f[fp]
+                    << " and " << f[nextFp] << " although have different"
+                    << " dual cells." << endl
+                    << "point " << f[fp] << " has dual cells "
+                    << currentDualCell0 << " and " << currentDualCell1
+                    << " ; point "<< f[nextFp] << " has dual cells "
+                    << dualCell0 << " and " << dualCell1
+                    << abort(FatalError);
+            }
+
+
+            // Close current face.
+            verts.shrink();
+            addInternalFace
+            (
+                -1,         // masterPointI
+                -1,         // masterEdgeI
+                faceI,      // masterFaceI
+                true,       // edgeOrder,
+                currentDualCell0,
+                currentDualCell1,
+                verts,
+                meshMod
+            );
+            break;
+        }
+
+        fp = nextFp;
+    }
+}
+
+
+// Given a point on a face converts the faces around the point.
+// (pointFaces()). Gets starting face and marks off visited faces in donePFaces.
+void Foam::meshDualiser::createFacesAroundBoundaryPoint
+(
+    const label patchI,
+    const label patchPointI,
+    const label startFaceI,
+    polyTopoChange& meshMod,
+    boolList& donePFaces            // pFaces visited
+) const
+{
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+    const polyPatch& pp = patches[patchI];
+    const labelList& pFaces = pp.pointFaces()[patchPointI];
+    const labelList& own = mesh_.faceOwner();
+
+    label pointI = pp.meshPoints()[patchPointI];
+
+    if (pointToDualPoint_[pointI] == -1)
+    {
+        // Not a feature point. Loop over all connected
+        // pointFaces.
+
+        // Starting face
+        label faceI = startFaceI;
+
+        DynamicList<label> verts(4);
+
+        while (true)
+        {
+            label index = findIndex(pFaces, faceI-pp.start());
+
+            // Has face been visited already?
+            if (donePFaces[index])
+            {
+                break;
+            }
+            donePFaces[index] = true;
+
+            // Insert face centre
+            verts.append(faceToDualPoint_[faceI]);
+
+            label dualCellI = findDualCell(own[faceI], pointI);
+
+            // Get the edge before the patchPointI
+            const face& f = mesh_.faces()[faceI];
+            label fp = findIndex(f, pointI);
+            label prevFp = f.rcIndex(fp);
+            label edgeI = mesh_.faceEdges()[faceI][prevFp];
+
+            if (edgeToDualPoint_[edgeI] != -1)
+            {
+                verts.append(edgeToDualPoint_[edgeI]);
+            }
+
+            // Get next boundary face (whilst staying on edge).
+            edgeFaceCirculator circ
+            (
+                mesh_,
+                faceI,
+                true,   // ownerSide
+                prevFp, // index of edge in face
+                true    // isBoundaryEdge
+            );
+
+            do
+            {
+                ++circ;
+            }
+            while (mesh_.isInternalFace(circ.faceLabel()));
+
+            // Step to next face
+            faceI = circ.faceLabel();
+
+            if (faceI < pp.start() || faceI >= pp.start()+pp.size())
+            {
+                FatalErrorIn
+                (
+                    "meshDualiser::createFacesAroundBoundaryPoint(..)"
+                )   << "Walked from face on patch:" << patchI
+                    << " to face:" << faceI
+                    << " fc:" << mesh_.faceCentres()[faceI]
+                    << " on patch:" << patches.whichPatch(faceI) 
+                    << abort(FatalError);
+            }
+
+            // Check if different cell.
+            if (dualCellI != findDualCell(own[faceI], pointI))
+            {
+                FatalErrorIn
+                (
+                    "meshDualiser::createFacesAroundBoundaryPoint(..)"
+                )   << "Different dual cells but no feature edge"
+                    << " inbetween point:" << pointI
+                    << " coord:" << mesh_.points()[pointI]
+                    << abort(FatalError);
+            }
+        }
+
+        verts.shrink();
+
+        label dualCellI = findDualCell(own[faceI], pointI);
+
+        //Bit dodgy: create dualface from the last face (instead of from
+        // the central point). This will also use the original faceZone to
+        // put the new face (which might span multiple original faces) in.
+
+        addBoundaryFace
+        (
+            //pointI,     // masterPointI
+            -1,         // masterPointI
+            -1,         // masterEdgeI
+            faceI,      // masterFaceI
+            dualCellI,
+            patchI,
+            verts,
+            meshMod
+        );
+    }
+    else
+    {
+        label faceI = startFaceI;
+
+        // Storage for face
+        DynamicList<label> verts(mesh_.faces()[faceI].size());
+
+        // Starting point.
+        verts.append(pointToDualPoint_[pointI]);
+
+        // Find edge between pointI and next point on face.
+        const labelList& fEdges = mesh_.faceEdges()[faceI];
+        label nextEdgeI = fEdges[findIndex(mesh_.faces()[faceI], pointI)];
+        if (edgeToDualPoint_[nextEdgeI] != -1)
+        {
+            verts.append(edgeToDualPoint_[nextEdgeI]);
+        }
+
+        do
+        {
+            label index = findIndex(pFaces, faceI-pp.start());
+
+            // Has face been visited already?
+            if (donePFaces[index])
+            {
+                break;
+            }
+            donePFaces[index] = true;
+
+            // Face centre
+            verts.append(faceToDualPoint_[faceI]);
+
+            // Find edge before pointI on faceI
+            const labelList& fEdges = mesh_.faceEdges()[faceI];
+            const face& f = mesh_.faces()[faceI];
+            label prevFp = f.rcIndex(findIndex(f, pointI));
+            label edgeI = fEdges[prevFp];
+
+            if (edgeToDualPoint_[edgeI] != -1)
+            {
+                // Feature edge. Close any face so far. Note: uses face to
+                // create dualFace from. Could use pointI instead.
+                verts.append(edgeToDualPoint_[edgeI]);
+                addBoundaryFace
+                (
+                    -1,     // masterPointI
+                    -1,     // masterEdgeI
+                    faceI,  // masterFaceI
+                    findDualCell(own[faceI], pointI),
+                    patchI,
+                    verts.shrink(),
+                    meshMod
+                );
+                verts.clear();
+
+                verts.append(pointToDualPoint_[pointI]);
+                verts.append(edgeToDualPoint_[edgeI]);
+            }
+
+            // Cross edgeI to next boundary face
+            edgeFaceCirculator circ
+            (
+                mesh_,
+                faceI,
+                true,   // ownerSide
+                prevFp, // index of edge in face
+                true    // isBoundaryEdge
+            );
+
+            do
+            {
+                ++circ;
+            }
+            while (mesh_.isInternalFace(circ.faceLabel()));
+
+            // Step to next face. Quit if not on same patch.
+            faceI = circ.faceLabel();
+        }
+        while
+        (
+            faceI != startFaceI
+         && faceI >= pp.start()
+         && faceI < pp.start()+pp.size()
+        );
+
+        if (verts.size() > 2)
+        {
+            // Note: face created from face, not from pointI
+            addBoundaryFace
+            (
+                -1,             // masterPointI
+                -1,             // masterEdgeI
+                startFaceI,     // masterFaceI
+                findDualCell(own[faceI], pointI),
+                patchI,
+                verts.shrink(),
+                meshMod
+            );
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::meshDualiser::meshDualiser(const polyMesh& mesh)
+:
+    mesh_(mesh),
+    pointToDualCells_(mesh_.nPoints()),
+    pointToDualPoint_(mesh_.nPoints(), -1),
+    cellToDualPoint_(mesh_.nCells()),
+    faceToDualPoint_(mesh_.nFaces(), -1),
+    edgeToDualPoint_(mesh_.nEdges(), -1)
+{}
+  
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::meshDualiser::setRefinement
+(
+    const bool splitFace,
+    const labelList& featureFaces,
+    const labelList& featureEdges,
+    const labelList& singleCellFeaturePoints,
+    const labelList& multiCellFeaturePoints,
+    polyTopoChange& meshMod
+)
+{
+    const labelList& own = mesh_.faceOwner();
+    const labelList& nei = mesh_.faceNeighbour();
+    const vectorField& cellCentres = mesh_.cellCentres();
+
+    // Mark boundary edges and points.
+    // (Note: in 1.4.2 we can use the built-in mesh point ordering
+    //  facility instead)
+    PackedList<1> isBoundaryEdge(mesh_.nEdges());
+    for (label faceI = mesh_.nInternalFaces(); faceI < mesh_.nFaces(); faceI++)
+    {
+        const labelList& fEdges = mesh_.faceEdges()[faceI];
+
+        forAll(fEdges, i)
+        {
+            isBoundaryEdge.set(fEdges[i], 1);
+        }
+    }
+
+
+    if (splitFace)
+    {
+        // This is a special mode where whenever we are walking around an edge
+        // every area through a cell becomes a separate dualface. So two
+        // dual cells will probably have more than one dualface between them!
+        // This mode implies that
+        // - all faces have to be feature faces since there has to be a
+        //   dualpoint at the face centre.
+        // - all edges have to be feature edges ,,
+        boolList featureFaceSet(mesh_.nFaces(), false);
+        forAll(featureFaces, i)
+        {
+            featureFaceSet[featureFaces[i]] = true;
+        }
+        label faceI = findIndex(featureFaceSet, false);
+
+        if (faceI != -1)
+        {
+            FatalErrorIn
+            (
+                "meshDualiser::setRefinement"
+                "(const labelList&, const labelList&, const labelList&"
+                ", const labelList, polyTopoChange&)"
+            )   << "In split-face-mode (splitFace=true) but not all faces"
+                << " marked as feature faces." << endl
+                << "First conflicting face:" << faceI
+                << " centre:" << mesh_.faceCentres()[faceI]
+                << abort(FatalError);
+        }
+
+        boolList featureEdgeSet(mesh_.nEdges(), false);
+        forAll(featureEdges, i)
+        {
+            featureEdgeSet[featureEdges[i]] = true;
+        }
+        label edgeI = findIndex(featureEdgeSet, false);
+
+        if (edgeI != -1)
+        {
+            const edge& e = mesh_.edges()[edgeI];
+            FatalErrorIn
+            (
+                "meshDualiser::setRefinement"
+                "(const labelList&, const labelList&, const labelList&"
+                ", const labelList, polyTopoChange&)"
+            )   << "In split-face-mode (splitFace=true) but not all edges"
+                << " marked as feature edges." << endl
+                << "First conflicting edge:" << edgeI
+                << " verts:" << e
+                << " coords:" << mesh_.points()[e[0]] << mesh_.points()[e[1]]
+                << abort(FatalError);
+        }
+    }
+    else
+    {
+        // Check that all boundary faces are feature faces.
+
+        boolList featureFaceSet(mesh_.nFaces(), false);
+        forAll(featureFaces, i)
+        {
+            featureFaceSet[featureFaces[i]] = true;
+        }
+        for
+        (
+            label faceI = mesh_.nInternalFaces();
+            faceI < mesh_.nFaces();
+            faceI++
+        )
+        {
+            if (!featureFaceSet[faceI])
+            {
+                FatalErrorIn
+                (
+                    "meshDualiser::setRefinement"
+                    "(const labelList&, const labelList&, const labelList&"
+                    ", const labelList, polyTopoChange&)"
+                )   << "Not all boundary faces marked as feature faces."
+                    << endl
+                    << "First conflicting face:" << faceI
+                    << " centre:" << mesh_.faceCentres()[faceI]
+                    << abort(FatalError);
+            }
+        }
+    }
+
+
+
+
+    // Start creating cells, points, and faces (in that order)
+
+
+    // 1. Mark which cells to create
+    // Mostly every point becomes one cell but sometimes (for feature points)
+    // all cells surrounding a feature point become cells. Also a non-manifold
+    // point can create two cells! So a dual cell is uniquely defined by a
+    // mesh point + cell (as in pointCells index)
+
+    // 2. Mark which face centres to create
+
+    // 3. Internal faces can now consist of
+    //      - only cell centres of walk around edge
+    //      - cell centres + face centres of walk around edge
+    //      - same but now other side is not a single cell
+
+    // 4. Boundary faces (or internal faces between cell zones!) now consist of
+    //      - walk around boundary point.
+
+
+
+    autoPtr<OFstream> dualCcStr;
+    if (debug)
+    {
+        dualCcStr.reset(new OFstream("dualCc.obj"));
+        Pout<< "Dumping centres of dual cells to " << dualCcStr().name()
+            << endl;
+    }
+
+
+    // Dual cells (from points)
+    // ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    // pointToDualCells_[pointI]
+    // - single entry : all cells surrounding point all become the same
+    //                  cell.
+    // - multiple entries: in order of pointCells.
+
+
+    // feature points that become single cell
+    forAll(singleCellFeaturePoints, i)
+    {
+        label pointI = singleCellFeaturePoints[i];
+
+        pointToDualPoint_[pointI] = meshMod.addPoint
+        (
+            mesh_.points()[pointI],
+            pointI,                                 // masterPoint
+            mesh_.pointZones().whichZone(pointI),   // zoneID
+            true                                    // inCell
+        );
+
+        // Generate single cell
+        pointToDualCells_[pointI].setSize(1);
+        pointToDualCells_[pointI][0] = meshMod.addCell
+        (
+            pointI, //masterPointID,
+            -1,     //masterEdgeID,
+            -1,     //masterFaceID,
+            -1,     //masterCellID,
+            -1      //zoneID
+        );
+        if (dualCcStr.valid())
+        {
+            meshTools::writeOBJ(dualCcStr(), mesh_.points()[pointI]);
+        }
+    }
+
+    // feature points that become multiple cells
+    forAll(multiCellFeaturePoints, i)
+    {
+        label pointI = multiCellFeaturePoints[i];
+
+        if (pointToDualCells_[pointI].size() > 0)
+        {
+            FatalErrorIn
+            (
+                "meshDualiser::setRefinement"
+                "(const labelList&, const labelList&, const labelList&"
+                ", const labelList, polyTopoChange&)"
+            )   << "Point " << pointI << " at:" << mesh_.points()[pointI]
+                << " is both in singleCellFeaturePoints"
+                << " and multiCellFeaturePoints."
+                << abort(FatalError);
+        }
+
+        pointToDualPoint_[pointI] = meshMod.addPoint
+        (
+            mesh_.points()[pointI],
+            pointI,                                 // masterPoint
+            mesh_.pointZones().whichZone(pointI),   // zoneID
+            true                                    // inCell
+        );
+
+        // Create dualcell for every cell connected to dual point
+
+        const labelList& pCells = mesh_.pointCells()[pointI];
+
+        pointToDualCells_[pointI].setSize(pCells.size());
+
+        forAll(pCells, pCellI)
+        {
+            pointToDualCells_[pointI][pCellI] = meshMod.addCell
+            (
+                pointI,                                     //masterPointID
+                -1,                                         //masterEdgeID
+                -1,                                         //masterFaceID
+                -1,                                         //masterCellID
+                mesh_.cellZones().whichZone(pCells[pCellI]) //zoneID
+            );
+            if (dualCcStr.valid())
+            {
+                meshTools::writeOBJ
+                (
+                    dualCcStr(),
+                    0.5*(mesh_.points()[pointI]+cellCentres[pCells[pCellI]])
+                );
+            }
+        }
+    }
+    // Normal points
+    forAll(mesh_.points(), pointI)
+    {
+        if (pointToDualCells_[pointI].size() == 0)
+        {
+            pointToDualCells_[pointI].setSize(1);
+            pointToDualCells_[pointI][0] = meshMod.addCell
+            (
+                pointI, //masterPointID,
+                -1,     //masterEdgeID,
+                -1,     //masterFaceID,
+                -1,     //masterCellID,
+                -1      //zoneID
+            );
+
+            if (dualCcStr.valid())
+            {
+                meshTools::writeOBJ(dualCcStr(), mesh_.points()[pointI]);
+            }
+        }
+    }
+
+
+    // Dual points (from cell centres, feature faces, feature edges)
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    forAll(cellToDualPoint_, cellI)
+    {
+        cellToDualPoint_[cellI] = meshMod.addPoint
+        (
+            cellCentres[cellI],
+            mesh_.faces()[mesh_.cells()[cellI][0]][0],     // masterPoint
+            -1,     // zoneID
+            true    // inCell
+        );
+    }
+
+    // From face to dual point
+
+    forAll(featureFaces, i)
+    {
+        label faceI = featureFaces[i];
+
+        faceToDualPoint_[faceI] = meshMod.addPoint
+        (
+            mesh_.faceCentres()[faceI],
+            mesh_.faces()[faceI][0],     // masterPoint
+            -1,     // zoneID
+            true    // inCell
+        );
+    }
+    // Detect whether different dual cells on either side of a face. This
+    // would neccesitate having a dual face built from the face and thus a
+    // dual point at the face centre.
+    for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
+    {
+        if (faceToDualPoint_[faceI] == -1)
+        {
+            const face& f = mesh_.faces()[faceI];
+
+            forAll(f, fp)
+            {
+                label ownDualCell = findDualCell(own[faceI], f[fp]);
+                label neiDualCell = findDualCell(nei[faceI], f[fp]);
+
+                if (ownDualCell != neiDualCell)
+                {
+                    faceToDualPoint_[faceI] = meshMod.addPoint
+                    (
+                        mesh_.faceCentres()[faceI],
+                        f[fp],  // masterPoint
+                        -1,     // zoneID
+                        true    // inCell
+                    );
+
+                    break;
+                }
+            }
+        }
+    }
+
+    // From edge to dual point
+
+    forAll(featureEdges, i)
+    {
+        label edgeI = featureEdges[i];
+
+        const edge& e = mesh_.edges()[edgeI];
+
+        edgeToDualPoint_[edgeI] = meshMod.addPoint
+        (
+            e.centre(mesh_.points()),
+            e[0],   // masterPoint
+            -1,     // zoneID
+            true    // inCell
+        );
+    }
+
+    // Detect whether different dual cells on either side of an edge. This
+    // would neccesitate having a dual face built perpendicular to the edge
+    // and thus a dual point at the mid of the edge.
+    // Note: not really true - the face can be built without the edge centre!
+    const labelListList& edgeCells = mesh_.edgeCells();
+
+    forAll(edgeCells, edgeI)
+    {
+       if (edgeToDualPoint_[edgeI] == -1)
+       {
+            const edge& e = mesh_.edges()[edgeI];
+
+            // We need a point on the edge if not all cells on both sides
+            // are the same. 
+
+            const labelList& eCells = mesh_.edgeCells()[edgeI];
+
+            label dualE0 = findDualCell(eCells[0], e[0]);
+            label dualE1 = findDualCell(eCells[0], e[1]);
+
+            for (label i = 1; i < eCells.size(); i++)
+            {
+                label newDualE0 = findDualCell(eCells[i], e[0]);
+
+                if (dualE0 != newDualE0)
+                {
+                    edgeToDualPoint_[edgeI] = meshMod.addPoint
+                    (
+                        e.centre(mesh_.points()),
+                        e[0],                               // masterPoint
+                        mesh_.pointZones().whichZone(e[0]), // zoneID
+                        true                                // inCell
+                    );
+
+                    break;
+                }
+
+                label newDualE1 = findDualCell(eCells[i], e[1]);
+
+                if (dualE1 != newDualE1)
+                {
+                    edgeToDualPoint_[edgeI] = meshMod.addPoint
+                    (
+                        e.centre(mesh_.points()),
+                        e[1],   // masterPoint
+                        mesh_.pointZones().whichZone(e[1]), // zoneID
+                        true    // inCell
+                    );
+
+                    break;
+                }
+            }
+        }
+    }
+
+    // Make sure all boundary edges emanating from feature points are
+    // feature edges as well.
+    forAll(singleCellFeaturePoints, i)
+    {
+        generateDualBoundaryEdges
+        (
+            isBoundaryEdge,
+            singleCellFeaturePoints[i],
+            meshMod
+        );
+    }
+    forAll(multiCellFeaturePoints, i)
+    {
+        generateDualBoundaryEdges
+        (
+            isBoundaryEdge,
+            multiCellFeaturePoints[i],
+            meshMod
+        );
+    }
+
+
+    // Check for duplicate points
+    if (debug)
+    {
+        dumpPolyTopoChange(meshMod, "generatedPoints_");
+        checkPolyTopoChange(meshMod);
+    }
+
+
+    // Now we have all points and cells
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    //  - pointToDualCells_ : per point a single dualCell or multiple dualCells
+    //  - pointToDualPoint_ : per point -1 or the dual point at the coordinate
+    //  - edgeToDualPoint_  : per edge -1 or the edge centre
+    //  - faceToDualPoint_  : per face -1 or the face centre
+    //  - cellToDualPoint_  : per cell the cell centre
+    // Now we have to walk all edges and construct faces. Either single face
+    // per edge or multiple (-if nonmanifold edge -if different dualcells)
+
+    const edgeList& edges = mesh_.edges();
+
+    forAll(edges, edgeI)
+    {
+        const labelList& eFaces = mesh_.edgeFaces()[edgeI];
+
+        boolList doneEFaces(eFaces.size(), false);
+
+        forAll(eFaces, i)
+        {
+            if (!doneEFaces[i])
+            {
+                // We found a face that hasn't yet been visited. This might
+                // happen for non-manifold edges where a single edge can
+                // become multiple faces.
+
+                label startFaceI = eFaces[i];
+
+                //Pout<< "Walking edge:" << edgeI
+                //    << " points:" << mesh_.points()[e[0]]
+                //    << mesh_.points()[e[1]]
+                //    << " startFace:" << startFaceI
+                //    << " at:" << mesh_.faceCentres()[startFaceI]
+                //    << endl;
+
+                createFacesAroundEdge
+                (
+                    splitFace,
+                    isBoundaryEdge,
+                    edgeI,
+                    startFaceI,
+                    meshMod,
+                    doneEFaces
+                );
+            }
+        }
+    }
+
+    if (debug)
+    {
+        dumpPolyTopoChange(meshMod, "generatedFacesFromEdges_");
+    }
+
+    // Create faces from feature faces. These can be internal or external faces.
+    // - feature face : centre needs to be included.
+    //      - single cells on either side: triangulate
+    //      - multiple cells: create single face between unique cell pair. Only
+    //                        create face where cells differ on either side.
+    // - non-feature face : inbetween cell zones.
+    forAll(faceToDualPoint_, faceI)
+    {
+        if (faceToDualPoint_[faceI] != -1 && mesh_.isInternalFace(faceI))
+        {
+            const face& f = mesh_.faces()[faceI];
+            const labelList& fEdges = mesh_.faceEdges()[faceI];
+
+            // Starting edge
+            label fp = 0;
+
+            do
+            {
+                // Find edge that is in dual mesh and where the
+                // next point (fp+1) has different dual cells on either side.
+                bool foundStart = false;
+
+                do
+                {
+                    if
+                    (
+                        edgeToDualPoint_[fEdges[fp]] != -1
+                    && !sameDualCell(faceI, f.nextLabel(fp))
+                    )
+                    {
+                        foundStart = true;
+                        break;
+                    }
+                    fp = f.fcIndex(fp);
+                }
+                while (fp != 0);
+
+                if (!foundStart)
+                {
+                    break;
+                }
+
+                // Walk from edge fp and generate a face.
+                createFaceFromInternalFace
+                (
+                    faceI,
+                    fp,
+                    meshMod
+                );
+            }
+            while(fp != 0);
+        }
+    }
+
+    if (debug)
+    {
+        dumpPolyTopoChange(meshMod, "generatedFacesFromFeatFaces_");
+    }
+
+
+    // Create boundary faces. Every boundary point has one or more dualcells.
+    // These need to be closed.
+    const polyBoundaryMesh& patches = mesh_.boundaryMesh();
+
+    forAll(patches, patchI)
+    {
+        const polyPatch& pp = patches[patchI];
+
+        const labelListList& pointFaces = pp.pointFaces();
+
+        forAll(pointFaces, patchPointI)
+        {
+            const labelList& pFaces = pointFaces[patchPointI];
+
+            boolList donePFaces(pFaces.size(), false);
+
+            forAll(pFaces, i)
+            {
+                if (!donePFaces[i])
+                {
+                    // Starting face
+                    label startFaceI = pp.start()+pFaces[i];
+
+                    //Pout<< "Walking around point:" << pointI
+                    //    << " coord:" << mesh_.points()[pointI]
+                    //    << " on patch:" << patchI
+                    //    << " startFace:" << startFaceI
+                    //    << " at:" << mesh_.faceCentres()[startFaceI]
+                    //    << endl;
+
+                    createFacesAroundBoundaryPoint
+                    (
+                        patchI,
+                        patchPointI,
+                        startFaceI,
+                        meshMod,
+                        donePFaces            // pFaces visited
+                    );
+                }
+            }
+        }
+    }
+
+    if (debug)
+    {
+        dumpPolyTopoChange(meshMod, "generatedFacesFromBndFaces_");
+    }
+}
+
+
+
+// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
+
+
+// * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/conversion/polyDualMesh/meshDualiser.H b/applications/utilities/mesh/conversion/polyDualMesh/meshDualiser.H
new file mode 100644
index 0000000000000000000000000000000000000000..ee5599816c3c81fa9431af8c4929bd0ff5277cb6
--- /dev/null
+++ b/applications/utilities/mesh/conversion/polyDualMesh/meshDualiser.H
@@ -0,0 +1,262 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    meshDualiser
+
+Description
+    Creates dual of polyMesh. Every point becomes a cell (or multiple cells
+    for feature points), a walk around every edge creates faces between them.
+
+    Put all points you want in the final mesh into featurePoints; all edge(mid)s
+    you want in the final mesh into featureEdges; all face(centre)s in
+    faceFaces.
+
+    Usually to preserve boundaries:
+        - all boundary faces are featureFaces
+        - all edges and points inbetween different patches are
+          featureEdges/points.
+
+    In same way you can also preserve internal faces (e.g. faceZones)
+
+SourceFiles
+    meshDualiser.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef meshDualiser_H
+#define meshDualiser_H
+
+#include "DynamicList.H"
+#include "PackedList.H"
+#include "boolList.H"
+#include "typeInfo.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+class polyMesh;
+class polyTopoChange;
+
+/*---------------------------------------------------------------------------*\
+                           Class meshDualiser Declaration
+\*---------------------------------------------------------------------------*/
+
+class meshDualiser
+{
+    // Private data
+
+        const polyMesh& mesh_;
+
+        //- From point on cell to dual cell. Either single entry or
+        //  one entry per pointCells
+        labelListList pointToDualCells_;
+
+        //- From point to dual point (or -1 if not feature point).
+        labelList pointToDualPoint_;
+
+        //- From cell to dual point. All cells become point
+        labelList cellToDualPoint_;
+
+        //- From face to dual point (or -1 if not feature face)
+        labelList faceToDualPoint_;
+
+        //- From edge to dual point (or -1 if not feature edge)
+        labelList edgeToDualPoint_;
+
+
+    // Private Member Functions
+
+        static void checkPolyTopoChange(const polyTopoChange&);
+
+        static void dumpPolyTopoChange(const polyTopoChange&, const fileName&);
+
+        //- Find dual cell given point and cell
+        label findDualCell(const label cellI, const label pointI) const;
+
+        //- Helper function to generate dualpoints on all boundary edges
+        //  emanating from (boundary & feature) point
+        void generateDualBoundaryEdges
+        (
+            const PackedList<1>&,
+            const label pointI,
+            polyTopoChange&
+        );
+
+        //- Check that owner and neighbour of face have same dual cell
+        bool sameDualCell
+        (
+            const label faceI,
+            const label pointI
+        ) const;
+
+        //- Add internal face
+        label addInternalFace
+        (
+            const label masterPointI,
+            const label masterEdgeI,
+            const label masterFaceI,
+
+            const bool edgeOrder,
+            const label dualCell0,
+            const label dualCell1,
+            const DynamicList<label>& verts,
+            polyTopoChange& meshMod
+        ) const;
+
+        //- Add boundary face
+        label addBoundaryFace
+        (
+            const label masterPointI,
+            const label masterEdgeI,
+            const label masterFaceI,
+
+            const label dualCellI,
+            const label patchI,
+            const DynamicList<label>& verts,
+            polyTopoChange& meshMod
+        ) const;
+
+        //- Create internal faces walking around edge
+        void createFacesAroundEdge
+        (
+            const bool splitFace,
+            const PackedList<1>&,
+            const label edgeI,
+            const label startFaceI,
+            polyTopoChange&,
+            boolList& doneEFaces
+        ) const;
+
+        //- Create single internal face from internal face
+        void createFaceFromInternalFace
+        (
+            const label faceI,
+            label& fp,
+            polyTopoChange&
+        ) const;
+
+        //- Creates boundary faces walking around point on patchI.
+        void createFacesAroundBoundaryPoint
+        (
+            const label patchI,
+            const label patchPointI,
+            const label startFaceI,
+            polyTopoChange&,
+            boolList& donePFaces            // pFaces visited
+        ) const;
+
+        //- Disallow default bitwise copy construct
+        meshDualiser(const meshDualiser&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const meshDualiser&);
+
+
+public:
+
+    //- Runtime type information
+    ClassName("meshDualiser");
+
+
+    // Constructors
+
+        //- Construct from mesh
+        meshDualiser(const polyMesh&);
+
+
+    // Member Functions
+
+        // Access
+
+            //- From point on cell to dual cell. Either single entry or
+            //  one entry per pointCells.
+            const labelListList& pointToDualCells() const
+            {
+                return pointToDualCells_;
+            }
+
+            //- From point to dual point (or -1 if not feature point).
+            const labelList& pointToDualPoint() const
+            {
+                return pointToDualPoint_;
+            }
+
+            //- From cell to dual point (at cell centre). All cells become
+            //  points.
+            const labelList& cellToDualPoint() const
+            {
+                return cellToDualPoint_;
+            }
+
+            //- From face to dual point (at face centre; or -1 if not
+            //  feature face).
+            const labelList& faceToDualPoint() const
+            {
+                return faceToDualPoint_;
+            }
+
+            //- From edge to dual point (at edge mid; or -1 if not feature
+            //  edge).
+            const labelList& edgeToDualPoint() const
+            {
+                return edgeToDualPoint_;
+            }
+
+
+        // Edit
+
+
+            //- Insert all changes into meshMod to convert the polyMesh into
+            //  its dual.
+            //  featureFaces  : faces where we want a point at the face centre
+            //  featureEdges  : edges           ,,                 edge mid
+            //  featurePoints : points          ,,    point. Two variants:
+            //      singleCellFeaturePoints : point becomes one dualcell.
+            //          Use this for e.g. convex boundary points.
+            //      multiCellFeaturePoints : one dualcell per original cell
+            //          around point. Use this for e.g. concave boundary points
+            //          since it prevents big concave boundary cells.
+            void setRefinement
+            (
+                const bool splitFace,
+                const labelList& featureFaces,
+                const labelList& featureEdges,
+                const labelList& singleCellFeaturePoints,
+                const labelList& multiCellFeaturePoints,
+                polyTopoChange& meshMod
+            );
+};
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C
index ac924136e1cf104e13e9a1fdc861e9ad6ba9c911..2596ae61501f4b20bea2abb4b76f515b5b51326b 100644
--- a/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C
+++ b/applications/utilities/mesh/manipulation/checkMesh/checkTopology.C
@@ -109,7 +109,7 @@ Foam::label Foam::checkTopology
         {
             Info<< "    Number of regions: " << rs.nRegions() << " (OK)."
                 << endl;
-        
+
         }
         else
         {
@@ -214,7 +214,7 @@ Foam::label Foam::checkTopology
                 const pointField& pts = pp.points();
                 const labelList& mp = pp.meshPoints();
 
-                boundBox bb(vector::zero, vector::zero);
+                boundBox bb;   // zero-sized
                 if (returnReduce(mp.size(), sumOp<label>()) > 0)
                 {
                     bb.min() = pts[mp[0]];
diff --git a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
index bcd1c5c9ce3e86d66aa8f639a17f12edc3f7a8d0..99eea4a2ca2c7fc3ee90a577fcf19dbc84433388 100644
--- a/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
+++ b/applications/utilities/mesh/manipulation/mergeMeshes/mergePolyMesh.C
@@ -144,7 +144,7 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
     wordList curPointZoneNames = pointZones().names();
     if (curPointZoneNames.size() > 0)
     {
-        pointZoneNames_.setSize(2*curPointZoneNames.size());
+        pointZoneNames_.setCapacity(2*curPointZoneNames.size());
     }
 
     forAll (curPointZoneNames, zoneI)
@@ -157,7 +157,7 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
 
     if (curFaceZoneNames.size() > 0)
     {
-        faceZoneNames_.setSize(2*curFaceZoneNames.size());
+        faceZoneNames_.setCapacity(2*curFaceZoneNames.size());
     }
     forAll (curFaceZoneNames, zoneI)
     {
@@ -169,7 +169,7 @@ Foam::mergePolyMesh::mergePolyMesh(const IOobject& io)
 
     if (curCellZoneNames.size() > 0)
     {
-        cellZoneNames_.setSize(2*curCellZoneNames.size());
+        cellZoneNames_.setCapacity(2*curCellZoneNames.size());
     }
     forAll (curCellZoneNames, zoneI)
     {
diff --git a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
index 548f8247dc6f35fa62c2ca6a0644ab6749d3a2b1..c24e779a839104622ce20d152d12f373a081fb49 100644
--- a/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
+++ b/applications/utilities/parallelProcessing/decomposePar/domainDecomposition.C
@@ -354,7 +354,7 @@ bool domainDecomposition::writeDecomposition()
             // Estimate size
             forAll(zonePoints, zoneI)
             {
-                zonePoints[zoneI].setSize(pz[zoneI].size() / nProcs_);
+                zonePoints[zoneI].setCapacity(pz[zoneI].size() / nProcs_);
             }
 
             // Use the pointToZone map to find out the single zone (if any),
@@ -423,8 +423,8 @@ bool domainDecomposition::writeDecomposition()
             {
                 label procSize = fz[zoneI].size() / nProcs_;
 
-                zoneFaces[zoneI].setSize(procSize);
-                zoneFaceFlips[zoneI].setSize(procSize);
+                zoneFaces[zoneI].setCapacity(procSize);
+                zoneFaceFlips[zoneI].setCapacity(procSize);
             }
 
             // Go through all the zoned faces and find out if they
@@ -514,7 +514,7 @@ bool domainDecomposition::writeDecomposition()
             // Estimate size
             forAll(zoneCells, zoneI)
             {
-                zoneCells[zoneI].setSize(cz[zoneI].size() / nProcs_);
+                zoneCells[zoneI].setCapacity(cz[zoneI].size() / nProcs_);
             }
 
             forAll (curCellLabels, celli)
diff --git a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C
index 50818f4db9cdd78a60b23d6b4c2626d023b26018..3b5fca211ee43676feb69539dbbc058bb2f6f3c4 100644
--- a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C
+++ b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C
@@ -45,8 +45,10 @@ Description
 
 int main(int argc, char *argv[])
 {
+    // enable -constant ... if someone really wants it
+    // enable -zeroTime to prevent accidentally trashing the initial fields
+    timeSelector::addOptions(true, true);
     argList::noParallel();
-    timeSelector::addOptions();
 #   include "addRegionOption.H"
     argList::validOptions.insert("fields", "\"(list of fields)\"");
 
diff --git a/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C b/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C
index 834b75dfe6babdb595062c0f4fac95b59536b1ee..87b134f6e9dfed7b626a80314c0923ea3ce095a1 100644
--- a/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C
+++ b/applications/utilities/parallelProcessing/reconstructParMesh/reconstructParMesh.C
@@ -273,7 +273,7 @@ autoPtr<mapPolyMesh> mergeSharedPoints
         }
     }
 
-    return map;    
+    return map;
 }
 
 
@@ -418,11 +418,7 @@ int main(int argc, char *argv[])
     // Read point on individual processors to determine merge tolerance
     // (otherwise single cell domains might give problems)
 
-    boundBox bb
-    (
-        point(GREAT, GREAT, GREAT),
-        point(-GREAT, -GREAT, -GREAT)
-    );
+    boundBox bb = boundBox::invertedBox;
 
     for (label procI = 0; procI < nProcs; procI++)
     {
diff --git a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
index c8a7d89df2dafdcedcde44f7a982d6bfd5aaac1a..05501a904d7e545572ebbb7d03ad69d8cce98b39 100644
--- a/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
+++ b/applications/utilities/postProcessing/dataConversion/foamToEnsightParts/foamToEnsightParts.C
@@ -74,7 +74,9 @@ using namespace Foam;
 
 int main(int argc, char *argv[])
 {
-    // with -constant and -zeroTime
+    // enable -constant
+    // probably don't need -zeroTime though, since the fields are vetted
+    // afterwards anyhow
     timeSelector::addOptions(true, false);
     argList::noParallel();
     argList::validOptions.insert("ascii", "");
diff --git a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
index 7780ad3cfd71156946731ee7501d50e23ae59ab5..7ae5853896071eed97f745af3650334f3da92c2a 100644
--- a/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
+++ b/applications/utilities/postProcessing/graphics/PV3FoamReader/vtkPV3Foam/vtkPV3Foam.C
@@ -617,8 +617,10 @@ void Foam::vtkPV3Foam::addPatchNames(vtkRenderer* renderer)
         {
             const labelList& eFaces = edgeFaces[edgeI];
 
-            if (eFaces.size() != 2)
+            if (eFaces.size() == 1)
             {
+                // Note: could also do ones with > 2 faces but this gives
+                // too many zones for baffles
                 featEdge[edgeI] = true;
             }
             else if (mag(n[eFaces[0]] & n[eFaces[1]]) < 0.5)
diff --git a/applications/utilities/postProcessing/wall/wallHeatFlux/wallHeatFlux.C b/applications/utilities/postProcessing/wall/wallHeatFlux/wallHeatFlux.C
index 1eb405cf29728aaeade0fb40ca3024d2d414b4fd..49ac7d743140961aeafafff94de32a4a7b3ce2a5 100644
--- a/applications/utilities/postProcessing/wall/wallHeatFlux/wallHeatFlux.C
+++ b/applications/utilities/postProcessing/wall/wallHeatFlux/wallHeatFlux.C
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
         Info<< "\nWall heat fluxes [W]" << endl;
         forAll(patchHeatFlux, patchi)
         {
-            if (typeid(mesh.boundary()) == typeid(wallFvPatch))
+            if (typeid(mesh.boundary()[patchi]) == typeid(wallFvPatch))
             {
                 Info<< mesh.boundary()[patchi].name()
                     << " "
diff --git a/applications/utilities/preProcessing/foamUpgradeFvSolution/Make/files b/applications/utilities/preProcessing/foamUpgradeFvSolution/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..f667ed655e635c2c19b58d0c8adde570766b9e96
--- /dev/null
+++ b/applications/utilities/preProcessing/foamUpgradeFvSolution/Make/files
@@ -0,0 +1,3 @@
+foamUpgradeFvSolution.C
+
+EXE = $(FOAM_APPBIN)/foamUpgradeFvSolution
diff --git a/applications/utilities/preProcessing/foamUpgradeFvSolution/Make/options b/applications/utilities/preProcessing/foamUpgradeFvSolution/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/applications/utilities/preProcessing/foamUpgradeFvSolution/foamUpgradeFvSolution.C b/applications/utilities/preProcessing/foamUpgradeFvSolution/foamUpgradeFvSolution.C
new file mode 100644
index 0000000000000000000000000000000000000000..9128ad3d5c303e07c834288647538c0ac3775e14
--- /dev/null
+++ b/applications/utilities/preProcessing/foamUpgradeFvSolution/foamUpgradeFvSolution.C
@@ -0,0 +1,109 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Application
+    foamUpgradeFvSolution
+
+Description
+    Simple tool to upgrade the syntax of system/fvSolution::solvers
+
+Usage
+
+    - foamUpgradeFvSolution [OPTION]
+
+    @param -test \n
+    Suppress writing the updated fvSolution file
+
+\*---------------------------------------------------------------------------*/
+
+#include "argList.H"
+#include "Time.H"
+#include "IOdictionary.H"
+#include "solution.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Main program:
+
+int main(int argc, char *argv[])
+{
+    argList::noParallel();
+    argList::validOptions.insert("test", "");
+
+#   include "setRootCase.H"
+#   include "createTime.H"
+
+    IOdictionary solutionDict
+    (
+        IOobject
+        (
+            "fvSolution",
+            runTime.system(),
+            runTime,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE,
+            false
+        )
+    );
+
+    label nChanged = 0;
+    entry* e = solutionDict.lookupEntryPtr("solvers", false, false);
+    if (e && e->isDict())
+    {
+        nChanged = solution::upgradeSolverDict(e->dict(), true);
+    }
+
+    Info<< nChanged << " solver settings changed" << nl << endl;
+    if (nChanged)
+    {
+        if (args.options().found("test"))
+        {
+            Info<< "-test option: no changes made" << nl << endl;
+        }
+        else
+        {
+            mv
+            (
+                solutionDict.objectPath(),
+                solutionDict.objectPath() + ".old"
+            );
+
+            solutionDict.writeObject
+            (
+                IOstream::ASCII,
+                IOstream::currentVersion,
+                IOstream::UNCOMPRESSED
+            );
+
+            Info<< "Backup to    " << (solutionDict.objectPath() + ".old") << nl
+                << "Write  to    " << solutionDict.objectPath() << nl << endl;
+        }
+    }
+
+    return 0;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/preProcessing/mapFields/MapVolFields.H b/applications/utilities/preProcessing/mapFields/MapVolFields.H
index d72ae2948dec5f75fbf3b0749b5c54a608a2a08b..affbbb68f0793e0d91ce682c15959a6b5236330e 100644
--- a/applications/utilities/preProcessing/mapFields/MapVolFields.H
+++ b/applications/utilities/preProcessing/mapFields/MapVolFields.H
@@ -29,7 +29,6 @@ License
 
 #include "GeometricField.H"
 #include "meshToMesh.H"
-#include "cuttingPlane.H"
 #include "IOobjectList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C b/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C
index 8453d6f94a1458f58c1c5914a4842ede0a31b534..a8b2f980ca0ded1337e5e5a2450b745c1942ed9d 100644
--- a/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C
+++ b/applications/utilities/surface/surfaceCoordinateSystemTransform/surfaceCoordinateSystemTransform.C
@@ -199,7 +199,6 @@ int main(int argc, char *argv[])
         if (args.options().found("clean"))
         {
             surf.cleanup(true);
-            surf.checkOrientation(true);
         }
 
         if (fromCsys.valid())
diff --git a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
index a907c7208cb6cecbf82ec6382638215d90e90cd9..0f18b5ac86fbd9da0d551b577f69c078ffbb6b5f 100644
--- a/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
+++ b/applications/utilities/surface/surfaceMeshConvert/surfaceMeshConvert.C
@@ -104,13 +104,19 @@ int main(int argc, char *argv[])
     {
         triSurface surf(importName);
 
+        Info<< "Read surface:" << endl;
+        surf.writeStats(Info);
+        Info<< endl;
+
         if (args.options().found("clean"))
         {
+            Info<< "Cleaning up surface" << endl;
             surf.cleanup(true);
-            surf.checkOrientation(true);
+            surf.writeStats(Info);
+            Info<< endl;
         }
 
-        Info << "writing " << exportName;
+        Info<< "writing " << exportName;
         if (scaleFactor <= 0)
         {
             Info<< " without scaling" << endl;
@@ -119,6 +125,8 @@ int main(int argc, char *argv[])
         {
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
+            surf.writeStats(Info);
+            Info<< endl;
         }
 
         // write sorted by region
@@ -128,13 +136,19 @@ int main(int argc, char *argv[])
     {
         UnsortedMeshedSurface<face> surf(importName);
 
+        Info<< "Read surface:" << endl;
+        surf.writeStats(Info);
+        Info<< endl;
+
         if (args.options().found("clean"))
         {
+            Info<< "Cleaning up surface" << endl;
             surf.cleanup(true);
-            surf.checkOrientation(true);
+            surf.writeStats(Info);
+            Info<< endl;
         }
 
-        Info << "writing " << exportName;
+        Info<< "writing " << exportName;
         if (scaleFactor <= 0)
         {
             Info<< " without scaling" << endl;
@@ -143,8 +157,9 @@ int main(int argc, char *argv[])
         {
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
+            surf.writeStats(Info);
+            Info<< endl;
         }
-
         surf.write(exportName);
     }
 #if 1
@@ -152,10 +167,16 @@ int main(int argc, char *argv[])
     {
         MeshedSurface<triFace> surf(importName);
 
+        Info<< "Read surface:" << endl;
+        surf.writeStats(Info);
+        Info<< endl;
+
         if (args.options().found("clean"))
         {
+            Info<< "Cleaning up surface" << endl;
             surf.cleanup(true);
-            surf.checkOrientation(true);
+            surf.writeStats(Info);
+            Info<< endl;
         }
 
         Info<< "writing " << exportName;
@@ -167,6 +188,8 @@ int main(int argc, char *argv[])
         {
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
+            surf.writeStats(Info);
+            Info<< endl;
         }
         surf.write(exportName);
     }
@@ -175,10 +198,16 @@ int main(int argc, char *argv[])
     {
         MeshedSurface<face> surf(importName);
 
+        Info<< "Read surface:" << endl;
+        surf.writeStats(Info);
+        Info<< endl;
+
         if (args.options().found("clean"))
         {
+            Info<< "Cleaning up surface" << endl;
             surf.cleanup(true);
-            surf.checkOrientation(true);
+            surf.writeStats(Info);
+            Info<< endl;
         }
 
         Info<< "writing " << exportName;
@@ -190,6 +219,8 @@ int main(int argc, char *argv[])
         {
             Info<< " with scaling " << scaleFactor << endl;
             surf.scalePoints(scaleFactor);
+            surf.writeStats(Info);
+            Info<< endl;
         }
         surf.write(exportName);
     }
diff --git a/bin/doxyFilt b/bin/doxyFilt
index e2f8ee0a1e695d99b9fbd337763e108efbab1955..c08851c53e93fd75810468f8c93e3d93e52feb38 100755
--- a/bin/doxyFilt
+++ b/bin/doxyFilt
@@ -50,9 +50,9 @@ then
    */applications/solvers/*.C | */applications/utilities/*.C )
       awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-top.awk
       ;;
-   */applications/solvers/*.H | */applications/utilities/*.H )
-      awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-ignore.awk
-      ;;
+#   */applications/solvers/*.H | */applications/utilities/*.H )
+#      awkScript=$WM_PROJECT_DIR/bin/tools/doxyFilt-ignore.awk
+#      ;;
    esac
 
    awk -f $awkScript $1 | \
diff --git a/bin/foamCheckSourceDeps b/bin/foamCheckSourceDeps
deleted file mode 100755
index 5653f050d162fe41f2ffab142176f7f57501df12..0000000000000000000000000000000000000000
--- a/bin/foamCheckSourceDeps
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/bin/sh
-#------------------------------------------------------------------------------
-# =========                 |
-# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-#  \\    /   O peration     |
-#   \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-#    \\/     M anipulation  |
-#-------------------------------------------------------------------------------
-# License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software; you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by the
-#     Free Software Foundation; either version 2 of the License, or (at your
-#     option) any later version.
-#
-#     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-#     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-#     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM; if not, write to the Free Software Foundation,
-#     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-#
-# Script
-#     foamCheckSourceDeps
-#
-# Description
-#     Usage: foamCheckSourceDeps [dir1 .. dirN]
-#
-#     Search for *.dep files that are without a corresponding .C or .L file.
-#     These could indicate a directory that has been moved.
-#         - print questionable directory  and dep file
-#------------------------------------------------------------------------------
-if [ "$1" = "-h" -o "$1" = "-help" ]
-then
-   cat <<USAGE 1>&2
-Usage: ${0##*/} [dir1 .. dirN]
-
-    Search for .dep files that are without a corresponding .C or .L file.
-    This could indicate a directory that has been moved.
-        - print questionable directory and file
-USAGE
-   exit 1
-fi
-
-if [ "$#" -eq 0 ]
-then
-   set -- .
-fi
-
-for checkDir
-do
-   if [ -d $checkDir ]
-   then
-      find $checkDir -name '*.dep' -print | while read depFile;
-      do
-         Cfile=$(echo $depFile | sed -e 's/\.dep$/.C/')
-         # also check flex files
-         Lfile=$(echo $depFile | sed -e 's/\.C$/.L/')
-         if [ ! -f $Cfile -a ! -f $Lfile ]
-         then
-            echo "$(dirname $Cfile)  ${depFile##*/}"
-         fi
-      done
-   fi
-done
-
-# -----------------------------------------------------------------------------
diff --git a/bin/paraFoam b/bin/paraFoam
index 101bba1674e1867ee9ddad85f2acbef9b7cc34bc..4fc5c3cb9fdf8fe65ed74711f79e2816c8cd3532 100755
--- a/bin/paraFoam
+++ b/bin/paraFoam
@@ -31,19 +31,19 @@
 #
 #------------------------------------------------------------------------------
 usage() {
-   while [ "$#" -ge 1 ]; do echo "$1"; shift; done
-   cat<<USAGE
+    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+    cat<<USAGE
 
 usage: ${0##*/} [OPTION]
 options:
   -case   dir    specify alternative case directory
   -region name   specify mesh region name
-  -touch         create the .OpenFOAM file only and exit
+  -touch         only create the .OpenFOAM file
 
 * start paraview $ParaView_VERSION with the OpenFOAM libraries
 
 USAGE
-   exit 1
+    exit 1
 }
 
 unset regionName touchOnly
@@ -51,81 +51,83 @@ unset regionName touchOnly
 # parse options
 while [ "$#" -gt 0 ]
 do
-   case "$1" in
-   -h | -help)
-      usage
-      ;;
-   -case)
-      [ "$#" -ge 2 ] || usage "'-case' option requires an argument"
-      caseDir=$2
-      shift 2
-      cd "$caseDir" 2>/dev/null || usage "directory does not exist:  '$caseDir'"
-      ;;
-   -region)
-      [ "$#" -ge 2 ] || usage "'-region' option requires an argument"
-      regionName=$2
-      shift 2
-      ;;
-   -touch)
-      touchOnly=1
-      shift
-      ;;
-   *)
-      usage "unknown option/argument: '$*'"
-      ;;
-   esac
+    case "$1" in
+    -h | -help)
+        usage
+        ;;
+    -case)
+        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+        cd "$2" 2>/dev/null || usage "directory does not exist:  '$2'"
+        shift 2
+        ;;
+    -region)
+        [ "$#" -ge 2 ] || usage "'$1' option requires an argument"
+        regionName=$2
+        shift 2
+        ;;
+    -touch)
+        touchOnly=true
+        shift
+        ;;
+    *)
+        usage "unknown option/argument: '$*'"
+        ;;
+    esac
 done
 
 # get a sensible caseName
 caseName=${PWD##*/}
 caseFile="$caseName.OpenFOAM"
+fvControls="system"
+
 if [ -n "$regionName" ]
 then
-   caseFile="$caseName{$regionName}.OpenFOAM"
+    caseFile="$caseName{$regionName}.OpenFOAM"
+    fvControls="$fvControls/$regionName"
 fi
 
-if [ -n "$touchOnly" ];
+if [ -n "$touchOnly" ]
 then
-   touch "$caseFile"
-   echo "created '$caseFile'"
-   exit 0
+    touch "$caseFile"
+    echo "created '$caseFile'"
+    exit 0
 fi
 
 # parent directory for normal or parallel results
 case "$caseName" in
-   processor*) parentDir=".." ;;
-   *)          parentDir="."  ;;
+    processor*) parentDir=".." ;;
+    *)          parentDir="."  ;;
 esac
 
 # check existence of essential files
-for check in system/controlDict system/fvSchemes system/fvSolution
+for check in system/controlDict $fvControls/fvSchemes $fvControls/fvSolution
 do
-   [ -s "$parentDir/$check" ] || usage "file does not exist:  '$parentDir/$check'"
+    [ -s "$parentDir/$check" ] || usage "file does not exist:  '$parentDir/$check'"
 done
 
 
 case "$ParaView_VERSION" in
 2*)
-   trap "rm -f paraFoam.pvs $caseFile 2>/dev/null; exit 0" EXIT TERM INT
-   touch $caseFile
+    trap "rm -f paraFoam.pvs $caseFile 2>/dev/null; exit 0" EXIT TERM INT
+    touch "$caseFile"
 
-   # since we are now in the cwd, %CASE% is '$PWD/$caseFile'
-   sed -e s@%CASE%@$PWD/$caseFile@g \
-       $WM_PROJECT_DIR/bin/paraFoam.pvs > paraFoam.pvs
+    # since we are now in the cwd, %CASE% is '$PWD/$caseFile'
+    sed -e s@%CASE%@$PWD/$caseFile@g \
+        $WM_PROJECT_DIR/bin/tools/paraFoam.pvs > paraFoam.pvs
 
-   paraview paraFoam.pvs
-   ;;
+    paraview paraFoam.pvs
+    ;;
 
 *)
-   # only create/remove caseFile if it doesn't exist
-   [ -e $caseFile ] || {
-      trap "rm -f $caseFile 2>/dev/null; exit 0" EXIT TERM INT
-      touch "$caseFile"
-      echo "created temporary '$caseFile'"
-   }
-
-   paraview --data="$caseFile"
-   ;;
+    # only create/remove caseFile if it didn't already exist
+    [ -e $caseFile ] || {
+        trap "rm -f $caseFile 2>/dev/null; exit 0" EXIT TERM INT
+        touch "$caseFile"
+        echo "created temporary '$caseFile'"
+    }
+
+    paraview --data="$caseFile"
+    ;;
 
 esac
 #------------------------------------------------------------------------------
diff --git a/bin/rmdepold b/bin/rmdepold
new file mode 100755
index 0000000000000000000000000000000000000000..72123a3cce769bee1123311432715f1d27df25fb
--- /dev/null
+++ b/bin/rmdepold
@@ -0,0 +1,109 @@
+#!/bin/sh
+#------------------------------------------------------------------------------
+# =========                 |
+# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+#  \\    /   O peration     |
+#   \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+#    \\/     M anipulation  |
+#-------------------------------------------------------------------------------
+# License
+#     This file is part of OpenFOAM.
+#
+#     OpenFOAM is free software; you can redistribute it and/or modify it
+#     under the terms of the GNU General Public License as published by the
+#     Free Software Foundation; either version 2 of the License, or (at your
+#     option) any later version.
+#
+#     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+#     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#     for more details.
+#
+#     You should have received a copy of the GNU General Public License
+#     along with OpenFOAM; if not, write to the Free Software Foundation,
+#     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Script
+#     rmdepold
+#
+# Description
+#     Usage: rmdepold [dir1 .. dirN]
+#
+#     Remove *.dep files that are without a corresponding .C or .L file.
+#     This often occurs when a directory has been moved.
+#         - print questionable directory and the *.dep file
+#         - optionally remove empty directories
+#------------------------------------------------------------------------------
+usage() {
+    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+    cat<<USAGE 1>&2
+Usage: ${0##*/} [OPTION] [dir1 .. dirN]
+options:
+  -rmdir      find and remove empty directories (recursively)
+
+Remove *.dep files that are without a corresponding .C or .L file.
+This often occurs when a directory has been moved.
+  - print questionable directory and file
+  - optionally remove empty directories
+
+USAGE
+    exit 1
+}
+
+unset optRmdir
+
+# parse options
+while [ "$#" -gt 0 ]
+do
+    case "$1" in
+    -h | -help)
+        usage
+        ;;
+    -rmdir)
+        optRmdir=true
+        shift
+        ;;
+    -*)
+       usage "unknown option: '$*'"
+       ;;
+    *)
+       break
+       ;;
+    esac
+done
+
+# default is the current directory
+[ "$#" -gt 0 ] || set -- .
+
+for checkDir
+do
+    if [ -d $checkDir ]
+    then
+        echo "searching: $checkDir"
+    else
+        echo "skipping non-dir: $checkDir"
+        continue
+    fi
+
+    find $checkDir -name '*.dep' -print | while read depFile
+    do
+        # check C++ and Flex files
+        if [ ! -r "${depFile%dep}C" -a ! -r "${depFile%dep}L" ];
+        then
+            echo "rm $depFile"
+            rm -f $depFile 2>/dev/null
+        fi
+    done
+
+    # remove empty dirs
+    if [ "$optRmdir" ]
+    then
+        # get subdirs ourselves so we can avoid particular directories
+        for dir in $(find $checkDir -mindepth 1 -maxdepth 1 -type d \( -name .git -prune -o -print \) )
+        do
+            echo "check dir: $dir"
+            find $dir -depth -type d -empty -exec rmdir {} \; -print
+        done
+    fi
+done
+# -----------------------------------------------------------------------------
diff --git a/bin/tools/README b/bin/tools/README
index c99723b20e19efb63e6e9dff7a312d9885a55edb..2b98a9702f3ad030ab7fb44f8075142abe3daa1b 100644
--- a/bin/tools/README
+++ b/bin/tools/README
@@ -1,2 +1,2 @@
-Misc. tools for building applications, etc that are useful to have
-but which don't really need to be in the PATH.
+Misc. tools, scripts, templates that are useful (eg, for building applications)
+but don't need to be in the PATH.
diff --git a/bin/paraFoam.pvs b/bin/tools/paraFoam.pvs
similarity index 100%
rename from bin/paraFoam.pvs
rename to bin/tools/paraFoam.pvs
diff --git a/doc/Doxygen/Doxyfile b/doc/Doxygen/Doxyfile
index f5ab1204243274fe5fd6471ea8031c14dee007ac..908fa543b949ae68c460d8d72c29cf91f7c190b2 100644
--- a/doc/Doxygen/Doxyfile
+++ b/doc/Doxygen/Doxyfile
@@ -538,6 +538,7 @@ EXCLUDE_SYMBOLS        =
 
 EXAMPLE_PATH           =
 
+
 # If the value of the EXAMPLE_PATH tag contains directories, you can use the
 # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
 # and *.h) to filter out the source-files in the directories. If left
@@ -787,6 +788,10 @@ TREEVIEW_WIDTH         = 250
 # configuration options related to the LaTeX output
 #---------------------------------------------------------------------------
 
+# Path for OpenCFD LaTeX macros
+
+@INCLUDE_PATH = $(WM_PROJECT_DIR)/doc/Doxygen/Macros/
+
 # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
 # generate Latex output.
 
@@ -824,7 +829,7 @@ PAPER_TYPE             = a4wide
 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
 # packages that should be included in the LaTeX output.
 
-EXTRA_PACKAGES         =
+EXTRA_PACKAGES         = $(WM_PROJECT_DIR)/doc/Doxygen/Macros/tensorOperator
 
 # The LATEX_HEADER tag can be used to specify a personal LaTeX header for
 # the generated latex document. The header should contain everything until
diff --git a/doc/Doxygen/Macros/tensorOperator.sty b/doc/Doxygen/Macros/tensorOperator.sty
new file mode 100644
index 0000000000000000000000000000000000000000..2b027493a8fb696d2cee1396c72d586841622aff
--- /dev/null
+++ b/doc/Doxygen/Macros/tensorOperator.sty
@@ -0,0 +1,129 @@
+%-----------------------------------------------------------------------------
+% =========                 |
+% \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+%  \\    /   O peration     |
+%   \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+%    \\/     M anipulation  |
+%------------------------------------------------------------------------------
+% License
+%     This file is part of OpenFOAM.
+%
+%     OpenFOAM is free software; you can redistribute it and/or modify it
+%     under the terms of the GNU General Public License as published by the
+%     Free Software Foundation; either version 2 of the License, or (at your
+%     option) any later version.
+%
+%     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+%     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+%     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+%     for more details.
+%
+%     You should have received a copy of the GNU General Public License
+%     along with OpenFOAM; if not, write to the Free Software Foundation,
+%     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+%
+% LaTeX Style file
+%     tensorOperator.sty
+%
+% Description
+%     Standard OpenCFD LaTeX macros for typesetting tensor algebra.
+%
+%------------------------------------------------------------------------------
+
+% tensor style
+% ~~~~~~~~~~~~
+\renewcommand{\vec}[1] {\ensuremath{\mathbf #1}}
+\newcommand{\gvec}[1] {\ensuremath{\mbox{\boldmath$\bf#1$}}}
+
+% products
+% ~~~~~~~~
+\newcommand{\anyprod}{\star}
+\newcommand{\cprod} {\times}
+\newcommand{\dprod} {\,{\scriptscriptstyle \stackrel{\bullet}{{}}}\,}
+\newcommand{\ddprod} {\,{\scriptscriptstyle \stackrel{\bullet}{\bullet}}\,}
+\newcommand{\tdprod} {\,{\scriptscriptstyle \stackrel{3}{\bullet}}\,}
+\newcommand{\tprod} {\,{\scriptscriptstyle \stackrel{\otimes}{{}}}\,}
+
+% operations
+% ~~~~~~~~~~
+\newcommand{\adj} {\ensuremath{\operatorname{adj}}}
+\newcommand{\cof} {\ensuremath{\operatorname{cof}}}
+\newcommand{\diag} {\ensuremath{\operatorname{diag}}}
+\newcommand{\dev} {\ensuremath{\operatorname{dev}}}
+
+\newcommand{\Hodge} {\ensuremath{\operatorname{\stackrel{\displaystyle \ast}{}}}}
+\newcommand{\hyd} {\ensuremath{\operatorname{hyd}}}
+\renewcommand{\max} {\ensuremath{\operatorname{max}}}
+\renewcommand{\min} {\ensuremath{\operatorname{min}}}
+\newcommand{\inv} {\ensuremath{\operatorname{inv}}}
+\newcommand{\sym} {\ensuremath{\operatorname{symm}}}    % symm ?
+\newcommand{\skw} {\ensuremath{\operatorname{skew}}}    % skew already defined
+\newcommand{\tr} {\ensuremath{\operatorname{tr}}}
+\newcommand{\trans}[1] {\ensuremath{#1^{\operatorname{T}}}}
+
+% alternative tensor operators for hypersonics etc.
+% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+\newcommand{\devs}[1] {\overset{\scriptscriptstyle\circ}{#1}}
+%\newcommand{\trans}[1] {\ensuremath{#1^{\operatorname{T}}}}
+\newcommand{\symms}[1] {\overleftrightarrow{#1}}
+\newlength{\skewslength}
+\newlength{\skewsheight}
+\newcommand{\skews}[1]{
+    \settowidth{\skewslength}{#1}%
+    \settoheight{\skewsheight}{#1}%
+    \addtolength{\skewsheight}{0.4mm}%
+    {\overleftrightarrow{#1}\hspace{-.5\skewslength}%
+    \rule[\skewsheight]{.4pt}{1.4mm}
+    \hspace{.5\skewslength}%
+}}
+%\newcommand{\skew}[1] {\ensuremath{#1^{\operatorname{A}}}}
+
+% spatial derivatives
+% ~~~~~~~~~~~~~~~~~~~
+\newcommand{\curl}{\ensuremath{\nabla\cprod}}
+\renewcommand{\div} {\ensuremath{\nabla\dprod}}
+\newcommand{\grad}{\ensuremath{\nabla}}
+\newcommand{\laplacian}{\ensuremath{\nabla^{2}}}
+
+% temporal derivatives
+% ~~~~~~~~~~~~~~~~~~~~
+\newcommand{\ddt}[1] {\ensuremath{\frac{\partial #1}{\partial t }}}
+\newcommand{\DDt}[1] {\ensuremath{\frac{D #1}{D t}}}
+\newcommand{\DpDt}[2] {\ensuremath{\frac{d_{#1} #2}{d t }}}
+\newcommand{\dsdts}[1] {\ensuremath{\frac{\partial ^2 #1}{\partial t^2}}}
+\newcommand{\rate}[1] {\ensuremath{\dot{#1}}}
+
+\newcommand{\genDer}{\mathcal{L}}
+
+% time average symbols
+% ~~~~~~~~~~~~~~~~~~~~
+\newcommand{\av}[1] {\ensuremath{\overline{#1}}}
+\newcommand{\corrtwo}[2] {{\dwea{\dprime{#1} \dprime{#2}}}}
+\newcommand{\curly}[1] {{\cal #1}}
+\newcommand{\dprime}[1] {\ensuremath{{#1}^{^{\prime \prime}}}}
+\newcommand{\dwea}[1] {\ensuremath{\widetilde{#1}}}
+\newcommand{\dweafluc}[1] {\ensuremath{\dprime{#1}}}
+\newcommand{\fluc}[1] {\ensuremath{#1^{\prime}}}
+
+% index style
+% ~~~~~~~~~~~
+\newcommand{\veci}[2][i] {\ensuremath{#2_{#1}}}
+\newcommand{\teni}[2][ij] {\ensuremath{#2_{#1}}}
+\newcommand{\tenTi}[2][ji] {\ensuremath{#2_{#1}}}
+
+% index operations
+% ~~~~~~~~~~~~~~~~
+\newcommand{\deltai}[1] {\ensuremath{\partial_{#1}}}
+
+% Sub-subscripts
+% ~~~~~~~~~~~~~~
+\newcommand{\eff} {{\scriptscriptstyle e\!f\!\!f\!}}
+
+% unknown use
+% ~~~~~~~~~~~
+%\font\bigtenrm=cmr12 scaled 1200
+%\newcommand{\eexp}[1]{{\hbox{$\textfont1=\bigtenrm e$}}^{\raise3pt
+%\hbox{$#1$}}}
+
+
+% ------------------------------------------------------------------------------
diff --git a/etc/settings.csh b/etc/settings.csh
index 2c9a0eb656fccab2fb84d0de0004ca4ce24997d7..4bcf3eb5108e9aa5c54695574a8333ab510b065c 100644
--- a/etc/settings.csh
+++ b/etc/settings.csh
@@ -187,7 +187,7 @@ case MPICH-GM:
     setenv FOAM_MPI_LIBBIN $FOAM_LIBBIN/mpich-gm
     breaksw
 
-case MPICH-GM:
+case HPMPI:
     setenv MPI_HOME /opt/hpmpi
     setenv MPI_ARCH_PATH $MPI_HOME
     setenv MPICH_ROOT=$MPI_ARCH_PATH
diff --git a/src/OSspecific/Unix/Make/files b/src/OSspecific/Unix/Make/files
index 39c40b74c4353254e30ea7c50502dcd62e4da309..f83513ac4ac08d08f96d8cdbce23005b58c63584 100644
--- a/src/OSspecific/Unix/Make/files
+++ b/src/OSspecific/Unix/Make/files
@@ -2,6 +2,7 @@ signals/sigFpe.C
 signals/sigSegv.C
 signals/sigInt.C
 signals/sigQuit.C
+regExp.C
 timer.C
 fileStat.C
 Unix.C
diff --git a/src/OSspecific/Unix/regExp.C b/src/OSspecific/Unix/regExp.C
new file mode 100644
index 0000000000000000000000000000000000000000..62c69512b712f65639008e14bac85a3b2c8d8b96
--- /dev/null
+++ b/src/OSspecific/Unix/regExp.C
@@ -0,0 +1,196 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include <sys/types.h>
+#include "regExp.H"
+#include "label.H"
+#include "string.H"
+#include "List.H"
+#include "IOstreams.H"
+
+
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+void Foam::regExp::compile(const char* pat) const
+{
+    clear();
+    preg_ = new regex_t;
+
+    if (regcomp(preg_, pat, REG_EXTENDED) != 0)
+    {
+        FatalErrorIn
+        (
+            "regExp::compile(const char*)"
+        )   << "Failed to compile regular expression '" << pat << "'"
+            << exit(FatalError);
+    }
+}
+
+
+void Foam::regExp::clear() const
+{
+    if (preg_)
+    {
+        regfree(preg_);
+        delete preg_;
+        preg_ = 0;
+    }
+}
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::regExp::regExp()
+:
+    preg_(0)
+{}
+
+
+Foam::regExp::regExp(const string& pat)
+:
+    preg_(0)
+{
+    compile(pat.c_str());
+}
+
+
+Foam::regExp::regExp(const char* pat)
+:
+    preg_(0)
+{
+    compile(pat);
+}
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::regExp::~regExp()
+{
+    clear();
+}
+
+// * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * * //
+
+int Foam::regExp::ngroups() const
+{
+    return preg_ ? preg_->re_nsub : 0;
+}
+
+
+bool Foam::regExp::match
+(
+    const string& str,
+    bool partialMatch
+) const
+{
+    if (preg_ && str.size())
+    {
+        size_t nmatch = 1;
+        regmatch_t pmatch[1];
+
+        // match and also verify that the entire string was matched
+        if
+        (
+            regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0
+         &&
+            (
+                partialMatch
+             || (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size()))
+            )
+        )
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+bool Foam::regExp::match
+(
+    const string& str,
+    List<string>& groups,
+    bool partialMatch
+) const
+{
+    if (preg_ && str.size())
+    {
+        size_t nmatch = ngroups() + 1;
+        regmatch_t pmatch[nmatch];
+
+        // match and also verify that the entire string was matched
+        if
+        (
+            regexec(preg_, str.c_str(), nmatch, pmatch, 0) == 0
+         &&
+            (
+                partialMatch
+             || (pmatch[0].rm_so == 0 && pmatch[0].rm_eo == label(str.size()))
+            )
+        )
+        {
+            groups.setSize(ngroups());
+            label groupI = 0;
+
+            for (size_t matchI = 1; matchI < nmatch; matchI++)
+            {
+                if (pmatch[matchI].rm_so != -1 && pmatch[matchI].rm_eo != -1)
+                {
+                    groups[groupI] = str.substr
+                    (
+                        pmatch[matchI].rm_so,
+                        pmatch[matchI].rm_eo - pmatch[matchI].rm_so
+                    );
+                }
+                else
+                {
+                    groups[groupI].clear();
+                }
+                groupI++;
+            }
+
+            return true;
+        }
+    }
+
+    groups.clear();
+    return false;
+}
+
+// * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * * //
+
+
+void Foam::regExp::operator=(const string& pat)
+{
+    compile(pat.c_str());
+}
+
+
+void Foam::regExp::operator=(const char* pat)
+{
+    compile(pat);
+}
+
+// ************************************************************************* //
diff --git a/src/OSspecific/Unix/regularExpression.H b/src/OSspecific/Unix/regExp.H
similarity index 56%
rename from src/OSspecific/Unix/regularExpression.H
rename to src/OSspecific/Unix/regExp.H
index 9924caef28fb7ecec52a9d272a91aa3328b8e6ba..60ac68a3c2742183dd0e54238c2b27a0cec38b7d 100644
--- a/src/OSspecific/Unix/regularExpression.H
+++ b/src/OSspecific/Unix/regExp.H
@@ -23,19 +23,26 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::regularExpression
+    Foam::regExp
 
 Description
-    Wrapper around regular expressions.
+    Wrapper around POSIX extended regular expressions.
+
+    The beginning-of-line (^) and the end-of-line ($) anchors are implicit
+    by default.
+
+SeeAlso
+    The manpage regex(7) for more information about POSIX regular expressions.
+    These differ somewhat from @c Perl and @c sed regular expressions.
 
 SourceFiles
+    regExp.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef regularExpression_H
-#define regularExpression_H
+#ifndef regExp_H
+#define regExp_H
 
-#include <sys/types.h>
 #include <regex.h>
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -43,70 +50,81 @@ SourceFiles
 namespace Foam
 {
 
+// Forward declaration of classes
+class string;
+template<class T> class List;
+
 /*---------------------------------------------------------------------------*\
-                           Class regularExpression Declaration
+                          Class regExp Declaration
 \*---------------------------------------------------------------------------*/
 
-class regularExpression
+class regExp
 {
     // Private data
 
         //- Precompiled regular expression
-        regex_t* preg_;
-
+        mutable regex_t* preg_;
 
     // Private member functions
 
+        //- release allocated space
+        void clear() const;
+
+        //- compile into a regular expression
+        void compile(const char*) const;
+
         //- Disallow default bitwise copy construct
-        regularExpression(const regularExpression&);
+        regExp(const regExp&);
 
         //- Disallow default bitwise assignment
-        void operator=(const regularExpression&);
+        void operator=(const regExp&);
 
 public:
 
-
     // Constructors
 
-        //- Construct from string
-        inline regularExpression(const string& s)
-        {
-            preg_ = new regex_t;
+        //- Construct null
+        regExp();
 
-            if (regcomp(preg_, s.c_str(), REG_EXTENDED|REG_NOSUB) != 0)
-            {
-                FatalErrorIn
-                (
-                    "regularExpression::regularExpression(const char*)"
-                )   << "Failed to compile regular expression " << s
-                    << exit(FatalError);
-            }
-        }
+        //- Construct from string
+        regExp(const string&);
 
+        //- Construct from character array
+        regExp(const char*);
 
     // Destructor
 
-        //- Construct from string
-        inline ~regularExpression()
-        {
-            if (preg_)
-            {
-                regfree(preg_);
-                delete preg_;
-            }
-        }
-
+        ~regExp();
 
     // Member functions
 
-        //- Matches?
-        inline bool matches(const string& s) const
-        {
-            size_t nmatch = 0;
-            regmatch_t *pmatch = NULL;
+        //- Return the number of (groups)
+        int ngroups() const;
+
+        //- Return true if it matches, partial matches are optional
+        bool match
+        (
+            const string&,
+            bool partialMatch=false
+        ) const;
+
+        //- Return true if it matches and sets the sub-groups matched,
+        //  partial matches are optional
+        bool match
+        (
+            const string&,
+            List<string>& groups,
+            bool partialMatch=false
+        ) const;
+
+    // Member Operators
+
+        //- Assign from a string
+        void operator=(const string&);
+
+        //- Assign from a character array
+        void operator=(const char*);
 
-            return regexec(preg_, s.c_str(), nmatch, pmatch, 0) == 0;
-        }
 };
 
 
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C
index 24d1edea53c7311d316d6ec47ac7b0457c2b9b68..96159327c10b99f92072dbb2c66d8f9c0468ea97 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.C
@@ -28,23 +28,23 @@ License
 
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
 
-// Construct from Istream
+
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList(Istream& is)
 :
     List<T>(is),
-    allocSize_(List<T>::size())
+    capacity_(List<T>::size())
 {}
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 Foam::Ostream& Foam::operator<<
 (
-    Foam::Ostream& os,
-    const Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& DL
+    Ostream& os,
+    const DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
 )
 {
-    os << static_cast<const List<T>&>(DL);
+    os << static_cast<const List<T>&>(lst);
     return os;
 }
 
@@ -52,12 +52,12 @@ Foam::Ostream& Foam::operator<<
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 Foam::Istream& Foam::operator>>
 (
-    Foam::Istream& is,
-    Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>& DL
+    Istream& is,
+    DynamicList<T, SizeInc, SizeMult, SizeDiv>& lst
 )
 {
-    is >> static_cast<List<T>&>(DL);
-    DL.allocSize_ = DL.List<T>::size();
+    is >> static_cast<List<T>&>(lst);
+    lst.capacity_ = lst.List<T>::size();
 
     return is;
 }
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
index 214c78062007abfc5957b480afa3b6d3b5f2203b..847b94f647ceec49c1efd613b08acd6e5d24833e 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicList.H
@@ -32,7 +32,7 @@ Description
     Internal storage is a compact array and the list can be shrunk to compact
     storage. The increase of list size is controlled by three template
     parameters, which allows the list storage to either increase by the given
-    increment or the given multiplier and divider (allowing non-integer
+    increment or by the given multiplier and divider (allowing non-integer
     multiples).
 
 SourceFiles
@@ -81,14 +81,11 @@ class DynamicList
 {
     // Private data
 
-        //- Allocated size for underlying List.
-        label allocSize_;
+        //- The capacity (allocated size) of the underlying list.
+        label capacity_;
 
     // Private Member Functions
 
-        // Disabled, since the usefulness and semantics are not quite clear
-        void setSize(const label, const T&);
-
 public:
 
     // Related types
@@ -116,20 +113,30 @@ public:
         // Access
 
         //- Size of the underlying storage.
-        inline label allocSize() const;
-
+        inline label capacity() const;
 
         // Edit
 
-        //- Alter the list size.
-        //  When the new size is greater than the addressed list size, the
-        //  allocated list sizes is adjusted and the
-        //  addressed size does not change.
-        //  Otherwise the addressed list size is just reduced and the
-        //  allocated size does not change.
+        //- Alter the size of the underlying storage.
+        //  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);
+
+        //- 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);
 
-        //- Clear the list, i.e. set the size to zero.
+        //- Alter the addressed list size and fill new space with a constant.
+        inline void setSize(const label, const T&);
+
+        //- Reserve allocation space for at least this size.
+        //  Never shrinks the allocated size, use setCapacity() for that.
+        inline void reserve(const label);
+
+        //- Clear the addressed list, i.e. set the size to zero.
         //  Allocated size does not change
         inline void clear();
 
@@ -152,6 +159,9 @@ public:
         //- Append an element at the end of the list
         inline void append(const T& e);
 
+        //- Append a List at the end of this list
+        inline void append(const UList<T>&);
+
         //- Remove and return the top element
         inline T remove();
 
@@ -162,7 +172,7 @@ public:
         inline void operator=(const T&);
 
         //- Assignment from List<T>. Also handles assignment from DynamicList.
-        inline void operator=(const List<T>&);
+        inline void operator=(const UList<T>&);
 
 
     // IOstream operators
diff --git a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
index 1a40bdd0acd08f25e4acd25c3e60640d59a4ad72..1f7b8d40438c4f25324660add5af1c5158c9c7a7 100644
--- a/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
+++ b/src/OpenFOAM/containers/Lists/DynamicList/DynamicListI.H
@@ -30,7 +30,7 @@ template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
 :
     List<T>(SizeInc),
-    allocSize_(SizeInc)
+    capacity_(SizeInc)
 {
     List<T>::size(0);
 }
@@ -39,11 +39,11 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList()
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
 (
-    const label s
+    const label nElem
 )
 :
-    List<T>(s),
-    allocSize_(s)
+    List<T>(nElem),
+    capacity_(nElem)
 {
     List<T>::size(0);
 }
@@ -56,39 +56,101 @@ inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::DynamicList
 )
 :
     List<T>(lst),
-    allocSize_(lst.size())
+    capacity_(lst.size())
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-inline Foam::label Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::allocSize()
+inline Foam::label Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::capacity()
 const
 {
-    return allocSize_;
+    return capacity_;
 }
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
+inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setCapacity
 (
-    const label s
+    const label nElem
 )
 {
     label nextFree = List<T>::size();
-    if (s <= nextFree)
+    capacity_ = nElem;
+
+    if (nextFree > capacity_)
     {
-        // adjust addressed size, leave allocated size untouched
-        nextFree = s;
+        // truncate addressed sizes too
+        nextFree = capacity_;
     }
-    else
+
+    List<T>::setSize(capacity_);
+    List<T>::size(nextFree);
+}
+
+
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::reserve
+(
+    const label nElem
+)
+{
+    // allocate more capacity?
+    if (nElem > capacity_)
     {
+        capacity_ = max
+        (
+            nElem,
+            label(SizeInc + capacity_ * SizeMult / SizeDiv)
+        );
+
         // adjust allocated size, leave addressed size untouched
-        allocSize_ = s;
-        List<T>::setSize(allocSize_);
+        label nextFree = List<T>::size();
+        List<T>::setSize(capacity_);
+        List<T>::size(nextFree);
+    }
+}
+
+
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
+(
+    const label nElem
+)
+{
+    // allocate more capacity?
+    if (nElem > capacity_)
+    {
+        capacity_ = max
+        (
+            nElem,
+            label(SizeInc + capacity_ * SizeMult / SizeDiv)
+        );
+
+        List<T>::setSize(capacity_);
+    }
+
+    // adjust addressed size
+    List<T>::size(nElem);
+}
+
+
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::setSize
+(
+    const label nElem,
+    const T& t
+)
+{
+    label nextFree = List<T>::size();
+    setSize(nElem);
+
+    // set new elements to constant value
+    while (nextFree < nElem)
+    {
+        this->operator[](nextFree++) = t;
     }
-    List<T>::size(nextFree);
 }
 
 
@@ -103,7 +165,7 @@ template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::clearStorage()
 {
     List<T>::clear();
-    allocSize_ = 0;
+    capacity_ = 0;
 }
 
 
@@ -111,13 +173,15 @@ template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>&
 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::shrink()
 {
-    if (allocSize_ > List<T>::size())
+    label nextFree = List<T>::size();
+    if (capacity_ > nextFree)
     {
-        allocSize_ = List<T>::size();
-        // force re-allocation/copying in List<T>::setSize() by temporarily
-        // faking a larger list size that will be truncated
-        List<T>::size(allocSize_+1);
-        List<T>::setSize(allocSize_);
+        // use the full list when resizing
+        List<T>::size(capacity_);
+        // the new size
+        capacity_ = nextFree;
+        List<T>::setSize(capacity_);
+        List<T>::size(nextFree);
     }
     return *this;
 }
@@ -127,7 +191,7 @@ template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline void
 Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer(List<T>& lst)
 {
-    allocSize_ = lst.size();
+    capacity_ = lst.size();
     List<T>::transfer(lst);   // take over storage, clear addressing for lst.
 }
 
@@ -140,41 +204,58 @@ Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::transfer
 )
 {
     // take over storage as-is (without shrink), clear addressing for lst.
-    allocSize_ = lst.allocSize_;
-    lst.allocSize_ = 0;
+    capacity_ = lst.capacity_;
+    lst.capacity_ = 0;
 
     List<T>::transfer(static_cast<List<T>&>(lst));
 }
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
-inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append(const T& e)
+inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
+(
+    const T& t
+)
 {
-    // Work on copy free index since gets overwritten by setSize
-    label nextFree = List<T>::size();
+    label elemI = List<T>::size();
+    setSize(elemI + 1);
+
+    this->operator[](elemI) = t;
+}
 
-    nextFree++;
 
-    if (nextFree > allocSize_)
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::append
+(
+    const UList<T>& lst
+)
+{
+    label nextFree = List<T>::size();
+
+    if (this == &lst)
     {
-        allocSize_ = max
+        FatalErrorIn
         (
-            nextFree,
-            label(SizeMult*allocSize_/SizeDiv + SizeInc)
-        );
-        List<T>::setSize(allocSize_);
+            "DynamicList<T, SizeInc, SizeMult, SizeDiv>::append"
+            "(const UList<T>&)"
+        )   << "attempted appending to self" << abort(FatalError);
     }
 
-    List<T>::size(nextFree);
+    setSize(nextFree + lst.size());
 
-    this->operator[](nextFree - 1) = e;
+    forAll(lst, elemI)
+    {
+        this->operator[](nextFree++) = lst[elemI];
+    }
 }
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()
 {
-    if (List<T>::size() == 0)
+    label elemI = List<T>::size() - 1;
+
+    if (elemI < 0)
     {
         FatalErrorIn
         (
@@ -182,11 +263,9 @@ inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()
         )   << "List is empty" << abort(FatalError);
     }
 
-    label nextFree = List<T>::size()-1;
+    const T& val = List<T>::operator[](elemI);
 
-    const T& val = List<T>::operator[](nextFree);
-
-    List<T>::size(nextFree);
+    List<T>::size(elemI);
 
     return val;
 }
@@ -197,26 +276,15 @@ inline T Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::remove()
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline T& Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator()
 (
-    const label i
+    const label elemI
 )
 {
-    label nextFree = List<T>::size();
-
-    nextFree = max(nextFree, i + 1);
-
-    if (nextFree > allocSize_)
+    if (elemI >= List<T>::size())
     {
-        allocSize_ = max
-        (
-            nextFree,
-            label(SizeMult*allocSize_/SizeDiv + SizeInc)
-        );
-        List<T>::setSize(allocSize_);
+        setSize(elemI + 1);
     }
 
-    List<T>::size(nextFree);
-
-    return this->operator[](i);
+    return this->operator[](elemI);
 }
 
 
@@ -226,21 +294,39 @@ inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
     const T& t
 )
 {
-    List<T>::operator=(t);
+    UList<T>::operator=(t);
 }
 
 
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
 inline void Foam::DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator=
 (
-    const List<T>& lst
+    const UList<T>& lst
 )
 {
-    // make the entire storage available for the copy operation:
-    List<T>::size(allocSize_);
+    if (this == &lst)
+    {
+        FatalErrorIn
+        (
+            "DynamicList<T, SizeInc, SizeMult, SizeDiv>::operator="
+            "(const UList<T>&)"
+        )   << "attempted assignment to self" << abort(FatalError);
+    }
+
+    if (capacity_ >= lst.size())
+    {
+        // can copy w/o reallocating, match initial size to avoid reallocation
+        List<T>::size(lst.size());
+        List<T>::operator=(lst);
+    }
+    else
+    {
+        // make everything available for the copy operation
+        List<T>::size(capacity_);
 
-    List<T>::operator=(lst);
-    allocSize_ = List<T>::size();
+        List<T>::operator=(lst);
+        capacity_ = List<T>::size();
+    }
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.C b/src/OpenFOAM/containers/Lists/List/List.C
index 5d6c1608f726ea54a9c00c4998d8b612c3194d8b..83f3464ccae7ddb22f921bba296711b30e9b22d1 100644
--- a/src/OpenFOAM/containers/Lists/List/List.C
+++ b/src/OpenFOAM/containers/Lists/List/List.C
@@ -432,14 +432,19 @@ void Foam::List<T>::transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>& a)
 {
     // shrink the allocated space to the number of elements used
     a.shrink();
+    transfer(static_cast<List<T>&>(a));
+    a.clearStorage();
+}
 
-    if (this->v_) delete[] this->v_;
-    this->size_ = a.size_;
-    this->v_ = a.v_;
 
-    a.size_ = 0;
-    a.v_ = 0;
-    a.allocSize_ = 0;
+// Transfer the contents of the argument SortableList into this List
+// and anull the argument list
+template<class T>
+void Foam::List<T>::transfer(SortableList<T>& a)
+{
+    // shrink away the sort indices
+    a.shrink();
+    transfer(static_cast<List<T>&>(a));
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/List/List.H b/src/OpenFOAM/containers/Lists/List/List.H
index 4f51878d454edac1b47e9a0ec5f48fa303a8a6b8..c3fada1d6217f48709a74ee499ae7424ac910093 100644
--- a/src/OpenFOAM/containers/Lists/List/List.H
+++ b/src/OpenFOAM/containers/Lists/List/List.H
@@ -63,7 +63,8 @@ template<class T, label Size> class FixedList;
 template<class T> class PtrList;
 template<class T> class SLList;
 template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
- class DynamicList;
+    class DynamicList;
+template<class T> class SortableList;
 template<class T> class IndirectList;
 template<class T> class BiIndirectList;
 
@@ -173,6 +174,10 @@ public:
             template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
             void transfer(DynamicList<T, SizeInc, SizeMult, SizeDiv>&);
 
+            //- Transfer the contents of the argument List into this List
+            //  and annull the argument list.
+            void transfer(SortableList<T>&);
+
             //- Return subscript-checked element of UList.
             inline T& newElmt(const label);
 
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
index 889dd57d7eb3a6e56feb1e820862f69b0ddf28c7..67135f957ca4e002ce4d166b6ec6d50973680c27 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOps.H
@@ -82,6 +82,13 @@ void inplaceMapKey(const UList<label>& oldToNew, Container&);
 template<class T>
 void sortedOrder(const UList<T>&, labelList& order);
 
+//- Generate (sorted) indices corresponding to duplicate list values
+template<class T>
+void duplicateOrder(const UList<T>&, labelList& order);
+
+//- Generate (sorted) indices corresponding to unique list values
+template<class T>
+void uniqueOrder(const UList<T>&, labelList& order);
 
 //- Extract elements of List whose region is certain value.
 //  Use e.g. to extract all selected elements:
diff --git a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
index b048ef1bb8fda2196366ce4a47ec468865b0ed6b..942cb6e8c01d0eab25631f43d739f2a03fd64f39 100644
--- a/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
+++ b/src/OpenFOAM/containers/Lists/ListOps/ListOpsTemplates.C
@@ -174,16 +174,65 @@ void Foam::sortedOrder
 )
 {
     order.setSize(lst.size());
-
     forAll(order, elemI)
     {
         order[elemI] = elemI;
     }
-
     Foam::stableSort(order, typename UList<T>::less(lst));
 }
 
 
+template<class T>
+void Foam::duplicateOrder
+(
+    const UList<T>& lst,
+    labelList& order
+)
+{
+    if (lst.size() < 2)
+    {
+        order.clear();
+        return;
+    }
+
+    sortedOrder(lst, order);
+
+    label n = 0;
+    for (label i = 0; i < order.size() - 1; ++i)
+    {
+        if (lst[order[i]] == lst[order[i+1]])
+        {
+            order[n++] = order[i];
+        }
+    }
+    order.setSize(n);
+}
+
+
+template<class T>
+void Foam::uniqueOrder
+(
+    const UList<T>& lst,
+    labelList& order
+)
+{
+    sortedOrder(lst, order);
+
+    if (order.size() > 1)
+    {
+        label n = 0;
+        for (label i = 0; i < order.size() - 1; ++i)
+        {
+            if (lst[order[i]] != lst[order[i+1]])
+            {
+                order[n++] = order[i];
+            }
+        }
+        order.setSize(n);
+    }
+}
+
+
 template<class T, class ListType>
 ListType Foam::subset
 (
diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
index cb6c1571d3aef41c33fa7f3f782d21a7cc477d78..0ae74df8aff967c31b2358a00771f1cd69469036 100644
--- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
+++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.C
@@ -24,6 +24,23 @@ License
 
 \*---------------------------------------------------------------------------*/
 
+// * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
+
+template <class Type>
+void Foam::SortableList<Type>::sortIndices(List<label>& ind) const
+{
+    // list lengths must be identical
+    ind.setSize(this->size());
+
+    forAll(ind, i)
+    {
+        ind[i] = i;
+    }
+
+    Foam::stableSort(ind, typename UList<Type>::less(*this));
+}
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template <class Type>
@@ -73,13 +90,6 @@ Foam::SortableList<Type>::SortableList(const SortableList<Type>& lst)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template <class Type>
-void Foam::SortableList<Type>::setSize(const label newSize)
-{
-    List<Type>::setSize(newSize);
-    indices_.setSize(newSize, -1);
-}
-
 
 template <class Type>
 void Foam::SortableList<Type>::clear()
@@ -100,20 +110,28 @@ Foam::List<Type>& Foam::SortableList<Type>::shrink()
 template <class Type>
 void Foam::SortableList<Type>::sort()
 {
-    // list lengths must be identical
-    indices_.setSize(this->size());
+    sortIndices(indices_);
 
+    List<Type> lst(this->size());
     forAll(indices_, i)
     {
-        indices_[i] = i;
+        lst[i] = this->operator[](indices_[i]);
     }
 
-    Foam::stableSort(indices_, typename UList<Type>::less(*this));
+    List<Type>::transfer(lst);
+}
+
+
+template <class Type>
+void Foam::SortableList<Type>::reverseSort()
+{
+    sortIndices(indices_);
 
     List<Type> lst(this->size());
+    label endI = indices_.size();
     forAll(indices_, i)
     {
-        lst[i] = this->operator[](indices_[i]);
+        lst[--endI] = this->operator[](indices_[i]);
     }
 
     List<Type>::transfer(lst);
@@ -123,7 +141,14 @@ void Foam::SortableList<Type>::sort()
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 template <class Type>
-void Foam::SortableList<Type>::operator=(const UList<Type>& rhs)
+inline void Foam::SortableList<Type>::operator=(const Type& t)
+{
+    UList<Type>::operator=(t);
+}
+
+
+template <class Type>
+inline void Foam::SortableList<Type>::operator=(const UList<Type>& rhs)
 {
     List<Type>::operator=(rhs);
     indices_.clear();
@@ -131,7 +156,7 @@ void Foam::SortableList<Type>::operator=(const UList<Type>& rhs)
 
 
 template <class Type>
-void Foam::SortableList<Type>::operator=(const SortableList<Type>& rhs)
+inline void Foam::SortableList<Type>::operator=(const SortableList<Type>& rhs)
 {
     List<Type>::operator=(rhs);
     indices_ = rhs.indices();
diff --git a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
index 01cdce37803ce0be4d3368d3d9791a116b2b8a31..40dc6dd68cf7fccdb7368b9aa0c045622dd042f7 100644
--- a/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
+++ b/src/OpenFOAM/containers/Lists/SortableList/SortableList.H
@@ -60,6 +60,9 @@ class SortableList
         //- Original indices
         labelList indices_;
 
+        //- Resize and sort the parameter according to the list values
+        void sortIndices(List<label>&) const;
+
 public:
 
     // Constructors
@@ -99,9 +102,6 @@ public:
             return indices_;
         }
 
-        //- Size the list. Growing can cause undefined indices (until next sort)
-        void setSize(const label);
-
         //- Clear the list and the indices
         void clear();
 
@@ -112,13 +112,19 @@ public:
         //  also resizes the indices as required
         void sort();
 
+        //- Reverse (stable) sort the list
+        void reverseSort();
+
     // Member Operators
 
+        //- Assignment of all entries to the given value
+        inline void operator=(const Type&);
+
         //- Assignment from UList operator. Takes linear time.
-        void operator=(const UList<Type>&);
+        inline void operator=(const UList<Type>&);
 
         //- Assignment operator. Takes linear time.
-        void operator=(const SortableList<Type>&);
+        inline void operator=(const SortableList<Type>&);
 
 };
 
diff --git a/src/OpenFOAM/containers/Lists/SubList/SubList.H b/src/OpenFOAM/containers/Lists/SubList/SubList.H
index dd5bcc673e785c04c02e78c68860eb29a8d018a1..0e8336dc504186b057ee46528784829babbd058b 100644
--- a/src/OpenFOAM/containers/Lists/SubList/SubList.H
+++ b/src/OpenFOAM/containers/Lists/SubList/SubList.H
@@ -87,6 +87,9 @@ public:
 
         //- Allow cast to a const List<T>&
         inline operator const Foam::List<T>&() const;
+
+        //- Assignment of all entries to the given value
+        inline void operator=(const T&);
 };
 
 
diff --git a/src/OpenFOAM/containers/Lists/SubList/SubListI.H b/src/OpenFOAM/containers/Lists/SubList/SubListI.H
index 6b142cab1f174ee6b26f6da858efa42913d91d89..7a112370fbcc8d6c8d73ba4980673160fb678b21 100644
--- a/src/OpenFOAM/containers/Lists/SubList/SubListI.H
+++ b/src/OpenFOAM/containers/Lists/SubList/SubListI.H
@@ -54,7 +54,7 @@ inline Foam::SubList<T>::SubList
 #   ifdef FULLDEBUG
 
     // Artificially allowing the start of a zero-sized subList to be
-    // one past the end of the original list.  
+    // one past the end of the original list.
     if (subSize > 0)
     {
         list.checkStart(startIndex);
@@ -73,7 +73,7 @@ inline Foam::SubList<T>::SubList
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class T>
-const Foam::SubList<T>& Foam::SubList<T>::null()
+inline const Foam::SubList<T>& Foam::SubList<T>::null()
 {
     SubList<T>* nullPtr = reinterpret_cast<SubList<T>*>(NULL);
     return *nullPtr;
@@ -89,4 +89,11 @@ inline Foam::SubList<T>::operator const Foam::List<T>&() const
 }
 
 
+template<class T>
+inline void Foam::SubList<T>::operator=(const T& t)
+{
+    UList<T>::operator=(t);
+}
+
+
 // ************************************************************************* //
diff --git a/src/OpenFOAM/containers/Lists/UList/UListI.H b/src/OpenFOAM/containers/Lists/UList/UListI.H
index 0e05218ca475b897c0d1a5d4ab2af852d0878998..3d78afcfc877db09c1eba1751b4452f150eb749b 100644
--- a/src/OpenFOAM/containers/Lists/UList/UListI.H
+++ b/src/OpenFOAM/containers/Lists/UList/UListI.H
@@ -50,14 +50,14 @@ inline Foam::UList<T>::UList(T* __restrict__ v, label size)
 template<class T>
 inline Foam::label Foam::UList<T>::fcIndex(const label i) const
 {
-    return (i == size()-1 ? 0 : i+1); 
+    return (i == size()-1 ? 0 : i+1);
 }
 
 
 template<class T>
 inline Foam::label Foam::UList<T>::rcIndex(const label i) const
 {
-    return (i == 0 ? size()-1 : i-1); 
+    return (i == 0 ? size()-1 : i-1);
 }
 
 
diff --git a/src/OpenFOAM/containers/Lists/UList/UListIO.C b/src/OpenFOAM/containers/Lists/UList/UListIO.C
index 29816341630407321d6225f7373adc780a549d82..9218e9a948db5e843f3a8b9a92679fdadfc1c2df 100644
--- a/src/OpenFOAM/containers/Lists/UList/UListIO.C
+++ b/src/OpenFOAM/containers/Lists/UList/UListIO.C
@@ -45,7 +45,7 @@ void Foam::UList<T>::writeEntry(Ostream& os) const
     {
         os  << word("List<" + word(pTraits<T>::typeName) + '>') << " ";
     }
-    
+
     os << *this;
 }
 
diff --git a/src/OpenFOAM/db/Time/timeSelector.C b/src/OpenFOAM/db/Time/timeSelector.C
index cfb2354d794ea6c87f67915bfc75e44b62db85fb..bace90c28ae61bd04d1a16b22ec7559e70fa5949 100644
--- a/src/OpenFOAM/db/Time/timeSelector.C
+++ b/src/OpenFOAM/db/Time/timeSelector.C
@@ -56,22 +56,12 @@ Foam::List<bool> Foam::timeSelector::selected(const List<instant>& Times) const
 {
     List<bool> lst(Times.size(), false);
 
-    // check ranges
-    forAll(Times, i)
+    // check ranges, avoid false positive on constant/
+    forAll(Times, timeI)
     {
-        if (selected(Times[i]))
+        if (Times[timeI].name() != "constant" && selected(Times[timeI]))
         {
-            lst[i] = true;
-        }
-    }
-
-    // avoid false positive on "constant"
-    forAll(Times, i)
-    {
-        if (Times[i].name() == "constant")
-        {
-            lst[i] = false;
-            break;
+            lst[timeI] = true;
         }
     }
 
@@ -85,15 +75,15 @@ Foam::List<bool> Foam::timeSelector::selected(const List<instant>& Times) const
             int nearestIndex = -1;
             scalar nearestDiff = Foam::GREAT;
 
-            forAll(Times, timeIndex)
+            forAll(Times, timeI)
             {
-                if (Times[timeIndex].name() == "constant") continue;
+                if (Times[timeI].name() == "constant") continue;
 
-                scalar diff = fabs(Times[timeIndex].value() - target);
+                scalar diff = fabs(Times[timeI].value() - target);
                 if (diff < nearestDiff)
                 {
                     nearestDiff = diff;
-                    nearestIndex = timeIndex;
+                    nearestIndex = timeI;
                 }
             }
 
@@ -141,7 +131,7 @@ void Foam::timeSelector::addOptions
         argList::validOptions.insert("zeroTime", "");
     }
     argList::validOptions.insert("noZero", "");
-    argList::validOptions.insert("time", "time");
+    argList::validOptions.insert("time", "ranges");
     argList::validOptions.insert("latestTime", "");
 }
 
@@ -156,35 +146,76 @@ Foam::List<Foam::instant> Foam::timeSelector::select
     {
         List<bool> selectTimes(timeDirs.size(), true);
 
+        // determine locations of constant/ and 0/ directories
+        label constantIdx = -1;
+        label zeroIdx = -1;
+
+        forAll(timeDirs, timeI)
+        {
+            if (timeDirs[timeI].name() == "constant")
+            {
+                constantIdx = timeI;
+            }
+            else if (timeDirs[timeI].value() == 0)
+            {
+                zeroIdx = timeI;
+            }
+
+            if (constantIdx >= 0 && zeroIdx >= 0)
+            {
+                break;
+            }
+        }
+
+        // determine latestTime selection (if any)
+        // this must appear before the -time option processing
+        label latestIdx = -1;
+        if (args.options().found("latestTime"))
+        {
+            selectTimes = false;
+            latestIdx = timeDirs.size() - 1;
+
+            // avoid false match on constant/
+            if (latestIdx == constantIdx)
+            {
+                latestIdx = -1;
+            }
+        }
+
         if (args.options().found("time"))
         {
+            // can match 0/, but can never match constant/
             selectTimes = timeSelector
             (
                 IStringStream(args.options()["time"])()
             ).selected(timeDirs);
         }
-        else if (args.options().found("latestTime"))
-        {
-            selectTimes = false;
 
-            // avoid false match on constant/ or 0/
-            if (timeDirs.size() > 2)
-            {
-                selectTimes[timeDirs.size() - 1] = true;
-            }
+
+        // add in latestTime (if selected)
+        if (latestIdx >= 0)
+        {
+            selectTimes[latestIdx] = true;
         }
 
-        if (timeDirs.size() > 1)
+        if (constantIdx >= 0)
         {
-            selectTimes[0] = args.options().found("constant");
+            // only add constant/ if specifically requested
+            selectTimes[constantIdx] = args.options().found("constant");
+        }
 
+        // special treatment for 0/
+        if (zeroIdx >= 0)
+        {
             if (args.options().found("noZero"))
             {
-                selectTimes[1] = false;
+                // exclude 0/ if specifically requested
+                selectTimes[zeroIdx] = false;
             }
             else if (argList::validOptions.found("zeroTime"))
             {
-                selectTimes[1] = args.options().found("zeroTime");
+                // with -zeroTime enabled, drop 0/ unless specifically requested
+                selectTimes[zeroIdx] = args.options().found("zeroTime");
             }
         }
 
diff --git a/src/OpenFOAM/db/Time/timeSelector.H b/src/OpenFOAM/db/Time/timeSelector.H
index 7d1f15fda1dd18115029487823a587cb2c84272f..6afa92ee0601a346f0e8cb9180029329bdc7b019 100644
--- a/src/OpenFOAM/db/Time/timeSelector.H
+++ b/src/OpenFOAM/db/Time/timeSelector.H
@@ -60,8 +60,9 @@ Description
     @endverbatim
 
     The first argument avoids adding the @b -constant option. The second
-    argument adds an additional @b -zeroTime option and prevents the @c 0/
-    directory from being included in the default time range.
+    argument adds an additional @b -zeroTime option and also prevents the
+    @c 0/ directory from being included in the default time range and in the
+    @b -latestTime selection.
 
 SourceFiles
     timeSelector.C
@@ -121,14 +122,17 @@ public:
         //
         // @param constant
         //   Add the @b -constant option to include the @c constant/ directory
+        //
         // @param zeroTime
-        //   Additional to the @b -noZero option (explicitly exclude the
-        //   @c 0/ directory), add the @b -zeroTime option to include the
-        //   @c 0/ directory. The @b -noZero option has precedence.
+        //   Enable the @b -zeroTime option and alter the normal time selection
+        //   behaviour (and @b -latestTime behaviour) to exclude the @c 0/
+        //   directory. The @c 0/ directory will only be included when
+        //   @b -zeroTime is specified.
+        //   The @b -noZero option has precedence over the @b -zeroTime option.
         static void addOptions
         (
-            const bool constant = true,
-            const bool zeroTime = false
+            const bool constant=true,
+            const bool zeroTime=false
         );
 
         //- Return the set of times selected based on the argList options
diff --git a/src/OpenFOAM/db/dictionary/dictionary.C b/src/OpenFOAM/db/dictionary/dictionary.C
index ad960e7405779f5cfb38063d6f246dbd84d7bc56..d54f1bc3d23481c36ba77583a5475e28c3de6716 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.C
+++ b/src/OpenFOAM/db/dictionary/dictionary.C
@@ -27,6 +27,7 @@ License
 #include "dictionary.H"
 #include "primitiveEntry.H"
 #include "dictionaryEntry.H"
+#include "regExp.H"
 
 /* * * * * * * * * * * * * * * Static Member Data  * * * * * * * * * * * * * */
 
@@ -42,21 +43,18 @@ bool Foam::dictionary::findInWildcards
     const bool wildCardMatch,
     const word& Keyword,
     DLList<entry*>::const_iterator& wcLink,
-    DLList<autoPtr<regularExpression> >::const_iterator& reLink
+    DLList<autoPtr<regExp> >::const_iterator& reLink
 ) const
 {
     if (wildCardEntries_.size() > 0)
     {
-        //wcLink = wildCardEntries_.begin();
-        //reLink = wildCardRegexps_.end();
-
         while (wcLink != wildCardEntries_.end())
         {
             if (!wildCardMatch && wcLink()->keyword() == Keyword)
             {
                 return true;
             }
-            else if (wildCardMatch && reLink()->matches(Keyword))
+            else if (wildCardMatch && reLink()->match(Keyword))
             {
                 return true;
             }
@@ -75,7 +73,7 @@ bool Foam::dictionary::findInWildcards
     const bool wildCardMatch,
     const word& Keyword,
     DLList<entry*>::iterator& wcLink,
-    DLList<autoPtr<regularExpression> >::iterator& reLink
+    DLList<autoPtr<regExp> >::iterator& reLink
 )
 {
     if (wildCardEntries_.size() > 0)
@@ -86,7 +84,7 @@ bool Foam::dictionary::findInWildcards
             {
                 return true;
             }
-            else if (wildCardMatch && reLink()->matches(Keyword))
+            else if (wildCardMatch && reLink()->match(Keyword))
             {
                 return true;
             }
@@ -132,10 +130,7 @@ Foam::dictionary::dictionary
             wildCardEntries_.insert(&iter());
             wildCardRegexps_.insert
             (
-                autoPtr<regularExpression>
-                (
-                    new regularExpression(iter().keyword())
-                )
+                autoPtr<regExp>(new regExp(iter().keyword()))
             );
         }
     }
@@ -165,10 +160,7 @@ Foam::dictionary::dictionary
             wildCardEntries_.insert(&iter());
             wildCardRegexps_.insert
             (
-                autoPtr<regularExpression>
-                (
-                    new regularExpression(iter().keyword())
-                )
+                autoPtr<regExp>(new regExp(iter().keyword()))
             );
         }
     }
@@ -228,7 +220,7 @@ bool Foam::dictionary::found(const word& keyword, bool recursive) const
         if (wildCardEntries_.size() > 0)
         {
             DLList<entry*>::const_iterator wcLink = wildCardEntries_.begin();
-            DLList<autoPtr<regularExpression> >::const_iterator reLink =
+            DLList<autoPtr<regExp> >::const_iterator reLink =
                 wildCardRegexps_.begin();
 
             // Find in wildcards using regular expressions only
@@ -265,7 +257,7 @@ const Foam::entry* Foam::dictionary::lookupEntryPtr
         {
             DLList<entry*>::const_iterator wcLink =
                 wildCardEntries_.begin();
-            DLList<autoPtr<regularExpression> >::const_iterator reLink =
+            DLList<autoPtr<regExp> >::const_iterator reLink =
                 wildCardRegexps_.begin();
 
             // Find in wildcards using regular expressions only
@@ -304,7 +296,7 @@ Foam::entry* Foam::dictionary::lookupEntryPtr
         {
             DLList<entry*>::iterator wcLink =
                 wildCardEntries_.begin();
-            DLList<autoPtr<regularExpression> >::iterator reLink =
+            DLList<autoPtr<regExp> >::iterator reLink =
                 wildCardRegexps_.begin();
             // Find in wildcards using regular expressions only
             if (findInWildcards(wildCardMatch, keyword, wcLink, reLink))
@@ -486,10 +478,7 @@ bool Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
                     wildCardEntries_.insert(entryPtr);
                     wildCardRegexps_.insert
                     (
-                        autoPtr<regularExpression>
-                        (
-                            new regularExpression(entryPtr->keyword())
-                        )
+                        autoPtr<regExp>(new regExp(entryPtr->keyword()))
                     );
                 }
 
@@ -518,10 +507,7 @@ bool Foam::dictionary::add(entry* entryPtr, bool mergeEntry)
             wildCardEntries_.insert(entryPtr);
             wildCardRegexps_.insert
             (
-                autoPtr<regularExpression>
-                (
-                    new regularExpression(entryPtr->keyword())
-                )
+                autoPtr<regExp>(new regExp(entryPtr->keyword()))
             );
         }
 
@@ -614,8 +600,7 @@ bool Foam::dictionary::remove(const word& Keyword)
         // Delete from wildcards first
         DLList<entry*>::iterator wcLink =
             wildCardEntries_.begin();
-        DLList<autoPtr<regularExpression> >::iterator reLink =
-            wildCardRegexps_.begin();
+        DLList<autoPtr<regExp> >::iterator reLink = wildCardRegexps_.begin();
 
         // Find in wildcards using exact match only
         if (findInWildcards(false, Keyword, wcLink, reLink))
@@ -682,7 +667,7 @@ bool Foam::dictionary::changeKeyword
                 // Delete from wildcards first
                 DLList<entry*>::iterator wcLink =
                     wildCardEntries_.begin();
-                DLList<autoPtr<regularExpression> >::iterator reLink =
+                DLList<autoPtr<regExp> >::iterator reLink =
                     wildCardRegexps_.begin();
 
                 // Find in wildcards using exact match only
@@ -696,7 +681,7 @@ bool Foam::dictionary::changeKeyword
             IDLList<entry>::replace(iter2(), iter());
             delete iter2();
             hashedEntries_.erase(iter2);
-            
+
         }
         else
         {
@@ -721,10 +706,7 @@ bool Foam::dictionary::changeKeyword
         wildCardEntries_.insert(iter());
         wildCardRegexps_.insert
         (
-            autoPtr<regularExpression>
-            (
-                new regularExpression(newKeyword)
-            )
+            autoPtr<regExp>(new regExp(newKeyword))
         );
     }
 
@@ -788,6 +770,8 @@ void Foam::dictionary::clear()
 {
     IDLList<entry>::clear();
     hashedEntries_.clear();
+    wildCardEntries_.clear();
+    wildCardRegexps_.clear();
 }
 
 
diff --git a/src/OpenFOAM/db/dictionary/dictionary.H b/src/OpenFOAM/db/dictionary/dictionary.H
index ac6ca6538968f56524931d0d6a84e2bf4c1f6370..1d87a08fd64d7505d4628c0cd2740dd6eb12db82 100644
--- a/src/OpenFOAM/db/dictionary/dictionary.H
+++ b/src/OpenFOAM/db/dictionary/dictionary.H
@@ -60,7 +60,6 @@ SourceFiles
 #include "HashTable.H"
 #include "wordList.H"
 #include "className.H"
-#include "regularExpression.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -68,7 +67,7 @@ namespace Foam
 {
 
 // Forward declaration of friend functions and operators
-
+class regExp;
 class dictionary;
 Istream& operator>>(Istream&, dictionary&);
 Ostream& operator<<(Ostream&, const dictionary&);
@@ -96,8 +95,8 @@ class dictionary
         //- Wildcard entries
         DLList<entry*> wildCardEntries_;
 
-        //- Wildcard precompiled regex
-        DLList<autoPtr<regularExpression> > wildCardRegexps_;
+        //- Wildcard precompiled regular expressions
+        DLList<autoPtr<regExp> > wildCardRegexps_;
 
    // Private Member Functions
 
@@ -108,7 +107,7 @@ class dictionary
             const bool wildCardMatch,
             const word& Keyword,
             DLList<entry*>::const_iterator& wcLink,
-            DLList<autoPtr<regularExpression> >::const_iterator& reLink
+            DLList<autoPtr<regExp> >::const_iterator& reLink
         ) const;
 
         //- Search wildcard table either for exact match or for regular
@@ -118,7 +117,7 @@ class dictionary
             const bool wildCardMatch,
             const word& Keyword,
             DLList<entry*>::iterator& wcLink,
-            DLList<autoPtr<regularExpression> >::iterator& reLink
+            DLList<autoPtr<regExp> >::iterator& reLink
         );
 
 
@@ -164,16 +163,16 @@ public:
         dictionary(Istream&);
 
         //- Construct as copy given the parent dictionary
-        dictionary(const dictionary& parentDict, const dictionary& dict);
+        dictionary(const dictionary& parentDict, const dictionary&);
 
         //- Construct top-level dictionary as copy
-        dictionary(const dictionary& dict);
+        dictionary(const dictionary&);
 
         //- Construct and return clone
         Foam::autoPtr<dictionary> clone() const;
 
         //- Construct top-level dictionary on freestore from Istream
-        static Foam::autoPtr<dictionary> New(Istream& is);
+        static Foam::autoPtr<dictionary> New(Istream&);
 
 
     // Destructor
@@ -212,12 +211,12 @@ public:
 
             //- Search dictionary for given keyword
             //  If recursive search parent dictionaries
-            bool found(const word& keyword, bool recursive=false) const;
+            bool found(const word&, bool recursive=false) const;
 
             //- Find and return an entry data stream pointer if present
             //  otherwise return NULL.
-            //  If recursive search parent dictionaries. If wildCardMatch
-            //  use wildcards.
+            //  If recursive search parent dictionaries.
+            //  If wildCardMatch use wildcards.
             const entry* lookupEntryPtr
             (
                 const word&,
@@ -227,8 +226,8 @@ public:
 
             //- Find and return an entry data stream pointer for manipulation
             //  if present otherwise return NULL.
-            //  If recursive search parent dictionaries. If wildCardMatch
-            //  use wildcards.
+            //  If recursive search parent dictionaries.
+            //  If wildCardMatch use wildcards.
             entry* lookupEntryPtr
             (
                 const word&,
@@ -237,8 +236,8 @@ public:
             );
 
             //- Find and return an entry data stream if present otherwise error.
-            //  If recursive search parent dictionaries. If wildCardMatch
-            //  use wildcards.
+            //  If recursive search parent dictionaries.
+            //  If wildCardMatch use wildcards.
             const entry& lookupEntry
             (
                 const word&,
@@ -332,13 +331,13 @@ public:
 
             //- Add a scalar entry
             //  optionally overwrite an existing entry
-            void add (const keyType&, const scalar, bool overwrite=false);
+            void add(const keyType&, const scalar, bool overwrite=false);
 
             //- Add a dictionary entry
             //  optionally merge with an existing sub-dictionary
             void add
             (
-                const keyType& keyword,
+                const keyType&,
                 const dictionary&,
                 bool mergeEntry=false
             );
@@ -346,7 +345,7 @@ public:
             //- Add a T entry
             //  optionally overwrite an existing entry
             template<class T>
-            void add(const keyType& keyword, const T&, bool overwrite=false);
+            void add(const keyType&, const T&, bool overwrite=false);
 
             //- Assign a new entry, overwrite any existing entry
             void set(entry*);
@@ -355,14 +354,14 @@ public:
             void set(const entry&);
 
             //- Assign a dictionary entry, overwrite any existing entry
-            void set(const keyType& keyword, const dictionary&);
+            void set(const keyType&, const dictionary&);
 
             //- Assign a T entry, overwrite any existing entry
             template<class T>
-            void set(const keyType& keyword, const T&);
+            void set(const keyType&, const T&);
 
             //- Remove an entry specified by keyword
-            bool remove(const word& keyword);
+            bool remove(const word&);
 
             //- Change the keyword for an entry,
             //  optionally forcing overwrite of an existing entry
@@ -370,7 +369,7 @@ public:
             (
                 const keyType& oldKeyword,
                 const keyType& newKeyword,
-                bool forceOverwrite = false
+                bool forceOverwrite=false
             );
 
             //- Merge entries from the given dictionary.
@@ -383,7 +382,7 @@ public:
 
         // Write
 
-            void write(Ostream& os, bool subDict = true) const;
+            void write(Ostream&, bool subDict=true) const;
 
 
     // Member Operators
diff --git a/src/OpenFOAM/db/dictionary/dictionaryIO.C b/src/OpenFOAM/db/dictionary/dictionaryIO.C
index b1d5fbcbc452f760e8d7805a4764fdd0e7240fa2..35746ea66561f6206ddbdfb36a3130319d433ad7 100644
--- a/src/OpenFOAM/db/dictionary/dictionaryIO.C
+++ b/src/OpenFOAM/db/dictionary/dictionaryIO.C
@@ -27,6 +27,7 @@ License
 #include "dictionary.H"
 #include "IFstream.H"
 #include "inputModeEntry.H"
+#include "regExp.H"
 
 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
 
@@ -136,9 +137,6 @@ Foam::Istream& Foam::operator>>(Istream& is, dictionary& dict)
     functionEntries::inputModeEntry::clear();
 
     dict.clear();
-    dict.hashedEntries_.clear();
-    dict.wildCardEntries_.clear();
-    dict.wildCardRegexps_.clear();
     dict.read(is);
 
     return is;
diff --git a/src/OpenFOAM/fields/Fields/transformField/transformField.C b/src/OpenFOAM/fields/Fields/transformField/transformField.C
index b81ef5ecda3dd3b07aa2703ecb884b82b065724f..3a4f596e4db7528a1e5823cb4cfdb0412f6b6f86 100644
--- a/src/OpenFOAM/fields/Fields/transformField/transformField.C
+++ b/src/OpenFOAM/fields/Fields/transformField/transformField.C
@@ -26,6 +26,7 @@ License
 
 #include "transformField.H"
 #include "FieldM.H"
+#include "diagTensor.H"
 
 // * * * * * * * * * * * * * * * global functions  * * * * * * * * * * * * * //
 
@@ -75,7 +76,8 @@ void Foam::transform
 {
     vector T = tr.t();
 
-    if (mag(tr.r().w()) > SMALL)
+    // Check if any rotation
+    if (mag(tr.r().R() - I) > SMALL)
     {
         transform(rtf, tr.r(), tf);
 
@@ -90,6 +92,10 @@ void Foam::transform
         {
             TFOR_ALL_F_OP_S_OP_F(vector, rtf, =, vector, T, +, vector, tf);
         }
+        else
+        {
+            rtf = vector::zero;
+        }
     }
 }
 
diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C
index a2faa64133a164011173bf5a2168accea365b3cc..ef8f88bfbd794644997d670791c84cab9b560c86 100644
--- a/src/OpenFOAM/global/argList/argList.C
+++ b/src/OpenFOAM/global/argList/argList.C
@@ -37,19 +37,17 @@ License
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-namespace Foam
-{
-    SLList<string>    argList::validArgs;
-    HashTable<string> argList::validOptions;
-    HashTable<string> argList::validParOptions;
-}
+Foam::SLList<Foam::string>    Foam::argList::validArgs;
+Foam::HashTable<Foam::string> Foam::argList::validOptions;
+Foam::HashTable<Foam::string> Foam::argList::validParOptions;
+bool Foam::argList::bannerEnabled(true);
 
 
 Foam::argList::initValidTables::initValidTables()
 {
-    validOptions.insert("case", "dir");
-    validOptions.insert("parallel", "");
-    validParOptions.insert("parallel", "");
+    validOptions.set("case", "dir");
+    validOptions.set("parallel", "");
+    validParOptions.set("parallel", "");
 
     Pstream::addValidParOptions(validParOptions);
 }
@@ -138,7 +136,7 @@ void Foam::argList::getRootCase()
         casePath = cwd();
 
         // we could add this back in as '-case'?
-        // options_.insert("case", casePath);
+        // options_.set("case", casePath);
     }
 
     rootPath_   = casePath.path();
@@ -285,7 +283,7 @@ Foam::argList::argList
     string timeString = clock::clockTime();
 
     // Print the banner once only for parallel runs
-    if (Pstream::master())
+    if (Pstream::master() && bannerEnabled)
     {
         IOobject::writeBanner(Info, true);
         Info<< "Exec   : " << argListString.c_str() << nl
@@ -315,8 +313,6 @@ Foam::argList::argList
         // For the master
         if (Pstream::master())
         {
-            fileNameList roots;
-
             // establish rootPath_/globalCase_/case_ for master
             getRootCase();
 
@@ -333,45 +329,25 @@ Foam::argList::argList
                     << exit(FatalError);
             }
 
-            dictionary decompositionDict(decompDictStream);
-
-            Switch distributed(false);
-
-            if
-            (
-                decompositionDict.readIfPresent("distributed", distributed)
-             && distributed
-            )
-            {
-                decompositionDict.lookup("roots") >> roots;
-
-                if (roots.size() != Pstream::nProcs()-1)
-                {
-                    FatalError
-                        << "number of entries in decompositionDict::roots"
-                        << " is not equal to the number of slaves "
-                        << Pstream::nProcs()-1
-                        << exit(FatalError);
-                }
-            }
-
+            dictionary decompDict(decompDictStream);
 
             label dictNProcs
             (
                 readLabel
                 (
-                    decompositionDict.lookup("numberOfSubdomains")
+                    decompDict.lookup("numberOfSubdomains")
                 )
             );
 
-            // Check number of processors. We have nProcs(number of
-            // actual processes), dictNProcs(wanted number of processes read
-            // from decompositionDict) and nProcDirs(number of processor
-            // directories - n/a when running distributed)
+            // Check number of processors.
+            // nProcs     => number of actual procs
+            // dictNProcs => number of procs specified in decompositionDict
+            // nProcDirs  => number of processor directories
+            //               (n/a when running distributed)
             //
             // - normal running : nProcs = dictNProcs = nProcDirs
-            // - decomposition to more processors : nProcs = dictNProcs
-            // - decomposition to less processors : nProcs = nProcDirs
+            // - decomposition to more  processors : nProcs = dictNProcs
+            // - decomposition to fewer processors : nProcs = nProcDirs
             if (dictNProcs > Pstream::nProcs())
             {
                 FatalError
@@ -382,38 +358,23 @@ Foam::argList::argList
                     << exit(FatalError);
             }
 
-            if (!distributed && dictNProcs < Pstream::nProcs())
+            // distributed data
+            if (decompDict.lookupOrDefault<Switch>("distributed", false))
             {
-                // Possibly going to fewer processors.
-                // Check if all procDirs are there.
-                label nProcDirs = 0;
-                while
-                (
-                    dir
-                    (
-                        rootPath_/globalCase_/"processor"
-                      + name(++nProcDirs)
-                    )
-                )
-                {}
+                fileNameList roots;
+                decompDict.lookup("roots") >> roots;
 
-                if (nProcDirs != Pstream::nProcs())
+                if (roots.size() != Pstream::nProcs()-1)
                 {
                     FatalError
-                        << "number of processor directories = "
-                        << nProcDirs
-                        << " is not equal to the number of processors = "
-                        << Pstream::nProcs()
+                        << "number of entries in decompositionDict::roots"
+                        << " is not equal to the number of slaves "
+                        << Pstream::nProcs()-1
                         << exit(FatalError);
                 }
-            }
-
-            // distributed data
-            if (roots.size())
-            {
-                bool hadOptCase = options_.found("case");
 
                 // Distribute the master's argument list (with new root)
+                bool hadCaseOpt = options_.found("case");
                 for
                 (
                     int slave=Pstream::firstSlave();
@@ -421,8 +382,7 @@ Foam::argList::argList
                     slave++
                 )
                 {
-                    options_.erase("case");
-                    options_.insert
+                    options_.set
                     (
                         "case",
                         fileName(roots[slave-1])/globalCase_
@@ -431,17 +391,42 @@ Foam::argList::argList
                     OPstream toSlave(Pstream::scheduled, slave);
                     toSlave << args_ << options_;
                 }
-
                 options_.erase("case");
 
                 // restore [-case dir]
-                if (hadOptCase)
+                if (hadCaseOpt)
                 {
-                    options_.insert("case", rootPath_/globalCase_);
+                    options_.set("case", rootPath_/globalCase_);
                 }
             }
             else
             {
+                // Possibly going to fewer processors.
+                // Check if all procDirs are there.
+                if (dictNProcs < Pstream::nProcs())
+                {
+                    label nProcDirs = 0;
+                    while
+                    (
+                        dir
+                        (
+                            rootPath_/globalCase_/"processor"
+                          + name(++nProcDirs)
+                        )
+                    )
+                    {}
+
+                    if (nProcDirs != Pstream::nProcs())
+                    {
+                        FatalError
+                            << "number of processor directories = "
+                            << nProcDirs
+                            << " is not equal to the number of processors = "
+                            << Pstream::nProcs()
+                            << exit(FatalError);
+                    }
+                }
+
                 // Distribute the master's argument list (unaltered)
                 for
                 (
@@ -472,7 +457,6 @@ Foam::argList::argList
     {
         // establish rootPath_/globalCase_/case_
         getRootCase();
-
         case_ = globalCase_;
     }
 
@@ -510,21 +494,21 @@ Foam::argList::argList
     }
 
 
-    if (Pstream::master())
+    if (Pstream::master() && bannerEnabled)
     {
         Info<< "Case   : " << (rootPath_/globalCase_).c_str() << nl
             << "nProcs : " << nProcs << endl;
-    }
 
-    if (parRunControl_.parRun() && Pstream::master())
-    {
-        Info<< "Slaves : " << slaveProcs << nl
-            << "Pstream initialized with:" << nl
-            << "    floatTransfer     : " << Pstream::floatTransfer << nl
-            << "    nProcsSimpleSum   : " << Pstream::nProcsSimpleSum << nl
-            << "    commsType         : "
-            << Pstream::commsTypeNames[Pstream::defaultCommsType]
-            << endl;
+        if (parRunControl_.parRun())
+        {
+            Info<< "Slaves : " << slaveProcs << nl
+                << "Pstream initialized with:" << nl
+                << "    floatTransfer     : " << Pstream::floatTransfer << nl
+                << "    nProcsSimpleSum   : " << Pstream::nProcsSimpleSum << nl
+                << "    commsType         : "
+                << Pstream::commsTypeNames[Pstream::defaultCommsType]
+                << endl;
+        }
     }
 
     jobInfo.add("root", rootPath_);
@@ -546,7 +530,7 @@ Foam::argList::argList
     sigQuit_.set();
     sigSegv_.set();
 
-    if (Pstream::master())
+    if (Pstream::master() && bannerEnabled)
     {
         Info<< endl;
         IOobject::writeDivider(Info);
@@ -564,6 +548,12 @@ Foam::argList::~argList()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+void Foam::argList::noBanner()
+{
+    bannerEnabled = false;
+}
+
+
 void Foam::argList::noParallel()
 {
     validOptions.erase("parallel");
diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H
index 648295da842bb5414ecdeeff1d507137d775c4a0..60dd1c01e9000bcbfb52b3905ec32b84e664936b 100644
--- a/src/OpenFOAM/global/argList/argList.H
+++ b/src/OpenFOAM/global/argList/argList.H
@@ -92,6 +92,7 @@ namespace Foam
 class argList
 {
     // Private data
+        static bool bannerEnabled;
 
         stringList args_;
         HashTable<string> options_;
@@ -213,6 +214,9 @@ public:
 
         // Edit
 
+            //- Disable emitting the banner information
+            static void noBanner();
+
             //- Remove the parallel options
             static void noParallel();
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
index 33fcda639db8e0bc5d10ac7118e27cece792139e..c9e797d2d207735714bdaac5b851fc4a80ff33ff 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrix.H
@@ -259,7 +259,7 @@ public:
                     const FieldField<Field, scalar>& interfaceBouCoeffs,
                     const FieldField<Field, scalar>& interfaceIntCoeffs,
                     const lduInterfaceFieldPtrsList& interfaces,
-                    Istream& solverData
+                    const dictionary& solverControls
                 ),
                 (
                     fieldName,
@@ -267,7 +267,7 @@ public:
                     interfaceBouCoeffs,
                     interfaceIntCoeffs,
                     interfaces,
-                    solverData
+                    solverControls
                 )
             );
 
@@ -282,7 +282,7 @@ public:
                     const FieldField<Field, scalar>& interfaceBouCoeffs,
                     const FieldField<Field, scalar>& interfaceIntCoeffs,
                     const lduInterfaceFieldPtrsList& interfaces,
-                    Istream& solverData
+                    const dictionary& solverControls
                 ),
                 (
                     fieldName,
@@ -290,7 +290,7 @@ public:
                     interfaceBouCoeffs,
                     interfaceIntCoeffs,
                     interfaces,
-                    solverData
+                    solverControls
                 )
             );
 
@@ -304,7 +304,7 @@ public:
                 const FieldField<Field, scalar>& interfaceBouCoeffs,
                 const FieldField<Field, scalar>& interfaceIntCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
-                Istream& solverData
+                const dictionary& solverControls
             );
 
         // Selectors
@@ -317,7 +317,7 @@ public:
                 const FieldField<Field, scalar>& interfaceBouCoeffs,
                 const FieldField<Field, scalar>& interfaceIntCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
-                Istream& solverData
+                const dictionary& solverControls
             );
 
 
@@ -359,7 +359,7 @@ public:
 
 
             //- Read and reset the solver parameters from the given stream
-            virtual void read(Istream& solverData);
+            virtual void read(const dictionary&);
 
             virtual solverPerformance solve
             (
@@ -396,6 +396,9 @@ public:
 
     public:
 
+        //- Find the smoother name (directly or from a sub-dictionary)
+        static word getName(const dictionary&);
+
         //- Runtime type information
         virtual const word& type() const = 0;
 
@@ -467,7 +470,7 @@ public:
                 const FieldField<Field, scalar>& interfaceBouCoeffs,
                 const FieldField<Field, scalar>& interfaceIntCoeffs,
                 const lduInterfaceFieldPtrsList& interfaces,
-                Istream& smootherData
+                const dictionary& solverControls
             );
 
 
@@ -531,6 +534,9 @@ public:
 
     public:
 
+        //- Find the preconditioner name (directly or from a sub-dictionary)
+        static word getName(const dictionary&);
+
         //- Runtime type information
         virtual const word& type() const = 0;
 
@@ -544,9 +550,9 @@ public:
                 symMatrix,
                 (
                     const solver& sol,
-                    Istream& preconditionerData
+                    const dictionary& solverControls
                 ),
-                (sol, preconditionerData)
+                (sol, solverControls)
             );
 
             declareRunTimeSelectionTable
@@ -556,9 +562,9 @@ public:
                 asymMatrix,
                 (
                     const solver& sol,
-                    Istream& preconditionerData
+                    const dictionary& solverControls
                 ),
-                (sol, preconditionerData)
+                (sol, solverControls)
             );
 
 
@@ -579,7 +585,7 @@ public:
             static autoPtr<preconditioner> New
             (
                 const solver& sol,
-                Istream& preconditionerData
+                const dictionary& solverControls
             );
 
 
@@ -593,7 +599,7 @@ public:
 
             //- Read and reset the preconditioner parameters
             //  from the given stream
-            virtual void read(Istream& preconditionerData)
+            virtual void read(const dictionary&)
             {}
 
             //- Return wA the preconditioned form of residual rA
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixPreconditioner.C
index 82f9a19ac20c59a3a5e4c303cb0f0a5cb7144c33..cb4a645df1c4f30ab96bf174bdb87d8c3025ebf1 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixPreconditioner.C
@@ -37,29 +37,66 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+Foam::word
+Foam::lduMatrix::preconditioner::getName
+(
+    const dictionary& solverControls
+)
+{
+    word name;
+
+    // handle primitive or dictionary entry
+    const entry& e = solverControls.lookupEntry("preconditioner", false, false);
+    if (e.isDict())
+    {
+        e.dict().lookup("preconditioner") >> name;
+    }
+    else
+    {
+        e.stream() >> name;
+    }
+
+    return name;
+}
+
+
 Foam::autoPtr<Foam::lduMatrix::preconditioner>
 Foam::lduMatrix::preconditioner::New
 (
     const solver& sol,
-    Istream& preconditionerData
+    const dictionary& solverControls
 )
 {
-    word preconditionerName(preconditionerData);
+    word name;
+
+    // handle primitive or dictionary entry
+    const entry& e = solverControls.lookupEntry("preconditioner", false, false);
+    if (e.isDict())
+    {
+        e.dict().lookup("preconditioner") >> name;
+    }
+    else
+    {
+        e.stream() >> name;
+    }
+
+    const dictionary& controls = e.isDict() ? e.dict() : dictionary::null;
 
     if (sol.matrix().symmetric())
     {
         symMatrixConstructorTable::iterator constructorIter =
-            symMatrixConstructorTablePtr_->find(preconditionerName);
+            symMatrixConstructorTablePtr_->find(name);
 
         if (constructorIter == symMatrixConstructorTablePtr_->end())
         {
             FatalIOErrorIn
             (
-                "lduMatrix::preconditioner::New(const solver&, Istream&)",
-                preconditionerData
+                "lduMatrix::preconditioner::New"
+                "(const solver&, const dictionary&)",
+                controls
             )   << "Unknown symmetric matrix preconditioner "
-                << preconditionerName << endl << endl
-                << "Valid symmetric matrix preconditioners are :" << endl
+                << name << nl << nl
+                << "Valid symmetric matrix preconditioners :" << endl
                 << symMatrixConstructorTablePtr_->toc()
                 << exit(FatalIOError);
         }
@@ -69,24 +106,25 @@ Foam::lduMatrix::preconditioner::New
             constructorIter()
             (
                 sol,
-                preconditionerData
+                controls
             )
         );
     }
     else if (sol.matrix().asymmetric())
     {
         asymMatrixConstructorTable::iterator constructorIter =
-            asymMatrixConstructorTablePtr_->find(preconditionerName);
+            asymMatrixConstructorTablePtr_->find(name);
 
         if (constructorIter == asymMatrixConstructorTablePtr_->end())
         {
             FatalIOErrorIn
             (
-                "lduMatrix::preconditioner::New(const solver&, Istream&)",
-                preconditionerData
+                "lduMatrix::preconditioner::New"
+                "(const solver&, const dictionary&)",
+                controls
             )   << "Unknown asymmetric matrix preconditioner "
-                << preconditionerName << endl << endl
-                << "Valid asymmetric matrix preconditioners are :" << endl
+                << name << nl << nl
+                << "Valid asymmetric matrix preconditioners :" << endl
                 << asymMatrixConstructorTablePtr_->toc()
                 << exit(FatalIOError);
         }
@@ -96,7 +134,7 @@ Foam::lduMatrix::preconditioner::New
             constructorIter()
             (
                 sol,
-                preconditionerData
+                controls
             )
         );
     }
@@ -104,9 +142,10 @@ Foam::lduMatrix::preconditioner::New
     {
         FatalIOErrorIn
         (
-            "lduMatrix::preconditioner::New(const solver&, Istream&)",
-            preconditionerData
-        )   << "cannot preconditione incomplete matrix, "
+            "lduMatrix::preconditioner::New"
+            "(const solver&, const dictionary&)",
+            controls
+        )   << "cannot solve incomplete matrix, "
                "no diagonal or off-diagonal coefficient"
             << exit(FatalIOError);
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSmoother.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSmoother.C
index 7554e4085c0e83e493b62f80f9f9ef904e8b867a..a18f65687d3476088a2b9e324c85f1cfa22891a4 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSmoother.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSmoother.C
@@ -34,9 +34,31 @@ namespace Foam
     defineRunTimeSelectionTable(lduMatrix::smoother, asymMatrix);
 }
 
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+Foam::word
+Foam::lduMatrix::smoother::getName
+(
+    const dictionary& solverControls
+)
+{
+    word name;
+
+    // handle primitive or dictionary entry
+    const entry& e = solverControls.lookupEntry("smoother", false, false);
+    if (e.isDict())
+    {
+        e.dict().lookup("smoother") >> name;
+    }
+    else
+    {
+        e.stream() >> name;
+    }
+
+    return name;
+}
+
+
 Foam::autoPtr<Foam::lduMatrix::smoother> Foam::lduMatrix::smoother::New
 (
     const word& fieldName,
@@ -44,23 +66,37 @@ Foam::autoPtr<Foam::lduMatrix::smoother> Foam::lduMatrix::smoother::New
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& smootherData
+    const dictionary& solverControls
 )
 {
-    word smootherName(smootherData);
+    word name;
+
+    // handle primitive or dictionary entry
+    const entry& e = solverControls.lookupEntry("smoother", false, false);
+    if (e.isDict())
+    {
+        e.dict().lookup("smoother") >> name;
+    }
+    else
+    {
+        e.stream() >> name;
+    }
+
+    // not (yet?) needed:
+    // const dictionary& controls = e.isDict() ? e.dict() : dictionary::null;
 
     if (matrix.symmetric())
     {
         symMatrixConstructorTable::iterator constructorIter =
-            symMatrixConstructorTablePtr_->find(smootherName);
+            symMatrixConstructorTablePtr_->find(name);
 
         if (constructorIter == symMatrixConstructorTablePtr_->end())
         {
             FatalIOErrorIn
             (
-                "lduMatrix::smoother::New", smootherData
-            )   << "Unknown symmetric matrix smoother " << smootherName
-                << endl << endl
+                "lduMatrix::smoother::New", solverControls
+            )   << "Unknown symmetric matrix smoother "
+                << name << nl << nl
                 << "Valid symmetric matrix smoothers are :" << endl
                 << symMatrixConstructorTablePtr_->toc()
                 << exit(FatalIOError);
@@ -81,15 +117,15 @@ Foam::autoPtr<Foam::lduMatrix::smoother> Foam::lduMatrix::smoother::New
     else if (matrix.asymmetric())
     {
         asymMatrixConstructorTable::iterator constructorIter =
-            asymMatrixConstructorTablePtr_->find(smootherName);
+            asymMatrixConstructorTablePtr_->find(name);
 
         if (constructorIter == asymMatrixConstructorTablePtr_->end())
         {
             FatalIOErrorIn
             (
-                "lduMatrix::smoother::New", smootherData
-            )   << "Unknown asymmetric matrix smoother " << smootherName
-                << endl << endl
+                "lduMatrix::smoother::New", solverControls
+            )   << "Unknown asymmetric matrix smoother "
+                << name << nl << nl
                 << "Valid asymmetric matrix smoothers are :" << endl
                 << asymMatrixConstructorTablePtr_->toc()
                 << exit(FatalIOError);
@@ -111,8 +147,9 @@ Foam::autoPtr<Foam::lduMatrix::smoother> Foam::lduMatrix::smoother::New
     {
         FatalIOErrorIn
         (
-            "lduMatrix::smoother::New", smootherData
-        )   << "cannot solve incomplete matrix, no off-diagonal coefficients"
+            "lduMatrix::smoother::New", solverControls
+        )   << "cannot solve incomplete matrix, "
+               "no diagonal or off-diagonal coefficient"
             << exit(FatalIOError);
 
         return autoPtr<lduMatrix::smoother>(NULL);
diff --git a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C
index 19fd2435a08ecad0afb0b37a487888042ce719eb..4b3b8d97a97f343addee636ffe05f6676e668256 100644
--- a/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/lduMatrix/lduMatrixSolver.C
@@ -45,10 +45,10 @@ Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 {
-    word solverName(solverData);
+    word name(solverControls.lookup("solver"));
 
     if (matrix.diagonal())
     {
@@ -61,22 +61,21 @@ Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
                 interfaceBouCoeffs,
                 interfaceIntCoeffs,
                 interfaces,
-                solverData
+                solverControls
             )
         );
     }
     else if (matrix.symmetric())
     {
         symMatrixConstructorTable::iterator constructorIter =
-            symMatrixConstructorTablePtr_->find(solverName);
+            symMatrixConstructorTablePtr_->find(name);
 
         if (constructorIter == symMatrixConstructorTablePtr_->end())
         {
             FatalIOErrorIn
             (
-                "lduMatrix::solver::New", solverData
-            )   << "Unknown symmetric matrix solver " << solverName
-                << endl << endl
+                "lduMatrix::solver::New", solverControls
+            )   << "Unknown symmetric matrix solver " << name << nl << nl
                 << "Valid symmetric matrix solvers are :" << endl
                 << symMatrixConstructorTablePtr_->toc()
                 << exit(FatalIOError);
@@ -91,22 +90,21 @@ Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
                 interfaceBouCoeffs,
                 interfaceIntCoeffs,
                 interfaces,
-                solverData
+                solverControls
             )
         );
     }
     else if (matrix.asymmetric())
     {
         asymMatrixConstructorTable::iterator constructorIter =
-            asymMatrixConstructorTablePtr_->find(solverName);
+            asymMatrixConstructorTablePtr_->find(name);
 
         if (constructorIter == asymMatrixConstructorTablePtr_->end())
         {
             FatalIOErrorIn
             (
-                "lduMatrix::solver::New", solverData
-            )   << "Unknown asymmetric matrix solver " << solverName
-                << endl << endl
+                "lduMatrix::solver::New", solverControls
+            )   << "Unknown asymmetric matrix solver " << name << nl << nl
                 << "Valid asymmetric matrix solvers are :" << endl
                 << asymMatrixConstructorTablePtr_->toc()
                 << exit(FatalIOError);
@@ -121,7 +119,7 @@ Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
                 interfaceBouCoeffs,
                 interfaceIntCoeffs,
                 interfaces,
-                solverData
+                solverControls
             )
         );
     }
@@ -129,7 +127,7 @@ Foam::autoPtr<Foam::lduMatrix::solver> Foam::lduMatrix::solver::New
     {
         FatalIOErrorIn
         (
-            "lduMatrix::solver::New", solverData
+            "lduMatrix::solver::New", solverControls
         )   << "cannot solve incomplete matrix, "
                "no diagonal or off-diagonal coefficient"
             << exit(FatalIOError);
@@ -148,7 +146,7 @@ Foam::lduMatrix::solver::solver
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 :
     fieldName_(fieldName),
@@ -156,12 +154,7 @@ Foam::lduMatrix::solver::solver
     interfaceBouCoeffs_(interfaceBouCoeffs),
     interfaceIntCoeffs_(interfaceIntCoeffs),
     interfaces_(interfaces),
-
-    controlDict_(solverData),
-
-    maxIter_(1000),
-    tolerance_(1e-6),
-    relTol_(0)
+    controlDict_(solverControls)
 {
     readControls();
 }
@@ -171,16 +164,15 @@ Foam::lduMatrix::solver::solver
 
 void Foam::lduMatrix::solver::readControls()
 {
-    controlDict_.readIfPresent("maxIter", maxIter_);
-    controlDict_.readIfPresent("tolerance", tolerance_);
-    controlDict_.readIfPresent("relTol", relTol_);
+    maxIter_   = controlDict_.lookupOrDefault<label>("maxIter", 1000);
+    tolerance_ = controlDict_.lookupOrDefault<scalar>("tolerance", 1e-6);
+    relTol_    = controlDict_.lookupOrDefault<scalar>("relTol", 0);
 }
 
 
-void Foam::lduMatrix::solver::read(Istream& solverData)
+void Foam::lduMatrix::solver::read(const dictionary& solverControls)
 {
-    word solverName(solverData);
-    solverData >> controlDict_;
+    controlDict_ = solverControls;
     readControls();
 }
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C
index 449a992cbe8a9cc0a895635cadbc4caf4cb09fa2..03141b88a610b75abf6ff5e63dd994200eb25bcd 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.C
@@ -43,7 +43,7 @@ namespace Foam
 Foam::DICPreconditioner::DICPreconditioner
 (
     const lduMatrix::solver& sol,
-    Istream&
+    const dictionary&
 )
 :
     lduMatrix::preconditioner(sol),
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H
index aa1367a76177a9d3e0137e72f84ddf81155c14e8..61feee478eb4a50bfc291eb09ea480f3b2f69fa6 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DICPreconditioner/DICPreconditioner.H
@@ -67,11 +67,11 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and preconditioner data stream
+        //- Construct from matrix components and preconditioner solver controls
         DICPreconditioner
         (
-            const lduMatrix::solver& sol,
-            Istream& preconditionerData
+            const lduMatrix::solver&,
+            const dictionary& solverControlsUnused
         );
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C
index 782283879350641090620fcbbbe02c8f3cca1b4e..f8778b0406ac539323cf29e9eb8be5777da89fb9 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.C
@@ -43,7 +43,7 @@ namespace Foam
 Foam::DILUPreconditioner::DILUPreconditioner
 (
     const lduMatrix::solver& sol,
-    Istream&
+    const dictionary&
 )
 :
     lduMatrix::preconditioner(sol),
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H
index 8e9776e5cbebe48f78332a9b28b5776b0b3ae1fd..aaaba8918fb98be87951e5062bbe56e3bc4e7a5c 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/DILUPreconditioner/DILUPreconditioner.H
@@ -67,11 +67,11 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and preconditioner data stream
+        //- Construct from matrix components and preconditioner solver controls
         DILUPreconditioner
         (
-            const lduMatrix::solver& sol,
-            Istream& preconditionerData
+            const lduMatrix::solver&,
+            const dictionary& solverControlsUnused
         );
 
 
@@ -94,8 +94,7 @@ public:
             const direction cmpt=0
         ) const;
 
-        //- Return wT the transpose-matrix preconditioned form of
-        //  residual rT.
+        //- Return wT the transpose-matrix preconditioned form of residual rT.
         virtual void preconditionT
         (
             scalarField& wT,
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C
index 8f38f29b047c18122b1311e49326626901188ed0..31574f1718d07bb5ea6e38ba99aeb570b44b6d66 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.C
@@ -43,7 +43,7 @@ namespace Foam
 Foam::FDICPreconditioner::FDICPreconditioner
 (
     const lduMatrix::solver& sol,
-    Istream&
+    const dictionary&
 )
 :
     lduMatrix::preconditioner(sol),
@@ -164,7 +164,7 @@ void Foam::FDICPreconditioner::precondition
         __builtin_prefetch (&uPtr[face+96],0,0);
         __builtin_prefetch (&lPtr[face+96],0,0);
         __builtin_prefetch (&rDuUpperPtr[face+96],0,0);
-        __builtin_prefetch (&wAPtr[uPtr[face+32]],0,1); 
+        __builtin_prefetch (&wAPtr[uPtr[face+32]],0,1);
         __builtin_prefetch (&wAPtr[lPtr[face+32]],0,1);
         #endif
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H
index 6312b8171f91772d9b4ccd51676faf3bdb23cc7c..53e0caac0f06720766dfbf5de794034e12736324 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/FDICPreconditioner/FDICPreconditioner.H
@@ -80,11 +80,11 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and preconditioner data stream
+        //- Construct from matrix components and preconditioner solver controls
         FDICPreconditioner
         (
-            const lduMatrix::solver& sol,
-            Istream& preconditionerData
+            const lduMatrix::solver&,
+            const dictionary& solverControlsUnused
         );
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C
index cfd2f4513ef64ee6dc58a999459006f520f15e91..3433168e2085618f5c70d49c740458fd79414209 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.C
@@ -45,7 +45,7 @@ namespace Foam
 Foam::GAMGPreconditioner::GAMGPreconditioner
 (
     const lduMatrix::solver& sol,
-    Istream& preconditionerData
+    const dictionary& solverControls
 )
 :
     GAMGSolver
@@ -55,7 +55,7 @@ Foam::GAMGPreconditioner::GAMGPreconditioner
         sol.interfaceBouCoeffs(),
         sol.interfaceIntCoeffs(),
         sol.interfaces(),
-        preconditionerData
+        solverControls
     ),
     lduMatrix::preconditioner(sol),
     nVcycles_(2)
@@ -75,13 +75,7 @@ Foam::GAMGPreconditioner::~GAMGPreconditioner()
 void Foam::GAMGPreconditioner::readControls()
 {
     GAMGSolver::readControls();
-    controlDict_.readIfPresent("nVcycles", nVcycles_);
-}
-
-
-void Foam::GAMGPreconditioner::read(Istream& solverData)
-{
-    GAMGSolver::read(solverData);
+    nVcycles_ = controlDict_.lookupOrDefault<label>("nVcycles", 2);
 }
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H
index 1e9bfae843aa186b1c448241a1222d2f345136a2..82ca63580b131a45fc2abc2716f367a0b194bcdd 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/GAMGPreconditioner/GAMGPreconditioner.H
@@ -55,17 +55,14 @@ class GAMGPreconditioner
     public GAMGSolver,
     public lduMatrix::preconditioner
 {
-    // Private data
+protected:
+    // Protected data
 
         //- Number of V-cycles to perform
         label nVcycles_;
 
-
-    // Private member functions
-
-        //- Read control parameters from the control dictionary
-        void readControls();
-
+        //- Read the control parameters from the controlDict_
+        virtual void readControls();
 
 public:
 
@@ -75,11 +72,11 @@ public:
 
     // Constructors
 
-        //- Construct for given solver and preconditioner data stream
+        //- Construct from matrix components and preconditioner solver controls
         GAMGPreconditioner
         (
-            const lduMatrix::solver& sol,
-            Istream& preconditionerData
+            const lduMatrix::solver&,
+            const dictionary& solverControls
         );
 
 
@@ -90,9 +87,6 @@ public:
 
     // Member Functions
 
-        //- Read and reset the preconditioner parameters from the given stream
-        virtual void read(Istream& preconditionerData);
-
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C
index 3bce37a2c77e1beb2efd83aa04da4e09c6af480d..04da54f1c46488e83202969217e7f14590639abc 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.C
@@ -47,7 +47,7 @@ namespace Foam
 Foam::diagonalPreconditioner::diagonalPreconditioner
 (
     const lduMatrix::solver& sol,
-    Istream&
+    const dictionary&
 )
 :
     lduMatrix::preconditioner(sol),
@@ -77,10 +77,6 @@ Foam::diagonalPreconditioner::diagonalPreconditioner
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::diagonalPreconditioner::read(Istream&)
-{}
-
-
 void Foam::diagonalPreconditioner::precondition
 (
     scalarField& wA,
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H
index cc6f8f82b3406e3ab02d7ae476d66b211fc45279..3a0bcb4b2be92acfca8ec15d4e365ed77790e2c6 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/diagonalPreconditioner/diagonalPreconditioner.H
@@ -56,7 +56,7 @@ class diagonalPreconditioner
 {
     // Private data
 
-        //- The reciprocal diagonal 
+        //- The reciprocal diagonal
         scalarField rD;
 
 
@@ -77,11 +77,11 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and preconditioner data stream
+        //- Construct from matrix components and preconditioner solver controls
         diagonalPreconditioner
         (
-            const lduMatrix::solver& sol,
-            Istream& preconditionerData
+            const lduMatrix::solver&,
+            const dictionary& solverControlsUnused
         );
 
 
@@ -93,9 +93,6 @@ public:
 
     // Member Functions
 
-        //- Read and reset the preconditioner parameters from the given stream
-        virtual void read(Istream& preconditionerData);
-
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
@@ -104,8 +101,7 @@ public:
             const direction cmpt=0
         ) const;
 
-        //- Return wT the transpose-matrix preconditioned form of
-        //  residual rT.
+        //- Return wT the transpose-matrix preconditioned form of residual rT.
         virtual void preconditionT
         (
             scalarField& wT,
@@ -113,7 +109,7 @@ public:
             const direction cmpt=0
         ) const
         {
-            return(precondition(wT, rT, cmpt));
+            return precondition(wT, rT, cmpt);
         }
 };
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C
index 00d1129b5bc306ad4809f17fcc04f3a07ad56d43..1f4fe2b4a4f8a3921f4ea6624ef92e87de7f3a2f 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.C
@@ -47,7 +47,7 @@ namespace Foam
 Foam::noPreconditioner::noPreconditioner
 (
     const lduMatrix::solver& sol,
-    Istream&
+    const dictionary&
 )
 :
     lduMatrix::preconditioner(sol)
@@ -56,10 +56,6 @@ Foam::noPreconditioner::noPreconditioner
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-void Foam::noPreconditioner::read(Istream&)
-{}
-
-
 void Foam::noPreconditioner::precondition
 (
     scalarField& wA,
diff --git a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H
index bedab173213546b84416ac4159db82eb2c2ed615..9668f217fcac66e8e2441b8cff7c09eabef4744c 100644
--- a/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H
+++ b/src/OpenFOAM/matrices/lduMatrix/preconditioners/noPreconditioner/noPreconditioner.H
@@ -68,11 +68,11 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and preconditioner data stream
+        //- Construct from matrix components and preconditioner solver controls
         noPreconditioner
         (
-            const lduMatrix::solver& sol,
-            Istream& preconditionerData
+            const lduMatrix::solver&, 
+            const dictionary& solverControlsUnused
         );
 
 
@@ -84,9 +84,6 @@ public:
 
     // Member Functions
 
-        //- Read and reset the preconditioner parameters from the given stream
-        virtual void read(Istream& preconditionerData);
-
         //- Return wA the preconditioned form of residual rA
         virtual void precondition
         (
@@ -95,8 +92,7 @@ public:
             const direction cmpt=0
         ) const;
 
-        //- Return wT the transpose-matrix preconditioned form of
-        //  residual rT.
+        //- Return wT the transpose-matrix preconditioned form of residual rT.
         virtual void preconditionT
         (
             scalarField& wT,
@@ -104,7 +100,7 @@ public:
             const direction cmpt=0
         ) const
         {
-            return(precondition(wT, rT, cmpt));
+            return precondition(wT, rT, cmpt);
         }
 };
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H
index 5a59ac98b369393c51f11acda6ba95dde24c8b4f..11346a51d1e0f5a5b84edf67366199f2042fbb09 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DIC/DICSmoother.H
@@ -27,8 +27,10 @@ Class
 
 Description
     Simplified diagonal-based incomplete Cholesky smoother for symmetric
-    matrices.  In order to improve efficiency the residual is evaluated after
-    every nSweeps sweeps.
+    matrices.
+
+    To improve efficiency, the residual is evaluated after every nSweeps
+    sweeps.
 
 SourceFiles
     DICSmoother.C
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H
index 55312c0ef5125d3b2f21f5723eb4419664a115a0..12a9c9c173b66edc3c3f8e60515c8b23cd55fc04 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DICGaussSeidel/DICGaussSeidelSmoother.H
@@ -26,9 +26,9 @@ Class
     Foam::DICGaussSeidelSmoother
 
 Description
-    Combined DIC/GaussSeidel smoother for symmetric
-    matrices in which DIC smoothing is followed by GaussSeidel to ensure that
-    any "spikes" created by the DIC sweeps are smoothed-out. 
+    Combined DIC/GaussSeidel smoother for symmetric matrices in which DIC
+    smoothing is followed by GaussSeidel to ensure that any "spikes" created
+    by the DIC sweeps are smoothed-out.
 
 SourceFiles
     DICGaussSeidelSmoother.C
@@ -47,7 +47,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class DICGaussSeidelSmoother Declaration
+                   Class DICGaussSeidelSmoother Declaration
 \*---------------------------------------------------------------------------*/
 
 class DICGaussSeidelSmoother
@@ -57,6 +57,7 @@ class DICGaussSeidelSmoother
     // Private data
 
         DICSmoother dicSmoother_;
+
         GaussSeidelSmoother gsSmoother_;
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H
index f95bd91972a822bbde86f65e754760e9eb20e9e1..a8218973dd2e3a04ab63e2b614b2db776ab0922c 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILU/DILUSmoother.H
@@ -27,8 +27,9 @@ Class
 
 Description
     Simplified diagonal-based incomplete LU smoother for asymmetric matrices.
-    In order to improve efficiency the residual is evaluated after every
-    nSweeps sweeps.
+
+    To improve efficiency, the residual is evaluated after every nSweeps
+    sweeps.
 
 SourceFiles
     DILUSmoother.C
@@ -46,7 +47,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class DILUSmoother Declaration
+                        Class DILUSmoother Declaration
 \*---------------------------------------------------------------------------*/
 
 class DILUSmoother
diff --git a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H
index 6783280f05183cfad176a79274bbc4ea15758f40..6523e259c25a6c118dcb71b7910243271396bf24 100644
--- a/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H
+++ b/src/OpenFOAM/matrices/lduMatrix/smoothers/DILUGaussSeidel/DILUGaussSeidelSmoother.H
@@ -26,9 +26,9 @@ Class
     Foam::DILUGaussSeidelSmoother
 
 Description
-    Combined DILU/GaussSeidel smoother for asymmetric
-    matrices in which DILU smoothing is followed by GaussSeidel to ensure that
-    any "spikes" created by the DILU sweeps are smoothed-out. 
+    Combined DILU/GaussSeidel smoother for asymmetric matrices in which
+    DILU smoothing is followed by GaussSeidel to ensure that any "spikes"
+    created by the DILU sweeps are smoothed-out.
 
 SourceFiles
     DILUGaussSeidelSmoother.C
@@ -47,7 +47,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class DILUGaussSeidelSmoother Declaration
+                   Class DILUGaussSeidelSmoother Declaration
 \*---------------------------------------------------------------------------*/
 
 class DILUGaussSeidelSmoother
@@ -57,6 +57,7 @@ class DILUGaussSeidelSmoother
     // Private data
 
         DILUSmoother diluSmoother_;
+
         GaussSeidelSmoother gsSmoother_;
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.C
index 7772f7c6a3ced7c9c00daab57545792a4f2967e3..e88b873f9f4ab407096b2bc596c3ee4f5575d3ca 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.C
@@ -37,36 +37,31 @@ namespace Foam
 }
 
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-Foam::IStringStream Foam::BICCG::solverDataStream
+Foam::dictionary Foam::BICCG::solverDict
 (
-    const scalar tolerance,
+    const scalar tol,
     const scalar relTol
-) const
+)
 {
-    return IStringStream
-    (
-        "{ preconditioner   DILU;"
-        "  tolerance " + name(tolerance) + "; relTol " + name(relTol) + "; }"
-    );
+    dictionary dict(IStringStream("solver PBiCG; preconditioner DILU;")());
+    dict.add("tolerance", tol);
+    dict.add("relTol", relTol);
+
+    return dict;
 }
 
 
-Foam::IStringStream Foam::BICCG::solverDataStream
+Foam::dictionary Foam::BICCG::solverDict
 (
-    const word& solverName,
-    Istream& solverData
-) const
+    Istream& is
+)
 {
-    scalar tolerance(readScalar(solverData));
-    scalar relTol(readScalar(solverData));
+    scalar tol(readScalar(is));
+    scalar relTol(readScalar(is));
 
-    return IStringStream
-    (
-        solverName + "{ preconditioner   DILU;"
-        "  tolerance " + name(tolerance) + "; relTol " + name(relTol) + "; }"
-    );
+    return solverDict(tol, relTol);
 }
 
 
@@ -79,8 +74,7 @@ Foam::BICCG::BICCG
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    const scalar tolerance,
-    const scalar relTol
+    const dictionary& solverControls
 )
 :
     PBiCG
@@ -90,7 +84,7 @@ Foam::BICCG::BICCG
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverDataStream(tolerance, relTol)()
+        solverControls
     )
 {}
 
@@ -102,7 +96,8 @@ Foam::BICCG::BICCG
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const scalar tolerance,
+    const scalar relTol
 )
 :
     PBiCG
@@ -112,18 +107,8 @@ Foam::BICCG::BICCG
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverDataStream(word::null, solverData)()
+        solverDict(tolerance, relTol)
     )
 {}
 
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::BICCG::read(Istream& solverData)
-{
-    word solverName(solverData);
-    PBiCG::read(solverDataStream(solverName, solverData)());
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.H b/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.H
index c6c140345ce4a6cc94f6a0a92583fdda30f2931a..f3058a9b67dfa96015e93bf9dc715351b8273188 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/BICCG/BICCG.H
@@ -32,7 +32,7 @@ Description
 
 Deprecated
     This solver is present for backward-compatibility and the PBiCG solver
-    should be used for preference.
+    should be used instead.
 
 SourceFiles
     BICCG.C
@@ -65,24 +65,20 @@ class BICCG
         //- Disallow default bitwise assignment
         void operator=(const BICCG&);
 
-        //- Return the dictionary data-stream constructed from the components.
-        //  Needed for backward compatibility
-        IStringStream solverDataStream
-        (
-            const scalar tolerance,
-            const scalar relTol
-        ) const;
+public:
 
-        //- Return the dictionary data-stream constructed from the old-style
-        //  data-stream.  Needed for backward compatibility
-        IStringStream solverDataStream
-        (
-            const word& solverName,
-            Istream& solverData
-        ) const;
+    //- Return the dictionary constructed from the components.
+    //  Needed for backward compatibility
+    static dictionary solverDict
+    (
+        const scalar tol,
+        const scalar relTol
+    );
 
+    //- Return the dictionary constructed from the old-style data-stream.
+    //  Needed for backward compatibility
+    static dictionary solverDict(Istream&);
 
-public:
 
     //- Runtime type information
     TypeName("BICCG");
@@ -90,7 +86,7 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and tolerances
+        //- Construct from matrix components and solver data stream
         BICCG
         (
             const word& fieldName,
@@ -98,11 +94,11 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            const scalar tolerance,
-            const scalar relTol = 0.0
+            const dictionary& solverControls
         );
 
-        //- Construct from matrix components and solver data stream
+
+        //- Construct from matrix components and tolerances
         BICCG
         (
             const word& fieldName,
@@ -110,20 +106,15 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const scalar tolerance,
+            const scalar relTol = 0.0
         );
 
-
     // Destructor
 
         virtual ~BICCG()
         {}
 
-
-    // Member Functions
-
-        //- Read and reset the solver parameters from the given stream
-        void read(Istream& solverData);
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C
index f8a29ba2413738a3820aae190206287e74c314c8..ef838342e8d2f9d6199a4751e4ffe91db60b2c2a 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.C
@@ -49,7 +49,7 @@ Foam::GAMGSolver::GAMGSolver
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 :
     lduMatrix::solver
@@ -59,7 +59,7 @@ Foam::GAMGSolver::GAMGSolver
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverData
+        solverControls
     ),
 
     // Default values for all controls
@@ -112,7 +112,7 @@ Foam::GAMGSolver::GAMGSolver
             "const FieldField<Field, scalar>& interfaceBouCoeffs,"
             "const FieldField<Field, scalar>& interfaceIntCoeffs,"
             "const lduInterfaceFieldPtrsList& interfaces,"
-            "Istream& solverData"
+            "const dictionary& solverControls"
             ")"
         )   << "No coarse levels created, either matrix too small for GAMG"
                " or nCellsInCoarsestLevel too large.\n"
@@ -154,6 +154,7 @@ void Foam::GAMGSolver::readControls()
 {
     lduMatrix::solver::readControls();
 
+    // we could also consider supplying defaults here too
     controlDict_.readIfPresent("cacheAgglomeration", cacheAgglomeration_);
     controlDict_.readIfPresent("nPreSweeps", nPreSweeps_);
     controlDict_.readIfPresent("nPostSweeps", nPostSweeps_);
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H
index 8c4596c888979d6642583d2e66b6599db59955fe..6cbef1f5092bd8ef361fd8ca7d2e4785e2a6a198 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolver.H
@@ -212,7 +212,7 @@ public:
 
     // Constructors
 
-        //- Construct from lduMatrix
+        //- Construct from lduMatrix and solver controls
         GAMGSolver
         (
             const word& fieldName,
@@ -220,7 +220,7 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const dictionary& solverControls
         );
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
index 431f2f179f01756a5484f9a13147398ce4ff7d37..e7e2a6339180035768c107e0b29ceb612d7c2f41 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/GAMG/GAMGSolverSolve.C
@@ -374,7 +374,7 @@ void Foam::GAMGSolver::initVcycle
             interfaceBouCoeffs_,
             interfaceIntCoeffs_,
             interfaces_,
-            controlDict_.lookup("smoother")
+            controlDict_
         )
     );
 
@@ -408,7 +408,7 @@ void Foam::GAMGSolver::initVcycle
                 interfaceLevelsBouCoeffs_[leveli],
                 interfaceLevelsIntCoeffs_[leveli],
                 interfaceLevels_[leveli],
-                controlDict_.lookup("smoother")
+                controlDict_
             )
         );
     }
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.C
index dbd4ae16d083f2561a49f4a4d5ba4492bd4f40d4..97a03b4f0d1a49afd1c1306c1e675ae7c4a87911 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.C
@@ -36,40 +36,33 @@ namespace Foam
         addICCGSymMatrixConstructorToTable_;
 }
 
+// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
-
-Foam::IStringStream Foam::ICCG::solverDataStream
+Foam::dictionary Foam::ICCG::solverDict
 (
-    const scalar tolerance,
+    const scalar tol,
     const scalar relTol
-) const
+)
 {
-    return IStringStream
-    (
-        "{ preconditioner   DIC;"
-        "  tolerance " + name(tolerance) + "; relTol " + name(relTol) + "; }"
-    );
+    dictionary dict(IStringStream("solver PCG; preconditioner DIC;")());
+    dict.add("tolerance", tol);
+    dict.add("relTol", relTol);
+
+    return dict;
 }
 
 
-Foam::IStringStream Foam::ICCG::solverDataStream
+Foam::dictionary Foam::ICCG::solverDict
 (
-    const word& solverName,
-    Istream& solverData
-) const
+    Istream& is
+)
 {
-    scalar tolerance(readScalar(solverData));
-    scalar relTol(readScalar(solverData));
+    scalar tol(readScalar(is));
+    scalar relTol(readScalar(is));
 
-    return IStringStream
-    (
-        solverName + "{ preconditioner   DIC;"
-        "  tolerance " + name(tolerance) + "; relTol " + name(relTol) + "; }"
-    );
+    return solverDict(tol, relTol);
 }
 
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::ICCG::ICCG
@@ -79,8 +72,7 @@ Foam::ICCG::ICCG
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    const scalar tolerance,
-    const scalar relTol
+    const dictionary& solverControls
 )
 :
     PCG
@@ -90,7 +82,7 @@ Foam::ICCG::ICCG
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverDataStream(tolerance, relTol)()
+        solverControls
     )
 {}
 
@@ -102,7 +94,8 @@ Foam::ICCG::ICCG
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const scalar tolerance,
+    const scalar relTol
 )
 :
     PCG
@@ -112,18 +105,8 @@ Foam::ICCG::ICCG
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverDataStream(word::null, solverData)()
+        solverDict(tolerance, relTol)
     )
 {}
 
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-void Foam::ICCG::read(Istream& solverData)
-{
-    word solverName(solverData);
-    PCG::read(solverDataStream(solverName, solverData)());
-}
-
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.H b/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.H
index c8f124f87ce35303a90562d242e3fc1f454928ea..850c3f47753698a7be22fc354c38ddbf9707fe27 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/ICCG/ICCG.H
@@ -65,24 +65,20 @@ class ICCG
         //- Disallow default bitwise assignment
         void operator=(const ICCG&);
 
-        //- Return the dictionary data-stream constructed from the components.
+public:
+
+        //- Return the dictionary constructed from the components.
         //  Needed for backward compatibility
-        IStringStream solverDataStream
+        static dictionary solverDict
         (
-            const scalar tolerance,
+            const scalar tol,
             const scalar relTol
-        ) const;
-
-        //- Return the dictionary data-stream constructed from the old-style
-        //  data-stream.  Needed for backward compatibility
-        IStringStream solverDataStream
-        (
-            const word& solverName,
-            Istream& solverData
-        ) const;
+        );
 
+        //- Return the dictionary constructed from the old-style data-stream.
+        //  Needed for backward compatibility
+        static dictionary solverDict(Istream&);
 
-public:
 
     //- Runtime type information
     TypeName("ICCG");
@@ -90,7 +86,7 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and tolerances
+        //- Construct from matrix components and solver data stream
         ICCG
         (
             const word& fieldName,
@@ -98,11 +94,10 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            const scalar tolerance,
-            const scalar relTol = 0.0
+            const dictionary& solverControls
         );
 
-        //- Construct from matrix components and solver data stream
+        //- Construct from matrix components and tolerances
         ICCG
         (
             const word& fieldName,
@@ -110,20 +105,15 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const scalar tolerance,
+            const scalar relTol = 0.0
         );
 
-
     // Destructor
 
         virtual ~ICCG()
         {}
 
-
-    // Member Functions
-
-        //- Read and reset the solver parameters from the given stream
-        void read(Istream& solverData);
 };
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
index 9100ae5777b8815e5d39bb20d09019bf4be7d761..af4137f689634bb1810e67bb75ad31e4dd02585d 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.C
@@ -46,7 +46,7 @@ Foam::PBiCG::PBiCG
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 :
     lduMatrix::solver
@@ -56,7 +56,7 @@ Foam::PBiCG::PBiCG
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverData
+        solverControls
     )
 {}
 
@@ -70,12 +70,10 @@ Foam::lduMatrix::solverPerformance Foam::PBiCG::solve
     const direction cmpt
 ) const
 {
-    word preconditionerName(controlDict_.lookup("preconditioner"));
-
     // --- Setup class containing solver performance data
     lduMatrix::solverPerformance solverPerf
     (
-        preconditionerName + typeName,
+        lduMatrix::preconditioner::getName(controlDict_) + typeName,
         fieldName_
     );
 
@@ -128,7 +126,7 @@ Foam::lduMatrix::solverPerformance Foam::PBiCG::solve
         lduMatrix::preconditioner::New
         (
             *this,
-            controlDict_.lookup("preconditioner")
+            controlDict_
         );
 
         // --- Solver iteration
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.H b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.H
index 07adf0c8e41add0e7b559cadaedcebc61f16a000..6ba96fe9692a1697034398e4bca08ad15b90f236 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PBiCG/PBiCG.H
@@ -77,7 +77,7 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const dictionary& solverControls
         );
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
index a21eeaca15ceda3cf18d2272418e1fd88a3d57ff..ad0ae5a08120b90b6e335416bd5727763843da66 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.C
@@ -46,7 +46,7 @@ Foam::PCG::PCG
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 :
     lduMatrix::solver
@@ -56,7 +56,7 @@ Foam::PCG::PCG
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverData
+        solverControls
     )
 {}
 
@@ -70,12 +70,10 @@ Foam::lduMatrix::solverPerformance Foam::PCG::solve
     const direction cmpt
 ) const
 {
-    word preconditionerName(controlDict_.lookup("preconditioner"));
-
     // --- Setup class containing solver performance data
     lduMatrix::solverPerformance solverPerf
     (
-        preconditionerName + typeName,
+        lduMatrix::preconditioner::getName(controlDict_) + typeName,
         fieldName_
     );
 
@@ -119,7 +117,7 @@ Foam::lduMatrix::solverPerformance Foam::PCG::solve
         lduMatrix::preconditioner::New
         (
             *this,
-            controlDict_.lookup("preconditioner")
+            controlDict_
         );
 
         // --- Solver iteration
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H
index 6627bd45b1e3dbb3ef3aee245533dcb734c74a18..4e0b5b4e2811b30582a18c4a28ea100c17a78275 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/PCG/PCG.H
@@ -27,7 +27,7 @@ Class
 
 Description
     Preconditioned conjugate gradient solver for symmetric lduMatrices
-    using a run-time selectable preconditiioner.
+    using a run-time selectable preconditioner.
 
 SourceFiles
     PCG.C
@@ -69,7 +69,7 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and solver data stream
+        //- Construct from matrix components and solver controls
         PCG
         (
             const word& fieldName,
@@ -77,7 +77,7 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const dictionary& solverControls
         );
 
 
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.C
index 583a2008e3d5f4e26dbb855fd1d245cbe633f433..3255ca896ae1402fa508b46f021ef797188be5c5 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.C
@@ -43,7 +43,7 @@ Foam::diagonalSolver::diagonalSolver
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 :
     lduMatrix::solver
@@ -53,19 +53,13 @@ Foam::diagonalSolver::diagonalSolver
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverData
+        solverControls
     )
 {}
 
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-void Foam::diagonalSolver::read(Istream& solverData)
-{
-    word solverName(solverData);
-}
-
-
 Foam::lduMatrix::solverPerformance Foam::diagonalSolver::solve
 (
     scalarField& psi,
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.H b/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.H
index 573f4cc233e2d3ea70d0b7654c613309ffce9126..b4ac77631262dea96216f3d95bfbbdb78008836f 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/diagonalSolver/diagonalSolver.H
@@ -68,7 +68,7 @@ public:
 
     // Constructors
 
-        //- Construct from matrix
+        //- Construct from matrix and solver controls
         diagonalSolver
         (
             const word& fieldName,
@@ -76,14 +76,15 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const dictionary& solverControls
         );
 
 
     // Member Functions
 
         //- Read and reset the solver parameters from the given stream
-        void read(Istream& solverData);
+        void read(const dictionary&)
+        {}
 
         //- Solve the matrix with this solver
         lduMatrix::solverPerformance solve
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
index 6b7c1cbcc3c66d9c9c33f9c1361f76433ca0602f..503e376bd28991ad8cfd5e9091aa6c8ee841567d 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.C
@@ -49,7 +49,7 @@ Foam::smoothSolver::smoothSolver
     const FieldField<Field, scalar>& interfaceBouCoeffs,
     const FieldField<Field, scalar>& interfaceIntCoeffs,
     const lduInterfaceFieldPtrsList& interfaces,
-    Istream& solverData
+    const dictionary& solverControls
 )
 :
     lduMatrix::solver
@@ -59,9 +59,8 @@ Foam::smoothSolver::smoothSolver
         interfaceBouCoeffs,
         interfaceIntCoeffs,
         interfaces,
-        solverData
-    ),
-    nSweeps_(1)
+        solverControls
+    )
 {
     readControls();
 }
@@ -72,7 +71,7 @@ Foam::smoothSolver::smoothSolver
 void Foam::smoothSolver::readControls()
 {
     lduMatrix::solver::readControls();
-    controlDict_.readIfPresent("nSweeps", nSweeps_);
+    nSweeps_ = controlDict_.lookupOrDefault<label>("nSweeps", 1);
 }
 
 
@@ -96,7 +95,7 @@ Foam::lduMatrix::solverPerformance Foam::smoothSolver::solve
             interfaceBouCoeffs_,
             interfaceIntCoeffs_,
             interfaces_,
-            controlDict_.lookup("smoother")
+            controlDict_
         );
 
         smootherPtr->smooth
@@ -144,7 +143,7 @@ Foam::lduMatrix::solverPerformance Foam::smoothSolver::solve
                 interfaceBouCoeffs_,
                 interfaceIntCoeffs_,
                 interfaces_,
-                controlDict_.lookup("smoother")
+                controlDict_
             );
 
             // Smoothing loop
diff --git a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.H b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.H
index 3d5687a8a93d81172d7b14448546618db1d27ed8..15ddf7bf3b2750b25c07f27d7f3eb537bed4f4b7 100644
--- a/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.H
+++ b/src/OpenFOAM/matrices/lduMatrix/solvers/smoothSolver/smoothSolver.H
@@ -66,7 +66,6 @@ protected:
         //- Read the control parameters from the controlDict_
         virtual void readControls();
 
-
 public:
 
     //- Runtime type information
@@ -75,7 +74,7 @@ public:
 
     // Constructors
 
-        //- Construct from matrix components and solver data stream
+        //- Construct from matrix components and solver controls
         smoothSolver
         (
             const word& fieldName,
@@ -83,10 +82,15 @@ public:
             const FieldField<Field, scalar>& interfaceBouCoeffs,
             const FieldField<Field, scalar>& interfaceIntCoeffs,
             const lduInterfaceFieldPtrsList& interfaces,
-            Istream& solverData
+            const dictionary& solverControls
         );
 
 
+    // Destructor
+
+        virtual ~smoothSolver()
+        {}
+
     // Member Functions
 
         //- Solve the matrix with this solver
diff --git a/src/OpenFOAM/matrices/solution/solution.C b/src/OpenFOAM/matrices/solution/solution.C
index 5429a20e8177fe8365fbdff1ebbcc9df2a5f1aee..44ecc4792cbb0592c203733fae129684c7970300 100644
--- a/src/OpenFOAM/matrices/solution/solution.C
+++ b/src/OpenFOAM/matrices/solution/solution.C
@@ -27,9 +27,22 @@ License
 #include "solution.H"
 #include "Time.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// these are for old syntax compatibility:
+#include "BICCG.H"
+#include "ICCG.H"
+#include "IStringStream.H"
 
-int Foam::solution::debug(Foam::debug::debugSwitch("solution", false));
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+int Foam::solution::debug(::Foam::debug::debugSwitch("solution", 0));
+
+// list of sub-dictionaries to rewrite
+//! @cond localScope
+static const Foam::List<Foam::word> subDictNames
+(
+    Foam::IStringStream("(preconditioner smoother)")()
+);
+//! @endcond localScope
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
@@ -55,6 +68,84 @@ Foam::solution::solution(const objectRegistry& obr, const fileName& dictName)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+Foam::label Foam::solution::upgradeSolverDict
+(
+    dictionary& dict,
+    const bool verbose
+)
+{
+    label nChanged = 0;
+
+    // backward compatibility:
+    // recast primitive entries into dictionary entries
+    forAllIter(dictionary, dict, iter)
+    {
+        if (!iter().isDict())
+        {
+            Istream& is = iter().stream();
+            word name(is);
+            dictionary subdict;
+
+            if (name == "BICCG")
+            {
+                // special treatment for very old syntax
+                subdict = BICCG::solverDict(is);
+            }
+            else if (name == "ICCG")
+            {
+                // special treatment for very old syntax
+                subdict = ICCG::solverDict(is);
+            }
+            else
+            {
+                subdict.add("solver", name);
+                subdict <<= dictionary(is);
+
+                // preconditioner and smoother entries can be
+                // 1) primitiveEntry w/o settings,
+                // 2) or a dictionaryEntry.
+                // transform primitiveEntry with settings -> dictionaryEntry
+                forAll(subDictNames, dictI)
+                {
+                    const word& dictName = subDictNames[dictI];
+                    entry* ePtr = subdict.lookupEntryPtr(dictName,false,false);
+
+                    if (ePtr && !ePtr->isDict())
+                    {
+                        Istream& is = ePtr->stream();
+                        is >> name;
+
+                        if (!is.eof())
+                        {
+                            dictionary newDict;
+                            newDict.add(dictName, name);
+                            newDict <<= dictionary(is);
+
+                            subdict.set(dictName, newDict);
+                        }
+                    }
+                }
+            }
+
+
+            // write out information to help people adjust to the new syntax
+            if (verbose)
+            {
+                Info<< "// using new solver syntax:\n"
+                    << iter().keyword() << subdict << endl;
+            }
+
+            // overwrite with dictionary entry
+            dict.set(iter().keyword(), subdict);
+
+            nChanged++;
+        }
+    }
+
+    return nChanged;
+}
+
+
 bool Foam::solution::read()
 {
     if (regIOobject::read())
@@ -69,6 +160,7 @@ bool Foam::solution::read()
         if (dict.found("solvers"))
         {
             solvers_ = dict.subDict("solvers");
+            upgradeSolverDict(solvers_);
         }
 
         return true;
@@ -97,7 +189,7 @@ bool Foam::solution::relax(const word& name) const
 {
     if (debug)
     {
-        Info<< "Lookup relax for " << name << endl;
+        Info<< "Find relax for " << name << endl;
     }
 
     return relaxationFactors_.found(name);
@@ -127,7 +219,7 @@ const Foam::dictionary& Foam::solution::solverDict(const word& name) const
 }
 
 
-Foam::ITstream& Foam::solution::solver(const word& name) const
+const Foam::dictionary& Foam::solution::solver(const word& name) const
 {
     if (debug)
     {
@@ -135,7 +227,7 @@ Foam::ITstream& Foam::solution::solver(const word& name) const
             << "Lookup solver for " << name << endl;
     }
 
-    return solvers_.lookup(name);
+    return solvers_.subDict(name);
 }
 
 
diff --git a/src/OpenFOAM/matrices/solution/solution.H b/src/OpenFOAM/matrices/solution/solution.H
index 3d455fdecc31e8f8ee3d18e80a394082e2d2877f..3db89d9fc15b8f73f69854fe71937599a43dc31a 100644
--- a/src/OpenFOAM/matrices/solution/solution.H
+++ b/src/OpenFOAM/matrices/solution/solution.H
@@ -44,7 +44,7 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class solution Declaration
+                          Class solution Declaration
 \*---------------------------------------------------------------------------*/
 
 class solution
@@ -59,7 +59,6 @@ class solution
         //- Dictionary of solver parameters for all the fields
         dictionary solvers_;
 
-
     // Private Member Functions
 
         //- Disallow default bitwise copy construct and assignment
@@ -69,6 +68,11 @@ class solution
 
 public:
 
+    //- Update from older solver controls syntax
+    //  Usually verbose, since we want to know about the changes
+    //  Returns the number of settings changed
+    static label upgradeSolverDict(dictionary& dict, const bool verbose=true);
+
     //- Debug switch
     static int debug;
 
@@ -84,7 +88,7 @@ public:
         // Access
 
             //- Return the selected sub-dictionary of solvers if the "select"
-            //  keyword is given othewise return the complete dictionary
+            //  keyword is given, otherwise return the complete dictionary
             const dictionary& solutionDict() const;
 
             //- Return true if the relaxation factor is given for the field
@@ -93,13 +97,11 @@ public:
             //- Return the relaxation factor for the given field
             scalar relaxationFactor(const word& name) const;
 
-            //- Return the dictionary of solver parameters for the given field
+            //- Return the solver controls dictionary for the given field
             const dictionary& solverDict(const word& name) const;
 
-            //- Return the stream of solver parameters for the given field
-            //  @deprecated Backward compatibility only - should use solverDict
-            ITstream& solver(const word& name) const;
-
+            //- Return the solver controls dictionary for the given field
+            const dictionary& solver(const word& name) const;
 
         // Read
 
diff --git a/src/OpenFOAM/meshes/boundBox/boundBox.C b/src/OpenFOAM/meshes/boundBox/boundBox.C
index f06687625383376e07eaa7bd14d83e75cd1ca253..078e613acacb56ce79b05be9bfbdc875764b79e9 100644
--- a/src/OpenFOAM/meshes/boundBox/boundBox.C
+++ b/src/OpenFOAM/meshes/boundBox/boundBox.C
@@ -27,18 +27,34 @@ License
 #include "boundBox.H"
 #include "PstreamReduceOps.H"
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+const Foam::boundBox Foam::boundBox::greatBox
+(
+    point(-VGREAT, -VGREAT, -VGREAT),
+    point(VGREAT, VGREAT, VGREAT)
+);
+
+
+const Foam::boundBox Foam::boundBox::invertedBox
+(
+    point(VGREAT, VGREAT, VGREAT),
+    point(-VGREAT, -VGREAT, -VGREAT)
+);
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 Foam::boundBox::boundBox(const pointField& points, const bool doReduce)
 :
-    min_(vector::zero),
-    max_(vector::zero)
+    min_(point::zero),
+    max_(point::zero)
 {
     if (points.size() == 0)
     {
         if (Pstream::parRun() && doReduce)
         {
-            // Use values which get overwritten by reduce minOp,maxOp below
+            // Use values that get overwritten by reduce minOp, maxOp below
             min_ = point(VGREAT, VGREAT, VGREAT);
             max_ = point(-VGREAT, -VGREAT, -VGREAT);
         }
@@ -89,7 +105,6 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)
 
     // Check state of Ostream
     os.check("Ostream& operator<<(Ostream&, const boundBox&)");
-
     return os;
 }
 
@@ -111,7 +126,6 @@ Foam::Istream& Foam::operator>>(Istream& is, boundBox& bb)
 
     // Check state of Istream
     is.check("Istream& operator>>(Istream&, boundBox&)");
-
     return is;
 }
 
diff --git a/src/OpenFOAM/meshes/boundBox/boundBox.H b/src/OpenFOAM/meshes/boundBox/boundBox.H
index 1493c0fe2f0100ac7d3c013f762a6f0ca017ddaa..4887e99715070a534f0c8a94098cf2856318ea29 100644
--- a/src/OpenFOAM/meshes/boundBox/boundBox.H
+++ b/src/OpenFOAM/meshes/boundBox/boundBox.H
@@ -48,7 +48,7 @@ Ostream& operator<<(Ostream& os, const boundBox& b);
 
 
 /*---------------------------------------------------------------------------*\
-                           Class boundBox Declaration
+                         Class boundBox Declaration
 \*---------------------------------------------------------------------------*/
 
 class boundBox
@@ -61,13 +61,22 @@ class boundBox
 
 public:
 
+    // Static data members
+
+        //- A very large boundBox: min/max == -/+ VGREAT
+        static const boundBox greatBox;
+
+        //- A very large inverted boundBox: min/max == +/- VGREAT
+        static const boundBox invertedBox;
+
+
     // Constructors
 
-        //- Construct null setting points to zero
+        //- Construct null, setting points to zero
         boundBox()
         :
-            min_(vector::zero),
-            max_(vector::zero)
+            min_(point::zero),
+            max_(point::zero)
         {}
 
         //- Construct from components
@@ -77,8 +86,8 @@ public:
             max_(max)
         {}
 
-        //- Construct as the bounding box of the given pointField. Does
-        //  parallel communication (doReduce = true)
+        //- Construct as the bounding box of the given pointField.
+        //  Does parallel communication (doReduce = true)
         boundBox(const pointField& points, const bool doReduce = true);
 
         //- Construct from Istream
@@ -117,39 +126,26 @@ public:
 
         // Query
 
-            //- Intersects other boundingbox?
+            //- Intersects other boundingBox?
             bool overlaps(const boundBox& bb) const
             {
-                if
+                return
                 (
-                    (min_.x() <= bb.max().x()) &&
-                    (min_.y() <= bb.max().y()) &&
-                    (min_.z() <= bb.max().z()) &&
-
-                    (max_.x() >= bb.min().x()) &&
-                    (max_.y() >= bb.min().y()) &&
-                    (max_.z() >= bb.min().z())
-                )
-                {
-                    return true;
-                }
-                else
-                {
-                    return false;
-                }
+                    min_.x() <= bb.max().x() && max_.x() >= bb.min().x()
+                 && min_.y() <= bb.max().y() && max_.y() >= bb.min().y()
+                 && min_.z() <= bb.max().z() && max_.z() >= bb.min().z()
+                );
             }
 
-
             //- Contains a point?
             bool contains(const point& pt) const
             {
                 return
-                    pt.x() >= min().x()
-                 && pt.y() >= min().y()
-                 && pt.z() >= min().z()
-                 && pt.x() <= max().x()
-                 && pt.y() <= max().y()
-                 && pt.z() <= max().z();
+                (
+                    pt.x() >= min().x() && pt.x() <= max().x()
+                 && pt.y() >= min().y() && pt.y() <= max().y()
+                 && pt.z() >= min().z() && pt.z() <= max().z()
+                );
             }
 
 
@@ -173,7 +169,7 @@ public:
 };
 
 
-//- Specify data associated with boundBox type is contiguous
+//- Specify data associated with boundBox type are contiguous
 template<>
 inline bool contiguous<boundBox>() {return contiguous<point>();}
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.C b/src/OpenFOAM/meshes/meshShapes/face/face.C
index 16d71fe9b06d83481672e25290f2b1f017cdcbd2..27f3eb0f6dcda6c577ea88188a847e265be48098 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.C
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.C
@@ -119,7 +119,7 @@ Foam::label Foam::face::mostConcaveAngle
 }
 
 
-void Foam::face::split
+Foam::label Foam::face::split
 (
     const face::splitMode mode,
     const pointField& points,
@@ -129,6 +129,8 @@ void Foam::face::split
     faceList& quadFaces
 ) const
 {
+    label oldIndices = (triI + quadI);
+
     if (size() <= 2)
     {
         FatalErrorIn
@@ -143,7 +145,7 @@ void Foam::face::split
     if (size() == 3)
     {
         // Triangle. Just copy.
-        if ((mode == COUNTQUAD) || (mode == COUNTTRIANGLE))
+        if (mode == COUNTTRIANGLE || mode == COUNTQUAD)
         {
             triI++;
         }
@@ -250,7 +252,7 @@ void Foam::face::split
         }
         else
         {
-            // folded round
+            // folded around
             diff = minIndex + size() - startIndex;
         }
 
@@ -281,6 +283,8 @@ void Foam::face::split
         face1.split(mode, points, triI, quadI, triFaces, quadFaces);
         face2.split(mode, points, triI, quadI, triFaces, quadFaces);
     }
+
+    return (triI + quadI - oldIndices);
 }
 
 
@@ -749,30 +753,27 @@ int Foam::face::edgeDirection(const edge& e) const
 
 
 // Number of triangles directly known from number of vertices
-Foam::label Foam::face::nTriangles
-(
-    const pointField&
-) const
+Foam::label Foam::face::nTriangles(const pointField&) const
 {
-    return size() - 2;
+    return nTriangles();
 }
 
 
-void Foam::face::triangles
+Foam::label Foam::face::triangles
 (
     const pointField& points,
     label& triI,
     faceList& triFaces
 ) const
 {
-    faceList quadFaces;
     label quadI = 0;
+    faceList quadFaces;
 
-    split(SPLITTRIANGLE, points, triI, quadI, triFaces, quadFaces);
+    return split(SPLITTRIANGLE, points, triI, quadI, triFaces, quadFaces);
 }
 
 
-void Foam::face::nTrianglesQuads
+Foam::label Foam::face::nTrianglesQuads
 (
     const pointField& points,
     label& triI,
@@ -782,11 +783,11 @@ void Foam::face::nTrianglesQuads
     faceList triFaces;
     faceList quadFaces;
 
-    split(COUNTQUAD, points, triI, quadI, triFaces, quadFaces);
+    return split(COUNTQUAD, points, triI, quadI, triFaces, quadFaces);
 }
 
 
-void Foam::face::trianglesQuads
+Foam::label Foam::face::trianglesQuads
 (
     const pointField& points,
     label& triI,
@@ -795,7 +796,7 @@ void Foam::face::trianglesQuads
     faceList& quadFaces
 ) const
 {
-    split(SPLITQUAD, points, triI, quadI, triFaces, quadFaces);
+    return split(SPLITQUAD, points, triI, quadI, triFaces, quadFaces);
 }
 
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/face.H b/src/OpenFOAM/meshes/meshShapes/face/face.H
index 875df604959d4219250b86307638d6d4a0c6501a..c9efe19cb3a08ecd028eb1e22bd1fa784c6b323b 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/face.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/face.H
@@ -57,11 +57,14 @@ namespace Foam
 
 class face;
 class triFace;
+
+template<class T, unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+class DynamicList;
+
 inline bool operator==(const face& a, const face& b);
 inline bool operator!=(const face& a, const face& b);
 inline Istream& operator>>(Istream&, face&);
 
-
 /*---------------------------------------------------------------------------*\
                            Class face Declaration
 \*---------------------------------------------------------------------------*/
@@ -108,9 +111,10 @@ class face
             SPLITQUAD       // split into triangles&quads
         };
 
-        //- Split face into triangles or triangles&quads. Stores results
-        //  quadFaces[quadI], triFaces[triI]
-        void split
+        //- Split face into triangles or triangles&quads.
+        //  Stores results quadFaces[quadI], triFaces[triI]
+        //  Returns number of new faces created
+        label split
         (
             const splitMode mode,
             const pointField& points,
@@ -270,30 +274,47 @@ public:
 
         // Face splitting utilities
 
+            //- Number of triangles after splitting
+            inline label nTriangles() const;
+
             //- Number of triangles after splitting
             label nTriangles(const pointField& points) const;
 
-            //- Split into triangles using existing points. Result in
-            //  triFaces[triI..triI+nTri]. Splits intelligently to maximize
-            //  triangle quality.
-            void triangles
+            //- Split into triangles using existing points.
+            //  Result in triFaces[triI..triI+nTri].
+            //  Splits intelligently to maximize triangle quality.
+            //  Returns number of faces created.
+            label triangles
             (
                 const pointField& points,
                 label& triI,
                 faceList& triFaces
             ) const;
 
+            //- Split into triangles using existing points.
+            //  Append to DynamicList.
+            //  Returns number of faces created.
+            template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+            label triangles
+            (
+                const pointField& points,
+                DynamicList<face, SizeInc, SizeMult, SizeDiv>& triFaces
+            ) const;
+
             //- Number of triangles and quads after splitting
-            void nTrianglesQuads
+            //  Returns the sum of both
+            label nTrianglesQuads
             (
                 const pointField& points,
                 label& nTris,
                 label& nQuads
             ) const;
 
-            //- Split into triangles and quads. Result in triFaces (starting at
-            //  triI and quadFaces (starting at quadI)
-            void trianglesQuads
+            //- Split into triangles and quads.
+            //  Results in triFaces (starting at triI) and quadFaces
+            //  (starting at quadI).
+            //  Returns number of new faces created.
+            label trianglesQuads
             (
                 const pointField& points,
                 label& triI,
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceI.H b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
index 8b1d9a38ab8d0f4d7ab25bb302b81bf46ba4c730..92670523bebbc9036e1844085399d98995b7f38a 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceI.H
@@ -127,6 +127,11 @@ 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;
+}
 
 // * * * * * * * * * * * * * * * Friend Operators  * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C b/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C
index 5d48a8d14702ea4319f249519945a5834bb9a136..33be464d13276dde04a3e80a34c71965c1cdc0fb 100644
--- a/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C
+++ b/src/OpenFOAM/meshes/meshShapes/face/faceTemplates.C
@@ -25,9 +25,28 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "face.H"
+#include "DynamicList.H"
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+template<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
+Foam::label Foam::face::triangles
+(
+    const pointField& points,
+    DynamicList<face, SizeInc, SizeMult, SizeDiv>& triFaces
+) const
+{
+    label triI = triFaces.size();
+    label quadI = 0;
+    faceList quadFaces;
+
+    // adjust the addressable size (and allocate space if needed)
+    triFaces.setSize(triI + nTriangles());
+
+    return split(SPLITTRIANGLE, points, triI, quadI, triFaces, quadFaces);
+}
+
+
 template<class Type>
 Type Foam::face::average
 (
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
index 0ce572361677b37589c0cba69f06cbb1ead10bd5..8b33c722cc4771b429dc4b9594477df13cf0ec1f 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFace.H
@@ -124,6 +124,12 @@ public:
             //- Return vector normal
             inline vector normal(const pointField&) const;
 
+            //- Number of triangles after splitting
+            inline label nTriangles() const;
+
+            //- Return face with reverse direction
+            inline triFace reverseFace() const;
+
             //- Return swept-volume
             inline scalar sweptVol
             (
diff --git a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
index 2bced4ccf2d42180714357d2ff2782f568590d44..e14f2fcee8161358352f868dfca852e01d645b39 100644
--- a/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
+++ b/src/OpenFOAM/meshes/meshShapes/triFace/triFaceI.H
@@ -78,9 +78,9 @@ inline Foam::triFace::triFace
 }
 
 
-inline Foam::triFace::triFace(const UList<label>& l)
+inline Foam::triFace::triFace(const UList<label>& lst)
 :
-    FixedList<label, 3>(l)
+    FixedList<label, 3>(lst)
 {}
 
 
@@ -96,7 +96,7 @@ inline Foam::label Foam::triFace::collapse()
 {
     // we cannot resize a FixedList, so mark duplicates with '-1'
     // (the lower vertex is retained)
-    // catch any '-1' - ie, if called twice
+    // catch any '-1' (eg, if called twice)
 
     label n = 3;
     if (operator[](0) == operator[](1) || operator[](1) == -1)
@@ -154,13 +154,13 @@ inline Foam::edgeList Foam::triFace::edges() const
     edgeList e(3);
 
     e[0].start() = operator[](0);
-    e[0].end() = operator[](1);
+    e[0].end()   = operator[](1);
 
     e[1].start() = operator[](1);
-    e[1].end() = operator[](2);
+    e[1].end()   = operator[](2);
 
     e[2].start() = operator[](2);
-    e[2].end() = operator[](0);
+    e[2].end()   = operator[](0);
 
     return e;
 }
@@ -213,7 +213,7 @@ inline Foam::scalar Foam::triFace::mag(const pointField& points) const
     return ::Foam::mag(normal(points));
 }
 
-
+// could also delegate to triPointRef(...).normal()
 inline Foam::vector Foam::triFace::normal(const pointField& points) const
 {
     return 0.5*
@@ -224,6 +224,19 @@ inline Foam::vector Foam::triFace::normal(const pointField& points) const
 }
 
 
+inline Foam::label Foam::triFace::nTriangles() const
+{
+    return 1;
+}
+
+
+inline Foam::triFace Foam::triFace::reverseFace() const
+{
+    // The starting points of the original and reverse face are identical.
+    return triFace(operator[](0), operator[](2), operator[](1));
+}
+
+
 inline Foam::scalar Foam::triFace::sweptVol
 (
     const pointField& opts,
diff --git a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
index e7d7567a138da742b2eb21630b1b0866aad718ad..2d5bd5eb972c38a5b2c0f5ad701c4e11171bf30e 100644
--- a/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
+++ b/src/OpenFOAM/meshes/polyMesh/polyBoundaryMesh/polyBoundaryMesh.C
@@ -28,6 +28,7 @@ License
 #include "polyMesh.H"
 #include "primitiveMesh.H"
 #include "processorPolyPatch.H"
+#include "stringListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -420,13 +421,13 @@ Foam::labelHashSet Foam::polyBoundaryMesh::patchSet
 
     forAll(patchNames, i)
     {
-        // Treat the diven patch names as wild-cards and search the set
+        // Treat the given patch names as wild-cards and search the set
         // of all patch names for matches
         labelList patchIDs = findStrings(patchNames[i], allPatchNames);
 
         if (patchIDs.size() == 0)
         {
-            WarningIn("polyBoundaryMesh::patchSet(const wordList& patchNames)")
+            WarningIn("polyBoundaryMesh::patchSet(const wordList&)")
                 << "Cannot find any patch names matching " << patchNames[i]
                 << endl;
         }
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellPoints.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellPoints.C
index f813c3b15ff456b0506bca8b79338a304d50409d..e2f5d968b5074f4f2321eb2699a8c8686d3f1c17 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellPoints.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshCellPoints.C
@@ -27,14 +27,9 @@ License
 #include "primitiveMesh.H"
 #include "ListOps.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const labelListList& primitiveMesh::cellPoints() const
+const Foam::labelListList& Foam::primitiveMesh::cellPoints() const
 {
     if (!cpPtr_)
     {
@@ -56,12 +51,12 @@ const labelListList& primitiveMesh::cellPoints() const
         cpPtr_ = new labelListList(nCells());
         invertManyToMany(nCells(), pointCells(), *cpPtr_);
     }
-    
+
     return *cpPtr_;
 }
 
 
-const labelList& primitiveMesh::cellPoints
+const Foam::labelList& Foam::primitiveMesh::cellPoints
 (
     const label cellI,
     DynamicList<label>& storage
@@ -84,14 +79,14 @@ const labelList& primitiveMesh::cellPoints
 
             forAll(f, fp)
             {
-                labelSet_.insert(f[fp]);    
+                labelSet_.insert(f[fp]);
             }
         }
 
         storage.clear();
-        if (labelSet_.size() > storage.allocSize())
+        if (labelSet_.size() > storage.capacity())
         {
-            storage.setSize(labelSet_.size());
+            storage.setCapacity(labelSet_.size());
         }
 
         forAllConstIter(labelHashSet, labelSet_, iter)
@@ -104,7 +99,7 @@ const labelList& primitiveMesh::cellPoints
 }
 
 
-const labelList& primitiveMesh::cellPoints(const label cellI) const
+const Foam::labelList& Foam::primitiveMesh::cellPoints(const label cellI) const
 {
     return cellPoints(cellI, labels_);
 }
@@ -112,6 +107,4 @@ const labelList& primitiveMesh::cellPoints(const label cellI) const
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshEdges.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshEdges.C
index d7a79fb8feed128ce45d95cda64516c2799c117c..ead3b14312f55aa578ea9725d6b6195e7c2d405e 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshEdges.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshEdges.C
@@ -30,15 +30,10 @@ License
 #include "SortableList.H"
 #include "ListOps.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 // Returns edgeI between two points.
-Foam::label primitiveMesh::getEdge
+Foam::label Foam::primitiveMesh::getEdge
 (
     List<DynamicList<label> >& pe,
     DynamicList<edge>& es,
@@ -76,7 +71,7 @@ Foam::label primitiveMesh::getEdge
 }
 
 
-void primitiveMesh::calcEdges(const bool doFaceEdges) const
+void Foam::primitiveMesh::calcEdges(const bool doFaceEdges) const
 {
     if (debug)
     {
@@ -113,7 +108,7 @@ void primitiveMesh::calcEdges(const bool doFaceEdges) const
         List<DynamicList<label> > pe(nPoints());
         forAll(pe, pointI)
         {
-            pe[pointI].setSize(primitiveMesh::edgesPerPoint_);
+            pe[pointI].setCapacity(primitiveMesh::edgesPerPoint_);
         }
 
         // Estimate edges storage
@@ -337,7 +332,7 @@ void primitiveMesh::calcEdges(const bool doFaceEdges) const
 
                         oldToNew[edgeI] = internal0EdgeI++;
                     }
-                }        
+                }
             }
             else
             {
@@ -460,8 +455,8 @@ void primitiveMesh::calcEdges(const bool doFaceEdges) const
 }
 
 
-label primitiveMesh::findFirstCommonElementFromSortedLists
-( 
+Foam::label Foam::primitiveMesh::findFirstCommonElementFromSortedLists
+(
     const labelList& list1,
     const labelList& list2
 )
@@ -494,7 +489,7 @@ label primitiveMesh::findFirstCommonElementFromSortedLists
             "primitiveMesh::findFirstCommonElementFromSortedLists"
             "(const labelList&, const labelList&)"
         )   << "No common elements in lists " << list1 << " and " << list2
-            << abort(FatalError);        
+            << abort(FatalError);
     }
     return result;
 }
@@ -502,7 +497,7 @@ label primitiveMesh::findFirstCommonElementFromSortedLists
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const edgeList& primitiveMesh::edges() const
+const Foam::edgeList& Foam::primitiveMesh::edges() const
 {
     if (!edgesPtr_)
     {
@@ -513,7 +508,7 @@ const edgeList& primitiveMesh::edges() const
     return *edgesPtr_;
 }
 
-const labelListList& primitiveMesh::pointEdges() const
+const Foam::labelListList& Foam::primitiveMesh::pointEdges() const
 {
     if (!pePtr_)
     {
@@ -525,7 +520,7 @@ const labelListList& primitiveMesh::pointEdges() const
 }
 
 
-const labelListList& primitiveMesh::faceEdges() const
+const Foam::labelListList& Foam::primitiveMesh::faceEdges() const
 {
     if (!fePtr_)
     {
@@ -576,7 +571,7 @@ const labelListList& primitiveMesh::faceEdges() const
 }
 
 
-void primitiveMesh::clearOutEdges()
+void Foam::primitiveMesh::clearOutEdges()
 {
     deleteDemandDrivenData(edgesPtr_);
     deleteDemandDrivenData(pePtr_);
@@ -586,7 +581,7 @@ void primitiveMesh::clearOutEdges()
 }
 
 
-const labelList& primitiveMesh::faceEdges
+const Foam::labelList& Foam::primitiveMesh::faceEdges
 (
     const label faceI,
     DynamicList<label>& storage
@@ -602,9 +597,9 @@ const labelList& primitiveMesh::faceEdges
         const face& f = faces()[faceI];
 
         storage.clear();
-        if (f.size() > storage.allocSize())
+        if (f.size() > storage.capacity())
         {
-            storage.setSize(f.size());
+            storage.setCapacity(f.size());
         }
 
         forAll(f, fp)
@@ -624,13 +619,13 @@ const labelList& primitiveMesh::faceEdges
 }
 
 
-const labelList& primitiveMesh::faceEdges(const label faceI) const
+const Foam::labelList& Foam::primitiveMesh::faceEdges(const label faceI) const
 {
     return faceEdges(faceI, labels_);
 }
 
 
-const labelList& primitiveMesh::cellEdges
+const Foam::labelList& Foam::primitiveMesh::cellEdges
 (
     const label cellI,
     DynamicList<label>& storage
@@ -652,15 +647,15 @@ const labelList& primitiveMesh::cellEdges
 
             forAll(fe, feI)
             {
-                labelSet_.insert(fe[feI]);    
+                labelSet_.insert(fe[feI]);
             }
         }
 
         storage.clear();
 
-        if (labelSet_.size() > storage.allocSize())
+        if (labelSet_.size() > storage.capacity())
         {
-            storage.setSize(labelSet_.size());
+            storage.setCapacity(labelSet_.size());
         }
 
         forAllConstIter(labelHashSet, labelSet_, iter)
@@ -673,7 +668,7 @@ const labelList& primitiveMesh::cellEdges
 }
 
 
-const labelList& primitiveMesh::cellEdges(const label cellI) const
+const Foam::labelList& Foam::primitiveMesh::cellEdges(const label cellI) const
 {
     return cellEdges(cellI, labels_);;
 }
@@ -681,6 +676,4 @@ const labelList& primitiveMesh::cellEdges(const label cellI) const
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointCells.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointCells.C
index 8a416eafaaf658137d0d4e322f8704b0fd887777..d9a75409616d1d6b59fbd3c6feb6d2ef231dc368 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointCells.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointCells.C
@@ -27,14 +27,9 @@ License
 #include "primitiveMesh.H"
 #include "cell.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void primitiveMesh::calcPointCells() const
+void Foam::primitiveMesh::calcPointCells() const
 {
     // Loop through cells and mark up points
 
@@ -111,7 +106,7 @@ void primitiveMesh::calcPointCells() const
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const labelListList& primitiveMesh::pointCells() const
+const Foam::labelListList& Foam::primitiveMesh::pointCells() const
 {
     if (!pcPtr_)
     {
@@ -122,7 +117,7 @@ const labelListList& primitiveMesh::pointCells() const
 }
 
 
-const labelList& primitiveMesh::pointCells
+const Foam::labelList& Foam::primitiveMesh::pointCells
 (
     const label pointI,
     DynamicList<label>& storage
@@ -155,26 +150,29 @@ const labelList& primitiveMesh::pointCells
         }
 
         // Filter duplicates
-        sort(storage);
-
-        label n = 1;
-
-        for (label i = 1; i < storage.size(); i++)
+        if (storage.size() > 1)
         {
-            if (storage[i] != storage[i-1])
+            sort(storage);
+
+            label n = 1;
+            for (label i = 1; i < storage.size(); i++)
             {
-                storage[n++] = storage[i];
+                if (storage[i-1] != storage[i])
+                {
+                    storage[n++] = storage[i];
+                }
             }
-        }
 
-        storage.setSize(n);
+            // truncate addressed list
+            storage.setSize(n);
+        }
 
         return storage;
     }
 }
 
 
-const labelList& primitiveMesh::pointCells(const label pointI) const
+const Foam::labelList& Foam::primitiveMesh::pointCells(const label pointI) const
 {
     return pointCells(pointI, labels_);
 }
@@ -182,6 +180,4 @@ const labelList& primitiveMesh::pointCells(const label pointI) const
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointPoints.C b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointPoints.C
index e1ffa07dff88201df77bcba1423a8bf7dba16950..df976953bc263a8d23ebf76f06b814e6dfab995f 100644
--- a/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointPoints.C
+++ b/src/OpenFOAM/meshes/primitiveMesh/primitiveMeshPointPoints.C
@@ -26,14 +26,9 @@ License
 
 #include "primitiveMesh.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void primitiveMesh::calcPointPoints() const
+void Foam::primitiveMesh::calcPointPoints() const
 {
     if (debug)
     {
@@ -94,7 +89,7 @@ void primitiveMesh::calcPointPoints() const
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-const labelListList& primitiveMesh::pointPoints() const
+const Foam::labelListList& Foam::primitiveMesh::pointPoints() const
 {
     if (!ppPtr_)
     {
@@ -105,7 +100,7 @@ const labelListList& primitiveMesh::pointPoints() const
 }
 
 
-const labelList& primitiveMesh::pointPoints
+const Foam::labelList& Foam::primitiveMesh::pointPoints
 (
     const label pointI,
     DynamicList<label>& storage
@@ -122,9 +117,9 @@ const labelList& primitiveMesh::pointPoints
 
         storage.clear();
 
-        if (pEdges.size() > storage.allocSize())
+        if (pEdges.size() > storage.capacity())
         {
-            storage.setSize(pEdges.size());
+            storage.setCapacity(pEdges.size());
         }
 
         forAll(pEdges, i)
@@ -137,7 +132,10 @@ const labelList& primitiveMesh::pointPoints
 }
 
 
-const labelList& primitiveMesh::pointPoints(const label pointI) const
+const Foam::labelList& Foam::primitiveMesh::pointPoints
+(
+    const label pointI
+) const
 {
     return pointPoints(pointI, labels_);
 }
@@ -145,6 +143,4 @@ const labelList& primitiveMesh::pointPoints(const label pointI) const
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/OpenFOAM/primitives/Lists/stringList.H b/src/OpenFOAM/primitives/Lists/stringList.H
index 2c02ae1c6f44ecedbb84b3d96ca4dc2d107606af..b3f60e2d1152cfb8fdd975889319c12d7cbae48e 100644
--- a/src/OpenFOAM/primitives/Lists/stringList.H
+++ b/src/OpenFOAM/primitives/Lists/stringList.H
@@ -34,27 +34,15 @@ Description
 #define stringList_H
 
 #include "string.H"
-#include "labelList.H"
+#include "List.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
     typedef List<string> stringList;
-
-    //- Return the indices of the strings in the list
-    //  that match the given regular expression
-    template<class StringList>
-    labelList findStrings(const string& regexp, const StringList&);
 }
 
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#ifdef NoRepository
-#   include "stringListTemplates.C"
-#endif
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/src/sampling/sampledSurface/writers/null/nullWriters.H b/src/OpenFOAM/primitives/Lists/stringListOps.H
similarity index 74%
rename from src/sampling/sampledSurface/writers/null/nullWriters.H
rename to src/OpenFOAM/primitives/Lists/stringListOps.H
index 3cb81e1a016a67d4a64e1e6b0d95d1f977bb4330..e814d88e13c27fdf67d212a045bf53bcd582c54c 100644
--- a/src/sampling/sampledSurface/writers/null/nullWriters.H
+++ b/src/OpenFOAM/primitives/Lists/stringListOps.H
@@ -22,39 +22,46 @@ License
     along with OpenFOAM; if not, write to the Free Software Foundation,
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
-InClass
-    Foam::nullWriters
+InNamspace
+    Foam
 
 Description
+    Operations on lists of strings.
 
 SourceFiles
-    nullWriters.C
+    stringListOpsTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef nullWriters_H
-#define nullWriters_H
+#ifndef stringListOps_H
+#define stringListOps_H
 
-#include "null.H"
-#include "surfaceWriters.H"
-#include "fieldTypes.H"
+#include "labelList.H"
+#include "stringList.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+    //- Return the indices of the strings in the list
+    //  that match the given regular expression
+    //  partial matches are optional
+    template<class StringType>
+    labelList findStrings
+    (
+        const string& regexpPattern,
+        const UList<StringType>&,
+        bool partialMatch=false
+    );
+}
 
-typedef null<scalar> nullScalarWriter;
-typedef null<vector> nullVectorWriter;
-typedef null<sphericalTensor> nullSphericalTensorWriter;
-typedef null<symmTensor> nullSymmTensorWriter;
-typedef null<tensor> nullTensorWriter;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
+#ifdef NoRepository
+#   include "stringListOpsTemplates.C"
+#endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/OpenFOAM/primitives/Lists/stringListTemplates.C b/src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C
similarity index 80%
rename from src/OpenFOAM/primitives/Lists/stringListTemplates.C
rename to src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C
index a93c46e8ac2f0269d44a9577ff885189c6043495..e1075b3ea5f8389951f8c3c535cb61322d00c366 100644
--- a/src/OpenFOAM/primitives/Lists/stringListTemplates.C
+++ b/src/OpenFOAM/primitives/Lists/stringListOpsTemplates.C
@@ -25,7 +25,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "labelList.H"
-#include "regularExpression.H"
+#include "regExp.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -34,25 +34,28 @@ namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-template<class StringList>
-labelList findStrings(const string& regexp, const StringList& sl)
+template<class StringType>
+labelList findStrings
+(
+    const string& pattern,
+    const UList<StringType>& lst,
+    bool  partialMatch
+)
 {
-    labelList matches(sl.size());
+    regExp re(pattern);
+    labelList matched(lst.size());
 
-    regularExpression re(regexp);
-
-    label matchi = 0;
-    forAll(sl, i)
+    label matchI = 0;
+    forAll(lst, elemI)
     {
-        if (re.matches(sl[i]))
+        if (re.match(lst[elemI], partialMatch))
         {
-            matches[matchi++] = i;
+            matched[matchI++] = elemI;
         }
     }
+    matched.setSize(matchI);
 
-    matches.setSize(matchi);
-
-    return matches;
+    return matched;
 }
 
 
diff --git a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C
index 950e1a31452bfbc715e2e78d1d6fd94dad2bc5d8..e4267a26e320bc838ba7fcc439eb9dd4a7b8c139 100644
--- a/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C
+++ b/src/autoMesh/autoHexMesh/autoHexMeshDriver/autoHexMeshDriver.C
@@ -96,11 +96,7 @@ Foam::scalar Foam::autoHexMeshDriver::getMergeDistance(const scalar mergeTol)
 //)
 //{
 //    // Determine outside point.
-//    boundBox overallBb
-//    (
-//        point(GREAT, GREAT, GREAT),
-//        point(-GREAT, -GREAT, -GREAT)
-//    );
+//    boundBox overallBb = boundBox::invertedBox;
 //
 //    bool hasSurface = false;
 //
diff --git a/src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C b/src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C
index 1a577acecbd31672108e5bcdece5c72da99ddc36..27740816ac815c42e78fa974062f28f1c5d49b85 100644
--- a/src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C
+++ b/src/autoMesh/autoHexMesh/shellSurfaces/shellSurfaces.C
@@ -158,11 +158,7 @@ void Foam::shellSurfaces::setAndCheckLevels
 void Foam::shellSurfaces::orient()
 {
     // Determine outside point.
-    boundBox overallBb
-    (
-        point(GREAT, GREAT, GREAT),
-        point(-GREAT, -GREAT, -GREAT)
-    );
+    boundBox overallBb = boundBox::invertedBox;
 
     bool hasSurface = false;
 
diff --git a/src/conversion/polyDualMesh/polyDualMesh.C b/src/conversion/polyDualMesh/polyDualMesh.C
index e2cce56a31ac2396ad2c812ced6a19f3d0734e50..9b310d2bf4843589658fc4f61e76fcb7861a2dac 100644
--- a/src/conversion/polyDualMesh/polyDualMesh.C
+++ b/src/conversion/polyDualMesh/polyDualMesh.C
@@ -236,13 +236,13 @@ Foam::labelList Foam::polyDualMesh::collectPatchSideFace
     if (pointToDualPoint[meshPointI] >= 0)
     {
         // Number of pFaces + 2 boundary edge + feature point
-        dualFace.setSize(pFaces.size()+2+1);
+        dualFace.setCapacity(pFaces.size()+2+1);
         // Store dualVertex for feature edge
         dualFace.append(pointToDualPoint[meshPointI]);
     }
     else
     {
-        dualFace.setSize(pFaces.size()+2);
+        dualFace.setCapacity(pFaces.size()+2);
     }
 
     // Store dual vertex for starting edge.
@@ -958,13 +958,13 @@ void Foam::polyDualMesh::calcDual
         if (edgeToDualPoint[edgeI] >= 0)
         {
             // Number of cells + 2 boundary faces + feature edge point
-            dualFace.setSize(mesh.edgeCells()[edgeI].size()+2+1);
+            dualFace.setCapacity(mesh.edgeCells()[edgeI].size()+2+1);
             // Store dualVertex for feature edge
             dualFace.append(edgeToDualPoint[edgeI]);
         }
         else
         {
-            dualFace.setSize(mesh.edgeCells()[edgeI].size()+2);
+            dualFace.setCapacity(mesh.edgeCells()[edgeI].size()+2);
         }
 
         // Store dual vertex for starting face.
diff --git a/src/dynamicMesh/boundaryMesh/boundaryMesh.C b/src/dynamicMesh/boundaryMesh/boundaryMesh.C
index ecb47ed70c256ef1abc8925a198688765bee85a3..76201ff987c91e29e48f6b5710a3fb1c398ad849 100644
--- a/src/dynamicMesh/boundaryMesh/boundaryMesh.C
+++ b/src/dynamicMesh/boundaryMesh/boundaryMesh.C
@@ -1250,7 +1250,7 @@ void Foam::boundaryMesh::patchify
 
         forAll(patchFaces, newPatchI)
         {
-            patchFaces[newPatchI].setSize(nAvgFaces);
+            patchFaces[newPatchI].setCapacity(nAvgFaces);
         }
 
         //
diff --git a/src/dynamicMesh/meshCut/cellLooper/topoCellLooper.C b/src/dynamicMesh/meshCut/cellLooper/topoCellLooper.C
index 73ca55fc7c8bd469e29a688037741a26c0121eb6..e74a5691e38ba712c8991707660917ed111c2287 100644
--- a/src/dynamicMesh/meshCut/cellLooper/topoCellLooper.C
+++ b/src/dynamicMesh/meshCut/cellLooper/topoCellLooper.C
@@ -37,16 +37,11 @@ License
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 namespace Foam
 {
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-defineTypeNameAndDebug(topoCellLooper, 0);
-
-addToRunTimeSelectionTable(cellLooper, topoCellLooper, word);
-
-
+   defineTypeNameAndDebug(topoCellLooper, 0);
+   addToRunTimeSelectionTable(cellLooper, topoCellLooper, word);
 }
 
 // Angle for polys to be considered splitHexes.
@@ -67,7 +62,7 @@ void Foam::topoCellLooper::subsetList
 {
     if (startI == 0)
     {
-        // Truncate (setsize decides itself not to do anything if nothing
+        // Truncate (setSize decides itself not to do anything if nothing
         // changed)
         if (freeI < 0)
         {
@@ -228,7 +223,7 @@ Foam::labelList Foam::topoCellLooper::getSuperEdge
 
     do
     {
-        vertI = mesh().edges()[edgeI].otherVertex(vertI);    
+        vertI = mesh().edges()[edgeI].otherVertex(vertI);
 
         superVerts[superVertI++] = vertI;
 
@@ -237,7 +232,7 @@ Foam::labelList Foam::topoCellLooper::getSuperEdge
         edgeI = meshTools::otherEdge(mesh(), fEdges, edgeI, vertI);
     }
     while (!features.isFeaturePoint(prevEdgeI, edgeI));
-  
+
     superVerts.setSize(superVertI);
 
     return superVerts;
@@ -500,7 +495,7 @@ void Foam::topoCellLooper::walkSplitHex
                 nextEdgeI,
                 nextVertI
             );
-            
+
             edgeI = nextEdgeI;
             vertI = nextVertI;
         }
@@ -615,7 +610,7 @@ void Foam::topoCellLooper::walkSplitHex
                 labelList nextFaces =
                     getVertFacesNonEdge
                     (
-                        cellI, 
+                        cellI,
                         edgeI,
                         vertI
                     );
@@ -720,7 +715,7 @@ bool Foam::topoCellLooper::cut
     if (mesh().cellShapes()[cellI].model() == hex_)
     {
         // Let parent handle hex case.
-        return 
+        return
             hexCellLooper::cut
             (
                 refDir,
@@ -752,7 +747,7 @@ bool Foam::topoCellLooper::cut
 
             if (edgeI != -1)
             {
-                // Found non-feature edge. Start walking from vertex on edge. 
+                // Found non-feature edge. Start walking from vertex on edge.
                 vertI = mesh().edges()[edgeI].start();
             }
             else
diff --git a/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C b/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C
index 3adafa0dfab9e907af7a61f65f64575b3f243309..b7edb38f2bb8af1b0eb0e925b562290f92fdaf16 100644
--- a/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C
+++ b/src/dynamicMesh/polyMeshAdder/polyMeshAdder.C
@@ -47,7 +47,7 @@ void Foam::polyMeshAdder::append
     DynamicList<label>& dynLst
 )
 {
-    dynLst.setSize(dynLst.size() + lst.size());
+    dynLst.setCapacity(dynLst.size() + lst.size());
 
     forAll(lst, i)
     {
@@ -902,7 +902,7 @@ void Foam::polyMeshAdder::mergePointZones
     List<DynamicList<label> >& pzPoints
 )
 {
-    zoneNames.setSize(pz0.size() + pz1.size());
+    zoneNames.setCapacity(pz0.size() + pz1.size());
 
     // Names
     append(pz0.names(), zoneNames);
@@ -922,7 +922,7 @@ void Foam::polyMeshAdder::mergePointZones
     {
         DynamicList<label>& newZone = pzPoints[zoneI];
 
-        newZone.setSize(pz0[zoneI].size());
+        newZone.setCapacity(pz0[zoneI].size());
 
         append(from0ToAllPoints, pz0[zoneI], newZone);
     }
@@ -933,7 +933,7 @@ void Foam::polyMeshAdder::mergePointZones
         // Relabel all points of zone and add to correct pzPoints.
         DynamicList<label>& newZone = pzPoints[from1ToAll[zoneI]];
 
-        newZone.setSize(newZone.size() + pz1[zoneI].size());
+        newZone.setCapacity(newZone.size() + pz1[zoneI].size());
 
         append(from1ToAllPoints, pz1[zoneI], newZone);
     }
@@ -958,7 +958,7 @@ void Foam::polyMeshAdder::mergeFaceZones
     List<DynamicList<bool> >& fzFlips
 )
 {
-    zoneNames.setSize(fz0.size() + fz1.size());
+    zoneNames.setCapacity(fz0.size() + fz1.size());
 
     append(fz0.names(), zoneNames);
 
@@ -979,8 +979,8 @@ void Foam::polyMeshAdder::mergeFaceZones
         DynamicList<label>& newZone = fzFaces[zoneI];
         DynamicList<bool>& newFlip = fzFlips[zoneI];
 
-        newZone.setSize(fz0[zoneI].size());
-        newFlip.setSize(newZone.size());
+        newZone.setCapacity(fz0[zoneI].size());
+        newFlip.setCapacity(newZone.size());
 
         const labelList& addressing = fz0[zoneI];
         const boolList& flipMap = fz0[zoneI].flipMap();
@@ -1003,8 +1003,8 @@ void Foam::polyMeshAdder::mergeFaceZones
         DynamicList<label>& newZone = fzFaces[from1ToAll[zoneI]];
         DynamicList<bool>& newFlip = fzFlips[from1ToAll[zoneI]];
 
-        newZone.setSize(newZone.size() + fz1[zoneI].size());
-        newFlip.setSize(newZone.size());
+        newZone.setCapacity(newZone.size() + fz1[zoneI].size());
+        newFlip.setCapacity(newZone.size());
 
         const labelList& addressing = fz1[zoneI];
         const boolList& flipMap = fz1[zoneI].flipMap();
@@ -1040,7 +1040,7 @@ void Foam::polyMeshAdder::mergeCellZones
     List<DynamicList<label> >& czCells
 )
 {
-    zoneNames.setSize(cz0.size() + cz1.size());
+    zoneNames.setCapacity(cz0.size() + cz1.size());
 
     append(cz0.names(), zoneNames);
 
@@ -1056,7 +1056,7 @@ void Foam::polyMeshAdder::mergeCellZones
     czCells.setSize(zoneNames.size());
     forAll(cz0, zoneI)
     {
-        czCells[zoneI].setSize(cz0[zoneI].size());
+        czCells[zoneI].setCapacity(cz0[zoneI].size());
         // Insert mesh0 cells
         append(cz0[zoneI], czCells[zoneI]);
     }
@@ -1067,7 +1067,7 @@ void Foam::polyMeshAdder::mergeCellZones
     {
         DynamicList<label>& newZone = czCells[from1ToAll[zoneI]];
 
-        newZone.setSize(newZone.size() + cz1[zoneI].size());
+        newZone.setCapacity(newZone.size() + cz1[zoneI].size());
 
         append(from1ToAllCells, cz1[zoneI], newZone);
     }
diff --git a/src/dynamicMesh/polyMeshAdder/polyMeshAdderTemplates.C b/src/dynamicMesh/polyMeshAdder/polyMeshAdderTemplates.C
index ffc70d9043316857913f84141bb33d9ea044fbee..0b8740a315be04fa386784f7d21ea3ec2176a2c2 100644
--- a/src/dynamicMesh/polyMeshAdder/polyMeshAdderTemplates.C
+++ b/src/dynamicMesh/polyMeshAdder/polyMeshAdderTemplates.C
@@ -31,7 +31,7 @@ License
 template<class T>
 void Foam::polyMeshAdder::append(const List<T>& lst, DynamicList<T>& dynLst)
 {
-    dynLst.setSize(dynLst.size() + lst.size());
+    dynLst.setCapacity(dynLst.size() + lst.size());
 
     forAll(lst, i)
     {
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C
index 4cfba30501e21a3676290aa06deba01e5f505cc6..8b510a706467c081c0f56f4f90feab541a151181 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/hexRef8.C
@@ -2432,8 +2432,8 @@ Foam::labelList Foam::hexRef8::consistentSlowRefinement
 
 
         // Transfer into seedFaces, seedFacesInfo
-        seedFaces.setSize(changedFacesInfo.size());
-        seedFacesInfo.setSize(changedFacesInfo.size());
+        seedFaces.setCapacity(changedFacesInfo.size());
+        seedFacesInfo.setCapacity(changedFacesInfo.size());
 
         forAllConstIter(Map<refinementData>, changedFacesInfo, iter)
         {
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
index d8611fae137ca2c902147e1731616468a7cf3adf..d743891f94fc99a1fb16d487b09401640c21c71d 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/polyTopoChange.C
@@ -726,7 +726,7 @@ void Foam::polyTopoChange::getFaceOrder
 }
 
 
-// Compact and reorder faces according to map.
+// Reorder and compact faces according to map.
 void Foam::polyTopoChange::reorderCompactFaces
 (
     const label newSize,
@@ -2999,9 +2999,6 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
             patchStarts,
             syncParallel
         );
-        // Invalidate new points to go into map.
-        newPoints.clear();
-
         mesh.changing(true);
     }
 
@@ -3010,14 +3007,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::changeMesh
         retiredPoints_.clear();
         retiredPoints_.resize(0);
 
-        faces_.clear();
-        faces_.setSize(0);
         region_.clear();
         region_.setSize(0);
-        faceOwner_.clear();
-        faceOwner_.setSize(0);
-        faceNeighbour_.clear();
-        faceNeighbour_.setSize(0);
     }
 
 
@@ -3237,27 +3228,20 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::polyTopoChange::makeMesh
         new fvMesh
         (
             io,
-            xferMove<pointField>(newPoints),
-            xferMove<faceList>(faces_),
-            xferMove<labelList>(faceOwner_),
-            xferMove<labelList>(faceNeighbour_)
+            xferMove(newPoints),
+            xferMoveTo<faceList>(faces_),
+            xferMoveTo<labelList>(faceOwner_),
+            xferMoveTo<labelList>(faceNeighbour_)
         )
     );
     fvMesh& newMesh = newMeshPtr();
 
     // Clear out primitives
     {
-        newPoints.clear();
         retiredPoints_.clear();
         retiredPoints_.resize(0);
-        faces_.clear();
-        faces_.setSize(0);
         region_.clear();
         region_.setSize(0);
-        faceOwner_.clear();
-        faceOwner_.setSize(0);
-        faceNeighbour_.clear();
-        faceNeighbour_.setSize(0);
     }
 
 
diff --git a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementHistory.C b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementHistory.C
index 45f1cb9e2acd5316012051020c43e24cfc94e1c5..82b053d535201d5060030ee108e92d7589928564 100644
--- a/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementHistory.C
+++ b/src/dynamicMesh/polyTopoChange/polyTopoChange/refinementHistory.C
@@ -411,7 +411,7 @@ Foam::refinementHistory::refinementHistory
     else
     {
         visibleCells_.setSize(nCells);
-        splitCells_.setSize(nCells);
+        splitCells_.setCapacity(nCells);
 
         for (label cellI = 0; cellI < nCells; cellI++)
         {
diff --git a/src/engine/ignition/ignitionSite.C b/src/engine/ignition/ignitionSite.C
index 26b084456c28f1239fd39b83a3228ab150bcc3f6..1df145f582234f7064454c05bb5b453ee5daab84 100644
--- a/src/engine/ignition/ignitionSite.C
+++ b/src/engine/ignition/ignitionSite.C
@@ -37,14 +37,17 @@ namespace Foam
 
 void ignitionSite::findIgnitionCells(const fvMesh& mesh)
 {
+    // Bit tricky: generate C and V before shortcutting if cannot find
+    // cell locally. mesh.C generation uses parallel communication.
+    const volVectorField& centres = mesh.C();
+    const scalarField& vols = mesh.V();
+
     label ignCell = mesh.findCell(location_);
     if (ignCell == -1)
     {
         return;
     }
 
-    const volVectorField& centres = mesh.C();
-    const scalarField& vols = mesh.V();
     scalar radius = diameter_/2.0;
 
     cells_.setSize(1);
diff --git a/src/finiteVolume/cfdTools/general/findRefCell/findRefCell.C b/src/finiteVolume/cfdTools/general/findRefCell/findRefCell.C
index 321eeba6a87be806089b4cafd53ea2195286ca56..ea2281266bbbf0288d27687a0a3e08fbe3236a2a 100644
--- a/src/finiteVolume/cfdTools/general/findRefCell/findRefCell.C
+++ b/src/finiteVolume/cfdTools/general/findRefCell/findRefCell.C
@@ -49,6 +49,22 @@ void Foam::setRefCell
             if (Pstream::master())
             {
                 refCelli = readLabel(dict.lookup(refCellName));
+
+                if (refCelli < 0 || refCelli >= field.mesh().nCells())
+                {
+                    FatalErrorIn
+                    (
+                        "void Foam::setRefCell"
+                         "("
+                         "    const volScalarField&,"
+                         "    const dictionary&,"
+                         "    label& scalar&,"
+                         "    bool"
+                         ")"
+                    )   << "Illegal master cellID " << refCelli
+                        << ". Should be 0.." << field.mesh().nCells()
+                        << exit(FatalError);
+                }
             }
             else
             {
@@ -75,7 +91,7 @@ void Foam::setRefCell
                 )
                   << "Unable to set reference cell for field " << field.name()
                   << nl << "    Reference point " << refPointName
-                  << " found on multiple domains" << nl << abort(FatalError);
+                  << " found on multiple domains" << nl << exit(FatalError);
             }
         }
         else
@@ -92,7 +108,7 @@ void Foam::setRefCell
             )
               << "Unable to set reference cell for field" << field.name() << nl
               << "    Please supply either " << refCellName
-              << " or " << refPointName << nl << abort(FatalError);
+              << " or " << refPointName << nl << exit(FatalError);
         }
 
         refValue = readScalar(dict.lookup(refValueName));
diff --git a/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C b/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C
index 91473124c0763933605c6820332885ff478ce2b7..ba46223e8169747fd2e201d0714e597f008f4158 100644
--- a/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C
+++ b/src/finiteVolume/fields/fvPatchFields/derived/timeVaryingMappedFixedValue/timeVaryingMappedFixedValueFvPatchField.C
@@ -207,8 +207,11 @@ void timeVaryingMappedFixedValueFvPatchField<Type>::autoMap
 )
 {
     fixedValueFvPatchField<Type>::autoMap(m);
-    startSampledValues_.autoMap(m);
-    endSampledValues_.autoMap(m);
+    if (startSampledValues_.size() > 0)
+    {
+        startSampledValues_.autoMap(m);
+        endSampledValues_.autoMap(m);
+    }
 }
 
 
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.C
index b8698eb17738d2e5e39adfd6ac0eaa3568356a15..20f36d23497a426acc3a4ab196fc587396a2b844 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.C
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.C
@@ -336,8 +336,8 @@ Foam::fvMatrix<Type>::fvMatrix
 {
     if (debug)
     {
-        Info<< "fvMatrix<Type>(GeometricField<Type, fvPatchField, volMesh>&,"
-               " Istream&) : "
+        Info<< "fvMatrix<Type>"
+               "(GeometricField<Type, fvPatchField, volMesh>&, Istream&) : "
                "constructing fvMatrix<Type> for field " << psi_.name()
             << endl;
     }
@@ -1257,7 +1257,7 @@ template<class Type>
 Foam::lduMatrix::solverPerformance Foam::solve
 (
     fvMatrix<Type>& fvm,
-    Istream& solverControls
+    const dictionary& solverControls
 )
 {
     return fvm.solve(solverControls);
@@ -1267,7 +1267,7 @@ template<class Type>
 Foam::lduMatrix::solverPerformance Foam::solve
 (
     const tmp<fvMatrix<Type> >& tfvm,
-    Istream& solverControls
+    const dictionary& solverControls
 )
 {
     lduMatrix::solverPerformance solverPerf =
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.H b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.H
index b7663db50f658d41783e1657f2ee401e134daa10..2df42847a20b3039158571066faada6ea23a7f8c 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.H
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrix.H
@@ -220,8 +220,8 @@ public:
         // Member functions
 
             //- Solve returning the solution statistics.
-            //  Solver controls read from Istream
-            lduMatrix::solverPerformance solve(Istream&);
+            //  Use the given solver controls
+            lduMatrix::solverPerformance solve(const dictionary&);
 
             //- Solve returning the solution statistics.
             //  Solver controls read from fvSolution
@@ -359,16 +359,16 @@ public:
             );
 
             //- Construct and return the solver
-            //  Solver controls read from Istream
-            autoPtr<fvSolver> solver(Istream&);
+            //  Use the given solver controls
+            autoPtr<fvSolver> solver(const dictionary&);
 
             //- Construct and return the solver
             //  Solver controls read from fvSolution
             autoPtr<fvSolver> solver();
 
             //- Solve returning the solution statistics.
-            //  Solver controls read from Istream
-            lduMatrix::solverPerformance solve(Istream&);
+            //  Use the given solver controls
+            lduMatrix::solverPerformance solve(const dictionary&);
 
             //- Solve returning the solution statistics.
             //  Solver controls read from fvSolution
@@ -518,16 +518,20 @@ void checkMethod
 
 
 //- Solve returning the solution statistics given convergence tolerance
-//  Solver controls read Istream
+//  Use the given solver controls
 template<class Type>
-lduMatrix::solverPerformance solve(fvMatrix<Type>&, Istream&);
+lduMatrix::solverPerformance solve(fvMatrix<Type>&, const dictionary&);
 
 
 //- Solve returning the solution statistics given convergence tolerance,
 //  deleting temporary matrix after solution.
-//  Solver controls read Istream
+//  Use the given solver controls
 template<class Type>
-lduMatrix::solverPerformance solve(const tmp<fvMatrix<Type> >&, Istream&);
+lduMatrix::solverPerformance solve
+(
+    const tmp<fvMatrix<Type> >&,
+    const dictionary&
+);
 
 
 //- Solve returning the solution statistics given convergence tolerance
diff --git a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
index 37e3fd8391b344a14c2f53af7a9d04f9ead6e7fd..53183114724c7dfdebb4893f81d799b34c7ed76e 100644
--- a/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
+++ b/src/finiteVolume/fvMatrices/fvMatrix/fvMatrixSolve.C
@@ -53,12 +53,12 @@ void Foam::fvMatrix<Type>::setComponentReference
 template<class Type>
 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
 (
-    Istream& solverControls
+    const dictionary& solverControls
 )
 {
     if (debug)
     {
-        Info<< "fvMatrix<Type>::solve(Istream& solverControls) : "
+        Info<< "fvMatrix<Type>::solve(const dictionary& solverControls) : "
                "solving fvMatrix<Type>"
             << endl;
     }
@@ -108,7 +108,7 @@ Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
             internalCoeffs_.component(cmpt)
         );
 
-        lduInterfaceFieldPtrsList interfaces = 
+        lduInterfaceFieldPtrsList interfaces =
             psi_.boundaryField().interfaces();
 
         // Use the initMatrixInterfaces and updateMatrixInterfaces to correct
@@ -142,7 +142,7 @@ Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve
             bouCoeffsCmpt,
             intCoeffsCmpt,
             interfaces,
-            solverControls.rewind()
+            solverControls
         )->solve(psiCmpt, sourceCmpt, cmpt);
 
         solverPerf.print();
@@ -170,20 +170,20 @@ template<class Type>
 Foam::autoPtr<typename Foam::fvMatrix<Type>::fvSolver>
 Foam::fvMatrix<Type>::solver()
 {
-    return solver(psi_.mesh().solver(psi_.name()));
+    return solver(psi_.mesh().solverDict(psi_.name()));
 }
 
 template<class Type>
 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::fvSolver::solve()
 {
-    return solve(psi_.mesh().solver(psi_.name()));
+    return solve(psi_.mesh().solverDict(psi_.name()));
 }
 
 
 template<class Type>
 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Type>::solve()
 {
-    return solve(psi_.mesh().solver(psi_.name()));
+    return solve(psi_.mesh().solverDict(psi_.name()));
 }
 
 
diff --git a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
index ad952b3e78f9b5bf52bc926b0b5982fc87a46c20..be97ac403a6db65de1d258881022e0a54b8a3735 100644
--- a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
+++ b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.C
@@ -45,7 +45,7 @@ void Foam::fvMatrix<Foam::scalar>::setComponentReference
             internalCoeffs_[patchi][facei] +=
                 diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]];
 
-            boundaryCoeffs_[patchi][facei] += 
+            boundaryCoeffs_[patchi][facei] +=
                 diag()[psi_.mesh().boundary()[patchi].faceCells()[facei]]
                *value;
         }
@@ -57,12 +57,12 @@ template<>
 Foam::autoPtr<Foam::fvMatrix<Foam::scalar>::fvSolver>
 Foam::fvMatrix<Foam::scalar>::solver
 (
-    Istream& solverControls
+    const dictionary& solverControls
 )
 {
     if (debug)
     {
-        Info<< "fvMatrix<scalar>::solver(Istream& solverControls) : "
+        Info<< "fvMatrix<scalar>::solver(const dictionary& solverControls) : "
                "solver for fvMatrix<scalar>"
             << endl;
     }
@@ -96,7 +96,7 @@ Foam::fvMatrix<Foam::scalar>::solver
 template<>
 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Foam::scalar>::fvSolver::solve
 (
-    Istream& solverControls
+    const dictionary& solverControls
 )
 {
     scalarField saveDiag = fvMat_.diag();
@@ -105,8 +105,10 @@ Foam::lduMatrix::solverPerformance Foam::fvMatrix<Foam::scalar>::fvSolver::solve
     scalarField totalSource = fvMat_.source();
     fvMat_.addBoundarySource(totalSource, false);
 
+    // assign new solver controls
     solver_->read(solverControls);
-    lduMatrix::solverPerformance solverPerf = 
+
+    lduMatrix::solverPerformance solverPerf =
         solver_->solve(fvMat_.psi().internalField(), totalSource);
 
     solverPerf.print();
@@ -122,12 +124,12 @@ Foam::lduMatrix::solverPerformance Foam::fvMatrix<Foam::scalar>::fvSolver::solve
 template<>
 Foam::lduMatrix::solverPerformance Foam::fvMatrix<Foam::scalar>::solve
 (
-    Istream& solverControls
+    const dictionary& solverControls
 )
 {
     if (debug)
     {
-        Info<< "fvMatrix<scalar>::solve(Istream& solverControls) : "
+        Info<< "fvMatrix<scalar>::solve(const dictionary& solverControls) : "
                "solving fvMatrix<scalar>"
             << endl;
     }
diff --git a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.H b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.H
index ff22889d49c2e17bbd7cb746c01f7e8632652cbb..19ec0abb2e84a5d32107098758ef4b3f61db3ad5 100644
--- a/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.H
+++ b/src/finiteVolume/fvMatrices/fvScalarMatrix/fvScalarMatrix.H
@@ -23,9 +23,10 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 InClass
-    Foam::fvScalarMatrix
+    Foam::fvMatrix
 
 Description
+    A scalar instance of fvMatrix
 
 SourceFiles
     fvScalarMatrix.C
@@ -56,13 +57,22 @@ void fvMatrix<scalar>::setComponentReference
 );
 
 template<>
-autoPtr<fvMatrix<scalar>::fvSolver> fvMatrix<scalar>::solver(Istream&);
+autoPtr<fvMatrix<scalar>::fvSolver> fvMatrix<scalar>::solver
+(
+    const dictionary&
+);
 
 template<>
-lduMatrix::solverPerformance fvMatrix<scalar>::fvSolver::solve(Istream&);
+lduMatrix::solverPerformance fvMatrix<scalar>::fvSolver::solve
+(
+    const dictionary&
+);
 
 template<>
-lduMatrix::solverPerformance fvMatrix<scalar>::solve(Istream&);
+lduMatrix::solverPerformance fvMatrix<scalar>::solve
+(
+    const dictionary&
+);
 
 template<>
 tmp<scalarField> fvMatrix<scalar>::residual() const;
diff --git a/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C b/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C
index 1dc8e8d1f6c6d84eafbfc529189378f7eed8ea3f..47ef5eb98fd05bdb4e5d1b280ab52224b5d5171a 100644
--- a/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C
+++ b/src/finiteVolume/fvMatrices/solvers/MULES/MULESTemplates.C
@@ -142,8 +142,8 @@ void Foam::MULES::implicitSolve
 {
     const fvMesh& mesh = psi.mesh();
 
-    dictionary MULESSolver(mesh.solver(psi.name()));
-    const dictionary& MULEScontrols = MULESSolver.subDict("MULESImplicit");
+    const dictionary& MULEScontrols = 
+       mesh.solverDict(psi.name()).subDict("MULESImplicit");
 
     label maxIter
     (
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C
index ba8498bba0524cf072e90856f37b28d2f1b5c356..88a15a4f233b7b72d4ee92eb31e81eea3bd7ad03 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.C
@@ -55,7 +55,7 @@ namespace Foam
 Foam::displacementSBRStressFvMotionSolver::displacementSBRStressFvMotionSolver
 (
     const polyMesh& mesh,
-    Istream& msData
+    Istream&
 )
 :
     fvMotionSolver(mesh),
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H
index 2232dd2e63286894aa5f66c93c6fc485369365c8..3af3d843947cfc038d017568307fb111742f1867 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/SBRStress/displacementSBRStressFvMotionSolver.H
@@ -93,8 +93,8 @@ public:
         //- Construct from polyMesh and data stream
         displacementSBRStressFvMotionSolver
         (
-            const polyMesh& mesh,
-            Istream& msData
+            const polyMesh&,
+            Istream& msDataUnused
         );
 
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H
index 57ba2978bbb1c8323445c0d68b3a15c0ce2abdae..d9d2bfd7edb746c4aa91de6f6203a9c20e5f098d 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/componentLaplacian/displacementComponentLaplacianFvMotionSolver.H
@@ -107,9 +107,10 @@ public:
 
     // Constructors
 
+        //- Construct from polyMesh and data stream
         displacementComponentLaplacianFvMotionSolver
         (
-            const polyMesh& mesh,
+            const polyMesh&,
             Istream& msData
         );
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.C
index dae6656380bb2acdf3039f3666c1b7af82baa87c..e7907295e42f7d57a6f2dd9d83a017e48cad28b4 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.C
@@ -58,7 +58,7 @@ Foam::displacementInterpolationFvMotionSolver::
 displacementInterpolationFvMotionSolver
 (
     const polyMesh& mesh,
-    Istream& msData
+    Istream&
 )
 :
     fvMotionSolver(mesh),
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.H
index 04f3eda5cc15f8e8535afb040da2afc4c864310f..b490634b3ece28efe89b345998e13c434fd03ced 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/interpolation/displacementInterpolationFvMotionSolver.H
@@ -115,10 +115,11 @@ public:
 
     // Constructors
 
+        //- Construct from polyMesh and data stream
         displacementInterpolationFvMotionSolver
         (
-            const polyMesh& mesh,
-            Istream& msData
+            const polyMesh&,
+            Istream& msDataUnused
         );
 
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
index 02e5f3b5eb157256d3b75ddda605b581dafc37f9..78c1b41355fe52c2238e8da791b2f07ede03d701 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.C
@@ -53,7 +53,7 @@ namespace Foam
 Foam::displacementLaplacianFvMotionSolver::displacementLaplacianFvMotionSolver
 (
     const polyMesh& mesh,
-    Istream& msData
+    Istream&
 )
 :
     fvMotionSolver(mesh),
diff --git a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H
index 47570239ba72b7547e11f1f3b68345813982f501..d9fc9e5758bcd650f25bc2eab655cbc5d0df0311 100644
--- a/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/displacement/laplacian/displacementLaplacianFvMotionSolver.H
@@ -101,8 +101,8 @@ public:
         //- Construct from polyMesh and data stream
         displacementLaplacianFvMotionSolver
         (
-            const polyMesh& mesh,
-            Istream& msData
+            const polyMesh&,
+            Istream& msDataUnused
         );
 
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/velocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/velocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H
index 223d7ed115280e67d375e5841e872283791dceff..9537b7576ec8387bd045d9c893430f428bb0659d 100644
--- a/src/fvMotionSolver/fvMotionSolvers/velocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/velocity/componentLaplacian/velocityComponentLaplacianFvMotionSolver.H
@@ -93,9 +93,10 @@ public:
 
     // Constructors
 
+        //- Construct from polyMesh and data stream (provides component)
         velocityComponentLaplacianFvMotionSolver
         (
-            const polyMesh& mesh,
+            const polyMesh&,
             Istream& msData
         );
 
diff --git a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
index 50a06de548608f435997ff9a21ace84d93aa6ae0..d6cbf1cc18b95a2c323418bed21cedf4de85884a 100644
--- a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
+++ b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.C
@@ -50,7 +50,7 @@ namespace Foam
 Foam::velocityLaplacianFvMotionSolver::velocityLaplacianFvMotionSolver
 (
     const polyMesh& mesh,
-    Istream& msData
+    Istream&
 )
 :
     fvMotionSolver(mesh),
diff --git a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H
index 2699e95d32fb2d56a62c82900d819bda5117f4af..c4d51123b1ec0b25d66dcca8e234043cd2996c34 100644
--- a/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H
+++ b/src/fvMotionSolver/fvMotionSolvers/velocity/laplacian/velocityLaplacianFvMotionSolver.H
@@ -88,7 +88,11 @@ public:
     // Constructors
 
         //- Construct from polyMesh and data stream
-        velocityLaplacianFvMotionSolver(const polyMesh& mesh, Istream& msData);
+        velocityLaplacianFvMotionSolver
+        (
+            const polyMesh&,
+            Istream& msDataUnused
+        );
 
 
     // Destructor
diff --git a/src/lagrangian/dieselSpray/Make/options b/src/lagrangian/dieselSpray/Make/options
index f204313eff02f55fd3886c1683ade26bc8aacded..d0817503ce4ed16a0798dbe5c0654e91f6df3420 100644
--- a/src/lagrangian/dieselSpray/Make/options
+++ b/src/lagrangian/dieselSpray/Make/options
@@ -1,6 +1,7 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
+    -I$(LIB_SRC)/turbulenceModels \
     -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
     -I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \
     -I$(LIB_SRC)/turbulenceModels/LES/LESdeltas/lnInclude \
diff --git a/src/lagrangian/intermediate/Make/options b/src/lagrangian/intermediate/Make/options
index 4facc47c17157d9762042012a611e8d641083db0..4304ffde9f967b3b3faac828a98e9a891e623b8b 100644
--- a/src/lagrangian/intermediate/Make/options
+++ b/src/lagrangian/intermediate/Make/options
@@ -10,6 +10,7 @@ EXE_INC = \
     -I$(LIB_SRC)/thermophysicalModels/solidMixture/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/combustion/lnInclude \
     -I$(LIB_SRC)/thermophysicalModels/radiation/lnInclude \
+    -I$(LIB_SRC)/turbulenceModels \
     -I$(LIB_SRC)/turbulenceModels/compressible/turbulenceModel \
     -I$(LIB_SRC)/turbulenceModels/compressible/RAS/lnInclude \
     -I$(LIB_SRC)/turbulenceModels/LES/LESdeltas/lnInclude \
diff --git a/src/meshTools/indexedOctree/indexedOctree.C b/src/meshTools/indexedOctree/indexedOctree.C
index 44259482abc61da1c02f831041935b8828345258..b8b18401df14a35a14a0143fb6ea6afdd1639fbc 100644
--- a/src/meshTools/indexedOctree/indexedOctree.C
+++ b/src/meshTools/indexedOctree/indexedOctree.C
@@ -157,7 +157,7 @@ void indexedOctree<Type>::divide
     List<DynamicList<label> > subIndices(8);
     for (direction octant = 0; octant < subIndices.size(); octant++)
     {
-        subIndices[octant].setSize(indices.size()/8);
+        subIndices[octant].setCapacity(indices.size()/8);
     }
 
     // Precalculate bounding boxes.
diff --git a/src/meshTools/octree/treeBoundBox.C b/src/meshTools/octree/treeBoundBox.C
index 1c67e72a7e2cfd3910f0ec48701e64fa9a65caff..38367eb74cfd2ef0d533291308ad38bf4f3730f2 100644
--- a/src/meshTools/octree/treeBoundBox.C
+++ b/src/meshTools/octree/treeBoundBox.C
@@ -110,8 +110,10 @@ Foam::treeBoundBox::treeBoundBox(const UList<point>& points)
 {
     if (points.size() == 0)
     {
-        WarningIn("treeBoundBox::treeBoundBox(const UList<point>&)")
-            << "cannot find bounding box for zero sized pointField"
+        WarningIn
+        (
+            "treeBoundBox::treeBoundBox(const UList<point>&)"
+        )   << "cannot find bounding box for zero-sized pointField"
             << "returning zero" << endl;
 
         return;
@@ -132,17 +134,18 @@ Foam::treeBoundBox::treeBoundBox(const UList<point>& points)
 Foam::treeBoundBox::treeBoundBox
 (
     const UList<point>& points,
-    const labelList& meshPoints
+    const UList<label>& meshPoints
 )
 :
     boundBox()
 {
-    if (meshPoints.size() == 0)
+    if (points.size() == 0 || meshPoints.size() == 0)
     {
         WarningIn
         (
-            "treeBoundBox::treeBoundBox(const UList<point>&, const labelList)"
-        )   << "cannot find bounding box for zero sized pointField"
+            "treeBoundBox::treeBoundBox"
+            "(const UList<point>&, const UList<label>&)"
+        )   << "cannot find bounding box for zero-sized pointField"
             << "returning zero" << endl;
 
         return;
diff --git a/src/meshTools/octree/treeBoundBox.H b/src/meshTools/octree/treeBoundBox.H
index 926b2f33366841ee6ce624c483d8e62ce35a9a46..ce3372146ba1da1b8a0365fe02b01e2dac384599 100644
--- a/src/meshTools/octree/treeBoundBox.H
+++ b/src/meshTools/octree/treeBoundBox.H
@@ -87,6 +87,7 @@ public:
 
     // Static data members
 
+        //- As per boundBox::greatBox, but with GREAT instead of VGREAT
         static const treeBoundBox greatBox;
 
         //- Bits used for octant/point coding. Every octant/corner point
@@ -171,7 +172,7 @@ public:
         treeBoundBox(const UList<point>& points);
 
         //- Construct as subset of points
-        treeBoundBox(const UList<point>&, const labelList& meshPoints);
+        treeBoundBox(const UList<point>&, const UList<label>& meshPoints);
 
         //- Construct from Istream
         treeBoundBox(Istream&);
diff --git a/src/meshTools/octree/treeBoundBoxI.H b/src/meshTools/octree/treeBoundBoxI.H
index 36143fedf1e3812e09852d04bae3e2b23f93d42a..4961fe4018f86d39cd4130d3257027cb9cf38702 100644
--- a/src/meshTools/octree/treeBoundBoxI.H
+++ b/src/meshTools/octree/treeBoundBoxI.H
@@ -27,29 +27,21 @@ License
 #include "treeBoundBox.H"
 #include "Random.H"
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct null setting points to zero
-inline treeBoundBox::treeBoundBox()
+inline Foam::treeBoundBox::treeBoundBox()
 :
     boundBox()
 {}
 
 
-// Construct from components
-inline treeBoundBox::treeBoundBox(const point& min, const point& max)
+inline Foam::treeBoundBox::treeBoundBox(const point& min, const point& max)
 :
     boundBox(min, max)
 {}
 
 
-// Construct from components
-inline treeBoundBox::treeBoundBox(const boundBox& bb)
+inline Foam::treeBoundBox::treeBoundBox(const boundBox& bb)
 :
     boundBox(bb)
 {}
@@ -57,7 +49,7 @@ inline treeBoundBox::treeBoundBox(const boundBox& bb)
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-inline scalar treeBoundBox::minDim() const
+inline Foam::scalar Foam::treeBoundBox::minDim() const
 {
     return ::Foam::min
     (
@@ -71,7 +63,7 @@ inline scalar treeBoundBox::minDim() const
 }
 
 
-inline scalar treeBoundBox::maxDim() const
+inline Foam::scalar Foam::treeBoundBox::maxDim() const
 {
     return ::Foam::max
     (
@@ -85,7 +77,7 @@ inline scalar treeBoundBox::maxDim() const
 }
 
 
-inline scalar treeBoundBox::avgDim() const
+inline Foam::scalar Foam::treeBoundBox::avgDim() const
 {
     return
     (
@@ -96,19 +88,19 @@ inline scalar treeBoundBox::avgDim() const
 }
 
 
-inline scalar treeBoundBox::typDim() const
+inline Foam::scalar Foam::treeBoundBox::typDim() const
 {
     return avgDim();
 }
 
 
-inline point treeBoundBox::mid() const
+inline Foam::point Foam::treeBoundBox::mid() const
 {
     return 0.5*(min() + max());
 }
 
 
-inline point treeBoundBox::corner(const direction octant) const
+inline Foam::point Foam::treeBoundBox::corner(const direction octant) const
 {
     return point
     (
@@ -119,7 +111,7 @@ inline point treeBoundBox::corner(const direction octant) const
 }
 
 // Returns octant in which sample resides. Reverse of subBbox.
-inline direction treeBoundBox::subOctant(const point& sample) const
+inline Foam::direction Foam::treeBoundBox::subOctant(const point& sample) const
 {
     point mid = 0.5*(max() + min());
 
@@ -146,7 +138,7 @@ inline direction treeBoundBox::subOctant(const point& sample) const
 
 // Returns octant in which sample resides. Reverse of subBbox. Precalculated
 // midpoint
-inline direction treeBoundBox::subOctant
+inline Foam::direction Foam::treeBoundBox::subOctant
 (
     const point& mid,
     const point& sample
@@ -175,8 +167,11 @@ inline direction treeBoundBox::subOctant
 
 // Returns octant in which sample resides. Reverse of subBbox. Flags sample
 // exactly on edge.
-inline direction treeBoundBox::subOctant(const point& sample, bool& onEdge)
- const
+inline Foam::direction Foam::treeBoundBox::subOctant
+(
+    const point& sample,
+    bool& onEdge
+) const
 {
     point mid = 0.5*(max() + min());
 
@@ -216,7 +211,7 @@ inline direction treeBoundBox::subOctant(const point& sample, bool& onEdge)
 
 // Returns octant in which sample resides. Reverse of subBbox. Precalculated
 // midpoint
-inline direction treeBoundBox::subOctant
+inline Foam::direction Foam::treeBoundBox::subOctant
 (
     const point& mid,
     const point& sample,
@@ -261,7 +256,7 @@ inline direction treeBoundBox::subOctant
 // Precalculated midpoint. If the sample is on the dividing line between
 // the octants the direction vector determines which octant to use
 // (i.e. in which octant the sample would be if it were moved along dir)
-inline direction treeBoundBox::subOctant
+inline Foam::direction Foam::treeBoundBox::subOctant
 (
     const point& mid,
     const vector& dir,
@@ -319,9 +314,9 @@ inline direction treeBoundBox::subOctant
 }
 
 
-// Returns reference to octantOrder which defines the 
+// Returns reference to octantOrder which defines the
 // order to do the search.
-inline void treeBoundBox::searchOrder
+inline void Foam::treeBoundBox::searchOrder
 (
     const point& sample,
     FixedList<direction,8>& octantOrder
@@ -380,7 +375,7 @@ inline void treeBoundBox::searchOrder
 	{
 	    min = treeBoundBox::FRONTHALF;
 	    mid = treeBoundBox::TOPHALF;
-	    max = treeBoundBox::RIGHTHALF;	    
+	    max = treeBoundBox::RIGHTHALF;
 	}
 	else if( dist.x() < dist.z())
 	{
@@ -412,13 +407,13 @@ inline void treeBoundBox::searchOrder
 
 // true if bb's intersect or overlap.
 // Note: <= to make sure we catch all.
-inline bool treeBoundBox::overlaps(const treeBoundBox& bb) const
+inline bool Foam::treeBoundBox::overlaps(const treeBoundBox& bb) const
 {
     return boundBox::overlaps(bb);
 }
 
 
-inline bool treeBoundBox::contains(const point& sample) const
+inline bool Foam::treeBoundBox::contains(const point& sample) const
 {
     return
     (
@@ -433,7 +428,11 @@ inline bool treeBoundBox::contains(const point& sample) const
 
 
 //- Return slightly wider bounding box
-inline treeBoundBox treeBoundBox::extend(Random& rndGen, const scalar s) const
+inline Foam::treeBoundBox Foam::treeBoundBox::extend
+(
+    Random& rndGen,
+    const scalar s
+) const
 {
     treeBoundBox bb(*this);
 
@@ -456,6 +455,4 @@ inline treeBoundBox treeBoundBox::extend(Random& rndGen, const scalar s) const
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-} // End namespace Foam
-
 // ************************************************************************* //
diff --git a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C
index a3e499bd6531be043fdcfd4ade801b92cf719b0a..e3c42e77beea8e9e198d48e601dba2746ba2f409 100644
--- a/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C
+++ b/src/meshTools/searchableSurface/distributedTriSurfaceMesh.C
@@ -97,7 +97,11 @@ void Foam::distributedTriSurfaceMesh::splitSegment
     point clipPt0, clipPt1;
 
 
-    // 1. Fully local already handled outside
+    // 1. Fully local already handled outside. Note: retest is cheap.
+    if (isLocal(procBb_[Pstream::myProcNo()], start, end))
+    {
+        return;
+    }
 
 
     // 2. Check if fully inside other processor. Rare occurrence
@@ -109,17 +113,14 @@ void Foam::distributedTriSurfaceMesh::splitSegment
         {
             const List<treeBoundBox>& bbs = procBb_[procI];
 
-            forAll(bbs, bbI)
+            if (isLocal(bbs, start, end))
             {
-                if (bbs[bbI].contains(start) && bbs[bbI].contains(end))
-                {
-                    //Pout<< "    Completely remote segment:"
-                    //    << start << end << " on proc:" << procI << endl;
-                    sendMap[procI].append(allSegments.size());
-                    allSegmentMap.append(segmentI);
-                    allSegments.append(segment(start, end));
-                    return;
-                }
+                //Pout<< "    Completely remote segment:"
+                //    << start << end << " on proc:" << procI << endl;
+                sendMap[procI].append(allSegments.size());
+                allSegmentMap.append(segmentI);
+                allSegments.append(segment(start, end));
+                return;
             }
         }
     }
@@ -776,8 +777,7 @@ void Foam::distributedTriSurfaceMesh::calcBounds
     pointIsUsed = 0U;
 
     nPoints = 0;
-    bb.min() = point(VGREAT, VGREAT, VGREAT);
-    bb.max() = point(-VGREAT, -VGREAT, -VGREAT);
+    bb = boundBox::invertedBox;
 
     const triSurface& s = static_cast<const triSurface&>(*this);
 
@@ -2123,7 +2123,7 @@ void Foam::distributedTriSurfaceMesh::distribute
            }
         }
     }
-    
+
 
     faceMap.reset
     (
diff --git a/src/meshTools/searchableSurface/searchableSphere.C b/src/meshTools/searchableSurface/searchableSphere.C
index 04f3f2f2b52c0f410487a6b68a13518682be0a80..74ac1929a6cc7968883451b715745fc4bb9d1c1a 100644
--- a/src/meshTools/searchableSurface/searchableSphere.C
+++ b/src/meshTools/searchableSurface/searchableSphere.C
@@ -292,7 +292,8 @@ void Foam::searchableSphere::getNormal
         if (info[i].hit())
         {
             normal[i] = info[i].hitPoint() - centre_;
-            normal[i] /= mag(normal[i]);
+
+            normal[i] /= mag(normal[i])+VSMALL;
         }
         else
         {
diff --git a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C
index 10662625f0a8afd55bb52daf62a78b8c98a55107..1732fb45d62f25fa19dcc6b4b51c75b43e512e7d 100644
--- a/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C
+++ b/src/meshTools/triSurface/surfaceFeatures/surfaceFeatures.C
@@ -247,7 +247,7 @@ Foam::label Foam::surfaceFeatures::nextFeatEdge
 // prevPointI. Marks feature edges visited in featVisited by assigning them
 // the current feature line number. Returns cumulative length of edges walked.
 // Works in one of two modes:
-// - mark : step to edges with featVisited = -1. 
+// - mark : step to edges with featVisited = -1.
 //          Mark edges visited with currentFeatI.
 // - clear : step to edges with featVisited = currentFeatI
 //           Mark edges visited with -2 and erase from feature edges.
@@ -257,7 +257,7 @@ Foam::surfaceFeatures::labelScalar Foam::surfaceFeatures::walkSegment
     const List<edgeStatus>& edgeStat,
     const label startEdgeI,
     const label startPointI,
-    const label currentFeatI,     
+    const label currentFeatI,
     labelList& featVisited
 )
 {
@@ -360,7 +360,7 @@ Foam::surfaceFeatures::surfaceFeatures
     const labelList& featureEdges,
     const label externalStart,
     const label internalStart
-)    
+)
 :
     surf_(surf),
     featurePoints_(featurePoints),
@@ -457,7 +457,7 @@ Foam::labelList Foam::surfaceFeatures::selectFeatureEdges
 
     if (regionEdges)
     {
-        selectedEdges.setSize(selectedEdges.size() + nRegionEdges());
+        selectedEdges.setCapacity(selectedEdges.size() + nRegionEdges());
 
         for (label i = 0; i < externalStart_; i++)
         {
@@ -467,7 +467,7 @@ Foam::labelList Foam::surfaceFeatures::selectFeatureEdges
 
     if (externalEdges)
     {
-        selectedEdges.setSize(selectedEdges.size() + nExternalEdges());
+        selectedEdges.setCapacity(selectedEdges.size() + nExternalEdges());
 
         for (label i = externalStart_; i < internalStart_; i++)
         {
@@ -477,7 +477,7 @@ Foam::labelList Foam::surfaceFeatures::selectFeatureEdges
 
     if (internalEdges)
     {
-        selectedEdges.setSize(selectedEdges.size() + nInternalEdges());
+        selectedEdges.setCapacity(selectedEdges.size() + nInternalEdges());
 
         for (label i = internalStart_; i < featureEdges_.size(); i++)
         {
@@ -530,8 +530,8 @@ void Foam::surfaceFeatures::findFeatures(const scalar includedAngle)
 
                     // Check if convex or concave by looking at angle
                     // between face centres and normal
-                    vector f0Tof1 = 
-                        surf_[face1].centre(points) 
+                    vector f0Tof1 =
+                        surf_[face1].centre(points)
                         - surf_[face0].centre(points);
 
                     if ((f0Tof1 & faceNormals[face0]) > 0.0)
@@ -683,11 +683,11 @@ void Foam::surfaceFeatures::writeDict(Ostream& writeFile) const
 {
 
     dictionary featInfoDict;
-    featInfoDict.add("externalStart", externalStart_); 
+    featInfoDict.add("externalStart", externalStart_);
     featInfoDict.add("internalStart", internalStart_);
     featInfoDict.add("featureEdges", featureEdges_);
     featInfoDict.add("featurePoints", featurePoints_);
-    
+
     featInfoDict.write(writeFile);
 }
 
@@ -1152,7 +1152,7 @@ void Foam::surfaceFeatures::nearestSurfEdge
 (
     const labelList& selectedEdges,
     const pointField& samples,
-    const vector& searchSpan,   // Search span 
+    const vector& searchSpan,   // Search span
     labelList& edgeLabel,
     labelList& edgeEndPoint,
     pointField& edgePoint
@@ -1163,7 +1163,7 @@ void Foam::surfaceFeatures::nearestSurfEdge
     edgePoint.setSize(samples.size());
 
     const pointField& localPoints = surf_.localPoints();
-    
+
     octree<octreeDataEdges> ppTree
     (
         treeBoundBox(localPoints),  // overall search domain
@@ -1232,7 +1232,7 @@ void Foam::surfaceFeatures::nearestSurfEdge
     const labelList& selectedSampleEdges,
     const pointField& samplePoints,
 
-    const vector& searchSpan,   // Search span 
+    const vector& searchSpan,   // Search span
     labelList& edgeLabel,       // label of surface edge or -1
     pointField& pointOnEdge,    // point on above edge
     pointField& pointOnFeature  // point on sample edge
@@ -1242,7 +1242,6 @@ void Foam::surfaceFeatures::nearestSurfEdge
     pointOnEdge.setSize(selectedSampleEdges.size());
     pointOnFeature.setSize(selectedSampleEdges.size());
 
-    
 
     octree<octreeDataEdges> ppTree
     (
diff --git a/src/sampling/Make/files b/src/sampling/Make/files
index 991057a157d640b8a0070c58e4e12967a74da0fe..c20d4aa7a6838ded07b2abede4248a20094bd485 100644
--- a/src/sampling/Make/files
+++ b/src/sampling/Make/files
@@ -12,11 +12,13 @@ sampledSet/midPointAndFace/midPointAndFaceSet.C
 sampledSet/sampledSets/sampledSets.C
 sampledSet/sampledSetsFunctionObject/sampledSetsFunctionObject.C
 
-sampledSet/writers/writer/writers.C
-sampledSet/writers/raw/rawWriters.C
-sampledSet/writers/xmgr/xmgrWriters.C
-sampledSet/writers/gnuplot/gnuplotWriters.C
-sampledSet/writers/jplot/jplotWriters.C
+setWriters = sampledSet/writers
+
+$(setWriters)/writers.C
+$(setWriters)/gnuplot/gnuplotSetWriterRunTime.C
+$(setWriters)/jplot/jplotSetWriterRunTime.C
+$(setWriters)/raw/rawSetWriterRunTime.C
+$(setWriters)/xmgrace/xmgraceSetWriterRunTime.C
 
 cuttingPlane/cuttingPlane.C
 
@@ -31,13 +33,15 @@ sampledSurface/sampledSurface/sampledSurface.C
 sampledSurface/sampledSurfaces/sampledSurfaces.C
 sampledSurface/sampledSurfacesFunctionObject/sampledSurfacesFunctionObject.C
 
-sampledSurface/writers/surfaceWriters.C
-sampledSurface/writers/foamFile/foamFileWriters.C
-sampledSurface/writers/dx/dxWriters.C
-sampledSurface/writers/raw/rawSurfaceWriters.C
-sampledSurface/writers/vtk/vtkWriters.C
-sampledSurface/writers/stl/stlWriters.C
-sampledSurface/writers/null/nullWriters.C
+surfWriters = sampledSurface/writers
+
+$(surfWriters)/surfaceWriters.C
+$(surfWriters)/dx/dxSurfaceWriterRunTime.C
+$(surfWriters)/foamFile/foamFileSurfaceWriterRunTime.C
+$(surfWriters)/null/nullSurfaceWriterRunTime.C
+$(surfWriters)/raw/rawSurfaceWriterRunTime.C
+$(surfWriters)/stl/stlSurfaceWriterRunTime.C
+$(surfWriters)/vtk/vtkSurfaceWriterRunTime.C
 
 graphField/writePatchGraph.C
 graphField/writeCellGraph.C
diff --git a/src/sampling/Make/options b/src/sampling/Make/options
index 5bfdcb260cee15abe17ecf4a2908a3b9fc7a5cf2..6629b3652c02317e37610ccc87b5ce0afcf52ca6 100644
--- a/src/sampling/Make/options
+++ b/src/sampling/Make/options
@@ -1,10 +1,12 @@
 EXE_INC = \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/meshTools/lnInclude \
+    -I$(LIB_SRC)/surfMesh/lnInclude \
     -I$(LIB_SRC)/triSurface/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude
 
 LIB_LIBS = \
     -lfiniteVolume \
     -lmeshTools \
+    -lsurfMesh \
     -ltriSurface
diff --git a/src/sampling/cuttingPlane/cuttingPlane.C b/src/sampling/cuttingPlane/cuttingPlane.C
index e1a0212ff04b10881fb684141f15fa1dccfa8448..8c36e11d28b0bb908ed14004af81fed36a10c4c6 100644
--- a/src/sampling/cuttingPlane/cuttingPlane.C
+++ b/src/sampling/cuttingPlane/cuttingPlane.C
@@ -45,7 +45,7 @@ void Foam::cuttingPlane::calcCutCells
 (
     const primitiveMesh& mesh,
     const scalarField& dotProducts,
-    const labelList& cellIdLabels
+    const UList<label>& cellIdLabels
 )
 {
     const labelListList& cellEdges = mesh.cellEdges();
@@ -103,11 +103,12 @@ void Foam::cuttingPlane::calcCutCells
 
 // Determine for each edge the intersection point. Calculates
 // - cutPoints_ : coordinates of all intersection points
-// - edgePoint  : per edge -1 or the index into cutPoints_
-Foam::labelList Foam::cuttingPlane::intersectEdges
+// - edgePoint  : per edge -1 or the index into cutPoints
+void Foam::cuttingPlane::intersectEdges
 (
     const primitiveMesh& mesh,
-    const scalarField& dotProducts
+    const scalarField& dotProducts,
+    List<label>& edgePoint
 )
 {
     // Use the dotProducts to find out the cut edges.
@@ -115,7 +116,7 @@ Foam::labelList Foam::cuttingPlane::intersectEdges
     const pointField& points = mesh.points();
 
     // Per edge -1 or the label of the intersection point
-    labelList edgePoint(edges.size(), -1);
+    edgePoint.setSize(edges.size());
 
     DynamicList<point> dynCuttingPoints(4*cutCells_.size());
 
@@ -129,7 +130,9 @@ Foam::labelList Foam::cuttingPlane::intersectEdges
          || (dotProducts[e[1]] < zeroish && dotProducts[e[0]] > positive)
         )
         {
-            // Edge is cut.
+            // Edge is cut
+            edgePoint[edgeI] = dynCuttingPoints.size();
+
             const point& p0 = points[e[0]];
             const point& p1 = points[e[1]];
 
@@ -139,7 +142,7 @@ Foam::labelList Foam::cuttingPlane::intersectEdges
             {
                 dynCuttingPoints.append(p0);
             }
-            else if (alpha > 1.0)
+            else if (alpha >= 1.0)
             {
                 dynCuttingPoints.append(p1);
             }
@@ -147,15 +150,14 @@ Foam::labelList Foam::cuttingPlane::intersectEdges
             {
                 dynCuttingPoints.append((1-alpha)*p0 + alpha*p1);
             }
-
-            edgePoint[edgeI] = dynCuttingPoints.size() - 1;
+        }
+        else
+        {
+            edgePoint[edgeI] = -1;
         }
     }
 
-    dynCuttingPoints.shrink();
-    cutPoints_.transfer(dynCuttingPoints);
-
-    return edgePoint;
+    this->storedPoints().transfer(dynCuttingPoints);
 }
 
 
@@ -164,7 +166,7 @@ Foam::labelList Foam::cuttingPlane::intersectEdges
 bool Foam::cuttingPlane::walkCell
 (
     const primitiveMesh& mesh,
-    const labelList& edgePoint,
+    const UList<label>& edgePoint,
     const label cellI,
     const label startEdgeI,
     DynamicList<label>& faceVerts
@@ -175,6 +177,7 @@ bool Foam::cuttingPlane::walkCell
 
     label nIter = 0;
 
+    faceVerts.clear();
     do
     {
         faceVerts.append(edgePoint[edgeI]);
@@ -255,11 +258,17 @@ bool Foam::cuttingPlane::walkCell
 void Foam::cuttingPlane::walkCellCuts
 (
     const primitiveMesh& mesh,
-    const labelList& edgePoint
+    const UList<label>& edgePoint
 )
 {
-    cutFaces_.setSize(cutCells_.size());
-    label cutFaceI = 0;
+    const pointField& cutPoints = this->points();
+
+    // use dynamic lists to handle triangulation and/or missed cuts
+    DynamicList<face>  dynCutFaces(cutCells_.size());
+    DynamicList<label> dynCutCells(cutCells_.size());
+
+    // scratch space for calculating the face vertices
+    DynamicList<label> faceVerts(10);
 
     forAll(cutCells_, i)
     {
@@ -290,7 +299,6 @@ void Foam::cuttingPlane::walkCellCuts
         }
 
         // Walk from starting edge around the circumference of the cell.
-        DynamicList<label> faceVerts(2*mesh.faces()[cellI].size());
         bool okCut = walkCell
         (
             mesh,
@@ -302,54 +310,46 @@ void Foam::cuttingPlane::walkCellCuts
 
         if (okCut)
         {
-            faceVerts.shrink();
-
-            face cutFace(faceVerts);
+            face f(faceVerts);
 
-            // Orient face.
-            if ((cutFace.normal(cutPoints_) && normal()) < 0)
+            // Orient face to point in the same direction as the plane normal
+            if ((f.normal(cutPoints) && normal()) < 0)
             {
-                cutFace = cutFace.reverseFace();
+                f = f.reverseFace();
             }
 
-            cutFaces_[cutFaceI++] = cutFace;
+            // the cut faces are usually quite ugly, so always triangulate
+            label nTri = f.triangles(cutPoints, dynCutFaces);
+            while (nTri--)
+            {
+                dynCutCells.append(cellI);
+            }
         }
     }
 
-    cutFaces_.setSize(cutFaceI);
+    this->storedFaces().transfer(dynCutFaces);
+    cutCells_.transfer(dynCutCells);
 }
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 // Construct without cutting
-Foam::cuttingPlane::cuttingPlane(const plane& newPlane)
+Foam::cuttingPlane::cuttingPlane(const plane& pln)
 :
-    plane(newPlane)
+    plane(pln)
 {}
 
 
-// Construct from components
-Foam::cuttingPlane::cuttingPlane
-(
-    const primitiveMesh& mesh,
-    const plane& newPlane
-)
-:
-    plane(newPlane)
-{
-    reCut(mesh);
-}
-
 // Construct from mesh reference and plane, restricted to a list of cells
 Foam::cuttingPlane::cuttingPlane
 (
     const primitiveMesh& mesh,
-    const plane& newPlane,
-    const labelList& cellIdLabels
+    const plane& pln,
+    const UList<label>& cellIdLabels
 )
 :
-    plane(newPlane)
+    plane(pln)
 {
     reCut(mesh, cellIdLabels);
 }
@@ -358,101 +358,51 @@ Foam::cuttingPlane::cuttingPlane
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-// reCut mesh with existing planeDesc
-void Foam::cuttingPlane::reCut
-(
-    const primitiveMesh& mesh
-)
-{
-    cutCells_.clear();
-    cutPoints_.clear();
-    cutFaces_.clear();
-
-    scalarField dotProducts = (mesh.points() - refPoint()) & normal();
-
-    //// Perturb points cuts so edges are cut properly.
-    //const tmp<scalarField> tdotProducts = stabilise(rawDotProducts, SMALL);
-    //const scalarField& dotProducts = tdotProducts();
-
-    // Determine cells that are (probably) cut.
-    calcCutCells(mesh, dotProducts);
-
-    // Determine cutPoints and return list of edge cuts. (per edge -1 or
-    // the label of the intersection point (in cutPoints_)
-    labelList edgePoint(intersectEdges(mesh, dotProducts));
-
-    // Do topological walk around cell to find closed loop.
-    walkCellCuts(mesh, edgePoint);
-}
-
-
 // recut mesh with existing planeDesc
 void Foam::cuttingPlane::reCut
 (
     const primitiveMesh& mesh,
-    const labelList& cellIdLabels
+    const UList<label>& cellIdLabels
 )
 {
+    MeshStorage::clear();
     cutCells_.clear();
-    cutPoints_.clear();
-    cutFaces_.clear();
 
     scalarField dotProducts = (mesh.points() - refPoint()) & normal();
 
     // Determine cells that are (probably) cut.
     calcCutCells(mesh, dotProducts, cellIdLabels);
 
-    // Determine cutPoints and return list of edge cuts. (per edge -1 or
-    // the label of the intersection point (in cutPoints_)
-    labelList edgePoint(intersectEdges(mesh, dotProducts));
+    // Determine cutPoints and return list of edge cuts.
+    // per edge -1 or the label of the intersection point
+    labelList edgePoint;
+    intersectEdges(mesh, dotProducts, edgePoint);
 
     // Do topological walk around cell to find closed loop.
     walkCellCuts(mesh, edgePoint);
 }
 
 
-
-// Return plane used
-const Foam::plane& Foam::cuttingPlane::planeDesc() const
-{
-    return static_cast<const plane&>(*this);
-}
-
-
-// Return vectorField of cutting points
-const Foam::pointField& Foam::cuttingPlane::points() const
-{
-    return cutPoints_;
-}
-
-
-// Return unallocFaceList of points in cells
-const Foam::faceList& Foam::cuttingPlane::faces() const
-{
-    return cutFaces_;
-}
-
-
-// Return labelList of cut cells
-const Foam::labelList& Foam::cuttingPlane::cells() const
-{
-    return cutCells_;
-}
-
-
-bool Foam::cuttingPlane::cut()
+// remap action on triangulation
+void Foam::cuttingPlane::remapFaces
+(
+    const UList<label>& faceMap
+)
 {
-    if (cutCells_.size() > 0)
-    {
-        return true;
-    }
-    else
+    // recalculate the cells cut
+    if (&faceMap && faceMap.size())
     {
-        return false;
+        MeshStorage::remapFaces(faceMap);
+
+        List<label> newCutCells(faceMap.size());
+        forAll(faceMap, faceI)
+        {
+            newCutCells[faceI] = cutCells_[faceMap[faceI]];
+        }
+        cutCells_.transfer(newCutCells);
     }
 }
 
-
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
@@ -465,11 +415,9 @@ void Foam::cuttingPlane::operator=(const cuttingPlane& rhs)
             << abort(FatalError);
     }
 
+    static_cast<MeshStorage&>(*this) = rhs;
     static_cast<plane&>(*this) = rhs;
-
-    cutCells_ = rhs.cells();
-    cutPoints_ = rhs.points();
-    cutFaces_ = rhs.faces();
+    cutCells_ = rhs.cutCells();
 }
 
 
diff --git a/src/sampling/cuttingPlane/cuttingPlane.H b/src/sampling/cuttingPlane/cuttingPlane.H
index 3e33be9da769c887a842b0a7c7b61084cc0bb671..5d3e4e714c6cca74d15bf644c8fdf0e1736d8782 100644
--- a/src/sampling/cuttingPlane/cuttingPlane.H
+++ b/src/sampling/cuttingPlane/cuttingPlane.H
@@ -28,7 +28,8 @@ Class
 Description
     Constructs plane through mesh.
 
-    No attempt at resolving degenerate cases.
+    No attempt at resolving degenerate cases. Since the cut faces are
+    usually quite ugly, they will always be triangulated.
 
 Note
     When the cutting plane coincides with a mesh face, the cell edge on the
@@ -45,6 +46,7 @@ SourceFiles
 #include "plane.H"
 #include "pointField.H"
 #include "faceList.H"
+#include "MeshedSurface.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -54,25 +56,22 @@ namespace Foam
 class primitiveMesh;
 
 /*---------------------------------------------------------------------------*\
-                           Class cuttingPlane Declaration
+                       Class cuttingPlane Declaration
 \*---------------------------------------------------------------------------*/
 
 class cuttingPlane
 :
+    public PrimitiveMeshedSurface<face>,
     public plane
 {
+    //- Private typedefs for convenience
+        typedef PrimitiveMeshedSurface<face> MeshStorage;
+
     // Private data
 
         //- List of cells cut by the plane
         labelList cutCells_;
 
-        //- Intersection points
-        pointField cutPoints_;
-
-        //- Cut faces in terms of intersection points
-        faceList cutFaces_;
-
-
     // Private Member Functions
 
         //- Determine cut cells, possibly restricted to a list of cells
@@ -80,22 +79,23 @@ class cuttingPlane
         (
             const primitiveMesh&,
             const scalarField& dotProducts,
-            const labelList& cellIdLabels = labelList::null()
+            const UList<label>& cellIdLabels = UList<label>::null()
         );
 
-        //- Determine intersection points (cutPoints_).
-        labelList intersectEdges
+        //- Determine intersection points (cutPoints).
+        void intersectEdges
         (
             const primitiveMesh&,
-            const scalarField& dotProducts
+            const scalarField& dotProducts,
+            List<label>& edgePoint
         );
 
-        //- Walk around circumference of cell starting from startEdgeI crossing
+        //- Walk circumference of cell, starting from startEdgeI crossing
         //  only cut edges. Record cutPoint labels in faceVerts.
         static bool walkCell
         (
             const primitiveMesh&,
-            const labelList& edgePoint,
+            const UList<label>& edgePoint,
             const label cellI,
             const label startEdgeI,
             DynamicList<label>& faceVerts
@@ -105,7 +105,7 @@ class cuttingPlane
         void walkCellCuts
         (
             const primitiveMesh& mesh,
-            const labelList& edgePoint
+            const UList<label>& edgePoint
         );
 
 
@@ -116,53 +116,51 @@ protected:
         //- Construct plane description without cutting
         cuttingPlane(const plane&);
 
-
     // Protected Member Functions
 
-        //- recut mesh with existing planeDesc
-        void reCut(const primitiveMesh&);
-
         //- recut mesh with existing planeDesc, restricted to a list of cells
         void reCut
         (
             const primitiveMesh&,
-            const labelList& cellIdLabels
+            const UList<label>& cellIdLabels = UList<label>::null()
         );
 
+        //- remap action on triangulation or cleanup
+        virtual void remapFaces(const UList<label>& faceMap);
 
 public:
 
     // Constructors
 
-        //- Construct from components: Mesh reference and plane
-        cuttingPlane(const primitiveMesh&, const plane&);
-
         //- Construct from mesh reference and plane,
-        //  restricted to a list of cells
+        //  possibly restricted to a list of cells
         cuttingPlane
         (
             const primitiveMesh&,
             const plane&,
-            const labelList& cellIdLabels
+            const UList<label>& cellIdLabels = UList<label>::null()
         );
 
 
     // Member Functions
 
         //- Return plane used
-        const plane& planeDesc() const;
-
-        //- Return pointField of cutting points
-        const pointField& points() const;
-
-        //- Return faceList of points in cells
-        const faceList& faces() const;
+        const plane& planeDesc() const
+        {
+            return static_cast<const plane&>(*this);
+        }
 
-        //- Return labelList of cut cells
-        const labelList& cells() const;
+        //- Return List of cells cut by the plane
+        const labelList& cutCells() const
+        {
+            return cutCells_;
+        }
 
         //- Return true or false to question: have any cells been cut?
-        bool cut();
+        bool cut() const
+        {
+            return (cutCells_.size() != 0);
+        }
 
         //- Sample the cell field
         template<class Type>
@@ -185,7 +183,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "cuttingPlaneSample.C"
+#   include "cuttingPlaneTemplates.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/cuttingPlane/cuttingPlaneSample.C b/src/sampling/cuttingPlane/cuttingPlaneTemplates.C
similarity index 96%
rename from src/sampling/cuttingPlane/cuttingPlaneSample.C
rename to src/sampling/cuttingPlane/cuttingPlaneTemplates.C
index 3a6c2175c5b462f5469ca931afb0b989425846be..8238501387b019e36b913d7f024ae36018223c6b 100644
--- a/src/sampling/cuttingPlane/cuttingPlaneSample.C
+++ b/src/sampling/cuttingPlane/cuttingPlaneTemplates.C
@@ -39,7 +39,7 @@ Foam::tmp<Foam::Field<Type> > Foam::cuttingPlane::sample
     const Field<Type>& sf
 ) const
 {
-    return tmp<Field<Type> >(new Field<Type>(sf, cells()));
+    return tmp<Field<Type> >(new Field<Type>(sf, cutCells()));
 }
 
 
diff --git a/src/sampling/sampledSet/writers/gnuplot/gnuplot.C b/src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriter.C
similarity index 91%
rename from src/sampling/sampledSet/writers/gnuplot/gnuplot.C
rename to src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriter.C
index e394de1d3a91272fe13fdda11d54c8b521b627e1..07976741bc0ed0f73bdf6ddb33ca28e292f31972 100644
--- a/src/sampling/sampledSet/writers/gnuplot/gnuplot.C
+++ b/src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "gnuplot.H"
+#include "gnuplotSetWriter.H"
 #include "clock.H"
 #include "coordSet.H"
 #include "fileName.H"
@@ -34,9 +34,8 @@ License
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 template<class Type>
-Foam::gnuplot<Type>::gnuplot()
+Foam::gnuplotSetWriter<Type>::gnuplotSetWriter()
 :
     writer<Type>()
 {}
@@ -44,14 +43,14 @@ Foam::gnuplot<Type>::gnuplot()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::gnuplot<Type>::~gnuplot()
+Foam::gnuplotSetWriter<Type>::~gnuplotSetWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::fileName Foam::gnuplot<Type>::getFileName
+Foam::fileName Foam::gnuplotSetWriter<Type>::getFileName
 (
     const coordSet& points,
     const wordList& valueSetNames
@@ -62,7 +61,7 @@ Foam::fileName Foam::gnuplot<Type>::getFileName
 
 
 template<class Type>
-void Foam::gnuplot<Type>::write
+void Foam::gnuplotSetWriter<Type>::write
 (
     const coordSet& points,
     const wordList& valueSetNames,
diff --git a/src/sampling/sampledSet/writers/gnuplot/gnuplot.H b/src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriter.H
similarity index 89%
rename from src/sampling/sampledSet/writers/gnuplot/gnuplot.H
rename to src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriter.H
index d531ac4aeb67d11d98b4786f71a747e3f2c73e9c..07022266ad0e4275d3b74e2603b93c9594165ecd 100644
--- a/src/sampling/sampledSet/writers/gnuplot/gnuplot.H
+++ b/src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::gnuplot
+    Foam::gnuplotSetWriter
 
 Description
 
 SourceFiles
-    gnuplot.C
+    gnuplotSetWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef gnuplot_H
-#define gnuplot_H
+#ifndef gnuplotSetWriter_H
+#define gnuplotSetWriter_H
 
 #include "writer.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class gnuplot Declaration
+                     Class gnuplotSetWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class gnuplot
+class gnuplotSetWriter
 :
     public writer<Type>
 {
@@ -61,11 +61,11 @@ public:
     // Constructors
 
         //- Construct null
-        gnuplot();
+        gnuplotSetWriter();
 
 
     //- Destructor
-    virtual ~gnuplot();
+    virtual ~gnuplotSetWriter();
 
 
     // Member Functions
@@ -93,7 +93,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "gnuplot.C"
+#   include "gnuplotSetWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSet/writers/xmgr/xmgrWriters.C b/src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSet/writers/xmgr/xmgrWriters.C
rename to src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriterRunTime.C
index 90828ad64f7cf4e041fe1362ca073b6a96a7bef1..f8855ea6579d244198c5d5d966b2101f35a7ce78 100644
--- a/src/sampling/sampledSet/writers/xmgr/xmgrWriters.C
+++ b/src/sampling/sampledSet/writers/gnuplot/gnuplotSetWriterRunTime.C
@@ -24,14 +24,15 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "xmgrWriters.H"
+#include "gnuplotSetWriter.H"
+#include "writers.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    makeWriters(xmgr)
+    makeSetWriters(gnuplotSetWriter)
 }
 
 // ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/gnuplot/gnuplotWriters.H b/src/sampling/sampledSet/writers/gnuplot/gnuplotWriters.H
deleted file mode 100644
index 6f125366f24422e96f235849c220ae5d764a601c..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSet/writers/gnuplot/gnuplotWriters.H
+++ /dev/null
@@ -1,51 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::gnuplotWriters
-
-SourceFiles
-    gnuplotWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef gnuplotWriters_H
-#define gnuplotWriters_H
-
-#include "gnuplot.H"
-#include "writers.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    makeWritersTypedefs(gnuplot)
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/jplot/jplot.C b/src/sampling/sampledSet/writers/jplot/jplotSetWriter.C
similarity index 87%
rename from src/sampling/sampledSet/writers/jplot/jplot.C
rename to src/sampling/sampledSet/writers/jplot/jplotSetWriter.C
index 31775302fbaaf4cdc45fec93a092dba0a135e8db..cc9ada6352b92df39bd35c50587af55d99006411 100644
--- a/src/sampling/sampledSet/writers/jplot/jplot.C
+++ b/src/sampling/sampledSet/writers/jplot/jplotSetWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "jplot.H"
+#include "jplotSetWriter.H"
 #include "clock.H"
 #include "coordSet.H"
 #include "fileName.H"
@@ -34,21 +34,19 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Type>
-Foam::Ostream& Foam::jplot<Type>::writeHeader(Ostream& os) const
+Foam::Ostream& Foam::jplotSetWriter<Type>::writeHeader(Ostream& os) const
 {
     return os
-        << "# JPlot input file" << endl
-        << "#" << endl
-        << endl
+        << "# JPlot input file" << nl
+        << "#" << nl << nl
         << "# Generated by sample on " << clock::date().c_str() << endl;
 }
 
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 template<class Type>
-Foam::jplot<Type>::jplot()
+Foam::jplotSetWriter<Type>::jplotSetWriter()
 :
     writer<Type>()
 {}
@@ -57,14 +55,14 @@ Foam::jplot<Type>::jplot()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::jplot<Type>::~jplot()
+Foam::jplotSetWriter<Type>::~jplotSetWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::fileName Foam::jplot<Type>::getFileName
+Foam::fileName Foam::jplotSetWriter<Type>::getFileName
 (
     const coordSet& points,
     const wordList& valueSetNames
@@ -75,7 +73,7 @@ Foam::fileName Foam::jplot<Type>::getFileName
 
 
 template<class Type>
-void Foam::jplot<Type>::write
+void Foam::jplotSetWriter<Type>::write
 (
     const coordSet& points,
     const wordList& valueSetNames,
@@ -83,7 +81,7 @@ void Foam::jplot<Type>::write
     Ostream& os
 ) const
 {
-    os  << "# JPlot file" << endl
+    os  << "# JPlot file" << nl
         << "# column 1: " << points.name() << endl;
 
     forAll(valueSets, i)
diff --git a/src/sampling/sampledSet/writers/jplot/jplot.H b/src/sampling/sampledSet/writers/jplot/jplotSetWriter.H
similarity index 90%
rename from src/sampling/sampledSet/writers/jplot/jplot.H
rename to src/sampling/sampledSet/writers/jplot/jplotSetWriter.H
index 45a39ebe161195bcd9215dbf1edd7436eeef141e..c6df63dc3a9ee49d5b81e1bb492373ea068f974d 100644
--- a/src/sampling/sampledSet/writers/jplot/jplot.H
+++ b/src/sampling/sampledSet/writers/jplot/jplotSetWriter.H
@@ -23,15 +23,15 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::jplot
+    Foam::jplotSetWriter
 
 SourceFiles
-    jplot.C
+    jplotSetWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef jplot_H
-#define jplot_H
+#ifndef jplotSetWriter_H
+#define jplotSetWriter_H
 
 #include "writer.H"
 #include "vector.H"
@@ -42,11 +42,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class jplot Declaration
+                      Class jplotSetWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class jplot
+class jplotSetWriter
 :
     public writer<Type>
 {
@@ -65,11 +65,11 @@ public:
     // Constructors
 
         //- Construct null
-        jplot();
+        jplotSetWriter();
 
 
     //- Destructor
-    virtual ~jplot();
+    virtual ~jplotSetWriter();
 
 
     // Member Functions
@@ -97,7 +97,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "jplot.C"
+#   include "jplotSetWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSet/writers/gnuplot/gnuplotWriters.C b/src/sampling/sampledSet/writers/jplot/jplotSetWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSet/writers/gnuplot/gnuplotWriters.C
rename to src/sampling/sampledSet/writers/jplot/jplotSetWriterRunTime.C
index 7abc5c8fd0bdea26b35858c0d41f24ba88c38f32..c5a6fe6a02e658e795fe0be71df35707388319c7 100644
--- a/src/sampling/sampledSet/writers/gnuplot/gnuplotWriters.C
+++ b/src/sampling/sampledSet/writers/jplot/jplotSetWriterRunTime.C
@@ -24,14 +24,15 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "gnuplotWriters.H"
+#include "jplotSetWriter.H"
+#include "writers.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    makeWriters(gnuplot)
+    makeSetWriters(jplotSetWriter)
 }
 
 // ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/jplot/jplotWriters.H b/src/sampling/sampledSet/writers/jplot/jplotWriters.H
deleted file mode 100644
index 21b0121ec02cb926f43552a847df698a5e475b04..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSet/writers/jplot/jplotWriters.H
+++ /dev/null
@@ -1,51 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::jplotWriters
-
-SourceFiles
-    jplotWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef jplotWriters_H
-#define jplotWriters_H
-
-#include "jplot.H"
-#include "writers.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    makeWritersTypedefs(jplot)
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/raw/raw.C b/src/sampling/sampledSet/writers/raw/rawSetWriter.C
similarity index 91%
rename from src/sampling/sampledSet/writers/raw/raw.C
rename to src/sampling/sampledSet/writers/raw/rawSetWriter.C
index 021e50c5c96e085291d90a340330d28fec1d2fa2..d8e6f060eda6c13d6b2118a70e63424fe572c8f9 100644
--- a/src/sampling/sampledSet/writers/raw/raw.C
+++ b/src/sampling/sampledSet/writers/raw/rawSetWriter.C
@@ -24,16 +24,15 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "raw.H"
+#include "rawSetWriter.H"
 #include "coordSet.H"
 #include "fileName.H"
 #include "OFstream.H"
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 template<class Type>
-Foam::raw<Type>::raw()
+Foam::rawSetWriter<Type>::rawSetWriter()
 :
     writer<Type>()
 {}
@@ -42,14 +41,14 @@ Foam::raw<Type>::raw()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::raw<Type>::~raw()
+Foam::rawSetWriter<Type>::~rawSetWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::fileName Foam::raw<Type>::getFileName
+Foam::fileName Foam::rawSetWriter<Type>::getFileName
 (
     const coordSet& points,
     const wordList& valueSetNames
@@ -60,7 +59,7 @@ Foam::fileName Foam::raw<Type>::getFileName
 
 
 template<class Type>
-void Foam::raw<Type>::write
+void Foam::rawSetWriter<Type>::write
 (
     const coordSet& points,
     const wordList& valueSetNames,
diff --git a/src/sampling/sampledSet/writers/raw/raw.H b/src/sampling/sampledSet/writers/raw/rawSetWriter.H
similarity index 90%
rename from src/sampling/sampledSet/writers/raw/raw.H
rename to src/sampling/sampledSet/writers/raw/rawSetWriter.H
index 1f4b856f66dfaf916667ea549c661947725591c0..961c5a5c7a2d32d4870cad5c3c9a9436e059b753 100644
--- a/src/sampling/sampledSet/writers/raw/raw.H
+++ b/src/sampling/sampledSet/writers/raw/rawSetWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::raw
+    Foam::rawSetWriter
 
 Description
 
 SourceFiles
-    raw.C
+    rawSetWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef raw_H
-#define raw_H
+#ifndef rawSetWriter_H
+#define rawSetWriter_H
 
 #include "writer.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class raw Declaration
+                       Class rawSetWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class raw
+class rawSetWriter
 :
     public writer<Type>
 {
@@ -61,11 +61,11 @@ public:
     // Constructors
 
         //- Construct null
-        raw();
+        rawSetWriter();
 
 
     //- Destructor
-    virtual ~raw();
+    virtual ~rawSetWriter();
 
 
     // Member Functions
@@ -93,7 +93,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "raw.C"
+#   include "rawSetWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSet/writers/raw/rawWriters.C b/src/sampling/sampledSet/writers/raw/rawSetWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSet/writers/raw/rawWriters.C
rename to src/sampling/sampledSet/writers/raw/rawSetWriterRunTime.C
index 0b3a28898cf81c9616e61ae890224bbc9ee9cbfa..d3ac5e272ba75e8fcb145f495bec83d11af39168 100644
--- a/src/sampling/sampledSet/writers/raw/rawWriters.C
+++ b/src/sampling/sampledSet/writers/raw/rawSetWriterRunTime.C
@@ -24,14 +24,15 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "rawWriters.H"
+#include "rawSetWriter.H"
+#include "writers.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    makeWriters(raw)
+    makeSetWriters(rawSetWriter)
 }
 
 // ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/raw/rawWriters.H b/src/sampling/sampledSet/writers/raw/rawWriters.H
deleted file mode 100644
index 020b750fe291443767bd9dbe2501fb91d3287cb9..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSet/writers/raw/rawWriters.H
+++ /dev/null
@@ -1,51 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::rawWriters
-
-SourceFiles
-    rawWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef rawWriters_H
-#define rawWriters_H
-
-#include "raw.H"
-#include "writers.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    makeWritersTypedefs(raw)
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/writer/writer.C b/src/sampling/sampledSet/writers/writer.C
similarity index 100%
rename from src/sampling/sampledSet/writers/writer/writer.C
rename to src/sampling/sampledSet/writers/writer.C
diff --git a/src/sampling/sampledSet/writers/writer/writer.H b/src/sampling/sampledSet/writers/writer.H
similarity index 69%
rename from src/sampling/sampledSet/writers/writer/writer.H
rename to src/sampling/sampledSet/writers/writer.H
index 73fe2fd10fa8f95d181c0400bc03ad221a1cc5b3..901575fde733825e2294744b0e94bde0b6306363 100644
--- a/src/sampling/sampledSet/writers/writer/writer.H
+++ b/src/sampling/sampledSet/writers/writer.H
@@ -205,49 +205,6 @@ public:
 #   include "writer.C"
 #endif
 
-// Only used internally
-#define makeTypeWritersTypeName(type)                                         \
-                                                                              \
-defineNamedTemplateTypeNameAndDebug(type, 0);
-
-// Used externally sometimes
-#define makeWritersTypeName(typeWriter)                                       \
-                                                                              \
-makeTypeWritersTypeName(typeWriter##ScalarWriter);                            \
-makeTypeWritersTypeName(typeWriter##VectorWriter);                            \
-makeTypeWritersTypeName(typeWriter##SphericalTensorWriter);                   \
-makeTypeWritersTypeName(typeWriter##SymmTensorWriter);                        \
-makeTypeWritersTypeName(typeWriter##TensorWriter);
-
-// Define type info for single template instantiation (e.g. vector)
-#define makeWriterTypes(WriterType, type)                                     \
-                                                                              \
-defineNamedTemplateTypeNameAndDebug(type, 0);                                 \
-                                                                              \
-addToRunTimeSelectionTable                                                    \
-(                                                                             \
-    WriterType, type, word                                                    \
-);
-
-
-// Define type info info for scalar, vector etc. instantiations
-#define makeWriters(typeWriter)                                               \
-                                                                              \
-makeWriterTypes(writerScalarWriter, typeWriter##ScalarWriter);                \
-makeWriterTypes(writerVectorWriter, typeWriter##VectorWriter);                \
-makeWriterTypes(writerSphericalTensorWriter, typeWriter##SphericalTensorWriter);\
-makeWriterTypes(writerSymmTensorWriter, typeWriter##SymmTensorWriter);        \
-makeWriterTypes(writerTensorWriter, typeWriter##TensorWriter);
-
-
-#define makeWritersTypedefs(typeWriter)                                       \
-                                                                              \
-typedef typeWriter<scalar> typeWriter##ScalarWriter;                          \
-typedef typeWriter<vector> typeWriter##VectorWriter;                          \
-typedef typeWriter<sphericalTensor> typeWriter##SphericalTensorWriter;        \
-typedef typeWriter<symmTensor> typeWriter##SymmTensorWriter;                  \
-typedef typeWriter<tensor> typeWriter##TensorWriter;
-
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/sampling/sampledSet/writers/writer/writers.C b/src/sampling/sampledSet/writers/writer/writers.C
deleted file mode 100644
index 8aaa5c4127a8f132c7d6bdd17832e8d9e98b51a7..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSet/writers/writer/writers.C
+++ /dev/null
@@ -1,55 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "writers.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-defineNamedTemplateTypeNameAndDebug(writerScalarWriter, 0);
-defineTemplateRunTimeSelectionTable(writerScalarWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(writerVectorWriter, 0);
-defineTemplateRunTimeSelectionTable(writerVectorWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(writerSphericalTensorWriter, 0);
-defineTemplateRunTimeSelectionTable(writerSphericalTensorWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(writerSymmTensorWriter, 0);
-defineTemplateRunTimeSelectionTable(writerSymmTensorWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(writerTensorWriter, 0);
-defineTemplateRunTimeSelectionTable(writerTensorWriter, word);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/writer/writers.H b/src/sampling/sampledSet/writers/writer/writers.H
deleted file mode 100644
index ba46c5880a3008e418aeadbcd8d7e5794532089a..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSet/writers/writer/writers.H
+++ /dev/null
@@ -1,50 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::rawWriters
-
-SourceFiles
-    writers.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef writers_H
-#define writers_H
-
-#include "writer.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    makeWritersTypedefs(writer)
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/writers.C b/src/sampling/sampledSet/writers/writers.C
new file mode 100644
index 0000000000000000000000000000000000000000..7e624292a3b771a764a1a4cde189730968dcd88c
--- /dev/null
+++ b/src/sampling/sampledSet/writers/writers.C
@@ -0,0 +1,50 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "writers.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+#define defineSetWriterType(dataType)                                         \
+    defineNamedTemplateTypeNameAndDebug(writer<dataType >, 0);                \
+    defineTemplatedRunTimeSelectionTable(writer, word, dataType);
+
+defineSetWriterType(scalar);
+defineSetWriterType(vector);
+defineSetWriterType(sphericalTensor);
+defineSetWriterType(symmTensor);
+defineSetWriterType(tensor);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/writers.H b/src/sampling/sampledSet/writers/writers.H
new file mode 100644
index 0000000000000000000000000000000000000000..080fb4f01380ed3e9254bd08e0c0da219915a83b
--- /dev/null
+++ b/src/sampling/sampledSet/writers/writers.H
@@ -0,0 +1,80 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+InClass
+    Foam::writer
+
+SourceFiles
+    writers.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef writers_H
+#define writers_H
+
+#include "writer.H"
+#include "fieldTypes.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Only used internally
+#define makeTypeSetWritersTypeName(typeWriter, dataType)                     \
+                                                                             \
+    defineNamedTemplateTypeNameAndDebug(typeWriter<dataType >, 0);
+
+// Sometimes used externally
+#define makeSetWritersTypeName(typeWriter)                                   \
+                                                                             \
+    makeTypeSetWritersTypeName(typeWriter, scalar);                          \
+    makeTypeSetWritersTypeName(typeWriter, vector);                          \
+    makeTypeSetWritersTypeName(typeWriter, sphericalTensor);                 \
+    makeTypeSetWritersTypeName(typeWriter, symmTensor);                      \
+    makeTypeSetWritersTypeName(typeWriter, tensor);
+
+// Define type info for single dataType template instantiation (eg, vector)
+#define makeSetWriterType(typeWriter, dataType)                              \
+                                                                             \
+    defineNamedTemplateTypeNameAndDebug(typeWriter<dataType >, 0);           \
+    addTemplatedToRunTimeSelectionTable                                      \
+    (                                                                        \
+        writer, typeWriter, dataType, word                                   \
+    );
+
+
+// Define type info for scalar, vector etc. instantiations
+#define makeSetWriters(typeWriter)                                            \
+                                                                              \
+    makeSetWriterType(typeWriter, scalar);                                    \
+    makeSetWriterType(typeWriter, vector);                                    \
+    makeSetWriterType(typeWriter, sphericalTensor);                           \
+    makeSetWriterType(typeWriter, symmTensor);                                \
+    makeSetWriterType(typeWriter, tensor);
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/xmgr/xmgrWriters.H b/src/sampling/sampledSet/writers/xmgr/xmgrWriters.H
deleted file mode 100644
index b1b554409a77b3e07cec4a2e84091ea7f916a7ad..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSet/writers/xmgr/xmgrWriters.H
+++ /dev/null
@@ -1,54 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::xmgrWriters
-
-Description
-
-SourceFiles
-    xmgrWriters.C
-
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef xmgrWriters_H
-#define xmgrWriters_H
-
-#include "xmgr.H"
-#include "writers.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-    makeWritersTypedefs(xmgr)
-}
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/xmgr/xmgr.C b/src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriter.C
similarity index 91%
rename from src/sampling/sampledSet/writers/xmgr/xmgr.C
rename to src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriter.C
index d8385a07de5c7c7413eb8380dfa9e029d3971fe3..cecc5f238c9e28b7276e0db97cd18bb9fe0a52f2 100644
--- a/src/sampling/sampledSet/writers/xmgr/xmgr.C
+++ b/src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "xmgr.H"
+#include "xmgraceSetWriter.H"
 #include "coordSet.H"
 #include "fileName.H"
 #include "OFstream.H"
@@ -32,9 +32,8 @@ License
 
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
-// Construct from components
 template<class Type>
-Foam::xmgr<Type>::xmgr()
+Foam::xmgraceSetWriter<Type>::xmgraceSetWriter()
 :
     writer<Type>()
 {}
@@ -43,14 +42,14 @@ Foam::xmgr<Type>::xmgr()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::xmgr<Type>::~xmgr()
+Foam::xmgraceSetWriter<Type>::~xmgraceSetWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::fileName Foam::xmgr<Type>::getFileName
+Foam::fileName Foam::xmgraceSetWriter<Type>::getFileName
 (
     const coordSet& points,
     const wordList& valueSetNames
@@ -61,7 +60,7 @@ Foam::fileName Foam::xmgr<Type>::getFileName
 
 
 template<class Type>
-void Foam::xmgr<Type>::write
+void Foam::xmgraceSetWriter<Type>::write
 (
     const coordSet& points,
     const wordList& valueSetNames,
@@ -85,5 +84,4 @@ void Foam::xmgr<Type>::write
     }
 }
 
-
 // ************************************************************************* //
diff --git a/src/sampling/sampledSet/writers/xmgr/xmgr.H b/src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriter.H
similarity index 89%
rename from src/sampling/sampledSet/writers/xmgr/xmgr.H
rename to src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriter.H
index 4478730fd8560f67d43b9db72b114fe5bba50473..c96438e91dd2148c922db82ce32ae6a3ee43d9bc 100644
--- a/src/sampling/sampledSet/writers/xmgr/xmgr.H
+++ b/src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::xmgr
+    Foam::xmgraceSetWriter
 
 Description
 
 SourceFiles
-    xmgr.C
+    xmgraceSetWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef xmgr_H
-#define xmgr_H
+#ifndef xmgraceSetWriter_H
+#define xmgraceSetWriter_H
 
 #include "writer.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class xmgr Declaration
+                     Class xmgraceSetWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class xmgr
+class xmgraceSetWriter
 :
     public writer<Type>
 {
@@ -61,11 +61,11 @@ public:
     // Constructors
 
         //- Construct null
-        xmgr();
+        xmgraceSetWriter();
 
 
     //- Destructor
-    virtual ~xmgr();
+    virtual ~xmgraceSetWriter();
 
 
     // Member Functions
@@ -93,7 +93,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "xmgr.C"
+#   include "xmgraceSetWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSet/writers/jplot/jplotWriters.C b/src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSet/writers/jplot/jplotWriters.C
rename to src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriterRunTime.C
index b117178971a3390ce794bb939bd44b9a154b4fd5..d4049cf2bf92591ec9457838a11716b3a9525e2d 100644
--- a/src/sampling/sampledSet/writers/jplot/jplotWriters.C
+++ b/src/sampling/sampledSet/writers/xmgrace/xmgraceSetWriterRunTime.C
@@ -24,14 +24,15 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "jplotWriters.H"
+#include "xmgraceSetWriter.H"
+#include "writers.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 namespace Foam
 {
-    makeWriters(jplot)
+    makeSetWriters(xmgraceSetWriter)
 }
 
 // ************************************************************************* //
diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C
index 8c4acea9967b39942148f148308d5ae83c0af641..f337d14253dd69b8e361200083f92899ef8530f5 100644
--- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.C
+++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.C
@@ -30,7 +30,8 @@ License
 #include "volPointInterpolation.H"
 #include "addToRunTimeSelectionTable.H"
 #include "fvMesh.H"
-#include "isoSurfaceCell.H"
+#include "isoSurface.H"
+//#include "isoSurfaceCell.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -42,19 +43,46 @@ namespace Foam
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::distanceSurface::createGeometry() const
+void Foam::distanceSurface::createGeometry()
 {
     // Clear any stored topo
     facesPtr_.clear();
 
+
+    const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
+
     // Distance to cell centres
-    scalarField cellDistance(mesh().nCells());
+    // ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    cellDistancePtr_.reset
+    (
+        new volScalarField
+        (
+            IOobject
+            (
+                "cellDistance",
+                fvm.time().timeName(),
+                fvm.time(),
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            ),
+            fvm,
+            dimensionedScalar("zero", dimless/dimTime, 0)
+        )
+    );
+    volScalarField& cellDistance = cellDistancePtr_();
+
+    // Internal field
     {
+        const pointField& cc = fvm.C();
+        scalarField& fld = cellDistance.internalField();
+
         List<pointIndexHit> nearest;
         surfPtr_().findNearest
         (
-            mesh().cellCentres(),
-            scalarField(mesh().nCells(), GREAT),
+            cc,
+            scalarField(cc.size(), GREAT),
             nearest
         );
 
@@ -63,98 +91,109 @@ void Foam::distanceSurface::createGeometry() const
             vectorField normal;
             surfPtr_().getNormal(nearest, normal);
 
-            forAll(cellDistance, cellI)
+            forAll(nearest, i)
             {
-                vector d(mesh().cellCentres()[cellI]-nearest[cellI].hitPoint());
+                vector d(cc[i]-nearest[i].hitPoint());
 
-                if ((d&normal[cellI]) > 0)
+                if ((d&normal[i]) > 0)
                 {
-                    cellDistance[cellI] = Foam::mag(d);
+                    fld[i] = Foam::mag(d);
                 }
                 else
                 {
-                    cellDistance[cellI] = -Foam::mag(d);
+                    fld[i] = -Foam::mag(d);
                 }
             }
         }
         else
         {
-            forAll(cellDistance, cellI)
+            forAll(nearest, i)
             {
-                cellDistance[cellI] = Foam::mag
-                (
-                    nearest[cellI].hitPoint()
-                  - mesh().cellCentres()[cellI]
-                );
+                fld[i] = Foam::mag(cc[i] - nearest[i].hitPoint());
             }
         }
     }
 
+    // Patch fields
+    {
+        forAll(fvm.C().boundaryField(), patchI)
+        {
+            const pointField& cc = fvm.C().boundaryField()[patchI];
+            fvPatchScalarField& fld = cellDistance.boundaryField()[patchI];
+
+            List<pointIndexHit> nearest;
+            surfPtr_().findNearest
+            (
+                cc,
+                scalarField(cc.size(), GREAT),
+                nearest
+            );
+
+            if (signed_)
+            {
+                vectorField normal;
+                surfPtr_().getNormal(nearest, normal);
+
+                forAll(nearest, i)
+                {
+                    vector d(cc[i]-nearest[i].hitPoint());
+
+                    if ((d&normal[i]) > 0)
+                    {
+                        fld[i] = Foam::mag(d);
+                    }
+                    else
+                    {
+                        fld[i] = -Foam::mag(d);
+                    }
+                }
+            }
+            else
+            {
+                forAll(nearest, i)
+                {
+                    fld[i] = Foam::mag(cc[i] - nearest[i].hitPoint());
+                }
+            }
+        }
+    }
+
+    // On processor patches the mesh.C() will already be the cell centre
+    // on the opposite side so no need to swap cellDistance.
+
+
     // Distance to points
-    scalarField pointDistance(mesh().nPoints());
+    pointDistance_.setSize(fvm.nPoints());
     {
         List<pointIndexHit> nearest;
         surfPtr_().findNearest
         (
-            mesh().points(),
-            scalarField(mesh().nPoints(), GREAT),
+            fvm.points(),
+            scalarField(fvm.nPoints(), GREAT),
             nearest
         );
-        forAll(pointDistance, pointI)
+        forAll(pointDistance_, pointI)
         {
-            pointDistance[pointI] = Foam::mag
+            pointDistance_[pointI] = Foam::mag
             (
                 nearest[pointI].hitPoint()
-              - mesh().points()[pointI]
+              - fvm.points()[pointI]
             );
         }
     }
 
     //- Direct from cell field and point field.
-    const isoSurfaceCell iso
+    isoSurfPtr_.reset
     (
-        mesh(),
-        cellDistance,
-        pointDistance,
-        distance_,
-        regularise_
+        new isoSurface
+        (
+            cellDistance,
+            pointDistance_,
+            distance_,
+            regularise_
+        )
     );
 
-    ////- From point field and interpolated cell.
-    //scalarField cellAvg(mesh().nCells(), scalar(0.0));
-    //labelField nPointCells(mesh().nCells(), 0);
-    //{
-    //    for (label pointI = 0; pointI < mesh().nPoints(); pointI++)
-    //    {
-    //        const labelList& pCells = mesh().pointCells(pointI);
-    //
-    //        forAll(pCells, i)
-    //        {
-    //            label cellI = pCells[i];
-    //
-    //            cellAvg[cellI] += pointDistance[pointI];
-    //            nPointCells[cellI]++;
-    //        }
-    //    }
-    //}
-    //forAll(cellAvg, cellI)
-    //{
-    //    cellAvg[cellI] /= nPointCells[cellI];
-    //}
-    //
-    //const isoSurface iso
-    //(
-    //    mesh(),
-    //    cellAvg,
-    //    pointDistance,
-    //    distance_,
-    //    regularise_
-    //);
-
-
-    const_cast<distanceSurface&>(*this).triSurface::operator=(iso);
-    meshCells_ = iso.meshCells();
-
     if (debug)
     {
         print(Pout);
@@ -193,9 +232,8 @@ Foam::distanceSurface::distanceSurface
     signed_(readBool(dict.lookup("signed"))),
     regularise_(dict.lookupOrDefault("regularise", true)),
     zoneName_(word::null),
-    facesPtr_(NULL),
-    storedTimeIndex_(-1),
-    meshCells_(0)
+    isoSurfPtr_(NULL),
+    facesPtr_(NULL)
 {
 //    label zoneId = -1;
 //    if (dict.readIfPresent("zone", zoneName_))
diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
index 82fba8a83f3ff696122ffb23102d4838cb6f6c4d..64aebb1a9a0a588c9201dac2261b2727dc554871 100644
--- a/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
+++ b/src/sampling/sampledSurface/distanceSurface/distanceSurface.H
@@ -37,8 +37,9 @@ SourceFiles
 #define distanceSurface_H
 
 #include "sampledSurface.H"
-#include "triSurface.H"
 #include "searchableSurface.H"
+//#include "isoSurfaceCell.H"
+#include "isoSurface.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -51,8 +52,7 @@ namespace Foam
 
 class distanceSurface
 :
-    public sampledSurface,
-    public triSurface
+    public sampledSurface
 {
     // Private data
 
@@ -71,23 +71,24 @@ class distanceSurface
         //- zone name (if restricted to zones)
         word zoneName_;
 
-        //- triangles converted to faceList
-        mutable autoPtr<faceList> facesPtr_;
 
+        //- Distance to cell centres
+        autoPtr<volScalarField> cellDistancePtr_;
 
-        // Recreated for every isoSurface
+        //- Distance to points
+        scalarField pointDistance_;
 
-            //- Time at last call
-            mutable label storedTimeIndex_;
+        //- Constructed iso surface
+        autoPtr<isoSurface> isoSurfPtr_;
 
-            //- For every triangle the original cell in mesh
-            mutable labelList meshCells_;
+        //- triangles converted to faceList
+        mutable autoPtr<faceList> facesPtr_;
 
 
     // Private Member Functions
 
-        //- Create iso surface (if time has changed)
-        void createGeometry() const;
+        //- Create iso surface
+        void createGeometry();
 
         //- sample field on faces
         template <class Type>
@@ -129,7 +130,7 @@ public:
         //- Points of surface
         virtual const pointField& points() const
         {
-            return triSurface::points();
+            return surface().points();
         }
 
         //- Faces of surface
@@ -137,7 +138,7 @@ public:
         {
             if (!facesPtr_.valid())
             {
-                const triSurface& s = *this;
+                const triSurface& s = surface();
 
                 facesPtr_.reset(new faceList(s.size()));
 
@@ -153,6 +154,10 @@ public:
         //- Correct for mesh movement and/or field changes
         virtual void correct(const bool meshChanged);
 
+        const isoSurface& surface() const
+        {
+            return isoSurfPtr_();
+        }
 
         //- sample field on surface
         virtual tmp<scalarField> sample
diff --git a/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C b/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C
index ce983c7f5f08bffe29eda422a0f47dbff83d08cb..fd1447af78ceae51b06ee26529dfdc8deb1f2734 100644
--- a/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C
+++ b/src/sampling/sampledSurface/distanceSurface/distanceSurfaceTemplates.C
@@ -39,7 +39,7 @@ Foam::distanceSurface::sampleField
     const GeometricField<Type, fvPatchField, volMesh>& vField
 ) const
 {
-    return tmp<Field<Type> >(new Field<Type>(vField, meshCells_));
+    return tmp<Field<Type> >(new Field<Type>(vField, surface().meshCells()));
 }
 
 
@@ -50,33 +50,25 @@ Foam::distanceSurface::interpolateField
     const interpolation<Type>& interpolator
 ) const
 {
-    // One value per point
-    tmp<Field<Type> > tvalues(new Field<Type>(points().size()));
-    Field<Type>& values = tvalues();
-
-    boolList pointDone(points().size(), false);
-
-    forAll(faces(), cutFaceI)
-    {
-        const face& f = faces()[cutFaceI];
-
-        forAll(f, faceVertI)
-        {
-            label pointI = f[faceVertI];
-
-            if (!pointDone[pointI])
-            {
-                values[pointI] = interpolator.interpolate
-                (
-                    points()[pointI],
-                    meshCells_[cutFaceI]
-                );
-                pointDone[pointI] = true;
-            }
-        }
-    }
-
-    return tvalues;
+    const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
+
+    // Get fields to sample. Assume volPointInterpolation!
+    const GeometricField<Type, fvPatchField, volMesh>& volFld =
+        interpolator.psi();
+
+    tmp<GeometricField<Type, pointPatchField, pointMesh> > pointFld
+    (
+        volPointInterpolation::New(fvm).interpolate(volFld)
+    );
+
+    // Sample.
+    return surface().interpolate
+    (
+        cellDistancePtr_(),
+        pointDistance_,
+        volFld,
+        pointFld()
+    );
 }
 
 
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurface.C b/src/sampling/sampledSurface/isoSurface/isoSurface.C
index 13c210d395bec3eafa6c287728dd9239954abba8..e4a11cc71d938708731494ae9417604e1d61a278 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurface.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurface.C
@@ -108,17 +108,15 @@ void Foam::isoSurface::calcCutTypes
         const polyPatch& pp = patches[patchI];
 
         label faceI = pp.start();
-        forAll(pp, i)
+
+        if (isA<emptyPolyPatch>(pp))
         {
-            bool ownLower = (cVals[own[faceI]] < iso_);
-            bool neiLower = (cVals.boundaryField()[patchI][i] < iso_);
+            // Assume zero gradient so owner and neighbour/boundary value equal
 
-            if (ownLower != neiLower)
-            {
-                faceCutType_[faceI] = CUT;
-            }
-            else
+            forAll(pp, i)
             {
+                bool ownLower = (cVals[own[faceI]] < iso_);
+
                 // Mesh edge.
                 const face f = mesh_.faces()[faceI];
 
@@ -129,15 +127,48 @@ void Foam::isoSurface::calcCutTypes
                     (
                         (fpLower != (pVals[f[f.fcIndex(fp)]] < iso_))
                      || (fpLower != ownLower)
-                     || (fpLower != neiLower)
                     )
                     {
                         faceCutType_[faceI] = CUT;
                         break;
                     }
                 }
+                faceI++;
+            }
+        }
+        else
+        {
+            forAll(pp, i)
+            {
+                bool ownLower = (cVals[own[faceI]] < iso_);
+                bool neiLower = (cVals.boundaryField()[patchI][i] < iso_);
+
+                if (ownLower != neiLower)
+                {
+                    faceCutType_[faceI] = CUT;
+                }
+                else
+                {
+                    // Mesh edge.
+                    const face f = mesh_.faces()[faceI];
+
+                    forAll(f, fp)
+                    {
+                        bool fpLower = (pVals[f[fp]] < iso_);
+                        if
+                        (
+                            (fpLower != (pVals[f[f.fcIndex(fp)]] < iso_))
+                         || (fpLower != ownLower)
+                         || (fpLower != neiLower)
+                        )
+                        {
+                            faceCutType_[faceI] = CUT;
+                            break;
+                        }
+                    }
+                }
+                faceI++;
             }
-            faceI++;
         }
     }
 
@@ -328,8 +359,17 @@ void Foam::isoSurface::getNeighbour
         label patchI = boundaryRegion[bFaceI];
         label patchFaceI = faceI-mesh_.boundaryMesh()[patchI].start();
 
-        nbrValue = cVals.boundaryField()[patchI][patchFaceI];
-        nbrPoint = mesh_.C().boundaryField()[patchI][patchFaceI];
+        if (isA<emptyPolyPatch>(mesh_.boundaryMesh()[patchI]))
+        {
+            // Assume zero gradient
+            nbrValue = cVals[own[faceI]];
+            nbrPoint = mesh_.C().boundaryField()[patchI][patchFaceI];
+        }
+        else
+        {
+            nbrValue = cVals.boundaryField()[patchI][patchFaceI];
+            nbrPoint = mesh_.C().boundaryField()[patchI][patchFaceI];
+        }
     }
 }
 
@@ -1333,20 +1373,31 @@ Foam::isoSurface::isoSurface
     {
         const polyPatch& pp = patches[patchI];
 
-        if (!pp.coupled())
+        if (pp.coupled())
         {
             label faceI = pp.start();
 
             forAll(pp, i)
             {
                 boundaryRegion[faceI-mesh_.nInternalFaces()] = patchI;
+                faceI++;
+            }
+        }
+        else
+        {
+            label faceI = pp.start();
 
-                const face& f = mesh_.faces()[faceI++];
+            forAll(pp, i)
+            {
+                boundaryRegion[faceI-mesh_.nInternalFaces()] = patchI;
+
+                const face& f = mesh_.faces()[faceI];
 
                 forAll(f, fp)
                 {
                     isBoundaryPoint.set(f[fp], 1);
                 }
+                faceI++;
             }
         }
     }
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
index 2812645aa3ff22db89ce62d68e40910e04cae3b6..5cffcdf0ddf4b8f21c8f2f2f01363ad97ec43df9 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.C
@@ -201,6 +201,34 @@ Foam::isoSurfaceCell::cellCutType Foam::isoSurfaceCell::calcCutType
 }
 
 
+void Foam::isoSurfaceCell::calcCutTypes
+(
+    const PackedList<1>& isTet,
+    const scalarField& cVals,
+    const scalarField& pVals
+)
+{
+    cellCutType_.setSize(mesh_.nCells());
+    nCutCells_ = 0;
+    forAll(mesh_.cells(), cellI)
+    {
+        cellCutType_[cellI] = calcCutType(isTet, cVals, pVals, cellI);
+
+        if (cellCutType_[cellI] == CUT)
+        {
+            nCutCells_++;
+        }
+    }
+
+    if (debug)
+    {
+        Pout<< "isoSurfaceCell : detected " << nCutCells_
+            << " candidate cut cells." << endl;
+    }
+}
+
+
+
 // Return the two common points between two triangles
 Foam::labelPair Foam::isoSurfaceCell::findCommonPoints
 (
@@ -325,7 +353,6 @@ void Foam::isoSurfaceCell::calcSnappedCc
     const PackedList<1>& isTet,
     const scalarField& cVals,
     const scalarField& pVals,
-    const List<cellCutType>& cellCutType,
 
     DynamicList<point>& snappedPoints,
     labelList& snappedCc
@@ -344,7 +371,7 @@ void Foam::isoSurfaceCell::calcSnappedCc
 
     forAll(mesh_.cells(), cellI)
     {
-        if (cellCutType[cellI] == CUT && isTet.get(cellI) == 0)
+        if (cellCutType_[cellI] == CUT && isTet.get(cellI) == 0)
         {
             scalar cVal = cVals[cellI];
 
@@ -604,7 +631,6 @@ void Foam::isoSurfaceCell::calcSnappedPoint
     const PackedList<1>& isTet,
     const scalarField& cVals,
     const scalarField& pVals,
-    const List<cellCutType>& cellCutType,
 
     DynamicList<point>& snappedPoints,
     labelList& snappedPoint
@@ -635,10 +661,10 @@ void Foam::isoSurfaceCell::calcSnappedPoint
 
             if
             (
-                cellCutType[mesh_.faceOwner()[faceI]] == CUT
+                cellCutType_[mesh_.faceOwner()[faceI]] == CUT
              || (
                     mesh_.isInternalFace(faceI)
-                 && cellCutType[mesh_.faceNeighbour()[faceI]] == CUT
+                 && cellCutType_[mesh_.faceNeighbour()[faceI]] == CUT
                 )
             )
             {
@@ -766,171 +792,6 @@ void Foam::isoSurfaceCell::calcSnappedPoint
 }
 
 
-Foam::point Foam::isoSurfaceCell::generatePoint
-(
-    const DynamicList<point>& snappedPoints,
-
-    const scalar s0,
-    const point& p0,
-    const label p0Index,
-
-    const scalar s1,
-    const point& p1,
-    const label p1Index
-) const
-{
-    scalar d = s1-s0;
-
-    if (mag(d) > VSMALL)
-    {
-        scalar s = (iso_-s0)/d;
-
-        if (s >= 0.5 && s <= 1 && p1Index != -1)
-        {
-            return snappedPoints[p1Index];
-        }
-        else if (s >= 0.0 && s <= 0.5 && p0Index != -1)
-        {
-            return snappedPoints[p0Index];
-        }
-        else
-        {
-            return s*p1 + (1.0-s)*p0;
-        }
-    }
-    else
-    {
-        scalar s = 0.4999;
-
-        return s*p1 + (1.0-s)*p0;
-    }
-}
-
-
-void Foam::isoSurfaceCell::generateTriPoints
-(
-    const DynamicList<point>& snapped,
-
-    const scalar s0,
-    const point& p0,
-    const label p0Index,
-
-    const scalar s1,
-    const point& p1,
-    const label p1Index,
-
-    const scalar s2,
-    const point& p2,
-    const label p2Index,
-
-    const scalar s3,
-    const point& p3,
-    const label p3Index,
-
-    DynamicList<point>& points
-) const
-{
-    int triIndex = 0;
-    if (s0 < iso_)
-    {
-        triIndex |= 1;
-    }
-    if (s1 < iso_)
-    {
-        triIndex |= 2;
-    }
-    if (s2 < iso_)
-    {
-        triIndex |= 4;
-    }
-    if (s3 < iso_)
-    {
-        triIndex |= 8;
-    }
-
-    /* Form the vertices of the triangles for each case */
-    switch (triIndex)
-    {
-        case 0x00:
-        case 0x0F:
-        break;
-
-        case 0x0E:
-        case 0x01:
-            points.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index));
-            points.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
-            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
-        break;
-
-        case 0x0D:
-        case 0x02:
-            points.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index));
-            points.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
-            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
-        break;
-
-        case 0x0C:
-        case 0x03:
-        {
-            point tp1 = generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index);
-            point tp2 = generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index);
-
-            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
-            points.append(tp1);
-            points.append(tp2);
-            points.append(tp2);
-            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
-            points.append(tp1);
-        }
-        break;
-
-        case 0x0B:
-        case 0x04:
-        {
-            points.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index));
-            points.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index));
-            points.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index));
-        }
-        break;
-
-        case 0x0A:
-        case 0x05:
-        {
-            point tp0 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
-            point tp1 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
-
-            points.append(tp0);
-            points.append(tp1);
-            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
-            points.append(tp0);
-            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
-            points.append(tp1);
-        }
-        break;
-
-        case 0x09:
-        case 0x06:
-        {
-            point tp0 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
-            point tp1 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
-
-            points.append(tp0);
-            points.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
-            points.append(tp1);
-            points.append(tp0);
-            points.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
-            points.append(tp1);
-        }
-        break;
-
-        case 0x07:
-        case 0x08:
-            points.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index));
-            points.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index));
-            points.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index));
-        break;
-    }
-}
 
 
 Foam::triSurface Foam::isoSurfaceCell::stitchTriPoints
@@ -1589,26 +1450,9 @@ Foam::isoSurfaceCell::isoSurfaceCell
 
 
     // Determine if any cut through cell
+    calcCutTypes(isTet, cVals, pVals);
 
-    List<cellCutType> cellCutType(mesh_.nCells());
-    label nCutCells = 0;
-    forAll(mesh_.cells(), cellI)
-    {
-        cellCutType[cellI] = calcCutType(isTet, cVals, pVals, cellI);
-
-        if (cellCutType[cellI] == CUT)
-        {
-            nCutCells++;
-        }
-    }
-
-    if (debug)
-    {
-        Pout<< "isoSurfaceCell : detected " << nCutCells
-            << " candidate cut cells." << endl;
-    }
-
-    DynamicList<point> snappedPoints(nCutCells);
+    DynamicList<point> snappedPoints(nCutCells_);
 
     // Per cc -1 or a point inside snappedPoints.
     labelList snappedCc;
@@ -1619,7 +1463,6 @@ Foam::isoSurfaceCell::isoSurfaceCell
             isTet,
             cVals,
             pVals,
-            cellCutType,
             snappedPoints,
             snappedCc
         );
@@ -1630,6 +1473,8 @@ Foam::isoSurfaceCell::isoSurfaceCell
         snappedCc = -1;
     }
 
+    snappedPoints.shrink();
+
     if (debug)
     {
         Pout<< "isoSurfaceCell : shifted " << snappedPoints.size()
@@ -1648,7 +1493,6 @@ Foam::isoSurfaceCell::isoSurfaceCell
             isTet,
             cVals,
             pVals,
-            cellCutType,
             snappedPoints,
             snappedPoint
         );
@@ -1667,115 +1511,24 @@ Foam::isoSurfaceCell::isoSurfaceCell
 
 
 
-    DynamicList<point> triPoints(nCutCells);
-    DynamicList<label> triMeshCells(nCutCells);
-
-    forAll(mesh_.cells(), cellI)
-    {
-        if (cellCutType[cellI] != NOTCUT)
-        {
-            label oldNPoints = triPoints.size();
-
-            const cell& cFaces = mesh_.cells()[cellI];
-
-            if (isTet.get(cellI) == 1)
-            {
-                // For tets don't do cell-centre decomposition, just use the
-                // tet points and values
-
-                const face& f0 = mesh_.faces()[cFaces[0]];
-
-                // Get the other point
-                const face& f1 = mesh_.faces()[cFaces[1]];
-                label oppositeI = -1;
-                forAll(f1, fp)
-                {
-                    oppositeI = f1[fp];
-
-                    if (findIndex(f0, oppositeI) == -1)
-                    {
-                        break;
-                    }
-                }
-
-                generateTriPoints
-                (
-                    snappedPoints,
-                    pVals[f0[0]],
-                    mesh_.points()[f0[0]],
-                    snappedPoint[f0[0]],
+    DynamicList<point> triPoints(nCutCells_);
+    DynamicList<label> triMeshCells(nCutCells_);
 
-                    pVals[f0[1]],
-                    mesh_.points()[f0[1]],
-                    snappedPoint[f0[1]],
-
-                    pVals[f0[2]],
-                    mesh_.points()[f0[2]],
-                    snappedPoint[f0[2]],
-
-                    pVals[oppositeI],
-                    mesh_.points()[oppositeI],
-                    snappedPoint[oppositeI],
-
-                    triPoints
-                );
-            }
-            else
-            {
-                const cell& cFaces = mesh_.cells()[cellI];
-
-                forAll(cFaces, cFaceI)
-                {
-                    label faceI = cFaces[cFaceI];
-                    const face& f = mesh_.faces()[faceI];
-
-                    for (label fp = 1; fp < f.size() - 1; fp++)
-                    {
-                        triFace tri(f[0], f[fp], f[f.fcIndex(fp)]);
-                    //List<triFace> tris(triangulate(f));
-                    //forAll(tris, i)
-                    //{
-                    //    const triFace& tri = tris[i];
-
-
-                        generateTriPoints
-                        (
-                            snappedPoints,
-
-                            pVals[tri[0]],
-                            mesh_.points()[tri[0]],
-                            snappedPoint[tri[0]],
-
-                            pVals[tri[1]],
-                            mesh_.points()[tri[1]],
-                            snappedPoint[tri[1]],
-
-                            pVals[tri[2]],
-                            mesh_.points()[tri[2]],
-                            snappedPoint[tri[2]],
-
-                            cVals[cellI],
-                            mesh_.cellCentres()[cellI],
-                            snappedCc[cellI],
-
-                            triPoints
-                        );
-                    }
-                }
-            }
+    generateTriPoints
+    (
+        cVals,
+        pVals,
 
+        mesh_.cellCentres(),
+        mesh_.points(),
 
-            // Every three triPoints is a cell
-            label nCells = (triPoints.size()-oldNPoints)/3;
-            for (label i = 0; i < nCells; i++)
-            {
-                triMeshCells.append(cellI);
-            }
-        }
-    }
+        snappedPoints,
+        snappedCc,
+        snappedPoint,
 
-    triPoints.shrink();
-    triMeshCells.shrink();
+        triPoints,
+        triMeshCells
+    );
 
     if (debug)
     {
@@ -1878,123 +1631,123 @@ Foam::isoSurfaceCell::isoSurfaceCell
 }
 
 
-//XXXXXXX
-// Experimental retriangulation of triangles per cell. Problem is that
-// -it is very expensive   -only gets rid of internal points, not of boundary
-// ones so limited benefit (e.g. 60 v.s. 88 triangles)
-void Foam::isoSurfaceCell::combineCellTriangles()
-{
-    if (size() > 0)
-    {
-        DynamicList<labelledTri> newTris(size());
-        DynamicList<label> newTriToCell(size());
-
-        label startTriI = 0;
-
-        DynamicList<labelledTri> tris;
-
-        for (label triI = 1; triI <= meshCells_.size(); triI++)
-        {
-            if
-            (
-                triI == meshCells_.size()
-             || meshCells_[triI] != meshCells_[startTriI]
-            )
-            {
-                label nTris = triI-startTriI;
-
-                if (nTris == 1)
-                {
-                    newTris.append(operator[](startTriI));
-                    newTriToCell.append(meshCells_[startTriI]);
-                }
-                else
-                {
-                    // Collect from startTriI to triI in a triSurface
-                    tris.clear();
-                    for (label i = startTriI; i < triI; i++)
-                    {
-                        tris.append(operator[](i));
-                    }
-                    triSurface cellTris(tris, patches(), points());
-                    tris.clear();
-
-                    // Get outside
-                    const labelListList& loops = cellTris.edgeLoops();
-
-                    forAll(loops, i)
-                    {
-                        // Do proper triangulation of loop
-                        face loop(renumber(cellTris.meshPoints(), loops[i]));
-
-                        faceTriangulation faceTris
-                        (
-                            points(),
-                            loop,
-                            true
-                        );
-
-                        // Copy into newTris
-                        forAll(faceTris, faceTriI)
-                        {
-                            const triFace& tri = faceTris[faceTriI];
-
-                            newTris.append
-                            (
-                                labelledTri
-                                (
-                                    tri[0],
-                                    tri[1],
-                                    tri[2],
-                                    operator[](startTriI).region()
-                                )
-                            );
-                            newTriToCell.append(meshCells_[startTriI]);
-                        }
-                    }
-                }
-
-                startTriI = triI;
-            }
-        }
-        newTris.shrink();
-        newTriToCell.shrink();
-
-        // Compact
-        pointField newPoints(points().size());
-        label newPointI = 0;
-        labelList oldToNewPoint(points().size(), -1);
-
-        forAll(newTris, i)
-        {
-            labelledTri& tri = newTris[i];
-            forAll(tri, j)
-            {
-                label pointI = tri[j];
-
-                if (oldToNewPoint[pointI] == -1)
-                {
-                    oldToNewPoint[pointI] = newPointI;
-                    newPoints[newPointI++] = points()[pointI];
-                }
-                tri[j] = oldToNewPoint[pointI];
-            }
-        }
-        newPoints.setSize(newPointI);
-
-        triSurface::operator=
-        (
-            triSurface
-            (
-                newTris,
-                patches(),
-                newPoints,
-                true
-            )
-        );
-        meshCells_.transfer(newTriToCell);
-    }
-}
-//XXXXXXX
+////XXXXXXX
+//// Experimental retriangulation of triangles per cell. Problem is that
+//// -it is very expensive   -only gets rid of internal points, not of boundary
+//// ones so limited benefit (e.g. 60 v.s. 88 triangles)
+//void Foam::isoSurfaceCell::combineCellTriangles()
+//{
+//    if (size() > 0)
+//    {
+//        DynamicList<labelledTri> newTris(size());
+//        DynamicList<label> newTriToCell(size());
+//
+//        label startTriI = 0;
+//
+//        DynamicList<labelledTri> tris;
+//
+//        for (label triI = 1; triI <= meshCells_.size(); triI++)
+//        {
+//            if
+//            (
+//                triI == meshCells_.size()
+//             || meshCells_[triI] != meshCells_[startTriI]
+//            )
+//            {
+//                label nTris = triI-startTriI;
+//
+//                if (nTris == 1)
+//                {
+//                    newTris.append(operator[](startTriI));
+//                    newTriToCell.append(meshCells_[startTriI]);
+//                }
+//                else
+//                {
+//                    // Collect from startTriI to triI in a triSurface
+//                    tris.clear();
+//                    for (label i = startTriI; i < triI; i++)
+//                    {
+//                        tris.append(operator[](i));
+//                    }
+//                    triSurface cellTris(tris, patches(), points());
+//                    tris.clear();
+//
+//                    // Get outside
+//                    const labelListList& loops = cellTris.edgeLoops();
+//
+//                    forAll(loops, i)
+//                    {
+//                        // Do proper triangulation of loop
+//                        face loop(renumber(cellTris.meshPoints(), loops[i]));
+//
+//                        faceTriangulation faceTris
+//                        (
+//                            points(),
+//                            loop,
+//                            true
+//                        );
+//
+//                        // Copy into newTris
+//                        forAll(faceTris, faceTriI)
+//                        {
+//                            const triFace& tri = faceTris[faceTriI];
+//
+//                            newTris.append
+//                            (
+//                                labelledTri
+//                                (
+//                                    tri[0],
+//                                    tri[1],
+//                                    tri[2],
+//                                    operator[](startTriI).region()
+//                                )
+//                            );
+//                            newTriToCell.append(meshCells_[startTriI]);
+//                        }
+//                    }
+//                }
+//
+//                startTriI = triI;
+//            }
+//        }
+//        newTris.shrink();
+//        newTriToCell.shrink();
+//
+//        // Compact
+//        pointField newPoints(points().size());
+//        label newPointI = 0;
+//        labelList oldToNewPoint(points().size(), -1);
+//
+//        forAll(newTris, i)
+//        {
+//            labelledTri& tri = newTris[i];
+//            forAll(tri, j)
+//            {
+//                label pointI = tri[j];
+//
+//                if (oldToNewPoint[pointI] == -1)
+//                {
+//                    oldToNewPoint[pointI] = newPointI;
+//                    newPoints[newPointI++] = points()[pointI];
+//                }
+//                tri[j] = oldToNewPoint[pointI];
+//            }
+//        }
+//        newPoints.setSize(newPointI);
+//
+//        triSurface::operator=
+//        (
+//            triSurface
+//            (
+//                newTris,
+//                patches(),
+//                newPoints,
+//                true
+//            )
+//        );
+//        meshCells_.transfer(newTriToCell);
+//    }
+//}
+////XXXXXXX
 
 // ************************************************************************* //
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H
index 86b2dbef468501f8d75514898320c39eed3a7c14..40e2b6d79378ab15f5552616785c7528717a3d5e 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCell.H
@@ -91,6 +91,11 @@ class isoSurfaceCell
         //- When to merge points
         const scalar mergeDistance_;
 
+        //- Whether cell might be cut
+        List<cellCutType> cellCutType_;
+
+        //- Estimated number of cut cells
+        label nCutCells_;
 
         //- For every triangle the original cell in mesh
         labelList meshCells_;
@@ -119,6 +124,13 @@ class isoSurfaceCell
             const label
         ) const;
 
+        void calcCutTypes
+        (
+            const PackedList<1>&,
+            const scalarField& cellValues,
+            const scalarField& pointValues
+        );
+
         static labelPair findCommonPoints
         (
             const labelledTri&,
@@ -140,7 +152,6 @@ class isoSurfaceCell
             const PackedList<1>& isTet,
             const scalarField& cVals,
             const scalarField& pVals,
-            const List<cellCutType>& cellCutType,
             DynamicList<point>& triPoints,
             labelList& snappedCc
         ) const;
@@ -173,39 +184,57 @@ class isoSurfaceCell
             const PackedList<1>& isTet,
             const scalarField& cVals,
             const scalarField& pVals,
-            const List<cellCutType>& cellCutType,
             DynamicList<point>& triPoints,
             labelList& snappedPoint
         ) const;
 
         //- Generate single point by interpolation or snapping
-        point generatePoint
+        template<class Type>
+        Type generatePoint
         (
-            const DynamicList<point>& snappedPoints,
+            const DynamicList<Type>& snappedPoints,
             const scalar s0,
-            const point& p0,
+            const Type& p0,
             const label p0Index,
             const scalar s1,
-            const point& p1,
+            const Type& p1,
             const label p1Index
         ) const;
 
+        template<class Type>
         void generateTriPoints
         (
-            const DynamicList<point>& snapped,
+            const DynamicList<Type>& snapped,
             const scalar s0,
-            const point& p0,
+            const Type& p0,
             const label p0Index,
             const scalar s1,
-            const point& p1,
+            const Type& p1,
             const label p1Index,
             const scalar s2,
-            const point& p2,
+            const Type& p2,
             const label p2Index,
             const scalar s3,
-            const point& p3,
+            const Type& p3,
             const label p3Index,
-            DynamicList<point>& points
+            DynamicList<Type>& points
+        ) const;
+
+        template<class Type>
+        void generateTriPoints
+        (
+            const scalarField& cVals,
+            const scalarField& pVals,
+
+            const Field<Type>& cCoords,
+            const Field<Type>& pCoords,
+
+            const DynamicList<Type>& snappedPoints,
+            const labelList& snappedCc,
+            const labelList& snappedPoint,
+
+            DynamicList<Type>& triPoints,
+            DynamicList<label>& triMeshCells
         ) const;
 
         triSurface stitchTriPoints
@@ -311,6 +340,18 @@ public:
         {
             return triPointMergeMap_;
         }
+
+
+        //- Interpolates cCoords,pCoords. Takes the original fields
+        //  used to create the iso surface.
+        template <class Type>
+        tmp<Field<Type> > interpolate
+        (
+            const scalarField& cVals,
+            const scalarField& pVals,
+            const Field<Type>& cCoords,
+            const Field<Type>& pCoords
+        ) const;
 };
 
 
@@ -320,6 +361,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+#   include "isoSurfaceCellTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #endif
 
 // ************************************************************************* //
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..748e1a3311dbc19e8e26ba0dea9d1b38ddd07faf
--- /dev/null
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceCellTemplates.C
@@ -0,0 +1,384 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "isoSurfaceCell.H"
+#include "polyMesh.H"
+#include "tetMatcher.H"
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+template<class Type>
+Type Foam::isoSurfaceCell::generatePoint
+(
+    const DynamicList<Type>& snappedPoints,
+
+    const scalar s0,
+    const Type& p0,
+    const label p0Index,
+
+    const scalar s1,
+    const Type& p1,
+    const label p1Index
+) const
+{
+    scalar d = s1-s0;
+
+    if (mag(d) > VSMALL)
+    {
+        scalar s = (iso_-s0)/d;
+
+        if (s >= 0.5 && s <= 1 && p1Index != -1)
+        {
+            return snappedPoints[p1Index];
+        }
+        else if (s >= 0.0 && s <= 0.5 && p0Index != -1)
+        {
+            return snappedPoints[p0Index];
+        }
+        else
+        {
+            return s*p1 + (1.0-s)*p0;
+        }
+    }
+    else
+    {
+        scalar s = 0.4999;
+
+        return s*p1 + (1.0-s)*p0;
+    }
+}
+
+
+template<class Type>
+void Foam::isoSurfaceCell::generateTriPoints
+(
+    const DynamicList<Type>& snapped,
+
+    const scalar s0,
+    const Type& p0,
+    const label p0Index,
+
+    const scalar s1,
+    const Type& p1,
+    const label p1Index,
+
+    const scalar s2,
+    const Type& p2,
+    const label p2Index,
+
+    const scalar s3,
+    const Type& p3,
+    const label p3Index,
+
+    DynamicList<Type>& points
+) const
+{
+    int triIndex = 0;
+    if (s0 < iso_)
+    {
+        triIndex |= 1;
+    }
+    if (s1 < iso_)
+    {
+        triIndex |= 2;
+    }
+    if (s2 < iso_)
+    {
+        triIndex |= 4;
+    }
+    if (s3 < iso_)
+    {
+        triIndex |= 8;
+    }
+
+    /* Form the vertices of the triangles for each case */
+    switch (triIndex)
+    {
+        case 0x00:
+        case 0x0F:
+        break;
+
+        case 0x0E:
+        case 0x01:
+            points.append(generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index));
+            points.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
+            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+        break;
+
+        case 0x0D:
+        case 0x02:
+            points.append(generatePoint(snapped,s1,p1,p1Index,s0,p0,p0Index));
+            points.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
+            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+        break;
+
+        case 0x0C:
+        case 0x03:
+        {
+            Type tp1 = generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index);
+            Type tp2 = generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index);
+
+            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+            points.append(tp1);
+            points.append(tp2);
+            points.append(tp2);
+            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+            points.append(tp1);
+        }
+        break;
+
+        case 0x0B:
+        case 0x04:
+        {
+            points.append(generatePoint(snapped,s2,p2,p2Index,s0,p0,p0Index));
+            points.append(generatePoint(snapped,s2,p2,p2Index,s1,p1,p1Index));
+            points.append(generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index));
+        }
+        break;
+
+        case 0x0A:
+        case 0x05:
+        {
+            Type tp0 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
+            Type tp1 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
+
+            points.append(tp0);
+            points.append(tp1);
+            points.append(generatePoint(snapped,s0,p0,p0Index,s3,p3,p3Index));
+            points.append(tp0);
+            points.append(generatePoint(snapped,s1,p1,p1Index,s2,p2,p2Index));
+            points.append(tp1);
+        }
+        break;
+
+        case 0x09:
+        case 0x06:
+        {
+            Type tp0 = generatePoint(snapped,s0,p0,p0Index,s1,p1,p1Index);
+            Type tp1 = generatePoint(snapped,s2,p2,p2Index,s3,p3,p3Index);
+
+            points.append(tp0);
+            points.append(generatePoint(snapped,s1,p1,p1Index,s3,p3,p3Index));
+            points.append(tp1);
+            points.append(tp0);
+            points.append(generatePoint(snapped,s0,p0,p0Index,s2,p2,p2Index));
+            points.append(tp1);
+        }
+        break;
+
+        case 0x07:
+        case 0x08:
+            points.append(generatePoint(snapped,s3,p3,p3Index,s0,p0,p0Index));
+            points.append(generatePoint(snapped,s3,p3,p3Index,s2,p2,p2Index));
+            points.append(generatePoint(snapped,s3,p3,p3Index,s1,p1,p1Index));
+        break;
+    }
+}
+
+
+template<class Type>
+void Foam::isoSurfaceCell::generateTriPoints
+(
+    const scalarField& cVals,
+    const scalarField& pVals,
+
+    const Field<Type>& cCoords,
+    const Field<Type>& pCoords,
+
+    const DynamicList<Type>& snappedPoints,
+    const labelList& snappedCc,
+    const labelList& snappedPoint,
+
+    DynamicList<Type>& triPoints,
+    DynamicList<label>& triMeshCells
+) const
+{
+    tetMatcher tet;
+
+    forAll(mesh_.cells(), cellI)
+    {
+        if (cellCutType_[cellI] != NOTCUT)
+        {
+            label oldNPoints = triPoints.size();
+
+            const cell& cFaces = mesh_.cells()[cellI];
+
+            if (tet.isA(mesh_, cellI))
+            {
+                // For tets don't do cell-centre decomposition, just use the
+                // tet points and values
+
+                const face& f0 = mesh_.faces()[cFaces[0]];
+
+                // Get the other point
+                const face& f1 = mesh_.faces()[cFaces[1]];
+                label oppositeI = -1;
+                forAll(f1, fp)
+                {
+                    oppositeI = f1[fp];
+
+                    if (findIndex(f0, oppositeI) == -1)
+                    {
+                        break;
+                    }
+                }
+
+                generateTriPoints
+                (
+                    snappedPoints,
+                    pVals[f0[0]],
+                    pCoords[f0[0]],
+                    snappedPoint[f0[0]],
+
+                    pVals[f0[1]],
+                    pCoords[f0[1]],
+                    snappedPoint[f0[1]],
+
+                    pVals[f0[2]],
+                    pCoords[f0[2]],
+                    snappedPoint[f0[2]],
+
+                    pVals[oppositeI],
+                    pCoords[oppositeI],
+                    snappedPoint[oppositeI],
+
+                    triPoints
+                );
+            }
+            else
+            {
+                const cell& cFaces = mesh_.cells()[cellI];
+
+                forAll(cFaces, cFaceI)
+                {
+                    label faceI = cFaces[cFaceI];
+                    const face& f = mesh_.faces()[faceI];
+
+                    for (label fp = 1; fp < f.size() - 1; fp++)
+                    {
+                        triFace tri(f[0], f[fp], f[f.fcIndex(fp)]);
+                    //List<triFace> tris(triangulate(f));
+                    //forAll(tris, i)
+                    //{
+                    //    const triFace& tri = tris[i];
+
+
+                        generateTriPoints
+                        (
+                            snappedPoints,
+
+                            pVals[tri[0]],
+                            pCoords[tri[0]],
+                            snappedPoint[tri[0]],
+
+                            pVals[tri[1]],
+                            pCoords[tri[1]],
+                            snappedPoint[tri[1]],
+
+                            pVals[tri[2]],
+                            pCoords[tri[2]],
+                            snappedPoint[tri[2]],
+
+                            cVals[cellI],
+                            cCoords[cellI],
+                            snappedCc[cellI],
+
+                            triPoints
+                        );
+                    }
+                }
+            }
+
+
+            // Every three triPoints is a cell
+            label nCells = (triPoints.size()-oldNPoints)/3;
+            for (label i = 0; i < nCells; i++)
+            {
+                triMeshCells.append(cellI);
+            }
+        }
+    }
+
+    triPoints.shrink();
+    triMeshCells.shrink();
+}
+
+
+template <class Type>
+Foam::tmp<Foam::Field<Type> >
+Foam::isoSurfaceCell::interpolate
+(
+    const scalarField& cVals,
+    const scalarField& pVals,
+    const Field<Type>& cCoords,
+    const Field<Type>& pCoords
+) const
+{
+    DynamicList<Type> triPoints(nCutCells_);
+    DynamicList<label> triMeshCells(nCutCells_);
+
+    // Dummy snap data
+    DynamicList<Type> snappedPoints;
+    labelList snappedCc(mesh_.nCells(), -1);
+    labelList snappedPoint(mesh_.nPoints(), -1);
+
+
+    generateTriPoints
+    (
+        cVals,
+        pVals,
+
+        cCoords,
+        pCoords,
+
+        snappedPoints,
+        snappedCc,
+        snappedPoint,
+
+        triPoints,
+        triMeshCells
+    );
+
+
+    // One value per point
+    tmp<Field<Type> > tvalues(new Field<Type>(points().size()));
+    Field<Type>& values = tvalues();
+
+    forAll(triPoints, i)
+    {
+        label mergedPointI = triPointMergeMap_[i];
+
+        if (mergedPointI >= 0)
+        {
+            values[mergedPointI] = triPoints[i];
+        }
+    }
+
+    return tvalues;
+}
+
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C b/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
index b4d440c4fde3059145f3b69a7173a330b0ee6b3f..28d994f67811dfabd4068fb314245df1470a28ff 100644
--- a/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
+++ b/src/sampling/sampledSurface/isoSurface/isoSurfaceTemplates.C
@@ -382,6 +382,39 @@ void Foam::isoSurface::generateTriPoints
                 }
             }
         }
+        else if (isA<emptyPolyPatch>(pp))
+        {
+            // Assume zero-gradient.
+            label faceI = pp.start();
+
+            forAll(pp, i)
+            {
+                if (faceCutType_[faceI] != NOTCUT)
+                {
+                    generateTriPoints
+                    (
+                        cVals,
+                        pVals,
+
+                        cCoords,
+                        pCoords,
+
+                        snappedPoints,
+                        snappedCc,
+                        snappedPoint,
+                        faceI,
+
+                        cVals[own[faceI]],
+                        cCoords.boundaryField()[patchI][i],
+                        -1, // fc not snapped
+
+                        triPoints,
+                        triMeshCells
+                    );
+                }
+                faceI++;
+            }
+        }
         else
         {
             label faceI = pp.start();
@@ -465,8 +498,12 @@ Foam::isoSurface::interpolate
 
 
     // One value per point
-    tmp<Field<Type> > tvalues(new Field<Type>(points().size()));
+    tmp<Field<Type> > tvalues
+    (
+        new Field<Type>(points().size(), pTraits<Type>::zero)
+    );
     Field<Type>& values = tvalues();
+    labelList nValues(values.size(), 0);
 
     forAll(triPoints, i)
     {
@@ -474,8 +511,34 @@ Foam::isoSurface::interpolate
 
         if (mergedPointI >= 0)
         {
-            values[mergedPointI] = triPoints[i];
+            values[mergedPointI] += triPoints[i];
+            nValues[mergedPointI]++;
+        }
+    }
+
+    if (debug)
+    {
+        Pout<< "nValues:" << values.size() << endl;
+        label nMult = 0;
+        forAll(nValues, i)
+        {
+            if (nValues[i] == 0)
+            {
+                FatalErrorIn("isoSurface::interpolate(..)")
+                    << "point:" << i << " nValues:" << nValues[i]
+                    << abort(FatalError);
+            }
+            else if (nValues[i] > 1)
+            {
+                nMult++;
+            }
         }
+        Pout<< "Of which mult:" << nMult << endl;
+    }
+
+    forAll(values, i)
+    {
+        values[i] /= scalar(nValues[i]);
     }
 
     return tvalues;
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C
index 782615107ba2498a486f8202a4a09a83c3cd4eb2..0c7832f176681eff6987201f2d9099cbb755ad2d 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurface.C
@@ -45,6 +45,8 @@ void Foam::sampledIsoSurface::getIsoFields() const
 {
     const fvMesh& fvm = static_cast<const fvMesh&>(mesh());
 
+    word pointFldName = "volPointInterpolate(" + isoField_ + ')';
+
     // Get volField
     // ~~~~~~~~~~~~
 
@@ -64,28 +66,56 @@ void Foam::sampledIsoSurface::getIsoFields() const
 
         if (debug)
         {
-            Info<< "sampledIsoSurface::getIsoField() : reading "
-                << isoField_ << " from time " <<fvm.time().timeName()
+            Info<< "sampledIsoSurface::getIsoField() : checking "
+                << isoField_ << " for same time " << fvm.time().timeName()
                 << endl;
         }
 
-        storedVolFieldPtr_.reset
+        if
         (
-            new volScalarField
+           !storedVolFieldPtr_.valid()
+         || (fvm.time().timeName() != storedVolFieldPtr_().instance())
+        )
+        {
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() : reading "
+                    << isoField_ << " from time " << fvm.time().timeName()
+                    << endl;
+            }
+
+            storedVolFieldPtr_.reset
             (
-                IOobject
+                new volScalarField
                 (
-                    isoField_,
-                    fvm.time().timeName(),
-                    fvm,
-                    IOobject::MUST_READ,
-                    IOobject::NO_WRITE,
-                    false
-                ),
-                fvm
-            )
-        );
-        volFieldPtr_ = storedVolFieldPtr_.operator->();
+                    IOobject
+                    (
+                        isoField_,
+                        fvm.time().timeName(),
+                        fvm,
+                        IOobject::MUST_READ,
+                        IOobject::NO_WRITE,
+                        false
+                    ),
+                    fvm
+                )
+            );
+            volFieldPtr_ = storedVolFieldPtr_.operator->();
+
+            // Interpolate to get pointField
+
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() : interpolating "
+                    << pointFldName << endl;
+            }
+
+            storedPointFieldPtr_.reset
+            (
+                volPointInterpolation::New(fvm).interpolate(*volFieldPtr_).ptr()
+            );
+            pointFieldPtr_ = storedPointFieldPtr_.operator->();
+        }
     }
 
 
@@ -93,8 +123,6 @@ void Foam::sampledIsoSurface::getIsoFields() const
     // Get pointField
     // ~~~~~~~~~~~~~~
 
-    word pointFldName = "volPointInterpolate(" + isoField_ + ')';
-
     if (fvm.foundObject<pointScalarField>(pointFldName))
     {
         if (debug)
@@ -102,7 +130,6 @@ void Foam::sampledIsoSurface::getIsoFields() const
             Info<< "sampledIsoSurface::getIsoField() : lookup "
                 << pointFldName << endl;
         }
-        storedPointFieldPtr_.clear();
         pointFieldPtr_ = &fvm.lookupObject<pointScalarField>(pointFldName);
     }
     else
@@ -111,23 +138,37 @@ void Foam::sampledIsoSurface::getIsoFields() const
 
         if (debug)
         {
-            Info<< "sampledIsoSurface::getIsoField() : interpolating "
-                << pointFldName << endl;
+            Info<< "sampledIsoSurface::getIsoField() : checking interpolate "
+                << isoField_ << " for same time " << fvm.time().timeName()
+                << endl;
         }
 
-        storedPointFieldPtr_.reset
+        if
         (
-            volPointInterpolation::New(fvm).interpolate(*volFieldPtr_).ptr()
-        );
-        pointFieldPtr_ = storedPointFieldPtr_.operator->();
+           !storedPointFieldPtr_.valid()
+         || (fvm.time().timeName() != storedPointFieldPtr_().instance())
+        )
+        {
+            if (debug)
+            {
+                Info<< "sampledIsoSurface::getIsoField() : interpolating "
+                    << pointFldName << endl;
+            }
+
+            storedPointFieldPtr_.reset
+            (
+                volPointInterpolation::New(fvm).interpolate(*volFieldPtr_).ptr()
+            );
+            pointFieldPtr_ = storedPointFieldPtr_.operator->();
+        }
     }
 
     if (debug)
     {
-        Info<< "sampledIsoSurface::getIsoField() : obtained volField "
+        Info<< "sampledIsoSurface::getIsoField() : volField "
             << volFieldPtr_->name() << " min:" << min(*volFieldPtr_).value()
             << " max:" << max(*volFieldPtr_).value() << endl;
-        Info<< "sampledIsoSurface::getIsoField() : obtained pointField "
+        Info<< "sampledIsoSurface::getIsoField() : pointField "
             << pointFieldPtr_->name()
             << " min:" << gMin(pointFieldPtr_->internalField())
             << " max:" << gMax(pointFieldPtr_->internalField()) << endl;
diff --git a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C
index 4d4f75c739c2ab441d2ee3c124a69435e1fea991..a36811b75e03336cba8c94b4d5cb2de4ac896ba9 100644
--- a/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C
+++ b/src/sampling/sampledSurface/isoSurface/sampledIsoSurfaceTemplates.C
@@ -57,11 +57,16 @@ Foam::sampledIsoSurface::interpolateField
     const GeometricField<Type, fvPatchField, volMesh>& volFld =
         interpolator.psi();
 
-    tmp<GeometricField<Type, pointPatchField, pointMesh> > pointFld
+    tmp<GeometricField<Type, pointPatchField, pointMesh> > tpointFld
     (
         volPointInterpolation::New(fvm).interpolate(volFld)
     );
 
+    const GeometricField<Type, pointPatchField, pointMesh>& pointFld =
+        tpointFld();
+
+    // Get pointers to sampling field (both original and interpolated one)
+    getIsoFields();
     // Recreate geometry if time has changed
     createGeometry();
 
@@ -71,7 +76,7 @@ Foam::sampledIsoSurface::interpolateField
         *volFieldPtr_,
         *pointFieldPtr_,
         volFld,
-        pointFld()
+        pointFld
     );
 }
 
diff --git a/src/sampling/sampledSurface/patch/sampledPatch.C b/src/sampling/sampledSurface/patch/sampledPatch.C
index fc7635f226993bbb638f53f2736132a74a0e045a..37f19ec1ea4ea137264d759df69864fa994fc33c 100644
--- a/src/sampling/sampledSurface/patch/sampledPatch.C
+++ b/src/sampling/sampledSurface/patch/sampledPatch.C
@@ -44,55 +44,30 @@ namespace Foam
 
 void Foam::sampledPatch::createGeometry()
 {
-    clearGeom();
-    points_.clear();
-    faces_.clear();
+    sampledSurface::clearGeom();
+    MeshStorage::clear();
     patchFaceLabels_.clear();
 
-    if (patchIndex() != -1)
+    if (patchIndex_ != -1)
     {
-        const polyPatch& patch = mesh().boundaryMesh()[patchIndex()];
-        const faceList& localFaces = patch.localFaces();
+        const polyPatch& p = mesh().boundaryMesh()[patchIndex_];
+        this->storedPoints() = p.localPoints();
+        this->storedFaces()  = p.localFaces();
 
-        points_ = patch.localPoints();
-
-        if (triangulate())
+        // an identity map
+        patchFaceLabels_.setSize(faces().size());
+        forAll(patchFaceLabels_, i)
         {
-            // Count triangles
-            label nTri = 0;
-            forAll(localFaces, faceI)
-            {
-                const face& f = localFaces[faceI];
-
-                nTri += f.nTriangles(patch.localPoints());
-            }
-
-            faces_.setSize(nTri);
-            patchFaceLabels_.setSize(nTri);
-
-            // split and fill mesh face references
-            nTri = 0;
-            forAll(localFaces, faceI)
-            {
-                const face& f = localFaces[faceI];
-
-                label fillIndex = nTri;
-
-                f.triangles(patch.localPoints(), nTri, faces_);
-                while (fillIndex < nTri)
-                {
-                    patchFaceLabels_[fillIndex++] = faceI;
-                }
-            }
+            patchFaceLabels_[i] = i;
         }
-        else
+
+        // triangulate uses remapFaces()
+        // - this is somewhat less efficient since it recopies the faces
+        // that we just created, but we probably don't want to do this
+        // too often anyhow.
+        if (triangulate_)
         {
-            faces_  = localFaces;
-            patchFaceLabels_.setSize(faces_.size());
-            forAll(localFaces, i)
-            {
-                patchFaceLabels_[i] = i;
-            }
+            MeshStorage::triangulate();
         }
     }
 
@@ -114,11 +89,10 @@ Foam::sampledPatch::sampledPatch
     const bool triangulate
 )
 :
-    sampledSurface(name, mesh, triangulate),
+    sampledSurface(name, mesh),
     patchName_(patchName),
     patchIndex_(mesh.boundaryMesh().findPatchID(patchName_)),
-    points_(0),
-    faces_(0),
+    triangulate_(triangulate),
     patchFaceLabels_(0)
 {
     createGeometry();
@@ -135,12 +109,9 @@ Foam::sampledPatch::sampledPatch
     sampledSurface(name, mesh, dict),
     patchName_(dict.lookup("patchName")),
     patchIndex_(mesh.boundaryMesh().findPatchID(patchName_)),
-    points_(0),
-    faces_(0),
+    triangulate_(dict.lookupOrDefault("triangulate", false)),
     patchFaceLabels_(0)
 {
-    // default: non-triangulated
-    triangulate() = dict.lookupOrDefault("triangulate", false);
     createGeometry();
 }
 
@@ -162,6 +133,28 @@ void Foam::sampledPatch::correct(const bool meshChanged)
 }
 
 
+// remap action on triangulation
+void Foam::sampledPatch::remapFaces
+(
+    const UList<label>& faceMap
+)
+{
+    // recalculate the cells cut
+    if (&faceMap && faceMap.size())
+    {
+        MeshStorage::remapFaces(faceMap);
+//
+//        List<label> newCutCells(faceMap.size());
+//        forAll(faceMap, faceI)
+//        {
+//            newCutCells[faceI] = cutCells_[faceMap[faceI]];
+//        }
+//        cutCells_.transfer(newCutCells);
+    }
+}
+
+
+
 Foam::tmp<Foam::scalarField>
 Foam::sampledPatch::sample
 (
diff --git a/src/sampling/sampledSurface/patch/sampledPatch.H b/src/sampling/sampledSurface/patch/sampledPatch.H
index 203b6357ee7b39af22ccae904db109d8fb5a675f..d94c9e2677713b9167de51d6920536d6658d4991 100644
--- a/src/sampling/sampledSurface/patch/sampledPatch.H
+++ b/src/sampling/sampledSurface/patch/sampledPatch.H
@@ -37,6 +37,7 @@ SourceFiles
 #define sampledPatch_H
 
 #include "sampledSurface.H"
+#include "MeshedSurface.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
@@ -49,8 +50,12 @@ namespace Foam
 
 class sampledPatch
 :
+    public PrimitiveMeshedSurface<face>,
     public sampledSurface
 {
+    //- Private typedefs for convenience
+        typedef PrimitiveMeshedSurface<face> MeshStorage;
+
     // Private data
 
         //- Name of patch
@@ -59,11 +64,8 @@ class sampledPatch
         //- Index of patch in boundaryMesh
         const label patchIndex_;
 
-        //- Zero size or copy of patch.localPoints()
-        pointField points_;
-
-        //- Faces (triangulated or non-triangulated)
-        faceList faces_;
+        //- Triangulated faces or keep faces as is
+        bool triangulate_;
 
         //- Local patch face labels
         labelList patchFaceLabels_;
@@ -86,6 +88,9 @@ class sampledPatch
         interpolateField(const interpolation<Type>&) const;
 
 
+        //- remap action on triangulation or cleanup 
+        virtual void remapFaces(const UList<label>& faceMap);
+
 public:
 
     //- Runtime type information
@@ -137,13 +142,13 @@ public:
         //- Points of surface
         virtual const pointField& points() const
         {
-            return points_;
+            return MeshStorage::points();
         }
 
         //- Faces of surface
         virtual const faceList& faces() const
         {
-            return faces_;
+            return MeshStorage::faces();
         }
 
 
diff --git a/src/sampling/sampledSurface/plane/sampledPlane.C b/src/sampling/sampledSurface/plane/sampledPlane.C
index fee6a4897bb2eaeac2dfe2557ccd8dfccb7430c6..cf007ed818990672fa6480c68a26a2fef2fc97bc 100644
--- a/src/sampling/sampledSurface/plane/sampledPlane.C
+++ b/src/sampling/sampledSurface/plane/sampledPlane.C
@@ -41,41 +41,21 @@ namespace Foam
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-void Foam::sampledPlane::createGeometry()
+void Foam::sampledPlane::createGeometry
+(
+    const polyMesh& mesh,
+    const label zoneId
+)
 {
-    clearGeom();
-    faces_.clear();
-    meshCells_.clear();
+    sampledSurface::clearGeom();
 
-    if (triangulate())
+    if (zoneId < 0)
     {
-        // Count triangles
-        label nTri = 0;
-        forAll(cuttingPlane::faces(), faceI)
-        {
-            const face& f = cuttingPlane::faces()[faceI];
-
-            nTri += f.nTriangles(points());
-        }
-
-        faces_.setSize(nTri);
-        meshCells_.setSize(nTri);
-
-        // split and fill mesh cell references
-        nTri = 0;
-        forAll(cuttingPlane::faces(), faceI)
-        {
-            const face& f = cuttingPlane::faces()[faceI];
-            label cellId  = cuttingPlane::cells()[faceI];
-
-            label fillIndex = nTri;
-
-            f.triangles(points(), nTri, faces_);
-            while (fillIndex < nTri)
-            {
-                meshCells_[fillIndex++] = cellId;
-            }
-        }
+        reCut(mesh);
+    }
+    else
+    {
+        reCut(mesh, mesh.cellZones()[zoneId]);
     }
 
     if (debug)
@@ -93,15 +73,12 @@ Foam::sampledPlane::sampledPlane
     const word& name,
     const polyMesh& mesh,
     const plane& planeDesc,
-    const word& zoneName,
-    const bool triangulate
+    const word& zoneName
 )
 :
-    sampledSurface(name, mesh, triangulate),
+    sampledSurface(name, mesh),
     cuttingPlane(planeDesc),
-    zoneName_(zoneName),
-    faces_(0),
-    meshCells_(0)
+    zoneName_(zoneName)
 {
     label zoneId = -1;
     if (zoneName_.size())
@@ -115,16 +92,7 @@ Foam::sampledPlane::sampledPlane
         }
     }
 
-    if (zoneId < 0)
-    {
-        reCut(mesh);
-    }
-    else
-    {
-        reCut(mesh, mesh.cellZones()[zoneId]);
-    }
-
-    createGeometry();
+    createGeometry(mesh, zoneId);
 }
 
 
@@ -137,9 +105,7 @@ Foam::sampledPlane::sampledPlane
 :
     sampledSurface(name, mesh, dict),
     cuttingPlane(plane(dict.lookup("basePoint"), dict.lookup("normalVector"))),
-    zoneName_(word::null),
-    faces_(0),
-    meshCells_(0)
+    zoneName_(word::null)
 {
 
     // make plane relative to the coordinateSystem (Cartesian)
@@ -169,16 +135,7 @@ Foam::sampledPlane::sampledPlane
     }
 
 
-    if (zoneId < 0)
-    {
-        reCut(mesh);
-    }
-    else
-    {
-        reCut(mesh, mesh.cellZones()[zoneId]);
-    }
-
-    createGeometry();
+    createGeometry(mesh, zoneId);
 }
 
 
@@ -201,16 +158,7 @@ void Foam::sampledPlane::correct(const bool meshChanged)
             zoneId = mesh().cellZones().findZoneID(zoneName_);
         }
 
-        if (zoneId < 0)
-        {
-            reCut(mesh());
-        }
-        else
-        {
-            reCut(mesh(), mesh().cellZones()[zoneId]);
-        }
-
-        createGeometry();
+        createGeometry(mesh(), zoneId);
     }
 }
 
diff --git a/src/sampling/sampledSurface/plane/sampledPlane.H b/src/sampling/sampledSurface/plane/sampledPlane.H
index 29c8363784120db1e084099a3b43a25c84d8082c..115fb842e9362125a4582004503ab381ec6b1190 100644
--- a/src/sampling/sampledSurface/plane/sampledPlane.H
+++ b/src/sampling/sampledSurface/plane/sampledPlane.H
@@ -26,7 +26,7 @@ Class
     Foam::sampledPlane
 
 Description
-    A sampledSurface defined by a cuttingPlane. Triangulated by default.
+    A sampledSurface defined by a cuttingPlane. Always triangulated.
 
 SourceFiles
     sampledPlane.C
@@ -58,17 +58,14 @@ class sampledPlane
         //- zone name (if restricted to zones)
         word zoneName_;
 
-        //- Triangulated faces in terms of intersection points.
-        //  Non-triangulated faces are obtained directly from cuttingPlane
-        faceList faces_;
-
-        //- For every triangulated face, the original cell in mesh
-        labelList meshCells_;
-
     // Private Member Functions
 
-        //- Do all to create geometry. Triangulate as required
-        void createGeometry();
+        //- Do all to create geometry.
+        void createGeometry
+        (
+            const polyMesh& mesh,
+            const label zoneId
+        );
 
         //- sample field on faces
         template <class Type>
@@ -97,8 +94,7 @@ public:
             const word& name,
             const polyMesh& mesh,
             const plane& planeDesc,
-            const word& zoneName = word::null,
-            const bool triangulate = true
+            const word& zoneName = word::null
         );
 
         //- Construct from dictionary
@@ -118,7 +114,7 @@ public:
     // Member Functions
 
         //- Points of surface
-        const pointField& points() const
+        virtual const pointField& points() const
         {
             return cuttingPlane::points();
         }
@@ -126,30 +122,15 @@ public:
         //- Faces of surface
         virtual const faceList& faces() const
         {
-            if (triangulate())
-            {
-                return faces_;
-            }
-            else
-            {
-                return cuttingPlane::faces();
-            }
+            return cuttingPlane::faces();
         }
 
         //- For every face original cell in mesh
         const labelList& meshCells() const
         {
-            if (triangulate())
-            {
-                return meshCells_;
-            }
-            else
-            {
-                return cuttingPlane::cells();
-            }
+            return cuttingPlane::cutCells();
         }
 
-
         //- Correct for mesh movement and/or field changes
         virtual void correct(const bool meshChanged);
 
diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C
index 79ccf2ff12b8d2cbc743fa32e3ce1472f974480f..098818604c69bc2a51e7b6cd812cffb45b4179b4 100644
--- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.C
+++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.C
@@ -153,13 +153,11 @@ Foam::sampledSurface::New
 Foam::sampledSurface::sampledSurface
 (
     const word& name,
-    const polyMesh& mesh,
-    const bool triangulate
+    const polyMesh& mesh
 )
 :
     name_(name),
     mesh_(mesh),
-    triangulate_(triangulate),
     interpolate_(false),
     SfPtr_(NULL),
     magSfPtr_(NULL),
@@ -178,7 +176,6 @@ Foam::sampledSurface::sampledSurface
 :
     name_(name),
     mesh_(mesh),
-    triangulate_(dict.lookupOrDefault("triangulate", true)),
     interpolate_(dict.lookupOrDefault("interpolate", false)),
     SfPtr_(NULL),
     magSfPtr_(NULL),
diff --git a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H
index fbddbbe2b68c18ff30666a9ab7f7c3d90f309d49..dcd45223fe8646f0f268d16069a1ff22de2479c5 100644
--- a/src/sampling/sampledSurface/sampledSurface/sampledSurface.H
+++ b/src/sampling/sampledSurface/sampledSurface/sampledSurface.H
@@ -68,9 +68,6 @@ class sampledSurface
         //- Reference to mesh
         const polyMesh& mesh_;
 
-        //- Triangulate faces or keep faces as it
-        bool triangulate_;
-
         //- Do we intend to interpolate the information?
         bool interpolate_;
 
@@ -132,12 +129,6 @@ protected:
 
         virtual void clearGeom() const;
 
-        //- Non-const access to triangulation
-        bool& triangulate()
-        {
-            return triangulate_;
-        }
-
 public:
 
     //- Runtime type information
@@ -189,8 +180,7 @@ public:
         sampledSurface
         (
             const word& name,
-            const polyMesh&,
-            const bool triangulate=true
+            const polyMesh&
         );
 
         //- Construct from dictionary
@@ -247,12 +237,6 @@ public:
             return interpolate_;
         }
 
-        //- triangulation requested for surface
-        bool triangulate() const
-        {
-            return triangulate_;
-        }
-
         //- Points of surface
         virtual const pointField& points() const = 0;
 
diff --git a/src/sampling/sampledSurface/writers/dx/dx.C b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C
similarity index 90%
rename from src/sampling/sampledSurface/writers/dx/dx.C
rename to src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C
index deb80de894fc14311a3fba8658084b31e3251379..45506e1797ceb76cd0182c46417a0d1da885c06d 100644
--- a/src/sampling/sampledSurface/writers/dx/dx.C
+++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "dx.H"
+#include "dxSurfaceWriter.H"
 #include "fileName.H"
 #include "OFstream.H"
 #include "faceList.H"
@@ -33,7 +33,7 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Type>
-void Foam::dx<Type>::writeDXGeometry
+void Foam::dxSurfaceWriter<Type>::writeDXGeometry
 (
     const pointField& points,
     const faceList& faces,
@@ -84,7 +84,7 @@ void Foam::dx<Type>::writeDXGeometry
 
 // Write scalarField in DX format
 template<class Type>
-void Foam::dx<Type>::writeDXData
+void Foam::dxSurfaceWriter<Type>::writeDXData
 (
     const pointField& points,
     const scalarField& values,
@@ -116,7 +116,7 @@ void Foam::dx<Type>::writeDXData
 
 // Write vectorField in DX format
 template<class Type>
-void Foam::dx<Type>::writeDXData
+void Foam::dxSurfaceWriter<Type>::writeDXData
 (
     const pointField& points,
     const vectorField& values,
@@ -150,7 +150,7 @@ void Foam::dx<Type>::writeDXData
 
 // Write sphericalTensorField in DX format
 template<class Type>
-void Foam::dx<Type>::writeDXData
+void Foam::dxSurfaceWriter<Type>::writeDXData
 (
     const pointField& points,
     const sphericalTensorField& values,
@@ -182,7 +182,7 @@ void Foam::dx<Type>::writeDXData
 
 // Write symmTensorField in DX format
 template<class Type>
-void Foam::dx<Type>::writeDXData
+void Foam::dxSurfaceWriter<Type>::writeDXData
 (
     const pointField& points,
     const symmTensorField& values,
@@ -219,7 +219,7 @@ void Foam::dx<Type>::writeDXData
 
 // Write tensorField in DX format
 template<class Type>
-void Foam::dx<Type>::writeDXData
+void Foam::dxSurfaceWriter<Type>::writeDXData
 (
     const pointField& points,
     const tensorField& values,
@@ -256,7 +256,7 @@ void Foam::dx<Type>::writeDXData
 
 // Write trailer in DX format
 template<class Type>
-void Foam::dx<Type>::writeDXTrailer(Ostream& os) const
+void Foam::dxSurfaceWriter<Type>::writeDXTrailer(Ostream& os) const
 {
     os  << "# the field, with three components: \"positions\","
         << " \"connections\", and \"data\"" << nl
@@ -272,7 +272,7 @@ void Foam::dx<Type>::writeDXTrailer(Ostream& os) const
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::dx<Type>::dx()
+Foam::dxSurfaceWriter<Type>::dxSurfaceWriter()
 :
     surfaceWriter<Type>()
 {}
@@ -281,14 +281,14 @@ Foam::dx<Type>::dx()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::dx<Type>::~dx()
+Foam::dxSurfaceWriter<Type>::~dxSurfaceWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::dx<Type>::write
+void Foam::dxSurfaceWriter<Type>::write
 (
     const fileName& samplePath,
     const fileName& timeDir,
@@ -307,22 +307,22 @@ void Foam::dx<Type>::write
         mkDir(surfaceDir);
     }
 
-    fileName planeFName(surfaceDir/fieldName + '_' + surfaceName + ".dx");
+    fileName fName(surfaceDir/fieldName + '_' + surfaceName + ".dx");
 
     if (verbose)
     {
-        Info<< "Writing field " << fieldName << " to " << planeFName << endl;
+        Info<< "Writing field " << fieldName << " to " << fName << endl;
     }
 
-    OFstream dxFile(planeFName);
+    OFstream os(fName);
 
-    writeDXGeometry(points, faces, dxFile);
+    writeDXGeometry(points, faces, os);
 
-    writeDXData(points, values, dxFile);
+    writeDXData(points, values, os);
 
-    writeDXTrailer(dxFile);
+    writeDXTrailer(os);
 
-    dxFile << "end" << nl;
+    os << "end" << nl;
 }
 
 
diff --git a/src/sampling/sampledSurface/writers/dx/dx.H b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H
similarity index 92%
rename from src/sampling/sampledSurface/writers/dx/dx.H
rename to src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H
index cccf64e3cf3f74a25ed3c3948a2453d67c197e25..1096d59b366be091a36db6df3b77a87eac73d9c6 100644
--- a/src/sampling/sampledSurface/writers/dx/dx.H
+++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::dx
+    Foam::dxSurfaceWriter
 
 Description
 
 SourceFiles
-    dx.C
+    dxSurfaceWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef dx_H
-#define dx_H
+#ifndef dxSurfaceWriter_H
+#define dxSurfaceWriter_H
 
 #include "surfaceWriter.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class dx Declaration
+                      Class dxSurfaceWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class dx
+class dxSurfaceWriter
 :
     public surfaceWriter<Type>
 {
@@ -107,12 +107,12 @@ public:
     // Constructors
 
         //- Construct null
-        dx();
+        dxSurfaceWriter();
 
 
     // Destructor
 
-        virtual ~dx();
+        virtual ~dxSurfaceWriter();
 
 
     // Member Functions
@@ -141,7 +141,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "dx.C"
+#   include "dxSurfaceWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSurface/writers/dx/dxWriters.C b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSurface/writers/dx/dxWriters.C
rename to src/sampling/sampledSurface/writers/dx/dxSurfaceWriterRunTime.C
index 1cac2b8d78338e7592fb215fb7845d5a5df42a1e..2201282834627aa8920dc3c35b109ff4a6674712 100644
--- a/src/sampling/sampledSurface/writers/dx/dxWriters.C
+++ b/src/sampling/sampledSurface/writers/dx/dxSurfaceWriterRunTime.C
@@ -24,7 +24,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "dxWriters.H"
+#include "dxSurfaceWriter.H"
+#include "surfaceWriters.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -34,7 +35,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-makeSurfaceWriters(dx);
+makeSurfaceWriters(dxSurfaceWriter);
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/sampling/sampledSurface/writers/dx/dxWriters.H b/src/sampling/sampledSurface/writers/dx/dxWriters.H
deleted file mode 100644
index 0700b647b414ab341fe342c71374d9b5dca4638a..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/dx/dxWriters.H
+++ /dev/null
@@ -1,63 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::dxWriters
-
-Description
-
-SourceFiles
-    dxWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef dxWriters_H
-#define dxWriters_H
-
-#include "dx.H"
-#include "surfaceWriters.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-typedef dx<scalar> dxScalarWriter;
-typedef dx<vector> dxVectorWriter;
-typedef dx<sphericalTensor> dxSphericalTensorWriter;
-typedef dx<symmTensor> dxSymmTensorWriter;
-typedef dx<tensor> dxTensorWriter;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFile.C b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C
similarity index 78%
rename from src/sampling/sampledSurface/writers/foamFile/foamFile.C
rename to src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C
index 334c490c43a414b1de65fd9aa560bd618ae9ba1c..4180dcd96363513abadb41009bf45e7d8344c950 100644
--- a/src/sampling/sampledSurface/writers/foamFile/foamFile.C
+++ b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "foamFile.H"
+#include "foamFileSurfaceWriter.H"
 #include "fileName.H"
 #include "OFstream.H"
 #include "faceList.H"
@@ -33,7 +33,7 @@ License
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::foamFile<Type>::foamFile()
+Foam::foamFileSurfaceWriter<Type>::foamFileSurfaceWriter()
 :
     surfaceWriter<Type>()
 {}
@@ -42,14 +42,14 @@ Foam::foamFile<Type>::foamFile()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::foamFile<Type>::~foamFile()
+Foam::foamFileSurfaceWriter<Type>::~foamFileSurfaceWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::foamFile<Type>::write
+void Foam::foamFileSurfaceWriter<Type>::write
 (
     const fileName& samplePath,
     const fileName& timeDir,
@@ -61,42 +61,36 @@ void Foam::foamFile<Type>::write
     const bool verbose
 ) const
 {
-    fileName planeFName(samplePath/timeDir/surfaceName);
+    fileName surfaceDir(samplePath/timeDir/surfaceName);
 
-    if (!exists(planeFName))
+    if (!exists(surfaceDir))
     {
-        mkDir(planeFName);
+        mkDir(surfaceDir);
     }
 
     if (verbose)
     {
-        Info<< "Writing field " << fieldName << " to " << planeFName << endl;
+        Info<< "Writing field " << fieldName << " to " << surfaceDir << endl;
     }
 
     // Points
-    OFstream pointsFile(planeFName/"points");
-
-    pointsFile << points;
+    OFstream(surfaceDir/"points")() << points;
 
     // Faces
-    OFstream facesFile(planeFName/"faces");
-
-    facesFile << faces;
+    OFstream(surfaceDir/"faces")() << faces;
 
     // Values to separate directory (e.g. "scalarField/p")
 
     fileName foamName(pTraits<Type>::typeName);
-
-    fileName valuesDir(planeFName  / (foamName + Field<Type>::typeName));
+    fileName valuesDir(surfaceDir  / (foamName + Field<Type>::typeName));
 
     if (!exists(valuesDir))
     {
         mkDir(valuesDir);
     }
 
-    OFstream valuesFile(valuesDir/fieldName);
-
-    valuesFile << values;
+    // values
+    OFstream(valuesDir/fieldName)() << values;
 }
 
 
diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFile.H b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H
similarity index 88%
rename from src/sampling/sampledSurface/writers/foamFile/foamFile.H
rename to src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H
index fcd5fe4f8a1703930dcfe2d625a42892cb6c2926..1fbee34b515d501d890eed2f070d481227887c2c 100644
--- a/src/sampling/sampledSurface/writers/foamFile/foamFile.H
+++ b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriter.H
@@ -23,18 +23,18 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::foamFile
+    Foam::foamFileSurfaceWriter
 
 Description
     A surfaceWriter for foamFiles
 
 SourceFiles
-    foamFile.C
+    foamFileSurfaceWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef foamFile_H
-#define foamFile_H
+#ifndef foamFileSurfaceWriter_H
+#define foamFileSurfaceWriter_H
 
 #include "surfaceWriter.H"
 
@@ -44,11 +44,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class foamFile Declaration
+                   Class foamFileSurfaceWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class foamFile
+class foamFileSurfaceWriter
 :
     public surfaceWriter<Type>
 {
@@ -62,12 +62,12 @@ public:
     // Constructors
 
         //- Construct null
-        foamFile();
+        foamFileSurfaceWriter();
 
 
     // Destructor
 
-        virtual ~foamFile();
+        virtual ~foamFileSurfaceWriter();
 
 
     // Member Functions
@@ -96,7 +96,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "foamFile.C"
+#   include "foamFileSurfaceWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriterRunTime.C b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriterRunTime.C
new file mode 100644
index 0000000000000000000000000000000000000000..6d669446f775b47a1e911190ac8f4371429ae772
--- /dev/null
+++ b/src/sampling/sampledSurface/writers/foamFile/foamFileSurfaceWriterRunTime.C
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "foamFileSurfaceWriter.H"
+#include "surfaceWriters.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+makeSurfaceWriters(foamFileSurfaceWriter);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFileWriters.H b/src/sampling/sampledSurface/writers/foamFile/foamFileWriters.H
deleted file mode 100644
index ff963568fb32b9958a1f924ba1c9523ae2a9fa89..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/foamFile/foamFileWriters.H
+++ /dev/null
@@ -1,63 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::foamFileWriters
-
-Description
-
-SourceFiles
-    foamFileWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef foamFileWriters_H
-#define foamFileWriters_H
-
-#include "foamFile.H"
-#include "surfaceWriters.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-typedef foamFile<scalar> foamFileScalarWriter;
-typedef foamFile<vector> foamFileVectorWriter;
-typedef foamFile<sphericalTensor> foamFileSphericalTensorWriter;
-typedef foamFile<symmTensor> foamFileSymmTensorWriter;
-typedef foamFile<tensor> foamFileTensorWriter;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/null/null.C b/src/sampling/sampledSurface/writers/null/nullSurfaceWriter.C
similarity index 92%
rename from src/sampling/sampledSurface/writers/null/null.C
rename to src/sampling/sampledSurface/writers/null/nullSurfaceWriter.C
index 979109a00b539753fb5018db1dabfa9056e4f7fc..b4efa9bd389265448885c89c301390e04926b1e4 100644
--- a/src/sampling/sampledSurface/writers/null/null.C
+++ b/src/sampling/sampledSurface/writers/null/nullSurfaceWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "null.H"
+#include "nullSurfaceWriter.H"
 #include "fileName.H"
 #include "OFstream.H"
 #include "faceList.H"
@@ -35,7 +35,7 @@ License
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::null<Type>::null()
+Foam::nullSurfaceWriter<Type>::nullSurfaceWriter()
 :
     surfaceWriter<Type>()
 {}
@@ -44,14 +44,14 @@ Foam::null<Type>::null()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::null<Type>::~null()
+Foam::nullSurfaceWriter<Type>::~nullSurfaceWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::null<Type>::write
+void Foam::nullSurfaceWriter<Type>::write
 (
     const fileName& samplePath,
     const fileName& timeDir,
diff --git a/src/sampling/sampledSurface/writers/null/null.H b/src/sampling/sampledSurface/writers/null/nullSurfaceWriter.H
similarity index 89%
rename from src/sampling/sampledSurface/writers/null/null.H
rename to src/sampling/sampledSurface/writers/null/nullSurfaceWriter.H
index baf84f218cc1708dc70b6471679319a2ee4bab24..a94c57d537a86f98807b952730277f4d8ace66cb 100644
--- a/src/sampling/sampledSurface/writers/null/null.H
+++ b/src/sampling/sampledSurface/writers/null/nullSurfaceWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::null
+    Foam::nullSurfaceWriter
 
 Description
 
 SourceFiles
-    null.C
+    nullSurfaceWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef null_H
-#define null_H
+#ifndef nullSurfaceWriter_H
+#define nullSurfaceWriter_H
 
 #include "surfaceWriter.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class null Declaration
+                     Class nullSurfaceWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class null
+class nullSurfaceWriter
 :
     public surfaceWriter<Type>
 {
@@ -61,12 +61,12 @@ public:
     // Constructors
 
         //- Construct null
-        null();
+        nullSurfaceWriter();
 
 
     // Destructor
 
-        virtual ~null();
+        virtual ~nullSurfaceWriter();
 
 
     // Member Functions
@@ -95,7 +95,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "null.C"
+#   include "nullSurfaceWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSurface/writers/null/nullSurfaceWriterRunTime.C b/src/sampling/sampledSurface/writers/null/nullSurfaceWriterRunTime.C
new file mode 100644
index 0000000000000000000000000000000000000000..4e779fcefd377355dc3922c505b1bce42a0a6da5
--- /dev/null
+++ b/src/sampling/sampledSurface/writers/null/nullSurfaceWriterRunTime.C
@@ -0,0 +1,44 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "nullSurfaceWriter.H"
+#include "surfaceWriters.H"
+#include "addToRunTimeSelectionTable.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+makeSurfaceWriters(nullSurfaceWriter);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C
index 2f281c20dfa07ee79a95fa274e94f16a9b23792f..f25249b1b075cdac79f9408cdd8c525845de9826 100644
--- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C
+++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriter.C
@@ -347,16 +347,15 @@ void Foam::rawSurfaceWriter<Type>::write
         mkDir(surfaceDir);
     }
 
-    fileName planeFName(surfaceDir/fieldName + '_' + surfaceName + ".raw");
+    fileName fName(surfaceDir/fieldName + '_' + surfaceName + ".raw");
 
     if (verbose)
     {
-        Info<< "Writing field " << fieldName << " to " << planeFName << endl;
+        Info<< "Writing field " << fieldName << " to " << fName << endl;
     }
 
-    OFstream rawFile(planeFName);
-
-    writeData(fieldName, points, faces, values, rawFile);
+    OFstream os(fName);
+    writeData(fieldName, points, faces, values, os);
 }
 
 
diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriters.C b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterRunTime.C
similarity index 96%
rename from src/sampling/sampledSurface/writers/raw/rawSurfaceWriters.C
rename to src/sampling/sampledSurface/writers/raw/rawSurfaceWriterRunTime.C
index cd147b3193bd652eceb90f125b5fee11bb4b534e..ee1168266c4e01dc2ccecfab8a1b7363951dd689 100644
--- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriters.C
+++ b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriterRunTime.C
@@ -24,7 +24,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "rawSurfaceWriters.H"
+#include "rawSurfaceWriter.H"
+#include "surfaceWriters.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriters.H b/src/sampling/sampledSurface/writers/raw/rawSurfaceWriters.H
deleted file mode 100644
index b96bc71dfdf963ce0582a70c11678a91b37da36d..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/raw/rawSurfaceWriters.H
+++ /dev/null
@@ -1,63 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::rawSurfaceWriters
-
-Description
-
-SourceFiles
-    rawSurfaceWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef rawSurfaceWriters_H
-#define rawSurfaceWriters_H
-
-#include "rawSurfaceWriter.H"
-#include "surfaceWriters.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-typedef rawSurfaceWriter<scalar> rawSurfaceWriterScalarWriter;
-typedef rawSurfaceWriter<vector> rawSurfaceWriterVectorWriter;
-typedef rawSurfaceWriter<sphericalTensor> rawSurfaceWriterSphericalTensorWriter;
-typedef rawSurfaceWriter<symmTensor> rawSurfaceWriterSymmTensorWriter;
-typedef rawSurfaceWriter<tensor> rawSurfaceWriterTensorWriter;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/stl/stl.C b/src/sampling/sampledSurface/writers/stl/stlSurfaceWriter.C
similarity index 89%
rename from src/sampling/sampledSurface/writers/stl/stl.C
rename to src/sampling/sampledSurface/writers/stl/stlSurfaceWriter.C
index 82c36b3df035803269896fe7028c7ae0a6771d0e..f5c42c02f1959bb451737ed4e3b1fe599507ddb5 100644
--- a/src/sampling/sampledSurface/writers/stl/stl.C
+++ b/src/sampling/sampledSurface/writers/stl/stlSurfaceWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "stl.H"
+#include "stlSurfaceWriter.H"
 #include "fileName.H"
 #include "OFstream.H"
 #include "faceList.H"
@@ -34,7 +34,7 @@ License
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::stl<Type>::stl()
+Foam::stlSurfaceWriter<Type>::stlSurfaceWriter()
 :
     surfaceWriter<Type>()
 {}
@@ -43,14 +43,14 @@ Foam::stl<Type>::stl()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::stl<Type>::~stl()
+Foam::stlSurfaceWriter<Type>::~stlSurfaceWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::stl<Type>::write
+void Foam::stlSurfaceWriter<Type>::write
 (
     const fileName& samplePath,
     const fileName& timeDir,
@@ -69,11 +69,11 @@ void Foam::stl<Type>::write
         mkDir(surfaceDir);
     }
 
-    fileName planeFName(surfaceDir/fieldName + '_' + surfaceName + ".stl");
+    fileName fName(surfaceDir/fieldName + '_' + surfaceName + ".stl");
 
     if (verbose)
     {
-        Info<< "Writing field " << fieldName << " to " << planeFName << endl;
+        Info<< "Writing field " << fieldName << " to " << fName << endl;
     }
 
     // Convert faces to triangles.
@@ -108,7 +108,7 @@ void Foam::stl<Type>::write
             )
         ),
         points
-    ).write(planeFName);
+    ).write(fName);
 }
 
 
diff --git a/src/sampling/sampledSurface/writers/stl/stl.H b/src/sampling/sampledSurface/writers/stl/stlSurfaceWriter.H
similarity index 90%
rename from src/sampling/sampledSurface/writers/stl/stl.H
rename to src/sampling/sampledSurface/writers/stl/stlSurfaceWriter.H
index 6941ab8c1be38428ea90732a042e0e5f628f6702..5e1c2e5ffb17af9dc216bfda87af2b8ed2093bd7 100644
--- a/src/sampling/sampledSurface/writers/stl/stl.H
+++ b/src/sampling/sampledSurface/writers/stl/stlSurfaceWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::stl
+    Foam::stlSurfaceWriter
 
 Description
 
 SourceFiles
-    stl.C
+    stlSurfaceWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef stl_H
-#define stl_H
+#ifndef stlSurfaceWriter_H
+#define stlSurfaceWriter_H
 
 #include "surfaceWriter.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class stl Declaration
+                     Class stlSurfaceWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class stl
+class stlSurfaceWriter
 :
     public surfaceWriter<Type>
 {
@@ -61,12 +61,12 @@ public:
     // Constructors
 
         //- Construct null
-        stl();
+        stlSurfaceWriter();
 
 
     // Destructor
 
-        virtual ~stl();
+        virtual ~stlSurfaceWriter();
 
 
     // Member Functions
@@ -95,7 +95,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "stl.C"
+#   include "stlSurfaceWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSurface/writers/foamFile/foamFileWriters.C b/src/sampling/sampledSurface/writers/stl/stlSurfaceWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSurface/writers/foamFile/foamFileWriters.C
rename to src/sampling/sampledSurface/writers/stl/stlSurfaceWriterRunTime.C
index 6db5497d3744dbea36df5411a8384d99fa0bea2b..a748733ecfaad3c15dbbb8d221f676542ab50300 100644
--- a/src/sampling/sampledSurface/writers/foamFile/foamFileWriters.C
+++ b/src/sampling/sampledSurface/writers/stl/stlSurfaceWriterRunTime.C
@@ -24,7 +24,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "foamFileWriters.H"
+#include "stlSurfaceWriter.H"
+#include "surfaceWriters.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -34,7 +35,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-makeSurfaceWriters(foamFile);
+makeSurfaceWriters(stlSurfaceWriter);
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/sampling/sampledSurface/writers/stl/stlWriters.C b/src/sampling/sampledSurface/writers/stl/stlWriters.C
deleted file mode 100644
index c0b923e758bc37c5b2e10b27bf7b089051547f0e..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/stl/stlWriters.C
+++ /dev/null
@@ -1,43 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "stlWriters.H"
-#include "addToRunTimeSelectionTable.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-makeSurfaceWriters(stl);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/stl/stlWriters.H b/src/sampling/sampledSurface/writers/stl/stlWriters.H
deleted file mode 100644
index b47d3d82c3af9388ef30f56d93beae982e09e876..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/stl/stlWriters.H
+++ /dev/null
@@ -1,63 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::stlWriters
-
-Description
-
-SourceFiles
-    stlWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef stlWriters_H
-#define stlWriters_H
-
-#include "stl.H"
-#include "surfaceWriters.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-typedef stl<scalar> stlScalarWriter;
-typedef stl<vector> stlVectorWriter;
-typedef stl<sphericalTensor> stlSphericalTensorWriter;
-typedef stl<symmTensor> stlSymmTensorWriter;
-typedef stl<tensor> stlTensorWriter;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/surfaceWriter.H b/src/sampling/sampledSurface/writers/surfaceWriter.H
index 4fd01fad39abcac135217956b312523f6229c329..3a894c6dd1e372c557efc314cb53282fb556e353 100644
--- a/src/sampling/sampledSurface/writers/surfaceWriter.H
+++ b/src/sampling/sampledSurface/writers/surfaceWriter.H
@@ -117,41 +117,6 @@ public:
 #   include "surfaceWriter.C"
 #endif
 
-// Only used internally
-#define makeTypeSurfaceWritersTypeName(type)                                 \
-                                                                             \
-defineNamedTemplateTypeNameAndDebug(type, 0);
-
-// Used externally sometimes
-#define makeSurfaceWritersTypeName(typeWriter)                               \
-                                                                             \
-makeTypeSurfaceWritersTypeName(typeWriter##ScalarWriter);                    \
-makeTypeSurfaceWritersTypeName(typeWriter##VectorWriter);                    \
-makeTypeSurfaceWritersTypeName(typeWriter##SphericalTensorWriter);           \
-makeTypeSurfaceWritersTypeName(typeWriter##SymmTensorWriter);                \
-makeTypeSurfaceWritersTypeName(typeWriter##TensorWriter);
-
-// Define type info for single template instantiation (e.g. vector)
-#define makeSurfaceWriterTypes(WriterType, type)                             \
-                                                                             \
-defineNamedTemplateTypeNameAndDebug(type, 0);                                \
-                                                                             \
-addToRunTimeSelectionTable                                                   \
-(                                                                            \
-    WriterType, type, word                                                   \
-);
-
-
-// Define type info info for scalar, vector etc. instantiations
-#define makeSurfaceWriters(typeWriter)                                       \
-                                                                             \
-makeSurfaceWriterTypes(scalarWriter, typeWriter##ScalarWriter);              \
-makeSurfaceWriterTypes(vectorWriter, typeWriter##VectorWriter);              \
-makeSurfaceWriterTypes(sphericalTensorWriter, typeWriter##SphericalTensorWriter);\
-makeSurfaceWriterTypes(symmTensorWriter, typeWriter##SymmTensorWriter);      \
-makeSurfaceWriterTypes(tensorWriter, typeWriter##TensorWriter);
-
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/src/sampling/sampledSurface/writers/surfaceWriters.C b/src/sampling/sampledSurface/writers/surfaceWriters.C
index e0d9487eb3c6d5c7e6b0c22c8230069e3d37614c..76781c6e3939775e86d9b37088f298d69c4f1330 100644
--- a/src/sampling/sampledSurface/writers/surfaceWriters.C
+++ b/src/sampling/sampledSurface/writers/surfaceWriters.C
@@ -32,21 +32,15 @@ namespace Foam
 {
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-defineNamedTemplateTypeNameAndDebug(scalarWriter, 0);
-defineTemplateRunTimeSelectionTable(scalarWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(vectorWriter, 0);
-defineTemplateRunTimeSelectionTable(vectorWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(sphericalTensorWriter, 0);
-defineTemplateRunTimeSelectionTable(sphericalTensorWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(symmTensorWriter, 0);
-defineTemplateRunTimeSelectionTable(symmTensorWriter, word);
-
-defineNamedTemplateTypeNameAndDebug(tensorWriter, 0);
-defineTemplateRunTimeSelectionTable(tensorWriter, word);
+#define defineSurfaceWriterType(dataType)                                     \
+    defineNamedTemplateTypeNameAndDebug(surfaceWriter<dataType >, 0);         \
+    defineTemplatedRunTimeSelectionTable(surfaceWriter, word, dataType);
+
+defineSurfaceWriterType(scalar);
+defineSurfaceWriterType(vector);
+defineSurfaceWriterType(sphericalTensor);
+defineSurfaceWriterType(symmTensor);
+defineSurfaceWriterType(tensor);
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/sampling/sampledSurface/writers/surfaceWriters.H b/src/sampling/sampledSurface/writers/surfaceWriters.H
index 969fa845d55e315de7450e53c6b43efad8b3792e..b4bb226a76370651a3de79ebd80d405a154c4265 100644
--- a/src/sampling/sampledSurface/writers/surfaceWriters.H
+++ b/src/sampling/sampledSurface/writers/surfaceWriters.H
@@ -36,21 +36,39 @@ Description
 #include "fieldTypes.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+// Only used internally
+#define makeTypeSurfaceWritersTypeName(typeWriter, dataType)                 \
+                                                                             \
+    defineNamedTemplateTypeNameAndDebug(typeWriter<dataType >, 0);
+
+// Sometimes used externally
+#define makeSurfaceWritersTypeName(typeWriter)                               \
+                                                                             \
+    makeTypeSurfaceWritersTypeName(typeWriter, scalar);                      \
+    makeTypeSurfaceWritersTypeName(typeWriter, vector);                      \
+    makeTypeSurfaceWritersTypeName(typeWriter, sphericalTensor);             \
+    makeTypeSurfaceWritersTypeName(typeWriter, symmTensor);                  \
+    makeTypeSurfaceWritersTypeName(typeWriter, tensor);
+
+// Define type info for single dataType template instantiation (eg, vector)
+#define makeSurfaceWriterType(typeWriter, dataType)                          \
+                                                                             \
+    defineNamedTemplateTypeNameAndDebug(typeWriter<dataType >, 0);           \
+    addTemplatedToRunTimeSelectionTable                                      \
+    (                                                                        \
+        surfaceWriter, typeWriter, dataType, word                            \
+    );
+
+
+// Define type info for scalar, vector etc. instantiations
+#define makeSurfaceWriters(typeWriter)                                       \
+                                                                             \
+    makeSurfaceWriterType(typeWriter, scalar);                               \
+    makeSurfaceWriterType(typeWriter, vector);                               \
+    makeSurfaceWriterType(typeWriter, sphericalTensor);                      \
+    makeSurfaceWriterType(typeWriter, symmTensor);                           \
+    makeSurfaceWriterType(typeWriter, tensor);
 
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-typedef surfaceWriter<scalar> scalarWriter;
-typedef surfaceWriter<vector> vectorWriter;
-typedef surfaceWriter<sphericalTensor> sphericalTensorWriter;
-typedef surfaceWriter<symmTensor> symmTensorWriter;
-typedef surfaceWriter<tensor> tensorWriter;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/sampling/sampledSurface/writers/vtk/vtk.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C
similarity index 85%
rename from src/sampling/sampledSurface/writers/vtk/vtk.C
rename to src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C
index b334be4ed4a5595a53ce4e92e9c8508151144623..b7f27b37106d2127495522ba1009c9153ead28df 100644
--- a/src/sampling/sampledSurface/writers/vtk/vtk.C
+++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.C
@@ -24,7 +24,7 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "vtk.H"
+#include "vtkSurfaceWriter.H"
 #include "fileName.H"
 #include "OFstream.H"
 #include "faceList.H"
@@ -33,7 +33,7 @@ License
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Type>
-void Foam::vtk<Type>::writeGeometry
+void Foam::vtkSurfaceWriter<Type>::writeGeometry
 (
     const pointField& points,
     const faceList& faces,
@@ -48,37 +48,33 @@ void Foam::vtk<Type>::writeGeometry
         << "ASCII" << nl
         << "DATASET POLYDATA" << nl;
 
+    // Write vertex coords
     os  << "POINTS " << points.size() << " float" << nl;
-
     forAll(points, pointI)
     {
         const point& pt = points[pointI];
-
-        os  << float(pt.x()) << ' ' << float(pt.y()) << ' ' << float(pt.z())
-            << nl;
+        os  << float(pt.x()) << ' '
+            << float(pt.y()) << ' '
+            << float(pt.z()) << nl;
     }
     os  << endl;
 
 
-    // Write triangles
-
-    label nFaceVerts = 0;
-
+    // Write faces
+    label nNodes = 0;
     forAll(faces, faceI)
     {
-        const face& f = faces[faceI];
-
-        nFaceVerts += f.size() + 1;
+        nNodes += faces[faceI].size();
     }
 
-    os  << "POLYGONS " << faces.size() << ' ' << nFaceVerts << nl;
+    os  << "POLYGONS " << faces.size() << ' '
+        << faces.size() + nNodes << nl;
 
     forAll(faces, faceI)
     {
         const face& f = faces[faceI];
 
         os << f.size();
-
         forAll(f, fp)
         {
             os << ' ' << f[fp];
@@ -90,7 +86,7 @@ void Foam::vtk<Type>::writeGeometry
 
 // Write scalarField in vtk format
 template<class Type>
-void Foam::vtk<Type>::writeData
+void Foam::vtkSurfaceWriter<Type>::writeData
 (
     const fileName& fieldName,
     const pointField& points,
@@ -116,16 +112,18 @@ void Foam::vtk<Type>::writeData
 
     forAll(values, elemI)
     {
-        os << float(values[elemI]);
-
-        if (elemI > 0 && (elemI%10) == 0)
+        if (elemI)
         {
-            os << nl;
-        }
-        else
-        {
-            os << ' ';
+            if (elemI % 10)
+            {
+                os << ' ';
+            }
+            else
+            {
+                os << nl;
+            }
         }
+        os << float(values[elemI]);
     }
     os << nl;
 }
@@ -133,7 +131,7 @@ void Foam::vtk<Type>::writeData
 
 // Write vectorField in vtk format
 template<class Type>
-void Foam::vtk<Type>::writeData
+void Foam::vtkSurfaceWriter<Type>::writeData
 (
     const fileName& fieldName,
     const pointField& points,
@@ -168,7 +166,7 @@ void Foam::vtk<Type>::writeData
 
 // Write sphericalTensorField in vtk format
 template<class Type>
-void Foam::vtk<Type>::writeData
+void Foam::vtkSurfaceWriter<Type>::writeData
 (
     const fileName& fieldName,
     const pointField& points,
@@ -204,7 +202,7 @@ void Foam::vtk<Type>::writeData
 
 // Write symmTensorField in vtk format
 template<class Type>
-void Foam::vtk<Type>::writeData
+void Foam::vtkSurfaceWriter<Type>::writeData
 (
     const fileName& fieldName,
     const pointField& points,
@@ -241,7 +239,7 @@ void Foam::vtk<Type>::writeData
 
 // Write tensorField in vtk format
 template<class Type>
-void Foam::vtk<Type>::writeData
+void Foam::vtkSurfaceWriter<Type>::writeData
 (
     const fileName& fieldName,
     const pointField& points,
@@ -281,7 +279,7 @@ void Foam::vtk<Type>::writeData
 
 // Construct from components
 template<class Type>
-Foam::vtk<Type>::vtk()
+Foam::vtkSurfaceWriter<Type>::vtkSurfaceWriter()
 :
     surfaceWriter<Type>()
 {}
@@ -290,14 +288,14 @@ Foam::vtk<Type>::vtk()
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Type>
-Foam::vtk<Type>::~vtk()
+Foam::vtkSurfaceWriter<Type>::~vtkSurfaceWriter()
 {}
 
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Type>
-void Foam::vtk<Type>::write
+void Foam::vtkSurfaceWriter<Type>::write
 (
     const fileName& samplePath,
     const fileName& timeDir,
@@ -316,18 +314,17 @@ void Foam::vtk<Type>::write
         mkDir(surfaceDir);
     }
 
-    fileName planeFName(surfaceDir/fieldName + '_' + surfaceName + ".vtk");
+    fileName fName(surfaceDir/fieldName + '_' + surfaceName + ".vtk");
 
     if (verbose)
     {
-        Info<< "Writing field " << fieldName << " to " << planeFName << endl;
+        Info<< "Writing field " << fieldName << " to " << fName << endl;
     }
 
-    OFstream vtkFile(planeFName);
-
-    writeGeometry(points, faces, vtkFile);
+    OFstream os(fName);
 
-    writeData(fieldName, points, values, vtkFile);
+    writeGeometry(points, faces, os);
+    writeData(fieldName, points, values, os);
 }
 
 
diff --git a/src/sampling/sampledSurface/writers/vtk/vtk.H b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H
similarity index 92%
rename from src/sampling/sampledSurface/writers/vtk/vtk.H
rename to src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H
index 5e8655ebebff90ff5ab91f81bcfe64f592f53bef..167241d19ac539a9469d7fdc96f8b171c6db502f 100644
--- a/src/sampling/sampledSurface/writers/vtk/vtk.H
+++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriter.H
@@ -23,17 +23,17 @@ License
     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 
 Class
-    Foam::vtk
+    Foam::vtkSurfaceWriter
 
 Description
 
 SourceFiles
-    vtk.C
+    vtkSurfaceWriter.C
 
 \*---------------------------------------------------------------------------*/
 
-#ifndef vtk_H
-#define vtk_H
+#ifndef vtkSurfaceWriter_H
+#define vtkSurfaceWriter_H
 
 #include "surfaceWriter.H"
 
@@ -43,11 +43,11 @@ namespace Foam
 {
 
 /*---------------------------------------------------------------------------*\
-                           Class vtk Declaration
+                     Class vtkSurfaceWriter Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Type>
-class vtk
+class vtkSurfaceWriter
 :
     public surfaceWriter<Type>
 {
@@ -110,12 +110,12 @@ public:
     // Constructors
 
         //- Construct null
-        vtk();
+        vtkSurfaceWriter();
 
 
     // Destructor
 
-        virtual ~vtk();
+        virtual ~vtkSurfaceWriter();
 
 
     // Member Functions
@@ -144,7 +144,7 @@ public:
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #ifdef NoRepository
-#   include "vtk.C"
+#   include "vtkSurfaceWriter.C"
 #endif
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/sampling/sampledSurface/writers/null/nullWriters.C b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterRunTime.C
similarity index 94%
rename from src/sampling/sampledSurface/writers/null/nullWriters.C
rename to src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterRunTime.C
index 159d23e597ee34785404f5e5da92121ffd0d9312..0cc5cf4ce4567f4a7084a5bbc6b8feab1cd15bf1 100644
--- a/src/sampling/sampledSurface/writers/null/nullWriters.C
+++ b/src/sampling/sampledSurface/writers/vtk/vtkSurfaceWriterRunTime.C
@@ -24,7 +24,8 @@ License
 
 \*---------------------------------------------------------------------------*/
 
-#include "nullWriters.H"
+#include "vtkSurfaceWriter.H"
+#include "surfaceWriters.H"
 #include "addToRunTimeSelectionTable.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -34,7 +35,7 @@ namespace Foam
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-makeSurfaceWriters(null);
+makeSurfaceWriters(vtkSurfaceWriter);
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
diff --git a/src/sampling/sampledSurface/writers/vtk/vtkWriters.C b/src/sampling/sampledSurface/writers/vtk/vtkWriters.C
deleted file mode 100644
index bd1ed10045ed55d17b10c660a9e1e920c87f50d4..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/vtk/vtkWriters.C
+++ /dev/null
@@ -1,43 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "vtkWriters.H"
-#include "addToRunTimeSelectionTable.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-
-makeSurfaceWriters(vtk);
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// ************************************************************************* //
diff --git a/src/sampling/sampledSurface/writers/vtk/vtkWriters.H b/src/sampling/sampledSurface/writers/vtk/vtkWriters.H
deleted file mode 100644
index 421098e8574f8c26d11cb152f8cb2d749067373b..0000000000000000000000000000000000000000
--- a/src/sampling/sampledSurface/writers/vtk/vtkWriters.H
+++ /dev/null
@@ -1,63 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-InClass
-    Foam::vtkWriters
-
-Description
-
-SourceFiles
-    vtkWriters.C
-
-\*---------------------------------------------------------------------------*/
-
-#ifndef vtkWriters_H
-#define vtkWriters_H
-
-#include "vtk.H"
-#include "surfaceWriters.H"
-#include "fieldTypes.H"
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-namespace Foam
-{
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-typedef vtk<scalar> vtkScalarWriter;
-typedef vtk<vector> vtkVectorWriter;
-typedef vtk<sphericalTensor> vtkSphericalTensorWriter;
-typedef vtk<symmTensor> vtkSymmTensorWriter;
-typedef vtk<tensor> vtkTensorWriter;
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-} // End namespace Foam
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-#endif
-
-// ************************************************************************* //
diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index d6e808f6f06647d9027e778f265e0e9391d3f35e..19c5eee8b532a48ed7527d6d84faf1e5908bf782 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -25,6 +25,7 @@ $(surfaceFormats)/starcd/STARCDsurfaceFormatRunTime.C
 $(surfaceFormats)/stl/STLsurfaceFormatCore.C
 $(surfaceFormats)/stl/STLsurfaceFormatRunTime.C
 $(surfaceFormats)/stl/STLsurfaceFormatASCII.L
+$(surfaceFormats)/tri/TRIsurfaceFormatCore.C
 $(surfaceFormats)/tri/TRIsurfaceFormatRunTime.C
 $(surfaceFormats)/vtk/VTKsurfaceFormatCore.C
 $(surfaceFormats)/vtk/VTKsurfaceFormatRunTime.C
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index cb4f795bc662fa13e9cc8a80dc0f873b9baf3f98..04a41a9ed3ee27486bc9059179b37ff615b69d5b 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -99,14 +99,14 @@ bool Foam::MeshedSurface<Face>::canWriteType
 template<class Face>
 bool Foam::MeshedSurface<Face>::canRead
 (
-    const fileName& fName,
+    const fileName& name,
     const bool verbose
 )
 {
-    word ext = fName.ext();
+    word ext = name.ext();
     if (ext == "gz")
     {
-        ext = fName.lessExt().ext();
+        ext = name.lessExt().ext();
     }
     return canReadType(ext, verbose);
 }
@@ -115,7 +115,7 @@ bool Foam::MeshedSurface<Face>::canRead
 template<class Face>
 void Foam::MeshedSurface<Face>::write
 (
-    const fileName& fName,
+    const fileName& name,
     const MeshedSurface& surf
 )
 {
@@ -123,16 +123,16 @@ void Foam::MeshedSurface<Face>::write
     {
         Info<< "MeshedSurface::write"
             "(const fileName&, const MeshedSurface&) : "
-            "writing to " << fName
+            "writing to " << name
             << endl;
     }
 
-    word ext = fName.ext();
+    word ext = name.ext();
 
     // handle 'native' format directly
     if (isNative(ext))
     {
-        surf.write(OFstream(fName)());
+        surf.write(OFstream(name)());
         return;
     }
 
@@ -150,7 +150,7 @@ void Foam::MeshedSurface<Face>::write
             << exit(FatalError);
     }
 
-    mfIter()(fName, surf);
+    mfIter()(name, surf);
 }
 
 
@@ -180,100 +180,25 @@ Foam::MeshedSurface<Face>::MeshedSurface
     const xfer<pointField>& pointLst,
     const xfer<List<Face> >& faceLst,
     const UList<label>& patchSizes,
-    const UList<word>& patchNames,
-    const UList<word>& patchTypes
+    const UList<word>& patchNames
 )
 :
     ParentType(pointLst, faceLst)
 {
-    surfGroupList newPatches(patchSizes.size());
-
-    label start = 0;
-    forAll(newPatches, patchI)
-    {
-        newPatches[patchI] = surfGroup
-        (
-            patchNames[patchI],
-            patchSizes[patchI],
-            start,
-            patchI
-        );
-
-        start += patchSizes[patchI];
-    }
-
-    patches_.transfer(newPatches);
-}
-
-
-template<class Face>
-Foam::MeshedSurface<Face>::MeshedSurface
-(
-    const xfer<pointField>& pointLst,
-    const xfer<List<Face> >& faceLst,
-    const UList<label>& regionIds,
-    const Map<word>& regionNames
-)
-:
-    ParentType(pointLst, faceLst)
-{
-    if (&regionIds && regionIds.size() && regionIds.size() != size())
+    if (&patchSizes)
     {
-        FatalErrorIn
-        (
-            "MeshedSurface::MeshedSurface(\n"
-            "(\n"
-            "    const xfer<pointField>&,\n"
-            "    const xfer<List<Face> >&,\n"
-            "    const UList<label>& regionIds,\n"
-            "    const Map<word>& regionNames\n"
-            " )\n"
-        )
-            << "size mismatch : region and face sizes"
-            << exit(FatalError);
-    }
-    else
-    {
-        sortFacesByRegion(regionIds, regionNames);
-    }
-}
-
-
-template<class Face>
-Foam::MeshedSurface<Face>::MeshedSurface
-(
-    const xfer<pointField>& pointLst,
-    const xfer<List<Face> >& faceLst,
-    const UList<label>& regionIds,
-    const HashTable<label>& nameToRegionMapping
-)
-:
-    ParentType(pointLst, faceLst)
-{
-    if (&regionIds && regionIds.size() && regionIds.size() != size())
-    {
-        FatalErrorIn
-        (
-            "MeshedSurface::MeshedSurface(\n"
-            "(\n"
-            "    const xfer<pointField>&,\n"
-            "    const xfer<List<Face> >&,\n"
-            "    const UList<label>& regionIds,\n"
-            "    const HashTable<label>& nameToRegionMapping\n"
-            " )\n"
-        )
-            << "size mismatch : region and face sizes"
-            << exit(FatalError);
+        if (&patchNames)
+        {
+            addPatches(patchSizes, patchNames);
+        }
+        else
+        {
+            addPatches(patchSizes);
+        }
     }
     else
     {
-        Map<word> regionNames;
-        forAllConstIter(HashTable<label>, nameToRegionMapping, iter)
-        {
-            regionNames.insert(iter(), iter.key());
-        }
-
-        sortFacesByRegion(regionIds, regionNames);
+        onePatch();
     }
 }
 
@@ -430,18 +355,18 @@ Foam::MeshedSurface<Face>::MeshedSurface
 template<class Face>
 Foam::MeshedSurface<Face>::MeshedSurface
 (
-    const fileName& fName,
+    const fileName& name,
     const word& ext
 )
 {
-    read(fName, ext);
+    read(name, ext);
 }
 
 
 template<class Face>
-Foam::MeshedSurface<Face>::MeshedSurface(const fileName& fName)
+Foam::MeshedSurface<Face>::MeshedSurface(const fileName& name)
 {
-    read(fName);
+    read(name);
 }
 
 
@@ -456,7 +381,6 @@ template<class Face>
 Foam::MeshedSurface<Face>::MeshedSurface(const Time& d)
 {
     read(IFstream(findMeshName(d))());
-    // setDefaultPatches();
 }
 
 
@@ -496,13 +420,26 @@ Foam::MeshedSurface<Face>::~MeshedSurface()
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
 template<class Face>
-void Foam::MeshedSurface<Face>::onePatch()
+void Foam::MeshedSurface<Face>::onePatch(const word& name)
 {
+    word patchName(name);
+    if (!patchName.size())
+    {
+        if (patches_.size() >= 1)
+        {
+            patchName = patches_[0].name();
+        }
+        if (!patchName.size())
+        {
+            patchName = "patch0";
+        }
+    }
+
     // set single default patch
     patches_.setSize(1);
     patches_[0] = surfGroup
     (
-        "patch0",
+        patchName,
         size(),         // patch size
         0,              // patch start
         0               // patch index
@@ -514,9 +451,12 @@ template<class Face>
 void Foam::MeshedSurface<Face>::checkPatches()
 {
     // extra safety, ensure we have at some patches,
-    // and they cover all the faces
-    // fix start silently
-    if (patches_.size() > 1)
+    // and they cover all the faces - fix start silently
+    if (patches_.size() <= 1)
+    {
+        onePatch();
+    }
+    else
     {
         label count = 0;
         forAll(patches_, patchI)
@@ -531,8 +471,7 @@ void Foam::MeshedSurface<Face>::checkPatches()
             (
                 "MeshedSurface::checkPatches()\n"
             )
-                << "more nFaces " << size()
-                << " than patches " << count
+                << "more face " << size() << " than patches " << count
                 << " ... extending final patch"
                 << endl;
 
@@ -544,97 +483,97 @@ void Foam::MeshedSurface<Face>::checkPatches()
             (
                 "MeshedSurface::checkPatches()\n"
             )
-                << "more patches " << count
-                << " than nFaces " << size()
+                << "more patches " << count << " than faces " << size()
                 << exit(FatalError);
         }
     }
-    else if (patches_.size() == 1)
-    {
-        // like onePatch, but preserve the name
-        patches_[0].size() = size();
-        patches_[0].start() = 0;
-        if (!patches_[0].name().size())
-        {
-            patches_[0].name() = "patch0";
-        }
-    }
-    else
-    {
-        onePatch();
-    }
 }
 
 
 template<class Face>
-void Foam::MeshedSurface<Face>::sortFacesByRegion
+void Foam::MeshedSurface<Face>::sortFacesAndStore
 (
-    const UList<label>& regionIds,
-    const Map<word>& regionNames
+    const xfer<List<Face> >& unsortedFaces,
+    const xfer<List<label> >& regionIds,
+    const bool sorted
 )
 {
-    const List<Face>& unsortedFaces = this->faces();
+    List<Face>  oldFaces(unsortedFaces);
+    List<label> regions(regionIds);
 
-    if (!&regionNames || !&regionIds || regionIds.size() == 0)
+    if (sorted)
     {
-        onePatch();
+        // already sorted - simply transfer faces
+        this->storedFaces().transfer(oldFaces);
     }
-    else if (regionIds.size() == unsortedFaces.size())
+    else
     {
-        labelList faceMap;
-        surfGroupList newPatches = UnsortedMeshedSurface<Face>::sortedRegions
-        (
-            regionIds,
-            regionNames,
-            faceMap
-        );
-        patches_.transfer(newPatches);
+        // unsorted - determine the sorted order:
+        // avoid SortableList since we discard the main list anyhow
+        List<label> faceMap;
+        sortedOrder(regions, faceMap);
+        regions.clear();
 
-        // this is somewhat like ListOps reorder and/or IndirectList
-        List<Face> newFaces(unsortedFaces.size());
-        forAll(newFaces, faceI)
+        // sorted faces
+        List<Face> newFaces(faceMap.size());
+        forAll(faceMap, faceI)
         {
-            newFaces[faceI] = unsortedFaces[faceMap[faceI]];
+            // use transfer to recover memory if possible
+            newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
         }
-        faceMap.clear();
-
         this->storedFaces().transfer(newFaces);
+
     }
+    regions.clear();
 }
 
 
 template<class Face>
-void Foam::MeshedSurface<Face>::remapRegions(List<label>& faceMap)
+void Foam::MeshedSurface<Face>::remapFaces
+(
+    const UList<label>& faceMap
+)
 {
     // recalculate the patch start/size
-    if (faceMap.size())
+    if (&faceMap && faceMap.size())
     {
-        label newFaceI = 0;
-        label oldPatchEnd = 0;
-        forAll(patches_, patchI)
+        if (patches_.size() == 0)
+        {
+            onePatch();
+        }
+        else if (patches_.size() == 1)
         {
-            surfGroup& p = patches_[patchI];
+            // optimized for one-patch case
+            patches_[0].size() = faceMap.size();
+        }
+        else
+        {
+            label newFaceI = 0;
+            label oldPatchEnd = 0;
+            forAll(patches_, patchI)
+            {
+                surfGroup& p = patches_[patchI];
 
-            // adjust patch start
-            p.start() = newFaceI;
-            oldPatchEnd += p.size();
+                // adjust patch start
+                p.start() = newFaceI;
+                oldPatchEnd += p.size();
 
-            for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
-            {
-                if (faceMap[faceI] < oldPatchEnd)
+                for (label faceI = newFaceI; faceI < faceMap.size(); ++faceI)
                 {
-                    ++newFaceI;
+                    if (faceMap[faceI] < oldPatchEnd)
+                    {
+                        ++newFaceI;
+                    }
+                    else
+                    {
+                        break;
+                    }
                 }
-                else
-                {
-                    break;
-                }
-            }
 
-            // adjust patch size
-            p.size() = newFaceI - p.start();
+                // adjust patch size
+                p.size() = newFaceI - p.start();
+            }
         }
-        faceMap.clear();
     }
 }
 
@@ -662,6 +601,7 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
     const pointField& locPoints = this->localPoints();
     const List<Face>& locFaces  = this->localFaces();
 
+
     // Fill pointMap, faceMap
     this->subsetMap(include, pointMap, faceMap);
 
@@ -751,10 +691,83 @@ Foam::MeshedSurface<Face> Foam::MeshedSurface<Face>::subsetMesh
 template<class Face>
 void Foam::MeshedSurface<Face>::addPatches
 (
-    const UList<surfGroup>& patchLst
+    const UList<surfGroup>& patches,
+    const bool cullEmpty
+)
+{
+    label nPatch = 0;
+
+    patches_.setSize(patches.size());
+    forAll(patches_, patchI)
+    {
+        if (patches[patchI].size() || !cullEmpty)
+        {
+            patches_[nPatch] = surfGroup(patches[patchI], nPatch);
+            nPatch++;
+        }
+    }
+    patches_.setSize(nPatch);
+}
+
+
+template<class Face>
+void Foam::MeshedSurface<Face>::addPatches
+(
+    const UList<label>& sizes,
+    const UList<word>& names,
+    const bool cullEmpty
 )
 {
-    patches_ = patchLst;
+    label start  = 0;
+    label nPatch = 0;
+
+    patches_.setSize(sizes.size());
+    forAll(patches_, patchI)
+    {
+        if (sizes[patchI] || !cullEmpty)
+        {
+            patches_[nPatch] = surfGroup
+            (
+                names[patchI],
+                sizes[patchI],
+                start,
+                nPatch
+            );
+            start += sizes[patchI];
+            nPatch++;
+        }
+    }
+    patches_.setSize(nPatch);
+}
+
+
+template<class Face>
+void Foam::MeshedSurface<Face>::addPatches
+(
+    const UList<label>& sizes,
+    const bool cullEmpty
+)
+{
+    label start  = 0;
+    label nPatch = 0;
+
+    patches_.setSize(sizes.size());
+    forAll(patches_, patchI)
+    {
+        if (sizes[patchI] || !cullEmpty)
+        {
+            patches_[nPatch] = surfGroup
+            (
+                word("patch") + ::Foam::name(nPatch),
+                sizes[patchI],
+                start,
+                nPatch
+            );
+            start += sizes[patchI];
+            nPatch++;
+        }
+    }
+    patches_.setSize(nPatch);
 }
 
 
@@ -781,39 +794,35 @@ void Foam::MeshedSurface<Face>::transfer
 
     labelList faceMap;
     surfGroupList patchLst = surf.sortedRegions(faceMap);
+    List<Face>& oldFaces = surf.storedFaces();
 
-    const List<Face>& oldFaces = surf.faces();
-    List<Face>  newFaces(oldFaces.size());
-
-    // this is somewhat like ListOps reorder and/or IndirectList
-    forAll(newFaces, faceI)
+    List<Face> newFaces(faceMap.size());
+    forAll(faceMap, faceI)
     {
-        newFaces[faceI] = oldFaces[faceMap[faceI]];
+        newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
     }
     faceMap.clear();
 
     reset(xferMove(surf.storedPoints()), xferMove(newFaces));
     patches_.transfer(patchLst);
 
-    surf.regions_.clear();
-    surf.patches_.clear();
     surf.clear();
 }
 
 
 // Read from file, determine format from extension
 template<class Face>
-bool Foam::MeshedSurface<Face>::read(const fileName& fName)
+bool Foam::MeshedSurface<Face>::read(const fileName& name)
 {
-    word ext = fName.ext();
+    word ext = name.ext();
     if (ext == "gz")
     {
-        fileName unzipName = fName.lessExt();
+        fileName unzipName = name.lessExt();
         return read(unzipName, unzipName.ext());
     }
     else
     {
-        return read(fName, ext);
+        return read(name, ext);
     }
 }
 
@@ -822,19 +831,19 @@ bool Foam::MeshedSurface<Face>::read(const fileName& fName)
 template<class Face>
 bool Foam::MeshedSurface<Face>::read
 (
-    const fileName& fName,
+    const fileName& name,
     const word& ext
 )
 {
     // handle 'native' format directly
     if (isNative(ext))
     {
-        return read(IFstream(fName)());
+        return read(IFstream(name)());
     }
     else
     {
         // use selector mechanism
-        transfer(New(fName, ext)());
+        transfer(New(name, ext)());
         return true;
     }
 }
@@ -864,7 +873,6 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "MeshedSurfaceCleanup.C"
 #include "MeshedSurfaceIO.C"
 #include "MeshedSurfaceNew.C"
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index e6665a2845172c4638067af285f1d28c7692bd23..dcef0c50b06989bfab349b4d5712c925bfb86287 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -28,7 +28,7 @@ Class
 Description
     A surface geometry mesh with patch information, not to be confused
     with a similarily named surfaceMesh, which actually refers to
-    the cell faces of a volume mesh!
+    the cell faces of a volume mesh.
 
    The MeshedSurface is intended to surfaces from a variety of sources.
    - A set of points and faces without any patch information.
@@ -94,12 +94,6 @@ private:
 
     // Private member functions
 
-        //- Sort faces by regionIds and set patches
-        void sortFacesByRegion(const UList<label>&, const Map<word>&);
-
-        //- Set new regions from faceMap
-        void remapRegions(List<label>& faceMap);
-
         //- Read OpenFOAM Surface format
         bool read(Istream&);
 
@@ -107,12 +101,20 @@ protected:
 
     // Protected Member functions
 
-        //- set a single patch
-        void onePatch();
-
         //- basic sanity check on patches
         void checkPatches();
 
+        //- sort faces by regions and store sorted faces
+        void sortFacesAndStore
+        (
+            const xfer<List<Face> >& unsortedFaces,
+            const xfer<List<label> >& regionIds,
+            const bool sorted
+        );
+
+        //- Set new regions from faceMap
+        virtual void remapFaces(const UList<label>& faceMap);
+
 public:
 
         //- Runtime type information
@@ -137,8 +139,7 @@ public:
         //- Construct null
         MeshedSurface();
 
-        //- Construct by transferring components
-        //  (points, faces and patches).
+        //- Construct by transferring components (points, faces, patches).
         MeshedSurface
         (
             const xfer<pointField>&,
@@ -146,35 +147,14 @@ public:
             const xfer<surfGroupList>&
         );
 
-        //- Construct from points, faces, and patch information
-        MeshedSurface
-        (
-            const xfer<pointField>&,
-            const xfer<List<Face> >&,
-            const UList<label>& patchSizes,
-            const UList<word>& patchNames,
-            const UList<word>& patchTypes
-        );
-
-        //- Construct by transferring points, faces.
-        //  Sort faces according to regionIds with the names of the regions,
-        //  or jsut set a single default patch.
-        MeshedSurface
-        (
-            const xfer<pointField>&,
-            const xfer<List<Face> >&,
-            const UList<label>& regionIds = UList<label>::null(),
-            const Map<word>& regionNames = Map<word>::null()
-        );
-
         //- Construct by transferring points, faces.
-        //  Sort faces according to regionIds with patch-names from hash
+        //  Use patch information, or set single default patch.
         MeshedSurface
         (
             const xfer<pointField>&,
             const xfer<List<Face> >&,
-            const UList<label>& regionIds,
-            const HashTable<label>& nameToRegionMapping
+            const UList<label>& patchSizes = UList<label>::null(),
+            const UList<word>& patchNames = UList<word>::null()
         );
 
         //- Construct from a boundary mesh with local points/faces
@@ -219,9 +199,9 @@ public:
             MeshedSurface,
             fileExtension,
             (
-                const fileName& fName
+                const fileName& name
             ),
-            (fName)
+            (name)
         );
 
     // Selectors
@@ -250,10 +230,10 @@ public:
             write,
             fileExtension,
             (
-                const fileName& fName,
+                const fileName& name,
                 const MeshedSurface<Face>& surf
             ),
-            (fName, surf)
+            (name, surf)
         );
 
         //- Write to file
@@ -275,31 +255,35 @@ public:
             return patches_;
         }
 
-        void addPatches(const UList<surfGroup>&);
-
-
-    // Edit
-
-        //- Clear all storage
-        virtual void clear();
+        //- set a single patch, optionally with a specific name
+        void onePatch(const word& name = word::null);
 
-        //- Remove invalid faces
-        void cleanup(const bool verbose);
+        //- add patches
+        void addPatches
+        (
+            const UList<surfGroup>&,
+            const bool cullEmpty=false
+        );
 
-        //- Check/fix duplicate/degenerate faces
-        virtual bool checkFaces(const bool verbose);
+        //- add patches
+        void addPatches
+        (
+            const UList<label>& sizes,
+            const UList<word>& names,
+            const bool cullEmpty=false
+        );
 
-        //- Join the faces by removing duplicate points.
-        //  Returns true if any points merged
-        virtual bool stitchFaces
+        //- add patches
+        void addPatches
         (
-            const scalar tol=SMALL,
-            const bool verbose=false
+            const UList<label>& sizes,
+            const bool cullEmpty=false
         );
 
-        //- Triangulate the surface, return the number of added faces.
-        //  The patch list will be adjusted accordingly.
-        virtual label triangulate();
+    // Edit
+
+        //- Clear all storage
+        virtual void clear();
 
         //- Return new surface.
         //  Returns return pointMap, faceMap from subsetMeshMap
@@ -338,9 +322,9 @@ public:
         virtual void write(Ostream&) const;
 
         //- Generic write routine. Chooses writer based on extension.
-        virtual void write(const fileName& fName) const
+        virtual void write(const fileName& name) const
         {
-            write(fName, *this);
+            write(name, *this);
         }
 
         //- Write to database
@@ -362,15 +346,6 @@ public:
 };
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-//- Specialization for holding triangulated information
-template<>
-inline label MeshedSurface<triFace>::triangulate()
-{
-    return 0;
-}
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceCleanup.C b/src/surfMesh/MeshedSurface/MeshedSurfaceCleanup.C
deleted file mode 100644
index ebe6d08402a5f4655f6ec7de35ff1acdffb4297e..0000000000000000000000000000000000000000
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceCleanup.C
+++ /dev/null
@@ -1,82 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "MeshedSurface.H"
-#include "mergePoints.H"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-// Remove badly degenerate faces, double faces.
-template<class Face>
-void Foam::MeshedSurface<Face>::cleanup(const bool verbose)
-{
-    // merge points (already done for STL, TRI)
-    stitchFaces(SMALL, verbose);
-
-    checkFaces(verbose);
-    ParentType::checkEdges(verbose);
-}
-
-
-template<class Face>
-bool Foam::MeshedSurface<Face>::stitchFaces
-(
-    const scalar tol,
-    const bool verbose
-)
-{
-    List<label> faceMap;
-    bool hasMerged = ParentType::stitchFaces(faceMap, tol, verbose);
-
-    remapRegions(faceMap);
-    return hasMerged;
-}
-
-
-
-// Remove badly degenerate faces and double faces.
-template<class Face>
-bool Foam::MeshedSurface<Face>::checkFaces(const bool verbose)
-{
-    List<label> faceMap;
-    bool changed = ParentType::checkFaces(faceMap, verbose);
-
-    remapRegions(faceMap);
-    return changed;
-}
-
-
-template<class Face>
-Foam::label Foam::MeshedSurface<Face>::triangulate()
-{
-    List<label> faceMap;
-    label nTri = ParentType::triangulate(this->storedFaces(), faceMap);
-
-    remapRegions(faceMap);
-    return nTri;
-}
-
-// ************************************************************************* //
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
index b37bc840205871c3356c2c5da7bc511f9b75e57f..fed91f0e62cab70e7253a8e82f44beab04b81c39 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
@@ -29,14 +29,10 @@ License
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-// all input is indirect via UnsortedMeshedSurface
+
 template<class Face>
 Foam::autoPtr<Foam::MeshedSurface<Face> >
-Foam::MeshedSurface<Face>::New
-(
-    const fileName& fName,
-    const word& ext
-)
+Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
 {
     if (debug)
     {
@@ -56,7 +52,7 @@ Foam::MeshedSurface<Face>::New
         {
             // create indirectly
             autoPtr<MeshedSurface<Face> > surf(new MeshedSurface<Face>);
-            surf().transfer(SiblingType::New(fName, ext)());
+            surf().transfer(SiblingType::New(name, ext)());
 
             return surf;
         }
@@ -67,8 +63,7 @@ Foam::MeshedSurface<Face>::New
 
         FatalErrorIn
         (
-            "MeshedSurface<Face>::New"
-            "(const fileName&, const word&) : "
+            "MeshedSurface<Face>::New(const fileName&, const word&) : "
             "constructing MeshedSurface"
         )   << "Unknown file extension " << ext << nl << nl
             << "Valid types are :" << nl
@@ -76,23 +71,20 @@ Foam::MeshedSurface<Face>::New
             << exit(FatalError);
     }
 
-    return autoPtr<MeshedSurface<Face> >(cstrIter()(fName));
+    return autoPtr<MeshedSurface<Face> >(cstrIter()(name));
 }
 
 
 template<class Face>
 Foam::autoPtr<Foam::MeshedSurface<Face> >
-Foam::MeshedSurface<Face>::New
-(
-    const fileName& fName
-)
+Foam::MeshedSurface<Face>::New(const fileName& name)
 {
-    word ext = fName.ext();
+    word ext = name.ext();
     if (ext == "gz")
     {
-        ext = fName.lessExt().ext();
+        ext = name.lessExt().ext();
     }
-    return New(fName, ext);
+    return New(name, ext);
 }
 
 // ************************************************************************* //
diff --git a/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.C b/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.C
index 8f54a7d4a84312c291f7970168b2d3b84c92e700..6c4337e3b2624c17ae14a8ff982e7f943e4313b5 100644
--- a/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.C
+++ b/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.C
@@ -25,8 +25,8 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "PrimitiveMeshedSurface.H"
+#include "boundBox.H"
 #include "mergePoints.H"
-
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
 template<class Face>
@@ -36,75 +36,6 @@ inline bool Foam::PrimitiveMeshedSurface<Face>::isTri()
 }
 
 
-template<class Face>
-Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate
-(
-    List<Face>& faceLst,
-    List<label>& faceMap
-)
-{
-    label nTri = 0;
-
-    // determine how many triangles are needed
-    forAll(faceLst, faceI)
-    {
-        nTri += faceLst[faceI].size() - 2;
-    }
-
-    // nothing to do
-    if (nTri <= faceLst.size())
-    {
-        if (&faceMap)
-        {
-            faceMap.clear();
-        }
-        return 0;
-    }
-
-    List<Face>  newFaces(nTri);
-    List<label> fMap(nTri);
-
-    // remember the number of *additional* faces
-    nTri -= faceLst.size();
-
-    label newFaceI = 0;
-    forAll(faceLst, faceI)
-    {
-        const Face& f = faceLst[faceI];
-        triFace fTri;
-
-        // Do simple face triangulation around f[0].
-        // we could also use face::triangulation, but that requires points
-        // and doesn't currently template nicely
-        fTri[0] = f[0];
-        for (label fp = 1; fp < f.size() - 1; ++fp)
-        {
-            label fp1 = (fp + 1) % f.size();
-
-            fTri[1] = f[fp];
-            fTri[2] = f[fp1];
-
-            newFaces[newFaceI] = fTri;
-            fMap[newFaceI] = faceI;
-            newFaceI++;
-        }
-    }
-
-    faceLst.transfer(newFaces);
-    if (&faceMap)
-    {
-        faceMap.transfer(fMap);
-    }
-    else
-    {
-        fMap.clear();
-    }
-
-    return nTri;
-}
-
-
-
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Face>
@@ -200,10 +131,21 @@ void Foam::PrimitiveMeshedSurface<Face>::reset
 }
 
 
+// Remove badly degenerate faces, double faces.
+template<class Face>
+void Foam::PrimitiveMeshedSurface<Face>::cleanup(const bool verbose)
+{
+    // merge points (already done for STL, TRI)
+    stitchFaces(SMALL, verbose);
+
+    checkFaces(verbose);
+    this->checkEdges(verbose);
+}
+
+
 template<class Face>
 bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
 (
-    List<label>& faceMap,
     const scalar tol,
     const bool verbose
 )
@@ -218,10 +160,6 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
 
     if (!hasMerged)
     {
-        if (&faceMap)
-        {
-            faceMap.clear();
-        }
         return false;
     }
 
@@ -236,13 +174,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
 
     List<Face>& faceLst = this->storedFaces();
 
-    // local copy
-    List<label> fMap;
-    if (&faceMap)
-    {
-        fMap.transfer(faceMap);
-    }
-    fMap.setSize(faceLst.size());
+    List<label> faceMap(faceLst.size());
 
     // Reset the point labels to the unique points array
     label newFaceI = 0;
@@ -261,7 +193,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
             {
                 faceLst[newFaceI] = f;
             }
-            fMap[newFaceI] = faceI;
+            faceMap[newFaceI] = faceI;
             newFaceI++;
         }
         else if (verbose)
@@ -282,18 +214,12 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
                 << " faces" << endl;
         }
         faceLst.setSize(newFaceI);
-        if (&faceMap)
-        {
-            faceMap.transfer(fMap);
-            faceMap.setSize(newFaceI);
-        }
+        remapFaces(faceMap);
     }
-    fMap.clear();
-
+    faceMap.clear();
 
     // Merging points might have changed geometric factors
     ParentType::clearOut();
-
     return true;
 }
 
@@ -302,20 +228,13 @@ bool Foam::PrimitiveMeshedSurface<Face>::stitchFaces
 template<class Face>
 bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
 (
-    List<label>& faceMap,
     const bool verbose
 )
 {
     bool changed = false;
     List<Face>& faceLst = this->storedFaces();
 
-    // local copy
-    List<label> fMap;
-    if (&faceMap)
-    {
-        fMap.transfer(faceMap);
-    }
-    fMap.setSize(faceLst.size());
+    List<label> faceMap(faceLst.size());
 
     label newFaceI = 0;
     // Detect badly labelled faces and mark degenerate faces
@@ -339,13 +258,13 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
                 }
             }
 
-            fMap[faceI] = faceI;
+            faceMap[faceI] = faceI;
             newFaceI++;
         }
         else
         {
             // mark as bad face
-            fMap[faceI] = -1;
+            faceMap[faceI] = -1;
 
             changed = true;
             if (verbose)
@@ -366,7 +285,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
     forAll(faceLst, faceI)
     {
         // skip already collapsed faces:
-        if (fMap[faceI] < 0)
+        if (faceMap[faceI] < 0)
         {
             continue;
         }
@@ -383,7 +302,7 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
         {
             const label neiFaceI = neighbours[neighI];
 
-            if (neiFaceI <= faceI || fMap[neiFaceI] < 0)
+            if (neiFaceI <= faceI || faceMap[neiFaceI] < 0)
             {
                 // lower numbered faces already checked
                 // skip neighbours that are themselves collapsed
@@ -414,12 +333,12 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
 
         if (okay)
         {
-            fMap[faceI] = faceI;
+            faceMap[faceI] = faceI;
             newFaceI++;
         }
         else
         {
-            fMap[faceI] = -1;
+            faceMap[faceI] = -1;
         }
     }
 
@@ -443,33 +362,158 @@ bool Foam::PrimitiveMeshedSurface<Face>::checkFaces
         newFaceI = 0;
         forAll(faceLst, faceI)
         {
-            if (fMap[faceI] >= 0)
+            if (faceMap[faceI] >= 0)
             {
                 if (newFaceI != faceI)
                 {
                     faceLst[newFaceI] = faceLst[faceI];
                 }
-                fMap[newFaceI] = faceI;
+                faceMap[newFaceI] = faceI;
                 newFaceI++;
             }
         }
 
         faceLst.setSize(newFaceI);
-        if (&faceMap)
+        remapFaces(faceMap);
+    }
+    faceMap.clear();
+
+    // Topology can change because of renumbering
+    ParentType::clearOut();
+    return changed;
+}
+
+
+template<class Face>
+Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate()
+{
+    return triangulate
+    (
+        const_cast<List<label>&>(List<label>::null())
+    );
+}
+
+
+template<class Face>
+Foam::label Foam::PrimitiveMeshedSurface<Face>::triangulate
+(
+    List<label>& faceMapOut
+)
+{
+    label nTri = 0;
+    label maxTri = 0;  // the maximum number of triangles for any single face
+    List<Face>& faceLst = this->storedFaces();
+
+    // determine how many triangles will be needed
+    forAll(faceLst, faceI)
+    {
+        const label n = faceLst[faceI].nTriangles();
+        if (maxTri < n)
+        {
+            maxTri = n;
+        }
+        nTri += n;
+    }
+
+    // nothing to do
+    if (nTri <= faceLst.size())
+    {
+        if (&faceMapOut)
         {
-            faceMap.transfer(fMap);
-            faceMap.setSize(newFaceI);
+            faceMapOut.clear();
         }
+        return 0;
+    }
+
+    List<Face>  newFaces(nTri);
+    List<label> faceMap;
+
+    // reuse storage from optional faceMap
+    if (&faceMapOut)
+    {
+        faceMap.transfer(faceMapOut);
     }
-    fMap.clear();
+    faceMap.setSize(nTri);
+
+    // remember the number of *additional* faces
+    nTri -= faceLst.size();
+
+    if (this->points().size() == 0)
+    {
+        // triangulate without points
+        // simple face triangulation around f[0]
+        label newFaceI = 0;
+        forAll(faceLst, faceI)
+        {
+            const Face& f = faceLst[faceI];
+
+            for (label fp = 1; fp < f.size() - 1; ++fp)
+            {
+                label fp1 = (fp + 1) % f.size();
+
+                newFaces[newFaceI] = triFace(f[0], f[fp], f[fp1]);
+                faceMap[newFaceI] = faceI;
+                newFaceI++;
+            }
+        }
+    }
+    else
+    {
+        // triangulate with points
+        List<face> tmpTri(maxTri);
+
+        label newFaceI = 0;
+        forAll(faceLst, faceI)
+        {
+            // 'face' not '<Face>'
+            const face& f = faceLst[faceI];
+
+            label nTmp;
+            f.triangles(this->points(), nTmp, tmpTri);
+            for (label triI = 0; triI < nTmp; triI++)
+            {
+                newFaces[newFaceI] = Face
+                (
+                    static_cast<UList<label>&>(tmpTri[triI])
+                );
+                faceMap[newFaceI] = faceI;
+                newFaceI++;
+            }
+        }
+    }
+
+    faceLst.transfer(newFaces);
+    remapFaces(faceMap);
+
+    // optionally return the faceMap
+    if (&faceMapOut)
+    {
+        faceMapOut.transfer(faceMap);
+    }
+    faceMap.clear();
 
     // Topology can change because of renumbering
     ParentType::clearOut();
+    return nTri;
+}
 
-    return changed;
+
+// dummy implementation to avoid a pure virtual class
+template<class Face>
+void Foam::PrimitiveMeshedSurface<Face>::remapFaces(const UList<label>&)
+{
 }
 
 
+template<class Face>
+void Foam::PrimitiveMeshedSurface<Face>::writeStats(Ostream& os) const
+{
+    os  << "points      : " << this->points().size() << nl
+        << (this->isTri() ? "triangles   : " : "faces       : ")
+        << this->size() << nl
+        << "boundingBox : " << boundBox(this->points()) << endl;
+}
+
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
diff --git a/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.H b/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.H
index 79a945f80fef2f87df6f68770f81a7ecdc80acaa..602bc9fc6856e00c8739ef8a0e2a4a3799768c74 100644
--- a/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.H
+++ b/src/surfMesh/PrimitiveMeshedSurface/PrimitiveMeshedSurface.H
@@ -84,6 +84,9 @@ protected:
             return static_cast<List<Face> &>(*this);
         }
 
+        //- Set new regions/patches from faceMap
+        virtual void remapFaces(const UList<label>& faceMap);
+
 public:
 
     // Static
@@ -91,14 +94,6 @@ public:
         //- Face storage only handles triangulated faces
         inline static bool isTri();
 
-        //- Triangulate faceLst in-place
-        //  Returning the number of triangles added and a map to the
-        //  the original face Ids
-        static label triangulate
-        (
-            List<Face>& faceLst,
-            List<label>& faceMap=const_cast<List<label>&>(List<label>::null())
-        );
 
     // Constructors
 
@@ -144,19 +139,35 @@ public:
             const xfer<List<Face> >&
         );
 
+        //- Remove invalid faces
+        virtual void cleanup(const bool verbose);
+
         virtual bool stitchFaces
         (
-            List<label>& faceMap=const_cast<List<label>&>(List<label>::null()),
             const scalar tol=SMALL,
             const bool verbose=false
         );
 
         virtual bool checkFaces
         (
-            List<label>& faceMap=const_cast<List<label>&>(List<label>::null()),
             const bool verbose=false
         );
 
+        //- Triangulate in-place
+        //  Returning the number of triangles added
+        //  Optionally returning a map of original face Ids (zero-sized when
+        //  no triangulation was done)
+        virtual label triangulate();
+
+        //- Triangulate in-place, setting a map of original face Ids
+        //  faceMap is zero-sized when no triangulation was done
+        virtual label triangulate(List<label>& faceMap);
+
+
+    // Write
+
+        void writeStats(Ostream& os) const;
+
 };
 
 
@@ -169,6 +180,25 @@ inline bool PrimitiveMeshedSurface<triFace>::isTri()
     return true;
 }
 
+//- Specialization for holding triangulated information
+template<>
+inline label PrimitiveMeshedSurface<triFace>::triangulate()
+{
+    return 0;
+}
+
+//- Specialization for holding triangulated information
+template<>
+inline label PrimitiveMeshedSurface<triFace>::triangulate(List<label>& faceMap)
+{
+    if (&faceMap)
+    {
+        faceMap.clear();
+    }
+
+    return 0;
+}
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index a4273ec54038f40da13e1f49eb0f2e4df4e9617e..9ab97c2ec4dd632649bc30a2bc32223f81a88421 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -95,14 +95,14 @@ bool Foam::UnsortedMeshedSurface<Face>::canWriteType
 template<class Face>
 bool Foam::UnsortedMeshedSurface<Face>::canRead
 (
-    const fileName& fName,
+    const fileName& name,
     const bool verbose
 )
 {
-    word ext = fName.ext();
+    word ext = name.ext();
     if (ext == "gz")
     {
-        ext = fName.lessExt().ext();
+        ext = name.lessExt().ext();
     }
     return canReadType(ext, verbose);
 }
@@ -111,7 +111,7 @@ bool Foam::UnsortedMeshedSurface<Face>::canRead
 template<class Face>
 void Foam::UnsortedMeshedSurface<Face>::write
 (
-    const fileName& fName,
+    const fileName& name,
     const UnsortedMeshedSurface<Face>& surf
 )
 {
@@ -119,16 +119,16 @@ void Foam::UnsortedMeshedSurface<Face>::write
     {
         Info<< "UnsortedMeshedSurface::write"
             "(const fileName&, const UnsortedMeshedSurface&) : "
-            "writing to " << fName
+            "writing to " << name
             << endl;
     }
 
-    const word ext = fName.ext();
+    const word ext = name.ext();
 
     // handle 'native' format directly
     if (isNative(ext))
     {
-        surf.write(OFstream(fName)());
+        surf.write(OFstream(name)());
         return;
     }
 
@@ -147,7 +147,7 @@ void Foam::UnsortedMeshedSurface<Face>::write
             << exit(FatalError);
     }
 
-    mfIter()(fName, surf);
+    mfIter()(name, surf);
 }
 
 
@@ -178,56 +178,30 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 (
     const xfer<pointField>& pointLst,
     const xfer<List<Face> >& faceLst,
-    const xfer<List<label> >& regionIds,
-    const Map<word>& regionNames
+    const UList<label>& patchSizes,
+    const UList<word>& patchNames
 )
 :
-    ParentType(pointLst, faceLst),
-    regions_(regionIds)
+    ParentType(pointLst, faceLst)
 {
-    if (&regionNames)
+    if (&patchSizes)
     {
-        // set patch names from (id => name) mapping
-        setPatches(regionNames);
+        if (&patchNames)
+        {
+            setPatches(patchSizes, patchNames);
+        }
+        else
+        {
+            setPatches(patchSizes);
+        }
     }
     else
     {
-        // find highest region ID and set patch names automatically
-        setPatches();
+        onePatch();
     }
 }
 
 
-template<class Face>
-Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
-(
-    const xfer<pointField>& pointLst,
-    const xfer<List<Face> >& faceLst,
-    const xfer<List<label> >& regionIds,
-    const HashTable<label>& labelToRegion
-)
-:
-    ParentType(pointLst, faceLst),
-    regions_(regionIds)
-{
-    // set patch names from (name => id) mapping
-    setPatches(labelToRegion);
-}
-
-
-template<class Face>
-Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
-(
-    const xfer<pointField>& pointLst,
-    const xfer<List<Face> >& faceLst
-)
-:
-    ParentType(pointLst, faceLst)
-{
-    onePatch();
-}
-
-
 template<class Face>
 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 (
@@ -249,39 +223,25 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 :
     ParentType(xferCopy(surf.points()), xferCopy(surf.faces()))
 {
-    const surfGroupList& patchLst = surf.patches();
-
-    regions_.setSize(size());
-    patches_.setSize(patchLst.size());
-
-    label faceI = 0;
-    forAll(patchLst, patchI)
-    {
-        patches_[patchI] = patchLst[patchI];
-
-        forAll(patchLst[patchI], patchFaceI)
-        {
-            regions_[faceI++] = patchI;
-        }
-    }
+    setPatches(surf.patches());
 }
 
 
 template<class Face>
 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 (
-    const fileName& fName,
+    const fileName& name,
     const word& ext
 )
 {
-    read(fName, ext);
+    read(name, ext);
 }
 
 
 template<class Face>
-Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& fName)
+Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
 {
-    read(fName);
+    read(name);
 }
 
 
@@ -341,99 +301,70 @@ Foam::UnsortedMeshedSurface<Face>::~UnsortedMeshedSurface()
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::onePatch()
+void Foam::UnsortedMeshedSurface<Face>::onePatch(const word& name)
 {
     regions_.setSize(size());
     regions_ = 0;
 
+    word patchName(name);
+    if (!patchName.size())
+    {
+        if (patches_.size() >= 1)
+        {
+            patchName = patches_[0].name();
+        }
+        if (!patchName.size())
+        {
+            patchName = "patch0";
+        }
+    }
+
     // set single default patch
     patches_.setSize(1);
-    patches_[0] = PatchRegionType("patch0", 0);
+    patches_[0] = surfPatchIdentifier(patchName, 0);
 }
 
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::setPatches(const label maxPatch)
+void Foam::UnsortedMeshedSurface<Face>::setPatches
+(
+    const surfGroupList& patches
+)
 {
-    patches_.setSize(maxPatch+1);
+    regions_.setSize(size());
+    patches_.setSize(patches.size());
 
-    forAll(patches_, patchI)
+    forAll(patches, patchI)
     {
-        patches_[patchI] = PatchRegionType
-        (
-            "patch" + ::Foam::name(patchI),
-            patchI
-        );
-    }
-}
+        const surfGroup& p = patches[patchI];
 
+        patches_[patchI] = p;
 
-template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::setPatches()
-{
-    label maxPatch = 0;
-
-    // find the max region that occurs
-    forAll(regions_, faceI)
-    {
-        const label regId = regions_[faceI];
-
-        if (maxPatch < regId)
-        {
-            maxPatch = regId;
-        }
+        SubList<label> subRegion(regions_, p.size(), p.start());
+        subRegion = patchI;
     }
-
-    setPatches(maxPatch);
 }
 
 
 template<class Face>
 void Foam::UnsortedMeshedSurface<Face>::setPatches
 (
-    const Map<word>& regionNames,
-    const label maxPatchHint
+    const UList<label>& sizes,
+    const UList<word>& names
 )
 {
-    label maxPatch = maxPatchHint;
-
-    // determine max patch ID if required
-    if (maxPatchHint < 0)
-    {
-        maxPatch = 0;
-        forAllConstIter(Map<word>, regionNames, iter)
-        {
-            if (maxPatch < iter.key())
-            {
-                maxPatch = iter.key();
-            }
-        }
-    }
-
-
-    // Info<< "setPatches with maxPatch: " << maxPatch << endl;
-
-    patches_.setSize(maxPatch+1);
+    regions_.setSize(size());
+    patches_.setSize(sizes.size());
 
+    label start = 0;
     forAll(patches_, patchI)
     {
-        Map<word>::const_iterator findPatch = regionNames.find(patchI);
-        word patchName;
+        patches_[patchI] = surfPatchIdentifier(names[patchI], patchI);
 
-        if (findPatch != regionNames.end())
-        {
-            patchName = findPatch();
-        }
-        else
-        {
-            patchName = "patch" + ::Foam::name(patchI);
-        }
+        SubList<label> subRegion(regions_, sizes[patchI], start);
+        subRegion = patchI;
 
-        patches_[patchI] = PatchRegionType
-        (
-            patchName,
-            patchI
-        );
+        start += sizes[patchI];
     }
 }
 
@@ -441,42 +372,61 @@ void Foam::UnsortedMeshedSurface<Face>::setPatches
 template<class Face>
 void Foam::UnsortedMeshedSurface<Face>::setPatches
 (
-    const HashTable<label>& groupToPatch
+    const UList<label>& sizes
 )
 {
-    // determine max patch Id
-    label maxPatch = 0;
-    Map<word> regionNames;
+    regions_.setSize(size());
+    patches_.setSize(sizes.size());
 
-    forAllConstIter(HashTable<label>, groupToPatch, iter)
+    label start = 0;
+    forAll(patches_, patchI)
     {
-        regionNames.insert(iter(), iter.key());
-        if (maxPatch < iter())
-        {
-            maxPatch = iter();
-        }
-    }
+        patches_[patchI] = surfPatchIdentifier
+        (
+            word("patch") + ::Foam::name(patchI),
+            patchI
+        );
+
+        SubList<label> subRegion(regions_, sizes[patchI], start);
+        subRegion = patchI;
 
-    setPatches(regionNames, maxPatch);
+        start += sizes[patchI];
+    }
 }
 
 
 template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::remapRegions(List<label>& faceMap)
+void Foam::UnsortedMeshedSurface<Face>::remapFaces
+(
+    const UList<label>& faceMap
+)
 {
     // re-assign the region Ids
-    if (faceMap.size())
+    if (&faceMap && faceMap.size())
     {
-        forAll(faceMap, faceI)
+        if (patches_.size() == 0)
+        {
+            onePatch();
+        }
+        else if (patches_.size() == 1)
+        {
+            // optimized for one-patch case
+            regions_ = 0;
+        }
+        else
         {
-            faceMap[faceI] = regions_[faceMap[faceI]];
+            List<label> newRegions(faceMap.size());
+
+            forAll(faceMap, faceI)
+            {
+                newRegions[faceI] = regions_[faceMap[faceI]];
+            }
+            regions_.transfer(newRegions);
         }
-        regions_.transfer(faceMap);
     }
 }
 
 
-
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
 template<class Face>
@@ -620,43 +570,25 @@ void Foam::UnsortedMeshedSurface<Face>::transfer
     MeshedSurface<Face>& surf
 )
 {
-    surfGroupList& patchLst = surf.patches_;
-
     reset(xferMove(surf.storedPoints()), xferMove(surf.storedFaces()));
-
-    regions_.setSize(size());
-    patches_.setSize(patchLst.size());
-
-    label faceIndex = 0;
-    forAll(patchLst, patchI)
-    {
-        // copy info
-        patches_[patchI] = patchLst[patchI];
-
-        forAll(patchLst[patchI], patchFaceI)
-        {
-            regions_[faceIndex++] = patchI;
-        }
-    }
-
-    patchLst.clear();
+    setPatches(surf.patches());
     surf.clear();
 }
 
 
 // Read from file, determine format from extension
 template<class Face>
-bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& fName)
+bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& name)
 {
-    word ext = fName.ext();
+    word ext = name.ext();
     if (ext == "gz")
     {
-        fileName unzipName = fName.lessExt();
+        fileName unzipName = name.lessExt();
         return read(unzipName, unzipName.ext());
     }
     else
     {
-        return read(fName, ext);
+        return read(name, ext);
     }
 }
 
@@ -665,19 +597,19 @@ bool Foam::UnsortedMeshedSurface<Face>::read(const fileName& fName)
 template<class Face>
 bool Foam::UnsortedMeshedSurface<Face>::read
 (
-    const fileName& fName,
+    const fileName& name,
     const word& ext
 )
 {
     // handle 'native' format directly
     if (isNative(ext))
     {
-        return read(IFstream(fName)());
+        return read(IFstream(name)());
     }
     else
     {
         // use selector mechanism
-        transfer(New(fName, ext)());
+        transfer(New(name, ext)());
         return true;
     }
 }
@@ -713,7 +645,6 @@ void Foam::UnsortedMeshedSurface<Face>::operator=
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-#include "UnsortedMeshedSurfaceCleanup.C"
 #include "UnsortedMeshedSurfaceIO.C"
 #include "UnsortedMeshedSurfaceNew.C"
 
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
index 1d1722d97f3ba080b26118d3813256c9b4313a04..8daeefa5519c4ca79b574f0b174be4be2dbd178c 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
@@ -91,9 +91,6 @@ private:
         typedef PrimitiveMeshedSurface<Face> ParentType;
         typedef MeshedSurface<Face> SiblingType;
 
-        //- Typedef for type holding the region (patch) informationm
-        typedef surfPatchIdentifier PatchRegionType;
-
     // Private Member Data
 
         //- The regions associated with the faces
@@ -101,7 +98,7 @@ private:
 
         //- Patch information (face ordering nFaces/startFace only used
         //  during reading and writing)
-        List<PatchRegionType> patches_;
+        List<surfPatchIdentifier> patches_;
 
     // Private member functions
 
@@ -111,38 +108,25 @@ private:
         //- Read OpenFOAM Surface format
         bool read(Istream&);
 
-        //- Set new regions from faceMap
-        void remapRegions(List<label>& faceMap);
-
 protected:
 
     // Protected Member functions
 
-        //- Set a single patch
-        void onePatch();
-
-        //- Sets default patch names based on the maximum patch number
-        void setPatches(const label maxPatch);
-
-        //- Finds maximum patch number and sets default patch names
-        void setPatches();
-
-        //- Sets patch names from hashed values (id -> name)
-        void setPatches
-        (
-            const Map<word>& regionNames,
-            const label maxPatch = -1
-        );
-
-        //- Sets patch names from hashed values (name -> id)
-        void setPatches(const HashTable<label>& groupToPatch);
-
         //- Return non-const access to the faces
         List<label>& storedRegions()
         {
             return regions_;
         }
 
+        //- Return non-const access to the patches
+        List<surfPatchIdentifier>& storedPatches()
+        {
+            return patches_;
+        }
+
+        //- Set new regions from faceMap
+        virtual void remapFaces(const UList<label>& faceMap);
+
 public:
 
         //- Runtime type information
@@ -177,32 +161,14 @@ public:
             const xfer<surfPatchIdentifierList>&
         );
 
-        //- Construct by transferring points, faces and regionIds
-        //  with region names per map or set to default.
-        UnsortedMeshedSurface
-        (
-            const xfer<pointField>&,
-            const xfer<List<Face> >&,
-            const xfer<List<label> >& regionIds,
-            const Map<word>& regionNames = Map<word>::null()
-        );
-
-        //- Construct by transferring points, faces and regionIds
-        //  with patch-names from hash
-        UnsortedMeshedSurface
-        (
-            const xfer<pointField>&,
-            const xfer<List<Face> >&,
-            const xfer<List<label> >& regionIds,
-            const HashTable<label>& labelToRegion
-        );
-
         //- Construct by transferring points, faces.
-        //  Set single default patch.
+        //  Use patch information, or set single default patch
         UnsortedMeshedSurface
         (
             const xfer<pointField>&,
-            const xfer<List<Face> >&
+            const xfer<List<Face> >&,
+            const UList<label>& patchSizes = UList<label>::null(),
+            const UList<word>& patchNames = UList<word>::null()
         );
 
         //- Construct from a boundary mesh with local points/faces
@@ -244,9 +210,9 @@ public:
             UnsortedMeshedSurface,
             fileExtension,
             (
-                const fileName& fName
+                const fileName& name
             ),
-            (fName)
+            (name)
         );
 
     // Selectors
@@ -275,10 +241,10 @@ public:
             write,
             fileExtension,
             (
-                const fileName& fName,
+                const fileName& name,
                 const UnsortedMeshedSurface<Face>& surf
             ),
-            (fName, surf)
+            (name, surf)
         );
 
         //- Write to file
@@ -314,28 +280,24 @@ public:
         //  Returns patch list and sets faceMap to index within faces()
         List<surfGroup> sortedRegions(labelList& faceMap) const;
 
+        //- Set regions to 0 and set a single patch
+        //  Optionally with a specific name
+        void onePatch(const word& name = word::null);
 
-    // Edit
+        //- Set regions and patches
+        void setPatches(const surfGroupList&);
 
-        //- Clear all storage
-        virtual void clear();
+        //- Set regions and patches
+        void setPatches(const UList<label>& sizes, const UList<word>& names);
 
-        //- Remove invalid faces
-        void cleanup(const bool verbose);
+        //- Set regions and patches with default names
+        void setPatches(const UList<label>& sizes);
 
-        //- Check/fix duplicate/degenerate faces
-        virtual bool checkFaces(const bool verbose);
 
-        //- Join the faces by removing duplicate points.
-        //  Returns true if any points merged
-        virtual bool stitchFaces
-        (
-            const scalar tol=SMALL,
-            const bool verbose=false
-        );
+    // Edit
 
-        //- Triangulate the surface, return the number of added faces.
-        virtual label triangulate();
+        //- Clear all storage
+        virtual void clear();
 
         //- Return new surface.
         //  Returns return pointMap, faceMap from subsetMeshMap
@@ -382,9 +344,9 @@ public:
         virtual void write(Ostream&) const;
 
         //- Generic write routine. Chooses writer based on extension.
-        virtual void write(const fileName& fName) const
+        virtual void write(const fileName& name) const
         {
-            write(fName, *this);
+            write(name, *this);
         }
 
         //- Write to database
@@ -408,15 +370,6 @@ public:
 };
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
-//- Specialization for holding triangulated information
-template<>
-inline label UnsortedMeshedSurface<triFace>::triangulate()
-{
-    return 0;
-}
-
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 } // End namespace Foam
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceCleanup.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceCleanup.C
deleted file mode 100644
index 4b4d7e066bc1e6b38502a28d0543e937482b8d54..0000000000000000000000000000000000000000
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceCleanup.C
+++ /dev/null
@@ -1,81 +0,0 @@
-/*---------------------------------------------------------------------------*\
-  =========                 |
-  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
-   \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
-     \\/     M anipulation  |
--------------------------------------------------------------------------------
-License
-    This file is part of OpenFOAM.
-
-    OpenFOAM is free software; you can redistribute it and/or modify it
-    under the terms of the GNU General Public License as published by the
-    Free Software Foundation; either version 2 of the License, or (at your
-    option) any later version.
-
-    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
-    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-    for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with OpenFOAM; if not, write to the Free Software Foundation,
-    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
-\*---------------------------------------------------------------------------*/
-
-#include "UnsortedMeshedSurface.H"
-#include "mergePoints.H"
-
-// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
-
-// Remove badly degenerate faces, double faces.
-template<class Face>
-void Foam::UnsortedMeshedSurface<Face>::cleanup(const bool verbose)
-{
-    // merge points (already done for STL, TRI)
-    stitchFaces(SMALL, verbose);
-
-    checkFaces(verbose);
-    ParentType::checkEdges(verbose);
-}
-
-
-template<class Face>
-bool Foam::UnsortedMeshedSurface<Face>::stitchFaces
-(
-    const scalar tol,
-    const bool verbose
-)
-{
-    List<label> faceMap;
-    bool hasMerged = ParentType::stitchFaces(faceMap, tol, verbose);
-
-    remapRegions(faceMap);
-    return hasMerged;
-}
-
-
-// Remove badly degenerate faces and double faces.
-template<class Face>
-bool Foam::UnsortedMeshedSurface<Face>::checkFaces(const bool verbose)
-{
-    List<label> faceMap;
-    bool changed = ParentType::checkFaces(faceMap, verbose);
-
-    remapRegions(faceMap);
-    return changed;
-}
-
-
-template<class Face>
-Foam::label Foam::UnsortedMeshedSurface<Face>::triangulate()
-{
-    List<label> faceMap;
-    label nTri = ParentType::triangulate(this->storedFaces(), faceMap);
-
-    remapRegions(faceMap);
-    return nTri;
-}
-
-// ************************************************************************* //
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
index 9df2077fb5aa67d476823ce259a2d77e8dd471c4..a94b00fe1f3e02f7962ab3c16047efce2ed20bf3 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurfaceNew.C
@@ -31,16 +31,11 @@ License
 
 template<class Face>
 Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> >
-Foam::UnsortedMeshedSurface<Face>::New
-(
-    const fileName& fName,
-    const word& ext
-)
+Foam::UnsortedMeshedSurface<Face>::New(const fileName& name, const word& ext)
 {
     if (debug)
     {
-        Info<< "UnsortedMeshedSurface<Face>::New"
-            "(const fileName&, const word&) : "
+        Info<< "UnsortedMeshedSurface::New(const fileName&, const word&) : "
             "constructing UnsortedMeshedSurface"
             << endl;
     }
@@ -59,7 +54,7 @@ Foam::UnsortedMeshedSurface<Face>::New
             (
                 new UnsortedMeshedSurface<Face>
             );
-            surf().transfer(SiblingType::New(fName, ext)());
+            surf().transfer(SiblingType::New(name, ext)());
 
             return surf;
         }
@@ -79,24 +74,21 @@ Foam::UnsortedMeshedSurface<Face>::New
             << exit(FatalError);
     }
 
-    return autoPtr<UnsortedMeshedSurface<Face> >(cstrIter()(fName));
+    return autoPtr<UnsortedMeshedSurface<Face> >(cstrIter()(name));
 }
 
 
 template<class Face>
 Foam::autoPtr<Foam::UnsortedMeshedSurface<Face> >
-Foam::UnsortedMeshedSurface<Face>::New
-(
-    const fileName& fName
-)
+Foam::UnsortedMeshedSurface<Face>::New(const fileName& name)
 {
-    word ext = fName.ext();
+    word ext = name.ext();
     if (ext == "gz")
     {
-        ext = fName.lessExt().ext();
+        ext = name.lessExt().ext();
     }
 
-    return New(fName, ext);
+    return New(name, ext);
 }
 
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
index 7e5a8068c70e4efc6108c38d655a289e02f399c0..7d4c5da2f2140ed51e8e2a11e6ad145f40247229 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.C
@@ -41,10 +41,10 @@ License
 template<class Face>
 Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -52,20 +52,20 @@ Foam::fileFormats::AC3DsurfaceFormat<Face>::AC3DsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     const bool mustTriangulate = this->isTri();
     this->clear();
 
-    IFstream is(fName);
+    IFstream is(filename);
     if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot read file " << fName
+            << "Cannot read file " << filename
             << exit(FatalError);
     }
 
@@ -81,7 +81,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
         (
             "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
         )
-            << "When reading AC3D file " << fName
+            << "When reading AC3D file " << filename
             << " read header " << line << " with version "
             << version << endl
             << "Only tested reading with version 'b'."
@@ -95,7 +95,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
         (
             "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot find \"OBJECT world\" in file " << fName
+            << "Cannot find \"OBJECT world\" in file " << filename
             << exit(FatalError);
     }
 
@@ -106,18 +106,16 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
     // Start of vertices for object/patch
     label patchVertOffset = 0;
 
-    DynamicList<point> pointLst;
-    DynamicList<Face>  faceLst;
-    DynamicList<label> regionLst;
-
-    // patchId => patchName
-    Map<word> regionNames;
+    DynamicList<point> dynPoints;
+    DynamicList<Face>  dynFaces;
+    List<word>         names(nPatches);
+    List<label>        sizes(nPatches, 0);
 
     for (label patchI = 0; patchI < nPatches; ++patchI)
     {
-        word patchName = word("patch") + Foam::name(patchI);
+        names[patchI] = word("patch") + Foam::name(patchI);
 
-        args = cueToOrDie(is, "OBJECT", "while reading " + patchName);
+        args = cueToOrDie(is, "OBJECT", "while reading " + names[patchI]);
 
         // number of vertices for this patch
         label  nPatchPoints = 0;
@@ -136,7 +134,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                     "fileFormats::AC3DsurfaceFormat::read(const fileName&)"
                 )
                     << "Did not read up to \"kids 0\" while reading patch "
-                    << patchI << " from file " << fName
+                    << patchI << " from file " << filename
                     << exit(FatalError);
             }
 
@@ -146,7 +144,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                 string str = parse<string>(args);
                 string::stripInvalid<word>(str);
 
-                patchName = str;
+                names[patchI] = str;
             }
             else if (cmd == "rot")
             {
@@ -193,7 +191,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                         >> pt.x() >> pt.y() >> pt.z();
 
                     // Offset with current translation vector
-                    pointLst.append(location + pt);
+                    dynPoints.append(location + pt);
                 }
             }
             else if (cmd == "numsurf")
@@ -206,7 +204,7 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                         string(" while reading face ")
                             + Foam::name(faceI) + " on patch "
                             + Foam::name(patchI)
-                            + " from file " + fName;
+                            + " from file " + filename;
 
                     cueToOrDie(is, "SURF", errorMsg);
                     cueToOrDie(is, "mat", errorMsg);
@@ -225,27 +223,20 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
 
                     if (mustTriangulate && f.size() > 3)
                     {
-                        triFace fTri;
-
-                        // simple face triangulation about f[0].
-                        // cannot use face::triangulation
-                        // since points are incomplete
-                        fTri[0] = verts[0];
-                        for (label fp1 = 1; fp1 < verts.size() - 1; ++fp1)
+                        // simple face triangulation about f[0]
+                        // points may be incomplete
+                        for (label fp1 = 1; fp1 < f.size() - 1; ++fp1)
                         {
-                            label fp2 = (fp1 + 1) % verts.size();
-
-                            fTri[1] = verts[fp1];
-                            fTri[2] = verts[fp2];
+                            label fp2 = (fp1 + 1) % f.size();
 
-                            faceLst.append(fTri);
-                            regionLst.append(patchI);
+                            dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                            sizes[patchI]++;
                         }
                     }
                     else
                     {
-                        faceLst.append(Face(f));
-                        regionLst.append(patchI);
+                        dynFaces.append(Face(f));
+                        sizes[patchI]++;
                     }
                 }
 
@@ -271,18 +262,17 @@ bool Foam::fileFormats::AC3DsurfaceFormat<Face>::read
                 }
 
                 // Done reading current patch
-                regionNames.insert(patchI, patchName);
                 break;
             }
         }
     }
 
     // transfer to normal lists
-    this->storedPoints().transfer(pointLst);
-    this->storedFaces().transfer(faceLst);
-    this->storedRegions().transfer(regionLst);
+    this->storedPoints().transfer(dynPoints);
+    this->storedFaces().transfer(dynFaces);
 
-    this->setPatches(regionNames);
+    // add patches, culling empty groups
+    this->addPatches(sizes, names, true);
     this->stitchFaces(SMALL);
     return true;
 }
@@ -292,15 +282,15 @@ template<class Face>
 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const UnsortedMeshedSurface<Face>& surf
+    const MeshedSurface<Face>& surf
 )
 {
-    labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    const pointField& pointLst = surf.points();
+    const List<Face>& faceLst = surf.faces();
+    const List<surfGroup>& patchLst = surf.patches();
 
     writeHeader(os, patchLst);
 
-    label faceIndex = 0;
     forAll(patchLst, patchI)
     {
         const surfGroup& p = patchLst[patchI];
@@ -308,32 +298,28 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
         os  << "OBJECT poly" << nl
             << "name \"" << p.name() << '"' << endl;
 
-        // Create patch with only patch faces included for ease of addressing
-        boolList include(surf.size(), false);
-
-        forAll(p, patchFaceI)
-        {
-            const label faceI = faceMap[faceIndex++];
-            include[faceI] = true;
-        }
-
-        UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
+        // Temporary PrimitivePatch to calculate compact points & faces
+        // use 'UList' to avoid allocations!
+        PrimitivePatch<Face, UList, const pointField&> patch
+        (
+            faceLst,
+            pointLst
+        );
 
-        // Now we have isolated surface for this patch alone. Write it.
-        os << "numvert " << subm.nPoints() << endl;
+        os << "numvert " << patch.nPoints() << endl;
 
-        forAll(subm.localPoints(), ptI)
+        forAll(patch.localPoints(), ptI)
         {
-            const point& pt = subm.localPoints()[ptI];
+            const point& pt = patch.localPoints()[ptI];
 
             os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
         }
 
-        os << "numsurf " << subm.localFaces().size() << endl;
+        os << "numsurf " << patch.localFaces().size() << endl;
 
-        forAll(subm.localFaces(), faceI)
+        forAll(patch.localFaces(), faceI)
         {
-            const Face& f = subm.localFaces()[faceI];
+            const Face& f = patch.localFaces()[faceI];
 
             os  << "SURF 0x20" << nl          // polygon
                 << "mat " << patchI << nl
@@ -354,15 +340,15 @@ template<class Face>
 void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const MeshedSurface<Face>& surf
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
-    const pointField& pointLst = surf.points();
-    const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    labelList faceMap;
+    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
 
     writeHeader(os, patchLst);
 
+    label faceIndex = 0;
     forAll(patchLst, patchI)
     {
         const surfGroup& p = patchLst[patchI];
@@ -370,28 +356,32 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
         os  << "OBJECT poly" << nl
             << "name \"" << p.name() << '"' << endl;
 
-        // Temporary PrimitivePatch to calculate compact points & faces
-        // use 'UList' to avoid allocations!
-        PrimitivePatch<Face, UList, const pointField&> patch
-        (
-            faceLst,
-            pointLst
-        );
+        // Create patch with only patch faces included for ease of addressing
+        boolList include(surf.size(), false);
 
-        os << "numvert " << patch.nPoints() << endl;
+        forAll(p, patchFaceI)
+        {
+            const label faceI = faceMap[faceIndex++];
+            include[faceI] = true;
+        }
 
-        forAll(patch.localPoints(), ptI)
+        UnsortedMeshedSurface<Face> subm = surf.subsetMesh(include);
+
+        // Now we have isolated surface for this patch alone. Write it.
+        os << "numvert " << subm.nPoints() << endl;
+
+        forAll(subm.localPoints(), ptI)
         {
-            const point& pt = patch.localPoints()[ptI];
+            const point& pt = subm.localPoints()[ptI];
 
             os << pt.x() << ' ' << pt.y() << ' ' << pt.z() << endl;
         }
 
-        os << "numsurf " << patch.localFaces().size() << endl;
+        os << "numsurf " << subm.localFaces().size() << endl;
 
-        forAll(patch.localFaces(), faceI)
+        forAll(subm.localFaces(), faceI)
         {
-            const Face& f = patch.localFaces()[faceI];
+            const Face& f = subm.localFaces()[faceI];
 
             os  << "SURF 0x20" << nl          // polygon
                 << "mat " << patchI << nl
@@ -407,4 +397,5 @@ void Foam::fileFormats::AC3DsurfaceFormat<Face>::write
     }
 }
 
+
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
index b95dfd7e20b3186da0de004f57cb97bfb675dd7d..e558d93b90ed93876a13f90746d215feb4de08a8 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormat.H
@@ -31,9 +31,7 @@ Description
     http://www.inivis.com/ac3d/man/ac3dfileformat.html
 
 Note
-   Since the faces are already organized as patches, the reader could be
-   optimized for this, but at expense of losing a common reading approach.
-
+   The faces are already organized as patches.
    The output is always sorted by regions.
 
 SourceFiles
@@ -64,7 +62,7 @@ namespace fileFormats
 template<class Face>
 class AC3DsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>,
+    public MeshedSurface<Face>,
     public AC3DsurfaceFormatCore
 {
     // Private Member Functions
@@ -85,14 +83,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
-            return autoPtr<UnsortedMeshedSurface<Face> >
+            return autoPtr<MeshedSurface<Face> >
             (
-                new AC3DsurfaceFormat<Face>(fName)
+                new AC3DsurfaceFormat<Face>(name)
             );
         }
 
@@ -117,11 +112,11 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
@@ -136,11 +131,11 @@ public:
         //  The output is always sorted by regions.
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
diff --git a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C
index 6e2ea87e9195a031839069dabd5655a924d285d3..b19709ffbbd30106f0f43e3101a9595e7ebdae27 100644
--- a/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/ac3d/AC3DsurfaceFormatRunTime.C
@@ -38,7 +38,7 @@ namespace fileFormats
 
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     AC3DsurfaceFormat,
     face,
     fileExtension,
@@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
 );
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     AC3DsurfaceFormat,
     triFace,
     fileExtension,
diff --git a/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C b/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C
index 748937ebc7998cb8f956e85c11c1c297e3a580a5..825ad5337001a9e0381f3654d1e7e966f0d4a1dd 100644
--- a/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.C
@@ -35,10 +35,10 @@ License
 template<class Face>
 Foam::fileFormats::FTRsurfaceFormat<Face>::FTRsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -47,19 +47,19 @@ Foam::fileFormats::FTRsurfaceFormat<Face>::FTRsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     this->clear();
 
-    IFstream is(fName);
+    IFstream is(filename);
     if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::FTRsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot read file " << fName
+            << "Cannot read file " << filename
             << exit(FatalError);
     }
 
@@ -85,13 +85,18 @@ bool Foam::fileFormats::FTRsurfaceFormat<Face>::read
     this->storedFaces().transfer(faceLst);
     this->storedRegions().transfer(regionLst);
 
-    Map<word> regionNames;
-    forAll(readPatches, patchI)
+    // cast ftrPatch into new form
+    List<surfPatchIdentifier> newPatches(readPatches.size());
+    forAll(newPatches, patchI)
     {
-        regionNames.insert(patchI, readPatches[patchI].name());
+        newPatches[patchI] = surfPatchIdentifier
+        (
+            readPatches[patchI].name(),
+            patchI
+        );
     }
 
-    this->setPatches(regionNames, readPatches.size() - 1);
+    this->storedPatches().transfer(newPatches);
     return true;
 }
 
diff --git a/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.H b/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.H
index f417a73958d335174d5bc2e5288b52fa274ec5e6..cdeb3ce7241a796afeb8a5b1637479adc98e4925 100644
--- a/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/ftr/FTRsurfaceFormat.H
@@ -99,14 +99,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<UnsortedMeshedSurface<Face> > New(const fileName& name)
         {
             return autoPtr<UnsortedMeshedSurface<Face> >
             (
-                new FTRsurfaceFormat<Face>(fName)
+                new FTRsurfaceFormat<Face>(name)
             );
         }
 
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
index 9fb539acda2bb5b45ab2f82dc977cc9a74867e07..d3404e9f52d702f3c54687bbb04f76f5be1757c9 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.C
@@ -38,10 +38,10 @@ License
 template<class Face>
 Foam::fileFormats::GTSsurfaceFormat<Face>::GTSsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -50,19 +50,19 @@ Foam::fileFormats::GTSsurfaceFormat<Face>::GTSsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     this->clear();
 
-    IFstream is(fName);
+    IFstream is(filename);
     if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::GTSsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot read file " << fName
+            << "Cannot read file " << filename
             << exit(FatalError);
     }
 
@@ -205,8 +205,18 @@ bool Foam::fileFormats::GTSsurfaceFormat<Face>::read
         regionLst[faceI] = regionI;
     }
 
-    this->setPatches(maxPatch);
-    // this->stitchFaces(SMALL);
+
+    List<surfPatchIdentifier> newPatches(maxPatch+1);
+    forAll(newPatches, patchI)
+    {
+        newPatches[patchI] = surfPatchIdentifier
+        (
+            "patch" + ::Foam::name(patchI),
+            patchI
+        );
+    }
+
+    this->storedPatches().transfer(newPatches);
     return true;
 }
 
@@ -215,15 +225,18 @@ template<class Face>
 void Foam::fileFormats::GTSsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const UnsortedMeshedSurface<Face>& surf
+    const MeshedSurface<Face>& surf
 )
 {
     const pointField& pointLst = surf.points();
     const List<Face>& faceLst  = surf.faces();
+    const List<surfGroup>& patchLst = surf.patches();
+
 
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
+    //
     if (!surf.isTri())
     {
         label nNonTris = 0;
@@ -240,7 +253,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
             FatalErrorIn
             (
                 "fileFormats::GTSsurfaceFormat::write"
-                "(Ostream&, const UnsortedMeshedSurfaces<Face>&)"
+                "(Ostream&, const MeshedSurface<Face>&)"
             )
                 << "Surface has " << nNonTris << "/" << faceLst.size()
                 << " non-triangulated faces - not writing!" << endl;
@@ -248,11 +261,6 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
-
-    labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
-
-
     // Write header, print patch names as comment
     os  << "# GTS file" << nl
         << "# Regions:" << nl;
@@ -264,7 +272,6 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     }
     os  << "#" << endl;
 
-
     os  << "# nPoints  nEdges  nTriangles" << nl
         << pointLst.size() << ' ' << surf.nEdges() << ' '
         << surf.size() << endl;
@@ -284,22 +291,23 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     const edgeList& es = surf.edges();
     const labelList& meshPts = surf.meshPoints();
 
-    forAll(es, edgeI)
+    forAll(es, edgei)
     {
-        os  << meshPts[es[edgeI].start()] + 1 << ' '
-            << meshPts[es[edgeI].end()] + 1 << endl;
+        os  << meshPts[es[edgei].start()] + 1 << ' '
+            << meshPts[es[edgei].end()] + 1 << endl;
     }
 
-
     // Write faces in terms of edges.
     const labelListList& faceEs = surf.faceEdges();
 
     label faceIndex = 0;
     forAll(patchLst, patchI)
     {
-        forAll(patchLst[patchI], patchFaceI)
+        const surfGroup& patch = patchLst[patchI];
+
+        forAll(patch, patchFaceI)
         {
-            const labelList& fEdges = faceEs[faceMap[faceIndex++]];
+            const labelList& fEdges = faceEs[faceIndex++];
 
             os  << fEdges[0] + 1 << ' '
                 << fEdges[1] + 1 << ' '
@@ -314,18 +322,17 @@ template<class Face>
 void Foam::fileFormats::GTSsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const MeshedSurface<Face>& surf
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
-    const pointField& pointLst = surf.points();
-    const List<Face>& faceLst  = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
-
+    const pointField& pointLst   = surf.points();
+    const List<Face>& faceLst    = surf.faces();
+    const List<label>& regionLst = surf.regions();
+    const List<surfPatchIdentifier>& patchInfo = surf.patches();
 
     // check if output triangulation would be required
     // It is too annoying to triangulate on-the-fly
     // just issue a warning and get out
-    //
     if (!surf.isTri())
     {
         label nNonTris = 0;
@@ -342,7 +349,7 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
             FatalErrorIn
             (
                 "fileFormats::GTSsurfaceFormat::write"
-                "(Ostream&, const MeshedSurface<Face>&)"
+                "(Ostream&, const UnsortedMeshedSurfaces<Face>&)"
             )
                 << "Surface has " << nNonTris << "/" << faceLst.size()
                 << " non-triangulated faces - not writing!" << endl;
@@ -350,17 +357,22 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
         }
     }
 
+    labelList faceMap;
+    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+
+
     // Write header, print patch names as comment
     os  << "# GTS file" << nl
         << "# Regions:" << nl;
 
-    forAll(patchLst, patchI)
+    forAll(patchInfo, patchI)
     {
         os  << "#     " << patchI << "    "
-            << patchLst[patchI].name() << nl;
+            << patchInfo[patchI].name() << nl;
     }
     os  << "#" << endl;
 
+
     os  << "# nPoints  nEdges  nTriangles" << nl
         << pointLst.size() << ' ' << surf.nEdges() << ' '
         << surf.size() << endl;
@@ -380,30 +392,26 @@ void Foam::fileFormats::GTSsurfaceFormat<Face>::write
     const edgeList& es = surf.edges();
     const labelList& meshPts = surf.meshPoints();
 
-    forAll(es, edgei)
+    forAll(es, edgeI)
     {
-        os  << meshPts[es[edgei].start()] + 1 << ' '
-            << meshPts[es[edgei].end()] + 1 << endl;
+        os  << meshPts[es[edgeI].start()] + 1 << ' '
+            << meshPts[es[edgeI].end()] + 1 << endl;
     }
 
+
     // Write faces in terms of edges.
     const labelListList& faceEs = surf.faceEdges();
 
-    label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(faceLst, faceI)
     {
-        const surfGroup& patch = patchLst[patchI];
-
-        forAll(patch, patchFaceI)
-        {
-            const labelList& fEdges = faceEs[faceIndex++];
+        const labelList& fEdges = faceEs[faceI];
 
-            os  << fEdges[0] + 1 << ' '
-                << fEdges[1] + 1 << ' '
-                << fEdges[2] + 1 << ' '
-                << patchI << endl;
-        }
+        os  << fEdges[0] + 1 << ' '
+            << fEdges[1] + 1 << ' '
+            << fEdges[2] + 1 << ' '
+            << regionLst[faceI] << endl;
     }
 }
 
+
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
index fefe168db813d0dea72f2ed7d2a19d2bf15e57d1..ba6f0e7f0801d559804ef66ceb4a1d4892816e06 100644
--- a/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/gts/GTSsurfaceFormat.H
@@ -27,6 +27,7 @@ Class
 
 Description
     Provide a means of reading/writing GTS format.
+    The output is never sorted by patch.
 
 SourceFiles
     GTSsurfaceFormat.C
@@ -75,14 +76,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<UnsortedMeshedSurface<Face> > New(const fileName& name)
         {
             return autoPtr<UnsortedMeshedSurface<Face> >
             (
-                new GTSsurfaceFormat<Face>(fName)
+                new GTSsurfaceFormat<Face>(name)
             );
         }
 
@@ -105,15 +103,15 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
-        //  The output is sorted by regions
+        //  The output remains unsorted
         static void write
         (
             Ostream&,
@@ -121,14 +119,14 @@ public:
         );
 
         //- Write UnsortedMeshedSurface
-        //  The output is sorted by regions
+        //  The output remains unsorted
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
index a393ca92c10e46f684cfcf91521370df8ba54e2f..5c5089a3c401fafa7e91c5a07a23754a8bea7bc6 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.C
@@ -38,10 +38,10 @@ License
 template<class Face>
 Foam::fileFormats::NASsurfaceFormat<Face>::NASsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -50,43 +50,44 @@ Foam::fileFormats::NASsurfaceFormat<Face>::NASsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::NASsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     const bool mustTriangulate = this->isTri();
     this->clear();
 
-    IFstream is(fName);
+    IFstream is(filename);
     if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::NASsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot read file " << fName
+            << "Cannot read file " << filename
             << exit(FatalError);
     }
 
-    DynamicList<point>  pointLst;
     // Nastran index of points
     DynamicList<label>  pointId;
-    DynamicList<Face>   faceLst;
-    DynamicList<label>  regionLst;
-    HashTable<label>    groupToPatch;
+    DynamicList<point>  dynPoints;
+    DynamicList<Face>   dynFaces;
+    DynamicList<label>  dynRegions;
+    DynamicList<label>  dynSizes;
+    Map<label>          lookup;
 
-    // From face groupId to patchId
-    Map<label> groupIdToPatchId;
-    label nPatches = 0;
+    // assume the types are not intermixed
+    bool sorted = true;
+    label regionI = 0;
 
     // Name for face group
-    Map<word> groupIdToName;
+    Map<word> nameLookup;
 
-    // Ansa tags. Denoted by $ANSA_NAME. These will appear just before the
-    // first use of a type. We read them and store the pshell types which
-    // are used to name the patches.
+    // Ansa tags. Denoted by $ANSA_NAME.
+    // These will appear just before the first use of a type.
+    // We read them and store the PSHELL types which are used to name
+    // the patches.
     label ansaId = -1;
-    word ansaType;
-    word ansaName;
+    word  ansaType, ansaName;
 
     // leave faces that didn't have a group in 0
     //    label groupID = 0;
@@ -134,7 +135,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                 string::stripInvalid<word>(rawName);
                 ansaName = rawName;
 
-                // Info<< "ANSA tag for NastranID:" << ansaID
+                // Info<< "ANSA tag for NastranID:" << ansaId
                 //     << " of type " << ansaType
                 //     << " name " << ansaName << endl;
             }
@@ -161,9 +162,9 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             string::stripInvalid<word>(rawName);
 
             word groupName(rawName);
-            groupIdToName.insert(groupId, groupName);
+            nameLookup.insert(groupId, groupName);
 
-            Info<< "group " << groupId << " => " << groupName << endl;
+            // Info<< "group " << groupId << " => " << groupName << endl;
         }
 
 
@@ -173,7 +174,6 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             continue;
         }
 
-
         // Check if character 72 is continuation
         if (line.size() > 72 && line[72] == '+')
         {
@@ -212,22 +212,27 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             fTri[2] = readLabel(IStringStream(line.substr(40,8))());
 
             // Convert groupID into patchID
-            Map<label>::const_iterator iter = groupIdToPatchId.find(groupId);
-
-            label patchI;
-            if (iter == groupIdToPatchId.end())
+            Map<label>::const_iterator fnd = lookup.find(groupId);
+            if (fnd != lookup.end())
             {
-                patchI = nPatches++;
-                groupIdToPatchId.insert(groupId, patchI);
-                Info<< "patch " << patchI << " => group " << groupId << endl;
+                if (regionI != fnd())
+                {
+                    // pshell types are intermixed
+                    sorted = false;
+                }
+                regionI = fnd();
             }
             else
             {
-                patchI = iter();
+                regionI = dynSizes.size();
+                lookup.insert(groupId, regionI);
+                dynSizes.append(0);
+                // Info<< "patch" << regionI << " => group " << groupId <<endl;
             }
 
-            faceLst.append(fTri);
-            regionLst.append(patchI);
+            dynFaces.append(fTri);
+            dynRegions.append(regionI);
+            dynSizes[regionI]++;
         }
         else if (cmd == "CQUAD4")
         {
@@ -240,43 +245,39 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             fQuad[2] = readLabel(IStringStream(line.substr(40,8))());
             fQuad[3] = readLabel(IStringStream(line.substr(48,8))());
 
-            // Convert group into patch
-            Map<label>::const_iterator iter = groupIdToPatchId.find(groupId);
-
-            label patchI;
-            if (iter == groupIdToPatchId.end())
+            // Convert groupID into patchID
+            Map<label>::const_iterator fnd = lookup.find(groupId);
+            if (fnd != lookup.end())
             {
-                patchI = nPatches++;
-                groupIdToPatchId.insert(groupId, patchI);
-                Info<< "patch " << patchI << " => group " << groupId << endl;
+                if (regionI != fnd())
+                {
+                    // pshell types are intermixed
+                    sorted = false;
+                }
+                regionI = fnd();
             }
             else
             {
-                patchI = iter();
+                regionI = dynSizes.size();
+                lookup.insert(groupId, regionI);
+                dynSizes.append(0);
+                // Info<< "patch" << regionI << " => group " << groupId <<endl;
             }
 
+
             if (mustTriangulate)
             {
-                faceLst.append(triFace(f[0], f[1], f[2]));
-                faceLst.append(triFace(f[0], f[2], f[3]));
-                regionLst.append(patchI);
-                regionLst.append(patchI);
+                dynFaces.append(triFace(f[0], f[1], f[2]));
+                dynFaces.append(triFace(f[0], f[2], f[3]));
+                dynRegions.append(regionI);
+                dynRegions.append(regionI);
+                dynSizes[regionI] += 2;
             }
             else
             {
-                faceLst.append(Face(f));
-                regionLst.append(patchI);
-            }
-        }
-        else if (cmd == "PSHELL")
-        {
-            // Read shell type since group gives patchnames.
-            label groupId = readLabel(IStringStream(line.substr(8,8))());
-
-            if (groupId == ansaId && ansaType == "PSHELL")
-            {
-                groupIdToName.insert(groupId, ansaName);
-                Info<< "group " << groupId << " => " << ansaName << endl;
+                dynFaces.append(Face(f));
+                dynRegions.append(regionI);
+                dynSizes[regionI]++;
             }
         }
         else if (cmd == "GRID")
@@ -287,7 +288,7 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
             scalar z = parseNASCoord(line.substr(40, 8));
 
             pointId.append(index);
-            pointLst.append(point(x, y, z));
+            dynPoints.append(point(x, y, z));
         }
         else if (cmd == "GRID*")
         {
@@ -309,76 +310,95 @@ bool Foam::fileFormats::NASsurfaceFormat<Face>::read
                     "fileFormats::NASsurfaceFormat::read(const fileName&)"
                 )
                     << "Expected continuation symbol '*' when reading GRID*"
-                    << " (double precision coordinate) output" << nl
+                    << " (double precision coordinate) format" << nl
                     << "Read:" << line << nl
-                    << "File:" << is.name()
-                    << " line:" << is.lineNumber()
+                    << "File:" << is.name() << " line:" << is.lineNumber()
                     << exit(FatalError);
             }
             scalar z = parseNASCoord(line.substr(8, 16));
 
             pointId.append(index);
-            pointLst.append(point(x, y, z));
+            dynPoints.append(point(x, y, z));
+        }
+        else if (cmd == "PSHELL")
+        {
+            // pshell type for patch names with the Ansa extension
+            label groupId = readLabel(IStringStream(line.substr(8,8))());
+
+            if (groupId == ansaId && ansaType == "PSHELL")
+            {
+                nameLookup.insert(ansaId, ansaName);
+                // Info<< "group " << groupId << " => " << ansaName << endl;
+            }
         }
         else if (unhandledCmd.insert(cmd))
         {
             Info<< "Unhandled Nastran command " << line << nl
-                << "File:" << is.name()
-                << " line:" << is.lineNumber()
+                << "File:" << is.name() << " line:" << is.lineNumber()
                 << endl;
         }
     }
 
-    Info<< "Read faces:" << faceLst.size()
-        << " points:" << pointLst.size()
-        << endl;
-
+    //    Info<< "Read faces:" << dynFaces.size()
+    //        << " points:" << dynPoints.size()
+    //        << endl;
 
     // transfer to normal lists
-    this->storedPoints().transfer(pointLst);
-    this->storedRegions().transfer(regionLst);
+    this->storedPoints().transfer(dynPoints);
 
     pointId.shrink();
-    faceLst.shrink();
+    dynFaces.shrink();
 
+    // Build inverse mapping (NASTRAN pointId -> index)
+    Map<label> mapPointId(2*pointId.size());
+    forAll(pointId, i)
     {
-        // Build inverse mapping (index to point)
-        Map<label> nasToFoamPoint(2*pointId.size());
-        forAll(pointId, i)
-        {
-            nasToFoamPoint.insert(pointId[i], i);
-        }
-        pointId.clearStorage();
-
+        mapPointId.insert(pointId[i], i);
+    }
 
-        // Relabel faces
-        forAll(faceLst, i)
+    // Relabel faces
+    // ~~~~~~~~~~~~~
+    forAll(dynFaces, i)
+    {
+        Face& f = dynFaces[i];
+        forAll(f, fp)
         {
-            Face& f = faceLst[i];
-            forAll(f, fp)
-            {
-                f[fp] = nasToFoamPoint[f[fp]];
-            }
+            f[fp] = mapPointId[f[fp]];
         }
     }
+    pointId.clearStorage();
+    mapPointId.clear();
 
 
-    // convert Nastran groupId => name to patchId => name
-    Map<word> regionNames;
-    forAllConstIter(Map<word>, groupIdToName, iter)
+    // create default patch names, or from ANSA/Hypermesh information
+    List<word> names(dynSizes.size());
+    forAllConstIter(Map<label>, lookup, iter)
     {
-        Map<label>::const_iterator iter2 = groupIdToPatchId.find(iter.key());
+        const label patchI = iter();
+        const label groupI = iter.key();
 
-        if (iter2 != groupIdToPatchId.end())
+        Map<word>::const_iterator fnd = nameLookup.find(groupI);
+        if (fnd != nameLookup.end())
         {
-            regionNames.insert(iter2.key(), iter());
+            names[patchI] = fnd();
+        }
+        else
+        {
+            names[patchI] = word("patch") + ::Foam::name(patchI);
         }
     }
 
-    // transfer to normal lists
-    this->storedFaces().transfer(faceLst);
 
-    this->setPatches(regionNames);
+    sortFacesAndStore
+    (
+        xferMoveTo<List<Face> >(dynFaces),
+        xferMoveTo<List<label> >(dynRegions),
+        sorted
+    );
+
+    // add patches, culling empty groups
+    this->addPatches(dynSizes, names, true);
+
     return true;
 }
 
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
index b8b82d62bd0ba1a274d90a3f9a8376517d639e59..1b409f102245e3f9f47938a388f18687c87a8d8a 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormat.H
@@ -58,13 +58,13 @@ namespace fileFormats
 {
 
 /*---------------------------------------------------------------------------*\
-                       Class NASsurfaceFormat Declaration
+                     Class NASsurfaceFormat Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Face>
 class NASsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>,
+    public MeshedSurface<Face>,
     public NASsurfaceFormatCore
 {
     // Private Member Functions
@@ -85,14 +85,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
-            return autoPtr<UnsortedMeshedSurface<Face> >
+            return autoPtr<MeshedSurface<Face> >
             (
-                new NASsurfaceFormat<Face>(fName)
+                new NASsurfaceFormat<Face>(name)
             );
         }
 
diff --git a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C
index fd07a95b1f3e8e14933a95bfec382dcd193cee91..49297ea629168379fb1f3226c2245a89ed965517 100644
--- a/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/nas/NASsurfaceFormatRunTime.C
@@ -37,9 +37,10 @@ namespace fileFormats
 {
 
 // .bdf (Bulk Data Format)
+// .nas (Nastran)
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     NASsurfaceFormat,
     face,
     fileExtension,
@@ -47,25 +48,24 @@ addNamedTemplatedToRunTimeSelectionTable
 );
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     NASsurfaceFormat,
-    triFace,
+    face,
     fileExtension,
-    bdf
+    nas
 );
 
-// .nas (Nastran)
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     NASsurfaceFormat,
-    face,
+    triFace,
     fileExtension,
-    nas
+    bdf
 );
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     NASsurfaceFormat,
     triFace,
     fileExtension,
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
index 7c7065d664a6ca82e270de8e56017ae84eaeebfd..6761d48a94b01d7b68a87681b60e9f12551ae959 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.C
@@ -27,6 +27,7 @@ License
 #include "OBJsurfaceFormat.H"
 #include "IFstream.H"
 #include "IStringStream.H"
+#include "ListOps.H"
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
@@ -35,10 +36,10 @@ License
 template<class Face>
 Foam::fileFormats::OBJsurfaceFormat<Face>::OBJsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -47,31 +48,38 @@ Foam::fileFormats::OBJsurfaceFormat<Face>::OBJsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     const bool mustTriangulate = this->isTri();
     this->clear();
 
-    IFstream is(fName);
+    IFstream is(filename);
     if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::OBJsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot read file " << fName
+            << "Cannot read file " << filename
             << exit(FatalError);
     }
 
-    DynamicList<point>    pointLst;
-    DynamicList<Face>     faceLst;
-    DynamicList<label>    regionLst;
-    HashTable<label>      groupToPatch;
+    // assume that the groups are not intermixed
+    bool sorted = true;
 
-    // leave faces that didn't have a group in 0
-    label groupID = 0;
-    label maxGroupID = -1;
+    DynamicList<point> dynPoints;
+    DynamicList<Face>  dynFaces;
+    DynamicList<label> dynRegions;
+    DynamicList<word>  dynNames;
+    DynamicList<label> dynSizes;
+    HashTable<label>   lookup;
+
+    // place faces without a group in patch0
+    label regionI = 0;
+    lookup.insert("patch0", regionI);
+    dynNames.append("patch0");
+    dynSizes.append(0);
 
     while (is.good())
     {
@@ -93,30 +101,29 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
         {
             scalar x, y, z;
             lineStream >> x >> y >> z;
-            pointLst.append(point(x, y, z));
+            dynPoints.append(point(x, y, z));
         }
         else if (cmd == "g")
         {
-            word groupName;
-            lineStream >> groupName;
-
-            HashTable<label>::const_iterator findGroup =
-                groupToPatch.find(groupName);
+            word name;
+            lineStream >> name;
 
-            if (findGroup != groupToPatch.end())
+            HashTable<label>::const_iterator fnd = lookup.find(name);
+            if (fnd != lookup.end())
             {
-                groupID = findGroup();
+                if (regionI != fnd())
+                {
+                    // group appeared out of order
+                    sorted = false;
+                }
+                regionI = fnd();
             }
             else
             {
-                // special treatment if any initial faces were not in a group
-                if (maxGroupID == -1 && faceLst.size())
-                {
-                    groupToPatch.insert("patch0", 0);
-                    maxGroupID = 0;
-                }
-                groupID = ++maxGroupID;
-                groupToPatch.insert(groupName, groupID);
+                regionI = dynSizes.size();
+                lookup.insert(name, regionI);
+                dynNames.append(name);
+                dynSizes.append(0);
             }
         }
         else if (cmd == "f")
@@ -171,36 +178,39 @@ bool Foam::fileFormats::OBJsurfaceFormat<Face>::read
 
             if (mustTriangulate && f.size() > 3)
             {
-                triFace fTri;
-
-                // simple face triangulation about f[0].
-                // Cannot use face::triangulation since points are incomplete
-                fTri[0] = f[0];
+                // simple face triangulation about f[0]
+                // points may be incomplete
                 for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
                 {
                     label fp2 = (fp1 + 1) % f.size();
 
-                    fTri[1] = f[fp1];
-                    fTri[2] = f[fp2];
-
-                    faceLst.append(fTri);
-                    regionLst.append(groupID);
+                    dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
+                    dynRegions.append(regionI);
+                    dynSizes[regionI]++;
                 }
             }
             else
             {
-                faceLst.append(Face(f));
-                regionLst.append(groupID);
+                dynFaces.append(Face(f));
+                dynRegions.append(regionI);
+                dynSizes[regionI]++;
             }
         }
     }
 
+
     // transfer to normal lists
-    this->storedPoints().transfer(pointLst);
-    this->storedFaces().transfer(faceLst);
-    this->storedRegions().transfer(regionLst);
+    this->storedPoints().transfer(dynPoints);
+
+    sortFacesAndStore
+    (
+        xferMoveTo<List<Face> >(dynFaces),
+        xferMoveTo<List<label> >(dynRegions),
+        sorted
+    );
 
-    this->setPatches(groupToPatch);
+    // add patches, culling empty groups
+    this->addPatches(dynSizes, dynNames, true);
     return true;
 }
 
@@ -209,27 +219,24 @@ template<class Face>
 void Foam::fileFormats::OBJsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const UnsortedMeshedSurface<Face>& surf
+    const MeshedSurface<Face>& surf
 )
 {
     const List<Face>& faceLst = surf.faces();
-
-    labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    const List<surfGroup>& patchLst = surf.patches();
 
     writeHeader(os, surf.points(), faceLst.size(), patchLst);
 
     label faceIndex = 0;
     forAll(patchLst, patchI)
     {
-        // Print all faces belonging to this region
         const surfGroup& patch = patchLst[patchI];
 
         os << "g " << patch.name() << endl;
 
         forAll(patch, patchFaceI)
         {
-            const Face& f = faceLst[faceMap[faceIndex++]];
+            const Face& f = faceLst[faceIndex++];
 
             os << 'f';
             forAll(f, fp)
@@ -239,7 +246,6 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
             os << endl;
         }
     }
-
     os << "# </faces>" << endl;
 }
 
@@ -248,24 +254,27 @@ template<class Face>
 void Foam::fileFormats::OBJsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const MeshedSurface<Face>& surf
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+
+    labelList faceMap;
+    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
 
     writeHeader(os, surf.points(), faceLst.size(), patchLst);
 
     label faceIndex = 0;
     forAll(patchLst, patchI)
     {
+        // Print all faces belonging to this region
         const surfGroup& patch = patchLst[patchI];
 
         os << "g " << patch.name() << endl;
 
         forAll(patch, patchFaceI)
         {
-            const Face& f = faceLst[faceIndex++];
+            const Face& f = faceLst[faceMap[faceIndex++]];
 
             os << 'f';
             forAll(f, fp)
@@ -275,6 +284,7 @@ void Foam::fileFormats::OBJsurfaceFormat<Face>::write
             os << endl;
         }
     }
+
     os << "# </faces>" << endl;
 }
 
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
index 6545592730d7264754a738eca7f386b3a89a87c3..5159cb3c7a912bed514cd92aa6a094b195116c6d 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormat.H
@@ -58,7 +58,7 @@ namespace fileFormats
 template<class Face>
 class OBJsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>,
+    public MeshedSurface<Face>,
     public OBJsurfaceFormatCore
 {
     // Private Member Functions
@@ -87,14 +87,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
-            return autoPtr<UnsortedMeshedSurface<Face> >
+            return autoPtr<MeshedSurface<Face> >
             (
-                new OBJsurfaceFormat<Face>(fName)
+                new OBJsurfaceFormat<Face>(name)
             );
         }
 
@@ -119,11 +116,11 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
@@ -138,11 +135,11 @@ public:
         //  The output is sorted by regions
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
diff --git a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C
index 64bc69760fa51ee255cc483051fe560f233d7bee..8ab23c2246c4d91e6e5d98940263aae14a935b0c 100644
--- a/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/obj/OBJsurfaceFormatRunTime.C
@@ -38,7 +38,7 @@ namespace fileFormats
 
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     OBJsurfaceFormat,
     face,
     fileExtension,
@@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
 );
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     OBJsurfaceFormat,
     triFace,
     fileExtension,
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
index 16ae9a7f3ab146a90db62f6abd2cb3206232e26e..336ee0b658f4a90f93ddb45d1dcfc3c7e21c40e8 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.C
@@ -37,10 +37,10 @@ License
 template<class Face>
 Foam::fileFormats::OFFsurfaceFormat<Face>::OFFsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -49,20 +49,20 @@ Foam::fileFormats::OFFsurfaceFormat<Face>::OFFsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     const bool mustTriangulate = this->isTri();
     this->clear();
 
-    IFstream is(fName);
+    IFstream is(filename);
     if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)"
         )
-            << "Cannot read file " << fName
+            << "Cannot read file " << filename
             << exit(FatalError);
     }
 
@@ -74,7 +74,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
         (
             "fileFormats::OFFsurfaceFormat<Face>::read(const fileName&)"
         )
-            << "OFF file " << fName << " does not start with 'OFF'"
+            << "OFF file " << filename << " does not start with 'OFF'"
             << exit(FatalError);
     }
 
@@ -103,7 +103,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
 
     // Read faces - ignore optional region information
     // use a DynamicList for possible on-the-fly triangulation
-    DynamicList<Face>  faceLst(nElems);
+    DynamicList<Face>  dynFaces(nElems);
 
     for (label faceI = 0; faceI < nElems; ++faceI)
     {
@@ -126,23 +126,18 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
 
             if (mustTriangulate && f.size() > 3)
             {
-                triFace fTri;
-
-                // simple face triangulation about f[0].
-                fTri[0] = f[0];
+                // simple face triangulation about f[0]
+                // cannot use face::triangulation (points may be incomplete)
                 for (label fp1 = 1; fp1 < f.size() - 1; fp1++)
                 {
                     label fp2 = (fp1 + 1) % f.size();
 
-                    fTri[1] = f[fp1];
-                    fTri[2] = f[fp2];
-
-                    faceLst.append(fTri);
+                    dynFaces.append(triFace(f[0], f[fp1], f[fp2]));
                 }
             }
             else
             {
-                faceLst.append(Face(f));
+                dynFaces.append(Face(f));
             }
         }
     }
@@ -151,7 +146,7 @@ bool Foam::fileFormats::OFFsurfaceFormat<Face>::read
     reset
     (
         xferMove(pointLst),
-        xferMoveTo<List<Face> >(faceLst)
+        xferMoveTo<List<Face> >(dynFaces)
     );
 
     // no region information
diff --git a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
index 1f31e1c48b9ca9b6d7890eeb00e2d5e83b25e451..8806c2b4183c4cc12f3cd2efdc01d5973bb38ba6 100644
--- a/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/off/OFFsurfaceFormat.H
@@ -95,14 +95,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<MeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
             return autoPtr<MeshedSurface<Face> >
             (
-                new OFFsurfaceFormat(fName)
+                new OFFsurfaceFormat(name)
             );
         }
 
@@ -125,11 +122,11 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
@@ -144,11 +141,11 @@ public:
         //  The output is sorted by region.
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
diff --git a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
index 8195719296a8710c42a8d9a0da43d700c15ddbf2..056b28866b03d0735a0f0eaaaf18e8ee85b35ade 100644
--- a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.C
@@ -42,22 +42,20 @@ template<class Face>
 void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const UnsortedMeshedSurface<Face>& surf
+    const MeshedSurface<Face>& surf
 )
 {
     const List<Face>& faceLst = surf.faces();
+    const List<surfGroup>& patchLst = surf.patches();
 
     writeHeader(os, surf.points(), faceLst.size());
 
-    labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
-
     label faceIndex = 0;
     forAll(patchLst, patchI)
     {
         forAll(patchLst[patchI], patchFaceI)
         {
-            const Face& f = faceLst[faceMap[faceIndex++]];
+            const Face& f = faceLst[faceIndex++];
 
             os << f.size();
             forAll(f, fp)
@@ -76,20 +74,22 @@ template<class Face>
 void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const MeshedSurface<Face>& surf
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
 
     writeHeader(os, surf.points(), faceLst.size());
 
+    labelList faceMap;
+    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+
     label faceIndex = 0;
     forAll(patchLst, patchI)
     {
         forAll(patchLst[patchI], patchFaceI)
         {
-            const Face& f = faceLst[faceIndex++];
+            const Face& f = faceLst[faceMap[faceIndex++]];
 
             os << f.size();
             forAll(f, fp)
@@ -103,4 +103,5 @@ void Foam::fileFormats::SMESHsurfaceFormat<Face>::write
     writeTail(os);
 }
 
+
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H
index 242bacbd207483879b7f68c3b9457ca3e0866745..e09c1d5523fbaf1b1ac2d326d396207616105f5e 100644
--- a/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/smesh/SMESHsurfaceFormat.H
@@ -63,7 +63,7 @@ namespace fileFormats
 template<class Face>
 class SMESHsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>,
+    public MeshedSurface<Face>,
     public SMESHsurfaceFormatCore
 {
     // Private Member Functions
@@ -101,11 +101,11 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
@@ -120,11 +120,11 @@ public:
         //  The output is sorted by region.
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
index 3f523865debc2226fa3556c5fe0d8e64f160ee70..49e48578f510fa922268b77a8d470aafc4451cce 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.C
@@ -25,6 +25,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "STARCDsurfaceFormat.H"
+#include "ListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -69,10 +70,10 @@ inline void Foam::fileFormats::STARCDsurfaceFormat<Face>::writeShell
 template<class Face>
 Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
@@ -80,93 +81,65 @@ Foam::fileFormats::STARCDsurfaceFormat<Face>::STARCDsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     const bool mustTriangulate = this->isTri();
     this->clear();
 
-    fileName baseName = fName.lessExt();
-    autoPtr<IFstream> isPtr;
+    fileName baseName = filename.lessExt();
 
-
-    DynamicList<point> pointLst;
     // STAR-CD index of points
-    DynamicList<label> pointId;
-
-    //
-    // read .vrt file
-    // ~~~~~~~~~~~~~~
-    isPtr.reset(new IFstream(baseName + ".vrt"));
-
-    if (!isPtr().good())
-    {
-        FatalErrorIn
-        (
-            "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
-        )
-            << "Cannot read file " << (baseName + ".vrt")
-            << exit(FatalError);
-    }
-
-    readHeader(isPtr(), "PROSTAR_VERTEX");
-
-    label lineLabel;
+    List<label> pointId;
 
-    while ((isPtr() >> lineLabel).good())
-    {
-        pointId.append(lineLabel);
-        scalar x, y, z;
-
-        isPtr() >> x >> y >> z;
-
-        pointLst.append(point(x, y, z));
-    }
-
-    // transfer to normal lists
-    this->storedPoints().transfer(pointLst);
+    // read points from .vrt file
+    readPoints
+    (
+        IFstream(baseName + ".vrt")(),
+        this->storedPoints(),
+        pointId
+    );
 
-    // Build inverse mapping (index to point)
-    pointId.shrink();
-    Map<label> mapToFoamPointId(2*pointId.size());
+    // Build inverse mapping (STAR-CD pointId -> index)
+    Map<label> mapPointId(2*pointId.size());
     forAll(pointId, i)
     {
-        mapToFoamPointId.insert(pointId[i], i);
+        mapPointId.insert(pointId[i], i);
     }
     pointId.clear();
 
-
-    DynamicList<Face>  faceLst;
-    DynamicList<label> regionLst;
-
-    // From face cellTableId to patchId
-    Map<label> cellTableToPatchId;
-    label nPatches = 0;
-
-
     //
     // read .cel file
     // ~~~~~~~~~~~~~~
-    isPtr.reset(new IFstream(baseName + ".cel"));
-
-    if (!isPtr().good())
+    IFstream is(baseName + ".cel");
+    if (!is.good())
     {
         FatalErrorIn
         (
             "fileFormats::STARCDsurfaceFormat::read(const fileName&)"
         )
-            << "Cannot read file " << (baseName + ".cel")
+            << "Cannot read file " << is.name()
             << exit(FatalError);
     }
 
-    readHeader(isPtr(), "PROSTAR_CELL");
+    readHeader(is, "PROSTAR_CELL");
+
+    DynamicList<Face>  dynFaces;
+    DynamicList<label> dynRegions;
+    DynamicList<word>  dynNames;
+    DynamicList<label> dynSizes;
+    Map<label> lookup;
+
+    // assume the cellTableIds are not intermixed
+    bool sorted = true;
+    label regionI = 0;
 
-    label shapeId, nLabels, cellTableId, typeId;
+    label lineLabel, shapeId, nLabels, cellTableId, typeId;
     labelList starLabels(64);
 
-    while ((isPtr() >> lineLabel).good())
+    while ((is >> lineLabel).good())
     {
-        isPtr() >> shapeId >> nLabels >> cellTableId >> typeId;
+        is >> shapeId >> nLabels >> cellTableId >> typeId;
 
         if (nLabels > starLabels.size())
         {
@@ -179,90 +152,81 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
         {
             if ((i % 8) == 0)
             {
-               isPtr() >> lineLabel;
+               is >> lineLabel;
             }
-            isPtr() >> starLabels[i];
+            is >> starLabels[i];
         }
 
         if (typeId == starcdShellType_)
         {
             // Convert groupID into patchID
-            Map<label>::const_iterator iter =
-                cellTableToPatchId.find(cellTableId);
-
-            label patchI;
-            if (iter == cellTableToPatchId.end())
+            Map<label>::const_iterator fnd = lookup.find(cellTableId);
+            if (fnd != lookup.end())
             {
-                patchI = nPatches++;
-
-                cellTableToPatchId.insert(cellTableId, patchI);
+                if (regionI != fnd())
+                {
+                    // cellTableIds are intermixed
+                    sorted = false;
+                }
+                regionI = fnd();
             }
             else
             {
-                patchI = iter();
+                regionI = dynSizes.size();
+                lookup.insert(cellTableId, regionI);
+                dynNames.append(word("cellTable_") + ::Foam::name(regionI));
+                dynSizes.append(0);
             }
 
+            SubList<label> vertices(starLabels, nLabels);
 
             // convert orig vertex id to point label
-            for (label i=0; i < nLabels; ++i)
+            forAll(vertices, i)
             {
-                starLabels[i] = mapToFoamPointId[starLabels[i]];
+                vertices[i] = mapPointId[vertices[i]];
             }
 
             if (mustTriangulate && nLabels > 3)
             {
-                face f
-                (
-                    SubList<label>(starLabels, nLabels)
-                );
+                face f(vertices);
 
-                faceList triFaces(f.nTriangles(this->points()));
+                faceList triFaces(f.nTriangles());
                 label nTri = 0;
                 f.triangles(this->points(), nTri, triFaces);
 
                 forAll(triFaces, faceI)
                 {
-                    // a triangle, but not yet a triFace
-                    faceLst.append
+                    // a triangular face, but not yet a triFace
+                    dynFaces.append
                     (
                         triFace
                         (
                             static_cast<UList<label>&>(triFaces[faceI])
                         )
                     );
-                    regionLst.append(patchI);
+                    dynRegions.append(regionI);
+                    dynSizes[regionI]++;
                 }
             }
             else
             {
-                faceLst.append
-                (
-                    Face(SubList<label>(starLabels, nLabels))
-                );
-                regionLst.append(patchI);
+                dynFaces.append(Face(vertices));
+                dynRegions.append(regionI);
+                dynSizes[regionI]++;
             }
         }
     }
+    mapPointId.clear();
 
-    mapToFoamPointId.clear();
-
-    // convert cellTable_N patchId => name
-    Map<word> regionNames;
-    forAllConstIter(Map<label>, cellTableToPatchId, iter)
-    {
-        regionNames.insert
-        (
-            iter(),
-            "cellTable_" + Foam::name(iter.key())
-        );
-    }
-
-    // transfer to normal lists
-    this->storedFaces().transfer(faceLst);
-    this->storedRegions().transfer(regionLst);
-
-    this->setPatches(regionNames);
+    sortFacesAndStore
+    (
+        xferMoveTo<List<Face> >(dynFaces),
+        xferMoveTo<List<label> >(dynRegions),
+        sorted
+    );
 
+    // add patches, culling empty groups
+    this->addPatches(dynSizes, dynNames, true);
     return true;
 }
 
@@ -270,19 +234,18 @@ bool Foam::fileFormats::STARCDsurfaceFormat<Face>::read
 template<class Face>
 void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 (
-    const fileName& fName,
-    const UnsortedMeshedSurface<Face>& surf
+    const fileName& filename,
+    const MeshedSurface<Face>& surf
 )
 {
-    fileName baseName = fName.lessExt();
+    fileName baseName = filename.lessExt();
 
     writePoints(OFstream(baseName + ".vrt")(), surf.points());
     OFstream os(baseName + ".cel");
     writeHeader(os, "CELL");
 
     const List<Face>& faceLst = surf.faces();
-    labelList faceMap;
-    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
+    const List<surfGroup>& patchLst = surf.patches();
 
     label faceIndex = 0;
     forAll(patchLst, patchI)
@@ -291,7 +254,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 
         forAll(patch, patchFaceI)
         {
-            const Face& f = faceLst[faceMap[faceIndex++]];
+            const Face& f = faceLst[faceIndex++];
             writeShell(os, f, faceIndex, patchI + 1);
         }
     }
@@ -310,18 +273,20 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 template<class Face>
 void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 (
-    const fileName& fName,
-    const MeshedSurface<Face>& surf
+    const fileName& filename,
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
-    fileName baseName = fName.lessExt();
+    fileName baseName = filename.lessExt();
 
     writePoints(OFstream(baseName + ".vrt")(), surf.points());
+
     OFstream os(baseName + ".cel");
     writeHeader(os, "CELL");
 
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
+    labelList faceMap;
+    List<surfGroup> patchLst = surf.sortedRegions(faceMap);
 
     label faceIndex = 0;
     forAll(patchLst, patchI)
@@ -330,7 +295,7 @@ void Foam::fileFormats::STARCDsurfaceFormat<Face>::write
 
         forAll(patch, patchFaceI)
         {
-            const Face& f = faceLst[faceIndex++];
+            const Face& f = faceLst[faceMap[faceIndex++]];
             writeShell(os, f, faceIndex, patchI + 1);
         }
     }
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H
index 6a47537881a4a69677db0a8b2fbbb1de7979c72f..2838e654ad7c1d83ab71bd6e35ad2d732e7e915a 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormat.H
@@ -62,7 +62,7 @@ namespace fileFormats
 template<class Face>
 class STARCDsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>,
+    public MeshedSurface<Face>,
     public STARCDsurfaceFormatCore
 {
     // Private Data
@@ -97,15 +97,12 @@ public:
 
     // Selectors
 
-        //- Read file and return keyedSurface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        //- Read file and return surface
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
-            return autoPtr<UnsortedMeshedSurface<Face> >
+            return autoPtr<MeshedSurface<Face> >
             (
-                new STARCDsurfaceFormat<Face>(fName)
+                new STARCDsurfaceFormat<Face>(name)
             );
         }
 
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
index d016c2cef04f30524ee59f21c8b199cf9f46e091..af68ddb424fd1e609c19f74426b8a118ddcb98f6 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.C
@@ -89,6 +89,52 @@ void Foam::fileFormats::STARCDsurfaceFormatCore::writeHeader
 }
 
 
+bool Foam::fileFormats::STARCDsurfaceFormatCore::readPoints
+(
+    IFstream& is,
+    pointField& points,
+    labelList& ids
+)
+{
+    //
+    // read .vrt file
+    // ~~~~~~~~~~~~~~
+
+    if (!is.good())
+    {
+        FatalErrorIn
+        (
+            "fileFormats::STARCDsurfaceFormatCore::readPoints(const fileName&)"
+        )
+            << "Cannot read file " << is.name()
+            << exit(FatalError);
+    }
+
+    readHeader(is, "PROSTAR_VERTEX");
+
+    DynamicList<point> dynPoints;
+    // STAR-CD index of points
+    DynamicList<label> dynPointId;
+
+    label lineLabel;
+    while ((is >> lineLabel).good())
+    {
+        scalar x, y, z;
+
+        is >> x >> y >> z;
+
+        dynPoints.append(point(x, y, z));
+        dynPointId.append(lineLabel);
+    }
+
+    points.transfer(dynPoints);
+    ids.transfer(dynPointId);
+
+    return true;
+}
+
+
+
 void Foam::fileFormats::STARCDsurfaceFormatCore::writePoints
 (
     Ostream& os,
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H
index b560207961883c79e7fb2844f8e87cd7bbe9398e..ecedca11ed9a4aef245e9cdc774ca04191856ed8 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatCore.H
@@ -61,6 +61,8 @@ protected:
 
     static void writeHeader(Ostream&, const char* filetype);
 
+    static bool readPoints(IFstream&, pointField&, labelList& ids);
+
     static void writePoints(Ostream&, const pointField&);
 
     static void writeCase
diff --git a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C
index 5cf59da6c8aab69cc43d5f6cafb4d581e0be96af..ccd1a4b98908d0176da0f373fa1aa8a342e89e21 100644
--- a/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/starcd/STARCDsurfaceFormatRunTime.C
@@ -38,7 +38,7 @@ namespace fileFormats
 
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     STARCDsurfaceFormat,
     face,
     fileExtension,
@@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
 );
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     STARCDsurfaceFormat,
     triFace,
     fileExtension,
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
index 5367e130a65aa36666233a830410a4fb3936add5..1800748570b0bf327e602b0b5666f850a3bf0c32 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.C
@@ -94,6 +94,36 @@ inline void Foam::fileFormats::STLsurfaceFormat<Face>::writeShell
 }
 
 
+// write sorted:
+template<class Face>
+void Foam::fileFormats::STLsurfaceFormat<Face>::writeASCII
+(
+    Ostream& os,
+    const MeshedSurface<Face>& surf
+)
+{
+    const pointField& pointLst = surf.points();
+    const List<Face>& faceLst = surf.faces();
+    const List<surfGroup>& patchLst = surf.patches();
+    const vectorField& normLst = surf.faceNormals();
+
+    label faceIndex = 0;
+    forAll(patchLst, patchI)
+    {
+        // Print all faces belonging to this region
+        const surfGroup& patch = patchLst[patchI];
+
+        os << "solid " << patch.name() << endl;
+        forAll(patch, patchFaceI)
+        {
+            const label faceI = faceIndex++;
+            writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
+        }
+        os << "endsolid " << patch.name() << endl;
+    }
+}
+
+
 // write sorted:
 template<class Face>
 void Foam::fileFormats::STLsurfaceFormat<Face>::writeASCII
@@ -136,53 +166,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeASCII
             os << "endsolid " << patch.name() << endl;
         }
    }
-
 }
 
 
 
-// write sorted:
-template<class Face>
-void Foam::fileFormats::STLsurfaceFormat<Face>::writeASCII
-(
-    Ostream& os,
-    const MeshedSurface<Face>& surf
-)
-{
-    const pointField& pointLst = surf.points();
-    const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
-    const vectorField& normLst = surf.faceNormals();
-
-    label faceIndex = 0;
-    forAll(patchLst, patchI)
-    {
-        // Print all faces belonging to this region
-        const surfGroup& patch = patchLst[patchI];
-
-        os << "solid " << patch.name() << endl;
-        forAll(patch, patchFaceI)
-        {
-            const label faceI = faceIndex++;
-            writeShell(os, pointLst, faceLst[faceI], normLst[faceI]);
-        }
-        os << "endsolid " << patch.name() << endl;
-    }
-}
-
-
-// write unsorted:
 template<class Face>
 void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
 (
     ostream& os,
-    const UnsortedMeshedSurface<Face>& surf
+    const MeshedSurface<Face>& surf
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>&  faceLst = surf.faces();
-    const List<label>& regionLst = surf.regions();
+    const List<Face>& faceLst  = surf.faces();
     const vectorField& normLst = surf.faceNormals();
+    const List<surfGroup>& patchLst = surf.patches();
 
     unsigned int nTris = 0;
     if (surf.isTri())
@@ -201,32 +199,38 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
     // Write the STL header
     STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
 
-    // always write unsorted
-    forAll(faceLst, faceI)
+    label faceIndex = 0;
+    forAll(patchLst, patchI)
     {
-        writeShell
-        (
-            os,
-            pointLst,
-            faceLst[faceI],
-            normLst[faceI],
-            regionLst[faceI]
-        );
+        forAll(patchLst[patchI], patchFaceI)
+        {
+            writeShell
+            (
+                os,
+                pointLst,
+                faceLst[faceIndex],
+                normLst[faceIndex],
+                patchI
+            );
+
+            ++faceIndex;
+        }
     }
 }
 
 
+// write unsorted:
 template<class Face>
 void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
 (
     ostream& os,
-    const MeshedSurface<Face>& surf
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
     const pointField& pointLst = surf.points();
-    const List<Face>& faceLst  = surf.faces();
+    const List<Face>&  faceLst = surf.faces();
+    const List<label>& regionLst = surf.regions();
     const vectorField& normLst = surf.faceNormals();
-    const List<surfGroup>& patchLst = surf.patches();
 
     unsigned int nTris = 0;
     if (surf.isTri())
@@ -245,22 +249,17 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
     // Write the STL header
     STLsurfaceFormatCore::writeHeaderBINARY(os, nTris);
 
-    label faceIndex = 0;
-    forAll(patchLst, patchI)
+    // always write unsorted
+    forAll(faceLst, faceI)
     {
-        forAll(patchLst[patchI], patchFaceI)
-        {
-            writeShell
-            (
-                os,
-                pointLst,
-                faceLst[faceIndex],
-                normLst[faceIndex],
-                patchI
-            );
-
-            ++faceIndex;
-        }
+        writeShell
+        (
+            os,
+            pointLst,
+            faceLst[faceI],
+            normLst[faceI],
+            regionLst[faceI]
+        );
     }
 }
 
@@ -270,10 +269,10 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::writeBINARY
 template<class Face>
 Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -282,78 +281,62 @@ Foam::fileFormats::STLsurfaceFormat<Face>::STLsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::STLsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     this->clear();
 
     // read in the values
-    STLsurfaceFormatCore reader(fName);
+    STLsurfaceFormatCore reader(filename);
 
     // transfer points
     this->storedPoints().transfer(reader.points());
 
-    // get the original region information
+    // retrieve the original region information
     List<word>  names(xferMove(reader.names()));
-    List<label> unsortedRegions(xferMove(reader.regions()));
-
-    // and determine the sorted order:
-    // avoid SortableList since we discard the main list anyhow
-    List<label> faceMap;
-    sortedOrder(unsortedRegions, faceMap);
+    List<label> sizes(xferMove(reader.sizes()));
+    List<label> regions(xferMove(reader.regions()));
 
-    // generate the sorted faces and sorted regions:
-    List<Face> faceLst(faceMap.size());
+    // generate the (sorted) faces
+    List<Face> faceLst(regions.size());
 
-    DynamicList<label> dynPatchSizes;
-    label prevRegion = -1;
-    label regionSize = 0;
-
-    forAll(faceMap, faceI)
+    if (reader.sorted())
     {
-        const label startPt = 3*faceMap[faceI];
-        const label regionI = unsortedRegions[faceMap[faceI]];
-
-        faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
-
-        if (prevRegion != regionI)
+        // already sorted - generate directly
+        forAll(faceLst, faceI)
         {
-            if (regionSize)
-            {
-                dynPatchSizes.append(regionSize);
-            }
-            prevRegion = regionI;
-            regionSize = 0;
+            const label startPt = 3*faceI;
+            faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
         }
-        regionSize++;
     }
-
-    if (regionSize)
+    else
     {
-        dynPatchSizes.append(regionSize);
+        // unsorted - determine the sorted order:
+        // avoid SortableList since we discard the main list anyhow
+        List<label> faceMap;
+        sortedOrder(regions, faceMap);
+
+        // generate sorted faces
+        forAll(faceMap, faceI)
+        {
+            const label startPt = 3*faceMap[faceI];
+            faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
+        }
     }
+    regions.clear();
 
     // transfer:
     this->storedFaces().transfer(faceLst);
-    unsortedRegions.clear();
-    faceMap.clear();
 
-    label start = 0;
-    surfGroupList newPatches(dynPatchSizes.size());
-    forAll(newPatches, patchI)
+    if (names.size())
     {
-        newPatches[patchI] = surfGroup
-        (
-            names[patchI],
-            dynPatchSizes[patchI],
-            start,
-            patchI
-        );
-
-        start += dynPatchSizes[patchI];
+        this->addPatches(sizes, names);
+    }
+    else
+    {
+        this->addPatches(sizes);
     }
 
-    this->addPatches(newPatches);
     this->stitchFaces(SMALL);
     return true;
 }
@@ -384,21 +367,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
 template<class Face>
 void Foam::fileFormats::STLsurfaceFormat<Face>::write
 (
-    const fileName& fName,
+    const fileName& filename,
     const UnsortedMeshedSurface<Face>& surf
 )
 {
-    word ext = fName.ext();
+    word ext = filename.ext();
 
     // handle 'stlb' as binary directly
     if (ext == "stlb")
     {
-        std::ofstream ofs(fName.c_str(), std::ios::binary);
+        std::ofstream ofs(filename.c_str(), std::ios::binary);
         writeBINARY(ofs, surf);
     }
     else
     {
-        writeASCII(OFstream(fName)(), surf);
+        writeASCII(OFstream(filename)(), surf);
     }
 }
 
@@ -406,21 +389,21 @@ void Foam::fileFormats::STLsurfaceFormat<Face>::write
 template<class Face>
 void Foam::fileFormats::STLsurfaceFormat<Face>::write
 (
-    const fileName& fName,
+    const fileName& filename,
     const MeshedSurface<Face>& surf
 )
 {
-    const word ext = fName.ext();
+    const word ext = filename.ext();
 
     // handle 'stlb' as binary directly
     if (ext == "stlb")
     {
-        std::ofstream ofs(fName.c_str(), std::ios::binary);
+        std::ofstream ofs(filename.c_str(), std::ios::binary);
         writeBINARY(ofs, surf);
     }
     else
     {
-        writeASCII(OFstream(fName)(), surf);
+        writeASCII(OFstream(filename)(), surf);
     }
 }
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
index 8d3f7c662d56b8a43f182fe35a1cf4f937ebab29..68c5ce66c49b529abbf699a6f872f8e819abfd09 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormat.H
@@ -111,14 +111,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<MeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
             return autoPtr<MeshedSurface<Face> >
             (
-                new STLsurfaceFormat<Face>(fName)
+                new STLsurfaceFormat<Face>(name)
             );
         }
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
index e01b96fbb85162286583c337f0facce39d6775bf..4737137b9cd22e18018930971b792db8b5bca810 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatASCII.L
@@ -72,6 +72,7 @@ class STLASCIILexer
 {
     // Private data
 
+        bool  sorted_;
         label groupID_;      // current region
         label lineNo_;
         word  startError_;
@@ -79,7 +80,8 @@ class STLASCIILexer
         DynamicList<point> points_;
         DynamicList<label> facets_;
         DynamicList<word>  names_;
-        HashTable<label>   nameIndex_;
+        DynamicList<label> sizes_;
+        HashTable<label>   lookup_;
 
 public:
 
@@ -96,6 +98,12 @@ public:
 
     // Access
 
+        //- Do all the solid groups appear in order
+        bool sorted() const
+        {
+            return sorted_;
+        }
+
         //- A list of points corresponding to a pointField
         DynamicList<point>& points()
         {
@@ -114,12 +122,19 @@ public:
         {
             return names_;
         }
+
+        //- region sizes
+        DynamicList<label>& sizes()
+        {
+            return sizes_;
+        }
 };
 
 
 STLASCIILexer::STLASCIILexer(istream* is, const label approxNpoints)
 :
     yyFlexLexer(is),
+    sorted_(true),
     groupID_(-1),
     lineNo_(1),
     points_(approxNpoints),
@@ -237,16 +252,22 @@ endsolid              {space}("endsolid"|"ENDSOLID")({some_space}{word})*
 <readSolidName>{string} {
         word name(Foam::string::validate<word>(YYText()));
 
-        HashTable<label>::const_iterator fnd = nameIndex_.find(name);
-        if (fnd != nameIndex_.end())
+        HashTable<label>::const_iterator fnd = lookup_.find(name);
+        if (fnd != lookup_.end())
         {
+            if (groupID_ != fnd())
+            {
+                // group appeared out of order
+                sorted_ = false;
+            }
             groupID_ = fnd();
         }
         else
         {
-            groupID_ = names_.size();
+            groupID_ = sizes_.size();
+            lookup_.insert(name, groupID_);
             names_.append(name);
-            nameIndex_.insert(name, groupID_);
+            sizes_.append(0);
         }
         BEGIN(INITIAL);
     }
@@ -254,16 +275,22 @@ endsolid              {space}("endsolid"|"ENDSOLID")({some_space}{word})*
 <readSolidName>{space}\n {
         word name("solid");
 
-        HashTable<label>::const_iterator fnd = nameIndex_.find(name);
-        if (fnd != nameIndex_.end())
+        HashTable<label>::const_iterator fnd = lookup_.find(name);
+        if (fnd != lookup_.end())
         {
+            if (groupID_ != fnd())
+            {
+                // group appeared out of order
+                sorted_ = false;
+            }
             groupID_ = fnd();
         }
         else
         {
-            groupID_ = names_.size();
+            groupID_ = sizes_.size();
+            lookup_.insert(name, groupID_);
             names_.append(name);
-            nameIndex_.insert(name, groupID_);
+            sizes_.append(0);
         }
 
         lineNo_++;
@@ -328,6 +355,7 @@ endsolid              {space}("endsolid"|"ENDSOLID")({some_space}{word})*
 
 <readFacet>{endfacet} {
         facets_.append(groupID_);
+        sizes_[groupID_]++;
         BEGIN(INITIAL);
     }
 
@@ -380,17 +408,18 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readASCII
     const off_t fileSize
 )
 {
-    binary_ = false;
-
     // Create the lexer with the approximate number of vertices in the STL
     // from the file size
     STLASCIILexer lexer(&ifs.stdStream(), fileSize/400);
     while (lexer.lex() != 0) {}
 
+    sorted_ = lexer.sorted();
+
     // transfer to normal lists
     points_.transfer(lexer.points());
     regions_.transfer(lexer.facets());
     names_.transfer(lexer.names());
+    sizes_.transfer(lexer.sizes());
 
     return true;
 }
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
index 7aa29789e2ec8d10517437de0dbba2cf8c901a84..cd33a4c347ec87afa5c0fb28e6b919c5bad9ee2b 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.C
@@ -42,12 +42,12 @@ License
 //   is detected ... this is not exactly what we want.
 int Foam::fileFormats::STLsurfaceFormatCore::detectBINARY
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    off_t fileSize = Foam::size(fName);
+    off_t fileSize = Foam::size(filename);
 
-    IFstream ifs(fName, IOstream::BINARY);
+    IFstream ifs(filename, IOstream::BINARY);
     istream& is = ifs.stdStream();
 
     // Read the STL header
@@ -92,7 +92,7 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
     const off_t fileSize
 )
 {
-    binary_ = true;
+    sorted_ = true;
     istream& is = ifs.stdStream();
 
     // Read the STL header
@@ -144,10 +144,11 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
     points_.setSize(3*nTris);
     regions_.setSize(nTris);
 
-    Map<label> regionToPatch;
-    DynamicList<word> dynNames;
+    Map<label> lookup;
+    DynamicList<label> dynSizes;
 
     label ptI = 0;
+    label regionI = -1;
     forAll(regions_, faceI)
     {
         // Read an STL triangle
@@ -161,20 +162,25 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
         // interprete colour as a region
         const label stlRegion = stlTri.region();
 
-        Map<label>::const_iterator fnd = regionToPatch.find(stlRegion);
-        label regionI;
-        if (fnd != regionToPatch.end())
+        Map<label>::const_iterator fnd = lookup.find(stlRegion);
+        if (fnd != lookup.end())
         {
+            if (regionI != fnd())
+            {
+                // group appeared out of order
+                sorted_ = false;
+            }
             regionI = fnd();
         }
         else
         {
-            regionI = dynNames.size();
-            dynNames.append(word("patch") + ::Foam::name(regionI));
-            regionToPatch.insert(stlRegion, regionI);
+            regionI = dynSizes.size();
+            lookup.insert(stlRegion, regionI);
+            dynSizes.append(0);
         }
 
         regions_[faceI] = regionI;
+        dynSizes[regionI]++;
 
 #ifdef DEBUG_STLBINARY
         if (prevRegion != regionI)
@@ -198,7 +204,8 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
 #endif
     }
 
-    names_.transfer(dynNames);
+    names_.clear();
+    sizes_.transfer(dynSizes);
 
     return true;
 }
@@ -208,24 +215,25 @@ bool Foam::fileFormats::STLsurfaceFormatCore::readBINARY
 
 Foam::fileFormats::STLsurfaceFormatCore::STLsurfaceFormatCore
 (
-    const fileName& fName
+    const fileName& filename
 )
 :
-    binary_(false),
+    sorted_(true),
     points_(0),
     regions_(0),
-    names_(0)
+    names_(0),
+    sizes_(0)
 {
-    off_t fileSize = Foam::size(fName);
+    off_t fileSize = Foam::size(filename);
 
     // auto-detect ascii/binary
-    if (detectBINARY(fName))
+    if (detectBINARY(filename))
     {
-        readBINARY(IFstream(fName, IOstream::BINARY)(), fileSize);
+        readBINARY(IFstream(filename, IOstream::BINARY)(), fileSize);
     }
     else
     {
-        readASCII(IFstream(fName)(), fileSize);
+        readASCII(IFstream(filename)(), fileSize);
     }
 }
 
diff --git a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
index 399aa0ecb78e8e56c7b7a4b759e1c5ecdd7a4449..0bcb2f1eee8a8796635c546513e684d624c6d6ed 100644
--- a/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
+++ b/src/surfMesh/surfaceFormats/stl/STLsurfaceFormatCore.H
@@ -59,7 +59,7 @@ class STLsurfaceFormatCore
 {
     // Private Data
 
-        bool binary_;
+        bool sorted_;
 
         //- The points supporting the facets
         pointField points_;
@@ -70,6 +70,9 @@ class STLsurfaceFormatCore
         //- The solid names, in the order of their first appearance
         List<word> names_;
 
+        //- The solid count, in the order of their first appearance
+        List<label> sizes_;
+
     // Private Member Functions
 
         //- Disallow default bitwise copy construct
@@ -81,10 +84,10 @@ class STLsurfaceFormatCore
         //- Determine the file type
         static int detectBINARY(const fileName&);
 
-        //- Read ASCII, set groupToPatch
+        //- Read ASCII
         bool readASCII(IFstream&, const off_t);
 
-        //- Read BINARY, set maxRegionId
+        //- Read BINARY
         bool readBINARY(IFstream&, const off_t);
 
 public:
@@ -110,27 +113,23 @@ public:
 
     // Member Functions
 
-        //- File was detected to be STL binary
-        bool binary() const
-        {
-            return binary_;
-        }
-
-        //- The number of facets is the number of regions
-        label size() const
+        //- File read was already sorted
+        bool sorted() const
         {
-            return regions_.size();
+            return sorted_;
         }
 
         //- Flush all values
         void clear()
         {
+            sorted_ = true;
             points_.clear();
             regions_.clear();
             names_.clear();
+            sizes_.clear();
         }
 
-        //- Return full access to the faces
+        //- Return full access to the points
         pointField& points()
         {
             return points_;
@@ -148,6 +147,12 @@ public:
             return names_;
         }
 
+        //- The list of solid sizes in the order of their first appearance
+        List<label>& sizes()
+        {
+            return sizes_;
+        }
+
 };
 
 
diff --git a/src/surfMesh/surfaceFormats/surfaceFormatsCore.C b/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
index cb8193eee86c2bdb4cd3e1ece477b28b37b15a55..c679191e791d68705d4e33b5b557e85ad441e617 100644
--- a/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
+++ b/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
@@ -186,53 +186,53 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
     // number of items, just do it ourselves
 
     // step 1: get region sizes and store (regionId => patchI)
-    Map<label> regionLookup;
+    Map<label> lookup;
     forAll(regionLst, faceI)
     {
         const label regId = regionLst[faceI];
 
-        Map<label>::iterator iter = regionLookup.find(regId);
-        if (iter == regionLookup.end())
+        Map<label>::iterator fnd = lookup.find(regId);
+        if (fnd != lookup.end())
         {
-            regionLookup.insert(regId, 1);
+            fnd()++;
         }
         else
         {
-            iter()++;
+            lookup.insert(regId, 1);
         }
     }
 
     // step 2: assign start/size (and name) to the newPatches
     // re-use the lookup to map (regionId => patchI)
-    surfGroupList patchLst(regionLookup.size());
-    label patchStart = 0;
+    surfGroupList patchLst(lookup.size());
+    label start = 0;
     label patchI = 0;
-    forAllIter(Map<label>, regionLookup, iter)
+    forAllIter(Map<label>, lookup, iter)
     {
         label regId = iter.key();
 
-        word patchName;
-        Map<word>::const_iterator iter2 = patchNames.find(regId);
-        if (iter2 == patchNames.end())
+        word name;
+        Map<word>::const_iterator fnd = patchNames.find(regId);
+        if (fnd != patchNames.end())
         {
-            patchName = word("patch") + ::Foam::name(patchI);
+            name = fnd();
         }
         else
         {
-            patchName = iter2();
+            name = word("patch") + ::Foam::name(patchI);
         }
 
         patchLst[patchI] = surfGroup
         (
-            patchName,
+            name,
             0,           // initialize with zero size
-            patchStart,
+            start,
             patchI
         );
 
         // increment the start for the next patch
         // and save the (regionId => patchI) mapping
-        patchStart += iter();
+        start += iter();
         iter() = patchI++;
     }
 
@@ -242,7 +242,7 @@ Foam::fileFormats::surfaceFormatsCore::sortedPatchRegions
 
     forAll(regionLst, faceI)
     {
-        label patchI = regionLookup[regionLst[faceI]];
+        label patchI = lookup[regionLst[faceI]];
         faceMap[faceI] = patchLst[patchI].start() + patchLst[patchI].size()++;
     }
 
@@ -260,7 +260,6 @@ Foam::fileFormats::surfaceFormatsCore::checkSupport
     const word& functionName
 )
 {
-
     if (available.found(ext))
     {
         return true;
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
index 7c552a81c8840d189dc03faa17a00f602bbb7841..177ea175e0801231f2e70b33335daab3d8f18651 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.C
@@ -25,9 +25,7 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "TRIsurfaceFormat.H"
-#include "IFstream.H"
-#include "IOmanip.H"
-#include "IStringStream.H"
+#include "ListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -66,10 +64,10 @@ inline void Foam::fileFormats::TRIsurfaceFormat<Face>::writeShell
 template<class Face>
 Foam::fileFormats::TRIsurfaceFormat<Face>::TRIsurfaceFormat
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
-    read(fName);
+    read(filename);
 }
 
 
@@ -78,123 +76,78 @@ Foam::fileFormats::TRIsurfaceFormat<Face>::TRIsurfaceFormat
 template<class Face>
 bool Foam::fileFormats::TRIsurfaceFormat<Face>::read
 (
-    const fileName& fName
+    const fileName& filename
 )
 {
     this->clear();
 
-    IFstream is(fName);
-    if (!is.good())
-    {
-        FatalErrorIn
-        (
-            "fileFormats::TRIsurfaceFormat::read(const fileName&)"
-        )
-            << "Cannot read file " << fName
-            << exit(FatalError);
-    }
+    // read in the values
+    TRIsurfaceFormatCore reader(filename);
 
-    // uses similar structure as STL, just some points
-    DynamicList<point> pointLst;
-    DynamicList<label> regionLst;
-    HashTable<label>   groupToPatch;
+    // transfer points
+    this->storedPoints().transfer(reader.points());
 
-    // leave faces that didn't have a group in 0
-    label nUngrouped = 0;
-    label groupID = 0;
-    label maxGroupID = -1;
+    // retrieve the original region information
+    List<label> sizes(xferMove(reader.sizes()));
+    List<label> regions(xferMove(reader.regions()));
 
-    while (is.good())
+    // generate the (sorted) faces
+    List<Face> faceLst(regions.size());
+
+    if (reader.sorted())
     {
-        string line = this->getLineNoComment(is);
-
-        // handle continuations ?
-        //          if (line[line.size()-1] == '\\')
-        //          {
-        //              line.substr(0, line.size()-1);
-        //              line += this->getLineNoComment(is);
-        //          }
-
-        IStringStream lineStream(line);
-
-        point p
-        (
-            readScalar(lineStream),
-            readScalar(lineStream),
-            readScalar(lineStream)
-        );
-
-        if (!lineStream) break;
-
-        pointLst.append(p);
-        pointLst.append
-        (
-            point
-            (
-                readScalar(lineStream),
-                readScalar(lineStream),
-                readScalar(lineStream)
-            )
-        );
-        pointLst.append
-        (
-            point
-            (
-                readScalar(lineStream),
-                readScalar(lineStream),
-                readScalar(lineStream)
-            )
-        );
-
-        // Region/colour in .tri file starts with 0x. Skip.
-        // ie, instead of having 0xFF, skip 0 and leave xFF to
-        // get read as a word and name it "patchFF"
-
-        char zero;
-        lineStream >> zero;
-
-        word rawName(lineStream);
-        word groupName("patch" + rawName(1, rawName.size()-1));
-
-        HashTable<label>::const_iterator fnd = groupToPatch.find(groupName);
-
-        if (fnd != groupToPatch.end())
+        // already sorted - generate directly
+        forAll(faceLst, faceI)
         {
-            groupID = fnd();
+            const label startPt = 3*faceI;
+            faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
         }
-        else
+    }
+    else
+    {
+        // unsorted - determine the sorted order:
+        // avoid SortableList since we discard the main list anyhow
+        List<label> faceMap;
+        sortedOrder(regions, faceMap);
+
+        // generate sorted faces
+        forAll(faceMap, faceI)
         {
-            // special treatment if any initial faces were not in a group
-            if (maxGroupID == -1 && regionLst.size())
-            {
-                groupToPatch.insert("patch0", 0);
-                nUngrouped = regionLst.size();
-                maxGroupID = 0;
-            }
-            groupID = ++maxGroupID;
-            groupToPatch.insert(groupName, groupID);
+            const label startPt = 3*faceMap[faceI];
+            faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
         }
-
-        regionLst.append(groupID);
     }
+    regions.clear();
+
+    // transfer:
+    this->storedFaces().transfer(faceLst);
+
+    this->addPatches(sizes);
+    this->stitchFaces(SMALL);
+    return true;
+}
 
-    // make our triangles directly
-    List<Face>& faceLst = this->storedFaces();
-    faceLst.setSize(regionLst.size());
 
-    // transfer to normal list
-    this->storedPoints().transfer(pointLst);
-    this->storedRegions().transfer(regionLst);
+template<class Face>
+void Foam::fileFormats::TRIsurfaceFormat<Face>::write
+(
+    Ostream& os,
+    const MeshedSurface<Face>& surf
+)
+{
+    const pointField& pointLst = surf.points();
+    const List<Face>& faceLst  = surf.faces();
+    const List<surfGroup>& patchLst = surf.patches();
 
-    forAll(faceLst, faceI)
+    label faceIndex = 0;
+    forAll(patchLst, patchI)
     {
-        const label startPt = 3 * faceI;
-        faceLst[faceI] = triFace(startPt, startPt+1, startPt+2);
+        forAll(patchLst[patchI], patchFaceI)
+        {
+            const Face& f = faceLst[faceIndex++];
+            writeShell(os, pointLst, f, patchI);
+        }
     }
-
-    this->setPatches(groupToPatch);
-    this->stitchFaces(SMALL);
-    return true;
 }
 
 
@@ -241,27 +194,4 @@ void Foam::fileFormats::TRIsurfaceFormat<Face>::write
     }
 }
 
-
-template<class Face>
-void Foam::fileFormats::TRIsurfaceFormat<Face>::write
-(
-    Ostream& os,
-    const MeshedSurface<Face>& surf
-)
-{
-    const pointField& pointLst = surf.points();
-    const List<Face>& faceLst  = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
-
-    label faceIndex = 0;
-    forAll(patchLst, patchI)
-    {
-        forAll(patchLst[patchI], patchFaceI)
-        {
-            const Face& f = faceLst[faceIndex++];
-            writeShell(os, pointLst, f, patchI);
-        }
-    }
-}
-
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
index ac5e473bf309ccbbe7d7dad963a1d5e6a5100d57..d33f43ccf2c22b3a3ea9ff2d772b1bcc7abe6245 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormat.H
@@ -28,6 +28,10 @@ Class
 Description
     Provide a means of reading/writing .tri format.
 
+Note
+    For efficiency, the regions are sorted before creating the faces.
+    The class is thus derived from MeshedSurface.
+
 SourceFiles
     TRIsurfaceFormat.C
 
@@ -36,6 +40,7 @@ SourceFiles
 #ifndef TRIsurfaceFormat_H
 #define TRIsurfaceFormat_H
 
+#include "TRIsurfaceFormatCore.H"
 #include "Ostream.H"
 #include "OFstream.H"
 #include "MeshedSurface.H"
@@ -49,13 +54,13 @@ namespace fileFormats
 {
 
 /*---------------------------------------------------------------------------*\
-                       Class TRIsurfaceFormat Declaration
+                     Class TRIsurfaceFormat Declaration
 \*---------------------------------------------------------------------------*/
 
 template<class Face>
 class TRIsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>
+    public MeshedSurface<Face>
 {
     // Private Member Functions
 
@@ -83,14 +88,11 @@ public:
     // Selectors
 
         //- Read file and return surface
-        static autoPtr<UnsortedMeshedSurface<Face> > New
-        (
-            const fileName& fName
-        )
+        static autoPtr<MeshedSurface<Face> > New(const fileName& name)
         {
-            return autoPtr<UnsortedMeshedSurface<Face> >
+            return autoPtr<MeshedSurface<Face> >
             (
-                new TRIsurfaceFormat<Face>(fName)
+                new TRIsurfaceFormat<Face>(name)
             );
         }
 
@@ -113,11 +115,11 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
@@ -132,15 +134,14 @@ public:
         //  By default, the output is not sorted by regions
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
-        //  By default, the output is not sorted by regions
         virtual void write(Ostream& os) const
         {
             write(os, *this);
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
new file mode 100644
index 0000000000000000000000000000000000000000..c1114dff6755577b7b74f6f90ba1403c0bf78967
--- /dev/null
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.C
@@ -0,0 +1,189 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+\*---------------------------------------------------------------------------*/
+
+#include "TRIsurfaceFormat.H"
+#include "IFstream.H"
+#include "IOmanip.H"
+#include "IStringStream.H"
+#include "Map.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::fileFormats::TRIsurfaceFormatCore::TRIsurfaceFormatCore
+(
+    const fileName& filename
+)
+:
+    sorted_(true),
+    points_(0),
+    regions_(0),
+    sizes_(0)
+{
+    read(filename);
+}
+
+// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
+
+Foam::fileFormats::TRIsurfaceFormatCore::~TRIsurfaceFormatCore()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::fileFormats::TRIsurfaceFormatCore::read
+(
+    const fileName& filename
+)
+{
+    this->clear();
+    sorted_ = true;
+
+    IFstream is(filename);
+    if (!is.good())
+    {
+        FatalErrorIn
+        (
+            "fileFormats::TRIsurfaceFormatCore::read(const fileName&)"
+        )
+            << "Cannot read file " << filename
+            << exit(FatalError);
+    }
+
+    // uses similar structure as STL, just some points
+    // the rest of the reader resembles the STL binary reader
+    DynamicList<point> dynPoints;
+    DynamicList<label> dynRegions;
+    DynamicList<label> dynSizes;
+    HashTable<label>   lookup;
+
+    // place faces without a group in patch0
+    label regionI = 0;
+    dynSizes.append(regionI);
+    lookup.insert("patch0", regionI);
+
+    while (is.good())
+    {
+        string line = this->getLineNoComment(is);
+
+        // handle continuations ?
+        //          if (line[line.size()-1] == '\\')
+        //          {
+        //              line.substr(0, line.size()-1);
+        //              line += this->getLineNoComment(is);
+        //          }
+
+        IStringStream lineStream(line);
+
+        point p
+        (
+            readScalar(lineStream),
+            readScalar(lineStream),
+            readScalar(lineStream)
+        );
+
+        if (!lineStream) break;
+
+        dynPoints.append(p);
+        dynPoints.append
+        (
+            point
+            (
+                readScalar(lineStream),
+                readScalar(lineStream),
+                readScalar(lineStream)
+            )
+        );
+        dynPoints.append
+        (
+            point
+            (
+                readScalar(lineStream),
+                readScalar(lineStream),
+                readScalar(lineStream)
+            )
+        );
+
+        // Region/colour in .tri file starts with 0x. Skip.
+        // ie, instead of having 0xFF, skip 0 and leave xFF to
+        // get read as a word and name it "patchFF"
+
+        char zero;
+        lineStream >> zero;
+
+        word rawName(lineStream);
+        word name("patch" + rawName(1, rawName.size()-1));
+
+        HashTable<label>::const_iterator fnd = lookup.find(name);
+        if (fnd != lookup.end())
+        {
+            if (regionI != fnd())
+            {
+                // group appeared out of order
+                sorted_ = false;
+            }
+            regionI = fnd();
+        }
+        else
+        {
+            regionI = dynSizes.size();
+            lookup.insert(name, regionI);
+            dynSizes.append(0);
+        }
+
+        dynRegions.append(regionI);
+        dynSizes[regionI]++;
+    }
+
+    // skip empty groups
+    label nPatch = 0;
+    forAll(dynSizes, patchI)
+    {
+        if (dynSizes[patchI])
+        {
+            if (nPatch != patchI)
+            {
+                dynSizes[nPatch] = dynSizes[patchI];
+            }
+            nPatch++;
+        }
+    }
+    // truncate addressed size
+    dynSizes.setSize(nPatch);
+
+    // transfer to normal lists
+    points_.transfer(dynPoints);
+    regions_.transfer(dynRegions);
+    sizes_.transfer(dynSizes);
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
new file mode 100644
index 0000000000000000000000000000000000000000..3b9b1d907a986b503750d187e1681e1a830c2dc8
--- /dev/null
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatCore.H
@@ -0,0 +1,143 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2008 OpenCFD Ltd.
+     \\/     M anipulation  |
+-------------------------------------------------------------------------------
+License
+    This file is part of OpenFOAM.
+
+    OpenFOAM is free software; you can redistribute it and/or modify it
+    under the terms of the GNU General Public License as published by the
+    Free Software Foundation; either version 2 of the License, or (at your
+    option) any later version.
+
+    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
+    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+    for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with OpenFOAM; if not, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Class
+    Foam::fileFormats::TRIsurfaceFormatCore
+
+Description
+    Internal class used by the TRIsurfaceFormat
+
+SourceFiles
+    TRIsurfaceFormatCore.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef TRIsurfaceFormatCore_H
+#define TRIsurfaceFormatCore_H
+
+#include "surfaceFormatsCore.H"
+#include "triFace.H"
+#include "IFstream.H"
+#include "Ostream.H"
+#include "OFstream.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace fileFormats
+{
+
+/*---------------------------------------------------------------------------*\
+                   Class TRIsurfaceFormatCore Declaration
+\*---------------------------------------------------------------------------*/
+
+class TRIsurfaceFormatCore
+:
+    public surfaceFormatsCore
+{
+    // Private Data
+
+        bool sorted_;
+
+        //- The points supporting the facets
+        pointField points_;
+
+        //- The regions associated with the faces
+        List<label> regions_;
+
+        //- The solid count, in the order of their first appearance
+        List<label> sizes_;
+
+    // Private Member Functions
+
+        //- Disallow default bitwise copy construct
+        TRIsurfaceFormatCore(const TRIsurfaceFormatCore&);
+
+        //- Disallow default bitwise assignment
+        void operator=(const TRIsurfaceFormatCore&);
+
+        bool read(const fileName&);
+
+public:
+
+    // Constructors
+
+        //- Read from file, filling in the information
+        TRIsurfaceFormatCore(const fileName&);
+
+    // Destructor
+
+        ~TRIsurfaceFormatCore();
+
+    // Member Functions
+
+        //- File read was already sorted
+        bool sorted() const
+        {
+            return sorted_;
+        }
+
+        //- Flush all values
+        void clear()
+        {
+            sorted_ = true;
+            points_.clear();
+            regions_.clear();
+            sizes_.clear();
+        }
+
+        //- Return full access to the points
+        pointField& points()
+        {
+            return points_;
+        }
+
+        //- Return full access to the regions
+        List<label>& regions()
+        {
+            return regions_;
+        }
+
+        //- The list of region sizes in the order of their first appearance
+        List<label>& sizes()
+        {
+            return sizes_;
+        }
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace fileFormats
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C
index 43e0cdf4925393eae8f8a856209d45692dafcc0c..488a3efb249b8661dffa487acc14bb9088f77bd8 100644
--- a/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C
+++ b/src/surfMesh/surfaceFormats/tri/TRIsurfaceFormatRunTime.C
@@ -38,7 +38,7 @@ namespace fileFormats
 
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     TRIsurfaceFormat,
     face,
     fileExtension,
@@ -46,7 +46,7 @@ addNamedTemplatedToRunTimeSelectionTable
 );
 addNamedTemplatedToRunTimeSelectionTable
 (
-    UnsortedMeshedSurface,
+    MeshedSurface,
     TRIsurfaceFormat,
     triFace,
     fileExtension,
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
index df65cc799a4d770474fe66687b8e3e9eb8f0849a..adc083c18870b3b8d13f421bc7e53ed2026e5df4 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.C
@@ -62,53 +62,21 @@ template<class Face>
 void Foam::fileFormats::VTKsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const UnsortedMeshedSurface<Face>& surf
+    const MeshedSurface<Face>& surf
 )
 {
     const List<Face>& faceLst = surf.faces();
+    const List<surfGroup>& patchLst = surf.patches();
 
     writeHeader(os, surf.points());
     writeHeaderPolygons(os, faceLst);
 
-    bool doSort = false;
-    // a single region needs no sorting
-    if (surf.patches().size() == 1)
-    {
-        doSort = false;
-    }
-
-    if (doSort)
-    {
-        labelList faceMap;
-        List<surfGroup> patchLst = surf.sortedRegions(faceMap);
-
-        label faceIndex = 0;
-        forAll(patchLst, patchI)
-        {
-            forAll(patchLst[patchI], patchFaceI)
-            {
-                const Face& f = faceLst[faceMap[faceIndex++]];
-
-                os << f.size();
-                forAll(f, fp)
-                {
-                    os << ' ' << f[fp];
-                }
-                os << ' ' << nl;
-            }
-        }
-
-        // Print region numbers
-        writeTail(os, patchLst);
-    }
-    else
+    label faceIndex = 0;
+    forAll(patchLst, patchI)
     {
-        labelList faceMap;
-        List<surfGroup> patchLst = surf.sortedRegions(faceMap);
-
-        forAll(faceLst, faceI)
+        forAll(patchLst[patchI], patchFaceI)
         {
-            const Face& f = faceLst[faceI];
+            const Face& f = faceLst[faceIndex++];
 
             os << f.size();
             forAll(f, fp)
@@ -117,10 +85,10 @@ void Foam::fileFormats::VTKsurfaceFormat<Face>::write
             }
             os << ' ' << nl;
         }
-
-        // Print region numbers
-        writeTail(os, surf.regions());
     }
+
+    // Print region numbers
+    writeTail(os, patchLst);
 }
 
 
@@ -128,33 +96,29 @@ template<class Face>
 void Foam::fileFormats::VTKsurfaceFormat<Face>::write
 (
     Ostream& os,
-    const MeshedSurface<Face>& surf
+    const UnsortedMeshedSurface<Face>& surf
 )
 {
     const List<Face>& faceLst = surf.faces();
-    const List<surfGroup>& patchLst = surf.patches();
 
     writeHeader(os, surf.points());
     writeHeaderPolygons(os, faceLst);
 
-    label faceIndex = 0;
-    forAll(patchLst, patchI)
+    forAll(faceLst, faceI)
     {
-        forAll(patchLst[patchI], patchFaceI)
-        {
-            const Face& f = faceLst[faceIndex++];
+        const Face& f = faceLst[faceI];
 
-            os << f.size();
-            forAll(f, fp)
-            {
-                os << ' ' << f[fp];
-            }
-            os << ' ' << nl;
+        os << f.size();
+        forAll(f, fp)
+        {
+            os << ' ' << f[fp];
         }
+        os << ' ' << nl;
     }
 
     // Print region numbers
-    writeTail(os, patchLst);
+    writeTail(os, surf.regions());
 }
 
+
 // ************************************************************************* //
diff --git a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
index f1f5bf8224c58d72b26c8624beaf561f143170be..c6ec82b24eaab27c15d72d1386df193cb8774691 100644
--- a/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
+++ b/src/surfMesh/surfaceFormats/vtk/VTKsurfaceFormat.H
@@ -27,6 +27,7 @@ Class
 
 Description
     Provide a means of writing VTK legacy format.
+    The output is never sorted by patch.
 
 SourceFiles
     VTKsurfaceFormat.C
@@ -56,7 +57,7 @@ namespace fileFormats
 template<class Face>
 class VTKsurfaceFormat
 :
-    public UnsortedMeshedSurface<Face>,
+    public MeshedSurface<Face>,
     public VTKsurfaceFormatCore
 {
     // Private Member Functions
@@ -98,15 +99,15 @@ public:
         //- Write MeshedSurface
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const MeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write UnsortedMeshedSurface
-        //  By default, the output is not sorted by regions.
+        //  The output remains unsorted
         static void write
         (
             Ostream&,
@@ -114,14 +115,14 @@ public:
         );
 
         //- Write UnsortedMeshedSurface
-        //  By default, the output is not sorted by regions.
+        //  The output remains unsorted
         static void write
         (
-            const fileName& fName,
+            const fileName& name,
             const UnsortedMeshedSurface<Face>& surf
         )
         {
-            write(OFstream(fName)(), surf);
+            write(OFstream(name)(), surf);
         }
 
         //- Write object
diff --git a/src/triSurface/triSurface/triSurface.C b/src/triSurface/triSurface/triSurface.C
index 64adb1bc74e90883e2085fb9eb483aaff3884787..833fcfde27986d03531d90f1609cb0d176048926 100644
--- a/src/triSurface/triSurface/triSurface.C
+++ b/src/triSurface/triSurface/triSurface.C
@@ -1213,11 +1213,7 @@ void Foam::triSurface::writeStats(Ostream& os) const
     pointIsUsed = 0U;
 
     label nPoints = 0;
-    boundBox bb
-    (
-        point(VGREAT, VGREAT, VGREAT),
-        point(-VGREAT, -VGREAT, -VGREAT)
-    );
+    boundBox bb = boundBox::invertedBox;
 
     forAll(*this, triI)
     {
diff --git a/src/turbulenceModels/LES/LESfilters/laplaceFilter/laplaceFilter.C b/src/turbulenceModels/LES/LESfilters/laplaceFilter/laplaceFilter.C
index efcb639170eebf7593900278587fe935c721de6c..d7fcc910aef5fc6e636bed6eb05b9c455ae23ba7 100644
--- a/src/turbulenceModels/LES/LESfilters/laplaceFilter/laplaceFilter.C
+++ b/src/turbulenceModels/LES/LESfilters/laplaceFilter/laplaceFilter.C
@@ -49,7 +49,7 @@ Foam::laplaceFilter::laplaceFilter(const fvMesh& mesh, scalar widthCoeff)
     (
         IOobject
         (
-            "anisotropicFilterCoeff",
+            "laplaceFilterCoeff",
             mesh.time().timeName(),
             mesh
         ),
@@ -70,7 +70,7 @@ Foam::laplaceFilter::laplaceFilter(const fvMesh& mesh, const dictionary& bd)
     (
         IOobject
         (
-            "anisotropicFilterCoeff",
+            "laplaceFilterCoeff",
             mesh.time().timeName(),
             mesh
         ),
diff --git a/src/turbulenceModels/compressible/LES/LESModel/LESModel.C b/src/turbulenceModels/compressible/LES/LESModel/LESModel.C
index 01d3a4110ca901bad2a7368bf38eaf26660146ef..95c282e822de14df7432fdc9d6409b8f69d1bf7c 100644
--- a/src/turbulenceModels/compressible/LES/LESModel/LESModel.C
+++ b/src/turbulenceModels/compressible/LES/LESModel/LESModel.C
@@ -38,6 +38,7 @@ namespace compressible
 
 defineTypeNameAndDebug(LESModel, 0);
 defineRunTimeSelectionTable(LESModel, dictionary);
+addToRunTimeSelectionTable(turbulenceModel, LESModel, turbulenceModel);
 
 // * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //
 
diff --git a/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C b/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C
index 22b646e55e2241cdc47b3264be9735efe9477199..ba1545d4eab2cc4615f9c7a1e56f080254a06bec 100644
--- a/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C
+++ b/src/turbulenceModels/compressible/RAS/RASModel/RASModel.C
@@ -39,6 +39,7 @@ namespace compressible
 
 defineTypeNameAndDebug(RASModel, 0);
 defineRunTimeSelectionTable(RASModel, dictionary);
+addToRunTimeSelectionTable(turbulenceModel, RASModel, turbulenceModel);
 
 // * * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * //