diff --git a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
index 7b998241d65bb686f7e2f22cfc751aca95b86587..ed0e635787ad1906f4c0c230423caf2943fd8008 100644
--- a/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
+++ b/applications/utilities/mesh/generation/snappyHexMesh/snappyHexMesh.C
@@ -901,33 +901,42 @@ int main(int argc, char *argv[])
 
     // Read decomposePar dictionary
     dictionary decomposeDict;
+    if (Pstream::parRun())
     {
-        if (Pstream::parRun())
-        {
-            fileName decompDictFile;
-            args.optionReadIfPresent("decomposeParDict", decompDictFile);
+        fileName decompDictFile;
+        args.optionReadIfPresent("decomposeParDict", decompDictFile);
+
+        // A demand-driven decompositionMethod can have issues finding
+        // an alternative decomposeParDict location.
 
-            decomposeDict = IOdictionary
+        IOdictionary* dictPtr = new IOdictionary
+        (
+            decompositionModel::selectIO
             (
-                decompositionModel::selectIO
+                IOobject
                 (
-                    IOobject
-                    (
-                        "decomposeParDict",
-                        runTime.system(),
-                        mesh,
-                        IOobject::MUST_READ_IF_MODIFIED,
-                        IOobject::NO_WRITE
-                    ),
-                    decompDictFile
-                )
-            );
-        }
-        else
-        {
-            decomposeDict.add("method", "none");
-            decomposeDict.add("numberOfSubdomains", 1);
-        }
+                    "decomposeParDict",
+                    runTime.system(),
+                    runTime,
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE
+                ),
+                decompDictFile
+            )
+        );
+
+        // Store it on the object registry, but to be found it must also
+        // have the expected "decomposeParDict" name.
+
+        dictPtr->rename("decomposeParDict");
+        runTime.store(dictPtr);
+
+        decomposeDict = *dictPtr;
+    }
+    else
+    {
+        decomposeDict.add("method", "none");
+        decomposeDict.add("numberOfSubdomains", 1);
     }
 
 
diff --git a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
index ab692d470605646adab53f672af4c8233106eecb..71013769a13b163f1fdcdf92d78ce4ceaa412193 100644
--- a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
+++ b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBaffles.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
-     \\/     M anipulation  |
+     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,15 +28,31 @@ Group
     grpMeshManipulationUtilities
 
 Description
-    Detects faces that share points (baffles). Either merge them or
+    Detects boundary faces that share points (baffles). Either merges them or
     duplicate the points.
 
-    Notes:
+Usage
+    \b mergeOrSplitBaffles [OPTION]
+
+    Options:
+      - \par -detect
+        Detect baffles and write to faceSet duplicateFaces.
+
+      - \par -merge
+        Detect baffles and convert to internal faces.
+
+      - \par -split
+        Detect baffles and duplicate the points (used so the two sides
+        can move independently)
+
+      - \par -dict \<dictionary\>
+        Specify a dictionary to read actions from.
+
+
+Note
     - can only handle pairwise boundary faces. So three faces using
       the same points is not handled (is illegal mesh anyway)
 
-    - there is no option to only split/merge some baffles.
-
     - surfaces consisting of duplicate faces can be topologically split
     if the points on the interior of the surface cannot walk to all the
     cells that use them in one go.
@@ -71,6 +87,7 @@ using namespace Foam;
 void insertDuplicateMerge
 (
     const polyMesh& mesh,
+    const labelList& boundaryFaces,
     const labelList& duplicates,
     polyTopoChange& meshMod
 )
@@ -87,8 +104,8 @@ void insertDuplicateMerge
         {
             // Two duplicate faces. Merge.
 
-            label face0 = mesh.nInternalFaces() + bFacei;
-            label face1 = mesh.nInternalFaces() + otherFacei;
+            label face0 = boundaryFaces[bFacei];
+            label face1 = boundaryFaces[otherFacei];
 
             label own0 = faceOwner[face0];
             label own1 = faceOwner[face1];
@@ -156,6 +173,45 @@ void insertDuplicateMerge
 }
 
 
+label patchSize(const polyMesh& mesh, const labelList& patchIDs)
+{
+    const polyBoundaryMesh& patches = mesh.boundaryMesh();
+   
+    label sz = 0;
+    forAll(patchIDs, i)
+    {
+        const polyPatch& pp = patches[patchIDs[i]];
+        sz += pp.size();
+    }
+    return sz;
+}
+
+
+labelList patchFaces(const polyMesh& mesh, const labelList& patchIDs)
+{
+    const polyBoundaryMesh& patches = mesh.boundaryMesh();
+   
+    labelList faceIDs(patchSize(mesh, patchIDs));
+    label sz = 0;
+    forAll(patchIDs, i)
+    {
+        const polyPatch& pp = patches[patchIDs[i]];
+
+        forAll(pp, ppi)
+        {
+            faceIDs[sz++] = pp.start()+ppi;
+        }
+    }
+
+if (faceIDs.size() != sz)
+{
+    FatalErrorInFunction << exit(FatalError);
+}
+
+    return faceIDs;
+}
+
+
 labelList findBaffles(const polyMesh& mesh, const labelList& boundaryFaces)
 {
     // Get all duplicate face labels (in boundaryFaces indices!).
@@ -173,7 +229,7 @@ labelList findBaffles(const polyMesh& mesh, const labelList& boundaryFaces)
     {
         if (duplicates[bFacei] != -1)
         {
-            label facei = mesh.nInternalFaces() + bFacei;
+            label facei = boundaryFaces[bFacei];
             label patchi = patches.whichPatch(facei);
 
             if (isA<processorPolyPatch>(patches[patchi]))
@@ -205,12 +261,12 @@ labelList findBaffles(const polyMesh& mesh, const labelList& boundaryFaces)
 
             if (otherFacei != -1 && otherFacei > bFacei)
             {
-                duplicateSet.insert(mesh.nInternalFaces() + bFacei);
-                duplicateSet.insert(mesh.nInternalFaces() + otherFacei);
+                duplicateSet.insert(boundaryFaces[bFacei]);
+                duplicateSet.insert(boundaryFaces[otherFacei]);
             }
         }
 
-        Pout<< "Writing " << duplicateSet.size()
+        Info<< "Writing " << returnReduce(duplicateSet.size(), sumOp<label>())
             << " duplicate faces to faceSet " << duplicateSet.objectPath()
             << nl << endl;
         duplicateSet.write();
@@ -220,8 +276,6 @@ labelList findBaffles(const polyMesh& mesh, const labelList& boundaryFaces)
 }
 
 
-
-
 int main(int argc, char *argv[])
 {
     argList::addNote
@@ -232,6 +286,7 @@ int main(int argc, char *argv[])
 
     #include "addOverwriteOption.H"
     #include "addRegionOption.H"
+    #include "addDictOption.H"
     argList::addBoolOption
     (
         "detectOnly",
@@ -249,27 +304,91 @@ int main(int argc, char *argv[])
     #include "createNamedMesh.H"
 
     const word oldInstance = mesh.pointsInstance();
+    const polyBoundaryMesh& patches = mesh.boundaryMesh();
 
+    const bool readDict   = args.optionFound("dict");
     const bool split      = args.optionFound("split");
     const bool overwrite  = args.optionFound("overwrite");
     const bool detectOnly = args.optionFound("detectOnly");
 
-    // Collect all boundary faces
-    labelList boundaryFaces(mesh.nFaces() - mesh.nInternalFaces());
+    if (readDict && (split || detectOnly))
+    {
+        FatalErrorInFunction
+            << "Use of dictionary for settings not compatible with"
+            << " using command line arguments for \"split\""
+            << " or \"detectOnly\"" << exit(FatalError);
+    }
+
+
+    labelList detectPatchIDs;
+    labelList splitPatchIDs;
+    labelList mergePatchIDs;
 
-    forAll(boundaryFaces, i)
+    if (readDict)
     {
-        boundaryFaces[i] = i+mesh.nInternalFaces();
+        const word dictName;
+        #include "setSystemMeshDictionaryIO.H"
+
+        Info<< "Reading " << dictName << "\n" << endl;
+        IOdictionary dict(dictIO);
+
+        if (dict.found("detect"))
+        {
+            wordReList patchNames(dict.subDict("detect").lookup("patches"));
+            detectPatchIDs = patches.patchSet(patchNames).sortedToc();
+            Info<< "Detecting baffles on " << detectPatchIDs.size()
+                << " patches with "
+                << returnReduce(patchSize(mesh, detectPatchIDs), sumOp<label>())
+                << " faces" << endl;
+        }
+        if (dict.found("merge"))
+        {
+            wordReList patchNames(dict.subDict("merge").lookup("patches"));
+            mergePatchIDs = patches.patchSet(patchNames).sortedToc();
+            Info<< "Detecting baffles on " << mergePatchIDs.size()
+                << " patches with "
+                << returnReduce(patchSize(mesh, mergePatchIDs), sumOp<label>())
+                << " faces" << endl;
+        }
+        if (dict.found("split"))
+        {
+            wordReList patchNames(dict.subDict("split").lookup("patches"));
+            splitPatchIDs = patches.patchSet(patchNames).sortedToc();
+            Info<< "Detecting baffles on " << splitPatchIDs.size()
+                << " patches with "
+                << returnReduce(patchSize(mesh, splitPatchIDs), sumOp<label>())
+                << " faces" << endl;
+        }
+    }
+    else
+    {
+        if (detectOnly)
+        {
+            detectPatchIDs = identity(patches.size());
+        }
+        else if (split)
+        {
+            splitPatchIDs = identity(patches.size());
+        }
+        else
+        {
+            mergePatchIDs = identity(patches.size());
+        }
     }
 
 
-    if (detectOnly)
+    if (detectPatchIDs.size())
     {
-        findBaffles(mesh, boundaryFaces);
-        return 0;
+        findBaffles(mesh, patchFaces(mesh, detectPatchIDs));
+
+        if (detectOnly)
+        {
+            return 0;
+        }
     }
 
 
+
     // Read objects in time directory
     IOobjectList objects(mesh, runTime.timeName());
 
@@ -308,64 +427,118 @@ int main(int argc, char *argv[])
     ReadFields(mesh, objects, stFlds);
 
 
-    // Mesh change engine
-    polyTopoChange meshMod(mesh);
 
+    if (mergePatchIDs.size())
+    {
+        Info<< "Merging duplicate faces" << nl << endl;
+
+        // Mesh change engine
+        polyTopoChange meshMod(mesh);
+
+        const labelList boundaryFaces(patchFaces(mesh, mergePatchIDs));
+
+        // Get all duplicate face pairs (in boundaryFaces indices!).
+        labelList duplicates(findBaffles(mesh, boundaryFaces));
+
+        // Merge into internal faces.
+        insertDuplicateMerge(mesh, boundaryFaces, duplicates, meshMod);
+
+        if (!overwrite)
+        {
+            runTime++;
+        }
 
-    if (split)
+        // Change the mesh. No inflation.
+        autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
+
+        // Update fields
+        mesh.updateMesh(map);
+
+        // Move mesh (since morphing does not do this)
+        if (map().hasMotionPoints())
+        {
+            mesh.movePoints(map().preMotionPoints());
+        }
+
+        if (overwrite)
+        {
+            mesh.setInstance(oldInstance);
+        }
+        Info<< "Writing mesh to time " << runTime.timeName() << endl;
+        mesh.write();
+    }
+
+
+    if (splitPatchIDs.size())
     {
-        Pout<< "Topologically splitting duplicate surfaces"
-            << ", i.e. duplicating points internal to duplicate surfaces."
+        Info<< "Topologically splitting duplicate surfaces"
+            << ", i.e. duplicating points internal to duplicate surfaces"
             << nl << endl;
 
+        // Determine points on split patches
+        DynamicList<label> candidates;
+        {
+            label sz = 0;
+            forAll(splitPatchIDs, i)
+            {
+                sz += patches[splitPatchIDs[i]].nPoints();
+            }
+            candidates.setCapacity(sz);
+
+            PackedBoolList isCandidate(mesh.nPoints());
+            forAll(splitPatchIDs, i)
+            {
+                const labelList& mp = patches[splitPatchIDs[i]].meshPoints();
+                forAll(mp, mpi)
+                {
+                    label pointi = mp[mpi];
+                    if (isCandidate.set(pointi))
+                    {
+                        candidates.append(pointi);
+                    }
+                }
+            }
+        }
+
+
         // Analyse which points need to be duplicated
-        localPointRegion regionSide(mesh);
+        localPointRegion regionSide(mesh, candidates);
 
         // Point duplication engine
         duplicatePoints pointDuplicator(mesh);
 
+        // Mesh change engine
+        polyTopoChange meshMod(mesh);
+
         // Insert topo changes
         pointDuplicator.setRefinement(regionSide, meshMod);
-    }
-    else
-    {
-        Pout<< "Merging duplicate faces."
-            << nl << endl;
 
-        // Get all duplicate face labels (in boundaryFaces indices!).
-        labelList duplicates(findBaffles(mesh, boundaryFaces));
-
-        // Merge into internal faces.
-        insertDuplicateMerge(mesh, duplicates, meshMod);
-    }
+        if (!overwrite)
+        {
+            runTime++;
+        }
 
-    if (!overwrite)
-    {
-        runTime++;
-    }
+        // Change the mesh. No inflation.
+        autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
 
-    // Change the mesh. No inflation.
-    autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
+        // Update fields
+        mesh.updateMesh(map);
 
-    // Update fields
-    mesh.updateMesh(map);
+        // Move mesh (since morphing does not do this)
+        if (map().hasMotionPoints())
+        {
+            mesh.movePoints(map().preMotionPoints());
+        }
 
-    // Move mesh (since morphing does not do this)
-    if (map().hasMotionPoints())
-    {
-        mesh.movePoints(map().preMotionPoints());
-    }
+        if (overwrite)
+        {
+            mesh.setInstance(oldInstance);
+        }
+        Info<< "Writing mesh to time " << runTime.timeName() << endl;
+        mesh.write();
 
-    if (overwrite)
-    {
-        mesh.setInstance(oldInstance);
-    }
-    Pout<< "Writing mesh to time " << runTime.timeName() << endl;
-    mesh.write();
 
-    // Dump duplicated points (if any)
-    if (split)
-    {
+        // Dump duplicated points (if any)
         const labelList& pointMap = map().pointMap();
 
         labelList nDupPerPoint(map().nOldPoints(), 0);
@@ -385,7 +558,7 @@ int main(int argc, char *argv[])
             }
         }
 
-        Pout<< "Writing " << dupPoints.size()
+        Info<< "Writing " << returnReduce(dupPoints.size(), sumOp<label>())
             << " duplicated points to pointSet "
             << dupPoints.objectPath() << nl << endl;
 
diff --git a/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBafflesDict b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBafflesDict
new file mode 100644
index 0000000000000000000000000000000000000000..b7ade863524616d6125e53220f3ce363039be15e
--- /dev/null
+++ b/applications/utilities/mesh/manipulation/mergeOrSplitBaffles/mergeOrSplitBafflesDict
@@ -0,0 +1,39 @@
+/*--------------------------------*- C++ -*----------------------------------*\
+| =========                 |                                                 |
+| \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
+|  \\    /   O peration     | Version:  plus                                  |
+|   \\  /    A nd           | Web:      www.OpenFOAM.com                      |
+|    \\/     M anipulation  |                                                 |
+\*---------------------------------------------------------------------------*/
+FoamFile
+{
+    version     2.0;
+    format      ascii;
+    class       dictionary;
+    object      mergeOrSplitBafflesDict;
+}
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Detect baffles (boundary faces sharing points) on selected set of patches
+// and write to a faceSet.
+detect
+{
+    patches (".*Wall");
+}
+
+// Detect baffles (on selected patches) and merge these into internal faces.
+merge
+{
+    patches ("mergePatch");
+}
+
+// Detect baffles (on selected patches) and duplicate the points. This is
+// used if e.g. the two sides need to move separately. Note that since the
+// points are duplicated the two faces are no longer baffles.
+split
+{
+    patches ("split.*Patches");
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
index 4eea56f1c0fa6290bfeffe8adbee281307b3353a..48cfbac21f09cf45ae823b0ecf214e9a80fc93ee 100644
--- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
+++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C
@@ -347,7 +347,7 @@ int main(int argc, char *argv[])
                         runTime.time().system(),
                         regionDir,          // use region if non-standard
                         runTime,
-                        IOobject::MUST_READ_IF_MODIFIED,
+                        IOobject::MUST_READ,
                         IOobject::NO_WRITE,
                         false
                     ),
diff --git a/applications/utilities/preProcessing/mapFields/mapFields.C b/applications/utilities/preProcessing/mapFields/mapFields.C
index 35d4faccc6072e7ccd93e5ae55ec8f59a2587ebc..8e9f95352237af642e43b1985b8601652f4e2fb9 100644
--- a/applications/utilities/preProcessing/mapFields/mapFields.C
+++ b/applications/utilities/preProcessing/mapFields/mapFields.C
@@ -69,7 +69,7 @@ int readNumProcs
                     dictName,
                     runTime.system(),
                     runTime,
-                    IOobject::MUST_READ_IF_MODIFIED,
+                    IOobject::MUST_READ,
                     IOobject::NO_WRITE,
                     false
                 ),
diff --git a/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C b/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C
index d478f8ab4071577eec16612442e90937e956eca9..219a4552090ae138d363cffc6d64b4faeca9e336 100644
--- a/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C
+++ b/applications/utilities/surface/surfaceRedistributePar/surfaceRedistributePar.C
@@ -161,7 +161,10 @@ int main(int argc, char *argv[])
         fileName decompDictFile;
         args.optionReadIfPresent("decomposeParDict", decompDictFile);
 
-        IOdictionary* dict = new IOdictionary
+        // A demand-driven decompositionMethod can have issues finding
+        // an alternative decomposeParDict location.
+
+        IOdictionary* dictPtr = new IOdictionary
         (
             decompositionModel::selectIO
             (
@@ -170,18 +173,18 @@ int main(int argc, char *argv[])
                     "decomposeParDict",
                     runTime.system(),
                     runTime,
-                    IOobject::MUST_READ_IF_MODIFIED,
+                    IOobject::MUST_READ,
                     IOobject::NO_WRITE
                 ),
                 decompDictFile
             )
         );
 
-        // The object must have the expected "decomposeParDict" name.
-        // This also implies that it cannot be changed during the run.
-        dict->rename("decomposeParDict");
+        // Store it on the object registry, but to be found it must also
+        // have the expected "decomposeParDict" name.
 
-        runTime.store(dict);
+        dictPtr->rename("decomposeParDict");
+        runTime.store(dictPtr);
     }
 
     // Determine mesh bounding boxes:
diff --git a/bin/tools/RunFunctions b/bin/tools/RunFunctions
index f99ab370b509b491ab5e957b153386c1e481ceb4..c3c6be894831806843952b5562a15d0feb0b0326 100755
--- a/bin/tools/RunFunctions
+++ b/bin/tools/RunFunctions
@@ -56,15 +56,17 @@ isTest()
 #
 getNumberOfProcessors()
 {
+    local dict="${1:-system/decomposeParDict}"
+
     # Re-use positional parameters for automatic whitespace elimination
-    set -- $(foamDictionary -entry numberOfSubdomains -value "${1:-system/decomposeParDict}")
+    set -- $(foamDictionary -entry numberOfSubdomains -value "$dict" 2>/dev/null)
 
     if [ "$#" -eq 1 ]
     then
         echo "$1"
     else
-        echo "Error retrieving 'numberOfSubdomains' from decomposeParDict" 1>&2
-        echo 1
+        echo "Warning no 'numberOfSubdomains' in '$dict'" 1>&2
+        echo 1 # serial as fallback
         return 1
     fi
 }
diff --git a/etc/config.csh/CGAL b/etc/config.csh/CGAL
index 84bc71bda6099e176d517c47763a95398a6d51d4..0caa0c51d7099635dee75c5a4b7731e4d9112096 100644
--- a/etc/config.csh/CGAL
+++ b/etc/config.csh/CGAL
@@ -50,8 +50,8 @@
 #
 #------------------------------------------------------------------------------
 
-set boost_version=boost_1_61_0
-set cgal_version=CGAL-4.8
+set boost_version=boost_1_62_0
+set cgal_version=CGAL-4.9
 
 setenv BOOST_ARCH_PATH $WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$boost_version
 setenv CGAL_ARCH_PATH $WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$cgal_version
diff --git a/etc/config.csh/FFTW b/etc/config.csh/FFTW
index 78d24e17b10babd88ffaa80f18a058c0dd157a8a..515c429e66c7e619ce90142892ddde2d17bf8052 100644
--- a/etc/config.csh/FFTW
+++ b/etc/config.csh/FFTW
@@ -22,7 +22,7 @@
 #     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
 #
 # File
-#     etc/config.sh/FFTW
+#     etc/config.csh/FFTW
 #
 # Description
 #     Setup file for FFTW include/libraries.
@@ -48,7 +48,7 @@
 #
 #------------------------------------------------------------------------------
 
-set fftw_version=fftw-3.3.4
+set fftw_version=fftw-3.3.5
 
 setenv FFTW_ARCH_PATH $WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$fftw_version
 
diff --git a/etc/config.csh/mpi b/etc/config.csh/mpi
index 974555857aacd833c58b40f6f453b8cb7d307077..876357d43572a2f3b87d5aa8be0d981227b134ee 100644
--- a/etc/config.csh/mpi
+++ b/etc/config.csh/mpi
@@ -51,7 +51,7 @@ case SYSTEMOPENMPI:
     breaksw
 
 case OPENMPI:
-    setenv FOAM_MPI openmpi-1.10.2
+    setenv FOAM_MPI openmpi-1.10.4
     # Optional configuration tweaks:
     _foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config.csh/openmpi`
 
diff --git a/etc/config.csh/paraview b/etc/config.csh/paraview
index 0fea6e0c07a1ff1fde18e450095c8452cf37a6cd..50973a93d47b1e90eb7c7370c9091938102d81bb 100644
--- a/etc/config.csh/paraview
+++ b/etc/config.csh/paraview
@@ -51,7 +51,7 @@
 #
 #------------------------------------------------------------------------------
 
-setenv ParaView_VERSION 5.1.2
+setenv ParaView_VERSION 5.2.0
 setenv ParaView_MAJOR detect            # Automatically determine major version
 
 set cmake_version=cmake-system
@@ -63,12 +63,10 @@ if ( ! $?ParaView_DIR ) setenv ParaView_DIR
 set cleaned=`$WM_PROJECT_DIR/bin/foamCleanPath "$PATH" "$ParaView_DIR $WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/cmake- $WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/paraview-"`
 if ( $status == 0 ) setenv PATH $cleaned
 
-# Environment for ThirdParty cmake
-unsetenv CMAKE_HOME
+# ThirdParty cmake
 set cmake=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$cmake_version
-if ( -r $cmake ) then
-    setenv CMAKE_HOME $cmake
-    setenv PATH ${CMAKE_HOME}/bin:${PATH}
+if ( -r $cmake/bin/cmake ) then
+    _foamAddPath $cmake/bin
 endif
 
 # Evaluate command-line parameters for ParaView
@@ -112,9 +110,9 @@ if ( $?ParaView_VERSION ) then
         set pvLibDir=${ParaView_DIR}/lib/$pvMajor
         set pvPython=$ParaView_DIR/Utilities/VTKPythonWrapping
 
+        setenv PATH ${ParaView_DIR}/bin:${PATH}
         setenv ParaView_INCLUDE_DIR $ParaView_DIR/include/$pvMajor
         setenv PV_PLUGIN_PATH $FOAM_LIBBIN/$pvMajor
-        setenv PATH ${ParaView_DIR}/bin:${PATH}
         setenv LD_LIBRARY_PATH "${pvLibDir}:${LD_LIBRARY_PATH}"
 
         # Add in python libraries if required
diff --git a/etc/config.sh/CGAL b/etc/config.sh/CGAL
index 044327109f64ec5c4762546ff1214e3c04b2c2fb..5f9c64b1b9f534b96c5ee4655be63507e2bd5eb2 100644
--- a/etc/config.sh/CGAL
+++ b/etc/config.sh/CGAL
@@ -49,8 +49,8 @@
 #         - the LD_LIBRARY_PATH is not adjusted.
 #------------------------------------------------------------------------------
 
-boost_version=boost_1_61_0
-cgal_version=CGAL-4.8
+boost_version=boost_1_62_0
+cgal_version=CGAL-4.9
 
 export BOOST_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$boost_version
 export CGAL_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$cgal_version
diff --git a/etc/config.sh/FFTW b/etc/config.sh/FFTW
index f3cb4ea70ee775ef7e4da0f1800c00833e099f6a..e3a6fee2fd6e03ed01cf605766ede045d27abdc0 100644
--- a/etc/config.sh/FFTW
+++ b/etc/config.sh/FFTW
@@ -47,7 +47,7 @@
 #         - the LD_LIBRARY_PATH is not adjusted.
 #------------------------------------------------------------------------------
 
-fftw_version=fftw-3.3.4
+fftw_version=fftw-3.3.5
 
 export FFTW_ARCH_PATH=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$fftw_version
 
diff --git a/etc/config.sh/mpi b/etc/config.sh/mpi
index d41751432e1d24aad15ed3ac3b3fa33d7dda0692..d8872685888d5b9c90b127a243d55038757e59d3 100644
--- a/etc/config.sh/mpi
+++ b/etc/config.sh/mpi
@@ -54,7 +54,7 @@ SYSTEMOPENMPI)
     ;;
 
 OPENMPI)
-    export FOAM_MPI=openmpi-1.10.2
+    export FOAM_MPI=openmpi-1.10.4
     # Optional configuration tweaks:
     _foamSource `$WM_PROJECT_DIR/bin/foamEtcFile config.sh/openmpi`
 
diff --git a/etc/config.sh/paraview b/etc/config.sh/paraview
index c9b8621d5251c93124f5882d38b12e87a33cc2f5..99a379422c78c39c09088c75f9ff8b0dead9be2b 100644
--- a/etc/config.sh/paraview
+++ b/etc/config.sh/paraview
@@ -51,7 +51,7 @@
 #
 #------------------------------------------------------------------------------
 
-ParaView_VERSION=5.1.2
+ParaView_VERSION=5.2.0
 ParaView_MAJOR=detect                   # Automatically determine major version
 
 cmake_version=cmake-system
@@ -66,14 +66,11 @@ cleaned=$($WM_PROJECT_DIR/bin/foamCleanPath "$PATH" \
         ) \
         && PATH="$cleaned"
 
-# Environment for ThirdParty cmake
-unset CMAKE_HOME
+# ThirdParty cmake
 cmake=$WM_THIRD_PARTY_DIR/platforms/$WM_ARCH$WM_COMPILER/$cmake_version
-if [ -r $cmake ]
+if [ -r $cmake/bin/cmake ]
 then
-    export CMAKE_HOME=$cmake
-    export CMAKE_ROOT=$cmake
-    export PATH=$CMAKE_HOME/bin:$PATH
+    _foamAddPath $cmake/bin
 fi
 
 # Evaluate command-line parameters for ParaView
@@ -125,9 +122,9 @@ then
         pvLibDir=$ParaView_DIR/lib/$pvMajor
         pvPython=$ParaView_DIR/Utilities/VTKPythonWrapping
 
+        export PATH=$ParaView_DIR/bin:$PATH
         export ParaView_INCLUDE_DIR=$ParaView_DIR/include/$pvMajor
         export PV_PLUGIN_PATH=$FOAM_LIBBIN/$pvMajor
-        export PATH=$ParaView_DIR/bin:$PATH
         export LD_LIBRARY_PATH=$pvLibDir:$LD_LIBRARY_PATH
 
         # Add in python libraries if required
diff --git a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C
index de5557bcb55d59a53b6c5dde4b659690e681aee8..38cb229c7dfbbdb3fbeeb7677f4b0f5c85c8e91b 100644
--- a/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C
+++ b/src/parallel/distributed/distributedTriSurfaceMesh/distributedTriSurfaceMesh.C
@@ -847,7 +847,7 @@ Foam::distributedTriSurfaceMesh::independentlyDistributedBbs
                             "decomposeParDict",
                             searchableSurface::time().system(),
                             searchableSurface::time(),
-                            IOobject::MUST_READ_IF_MODIFIED,
+                            IOobject::MUST_READ,
                             IOobject::NO_WRITE
                         )
                     )
diff --git a/tutorials/incompressible/simpleFoam/motorBike/Allrun b/tutorials/incompressible/simpleFoam/motorBike/Allrun
index f2d7ed6bb0f4d12f52191115084a78f20adc688b..c110f083ecd737c4e8180e63f5a5b7df9368f9b7 100755
--- a/tutorials/incompressible/simpleFoam/motorBike/Allrun
+++ b/tutorials/incompressible/simpleFoam/motorBike/Allrun
@@ -4,7 +4,10 @@ cd ${0%/*} || exit 1    # Run from this directory
 # Source tutorial run functions
 . $WM_PROJECT_DIR/bin/tools/RunFunctions
 
+# Alternative decomposeParDict name:
 decompDict="-decomposeParDict system/decomposeParDict.6"
+## Standard decomposeParDict name:
+# unset decompDict
 
 # copy motorbike surface from resources directory
 \cp $FOAM_TUTORIALS/resources/geometry/motorBike.obj.gz constant/triSurface/
@@ -13,6 +16,14 @@ runApplication surfaceFeatureExtract
 runApplication blockMesh
 
 runApplication decomposePar $decompDict
+
+# Using distributedTriSurfaceMesh?
+if foamDictionary -entry geometry -value system/snappyHexMeshDict | \
+   grep -q distributedTriSurfaceMesh
+then
+    runParallel $decompDict surfaceRedistributePar motorBike.obj independent
+fi
+
 runParallel $decompDict snappyHexMesh -overwrite
 
 #- For non-parallel running: - set the initial fields
diff --git a/tutorials/incompressible/simpleFoam/motorBike/system/decomposeParDict.6 b/tutorials/incompressible/simpleFoam/motorBike/system/decomposeParDict.6
index 82f0a4e81a972b7b9a398d5c3693750d6c0447cb..db5f0cd2c283170f048d8113451c047d7f062452 100644
--- a/tutorials/incompressible/simpleFoam/motorBike/system/decomposeParDict.6
+++ b/tutorials/incompressible/simpleFoam/motorBike/system/decomposeParDict.6
@@ -15,20 +15,20 @@ FoamFile
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
-numberOfSubdomains 4;
+numberOfSubdomains 6;
 
 method          hierarchical;
 // method          ptscotch;
 
 simpleCoeffs
 {
-    n               (4 1 1);
+    n               (6 1 1);
     delta           0.001;
 }
 
 hierarchicalCoeffs
 {
-    n               (2 2 1);
+    n               (3 2 1);
     delta           0.001;
     order           xyz;
 }