diff --git a/applications/utilities/mesh/manipulation/Optional/setSet/setSet.C b/applications/utilities/mesh/manipulation/Optional/setSet/setSet.C
index 64dd8c1ca7c5c3017dcf5fe95e9c0e0cbdd44157..705ffed422f6f7dd440fdbd71dd115b8e8255152 100644
--- a/applications/utilities/mesh/manipulation/Optional/setSet/setSet.C
+++ b/applications/utilities/mesh/manipulation/Optional/setSet/setSet.C
@@ -341,7 +341,7 @@ bool doCommand
                 parData.nTotalPoints()
             )
         )
-      / 10;
+      / (10*Pstream::nProcs());
 
 
     bool error = false;
diff --git a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
index 432595daf18cc675db599d23a8261243a2e40e80..5694b190b42f4c2192e3f0f10f08a109f4a95ee3 100644
--- a/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
+++ b/applications/utilities/mesh/manipulation/splitMeshRegions/splitMeshRegions.C
@@ -1081,13 +1081,14 @@ label findCorrespondingZone
     // Determine same zone over all processors.
     reduce(zoneI, maxOp<label>());
 
+
+    // 2. All of cellZone present?
+
     if (zoneI == labelMax)
     {
         zoneI = -1;
     }
-
-    // 2. All of cellZone present?
-    if (zoneI != -1)
+    else if (zoneI != -1)
     {
         const cellZone& cz = cellZones[zoneI];
 
@@ -1095,10 +1096,13 @@ label findCorrespondingZone
         {
             if (cellRegion[cz[i]] != regionI)
             {
-                zoneI = labelMax;
+                zoneI = -1;
                 break;
             }
         }
+        // If one in error, all should be in error. Note that branch gets taken
+        // on all procs.
+        reduce(zoneI, minOp<label>());
     }
 
     return zoneI;
@@ -1144,12 +1148,36 @@ int main(int argc, char *argv[])
     const cellZoneMesh& cellZones = mesh.cellZones();
 
 
+    // Collect zone per cell
+    // ~~~~~~~~~~~~~~~~~~~~~
+    // - non-unique zoning
+    // - coupled zones
+
     // Existing zoneID
     labelList zoneID(mesh.nCells(), -1);
 
     forAll(cellZones, zoneI)
     {
-        setValues(zoneID, cellZones[zoneI], zoneI);
+        const cellZone& cz = cellZones[zoneI];
+
+        forAll(cz, i)
+        {
+            label cellI = cz[i];
+            if (zoneID[cellI] == -1)
+            {
+                zoneID[cellI] = zoneI;
+            }
+            else
+            {
+                FatalErrorIn(args.executable())
+                    << "Cell " << cellI << " with cell centre "
+                    << mesh.cellCentres()[cellI]
+                    << " is multiple zones. This is not allowed." << endl
+                    << "It is in zone " << cellZones[zoneID[cellI]].name()
+                    << " and in zone " << cellZones[zoneI].name()
+                    << exit(FatalError);
+            }
+        }
     }
 
     // Neighbour zoneID.
diff --git a/applications/utilities/preProcessing/changeDictionary/changeDictionary.C b/applications/utilities/preProcessing/changeDictionary/changeDictionary.C
index 0d3093677929edd8670b2960dd6f020c13ca8cd8..693f58b1c320553ba34adfa78cb3d3ec0386394c 100644
--- a/applications/utilities/preProcessing/changeDictionary/changeDictionary.C
+++ b/applications/utilities/preProcessing/changeDictionary/changeDictionary.C
@@ -44,16 +44,24 @@ Description
     }
     @endverbatim
 
+
 \*---------------------------------------------------------------------------*/
 
 #include "argList.H"
 #include "IOobjectList.H"
+#include "IOPtrList.H"
 #include "volFields.H"
 
 using namespace Foam;
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+namespace Foam
+{
+    defineTemplateTypeNameAndDebug(IOPtrList<entry>, 0);
+}
+
+
 
 // Main program:
 
@@ -64,6 +72,12 @@ int main(int argc, char *argv[])
 #   include "createTime.H"
 #   include "createNamedMesh.H"
 
+    fileName regionPrefix = "";
+    if (regionName != fvMesh::defaultRegion)
+    {
+        regionPrefix = regionName;
+    }
+
     // Get the replacement rules from a dictionary
     IOdictionary dict
     (
@@ -89,38 +103,114 @@ int main(int argc, char *argv[])
         const word& fieldName = fieldIter().keyword();
         Info<< "Replacing entries in dictionary " << fieldName << endl;
 
-        // Read dictionary. (disable class type checking so we can load field)
-        Info<< "Loading dictionary " << fieldName << endl;
-        const word oldTypeName = IOdictionary::typeName;
-        const_cast<word&>(IOdictionary::typeName) = word::null;
-        IOdictionary fieldDict
-        (
-            IOobject
+        // Handle 'boundary' specially:
+        // - is PtrList of dictionaries
+        // - is in polyMesh/
+        if (fieldName == "boundary")
+        {
+            Info<< "Special handling of " << fieldName
+                << " as polyMesh/boundary file." << endl;
+
+            // Read PtrList of dictionary as dictionary.
+            const word oldTypeName = IOPtrList<entry>::typeName;
+            const_cast<word&>(IOPtrList<entry>::typeName) = word::null;
+            IOPtrList<entry> dictList
+            (
+                IOobject
+                (
+                    fieldName,
+                    runTime.findInstance
+                    (
+                        regionPrefix/polyMesh::meshSubDir,
+                        fieldName
+                    ),
+                    polyMesh::meshSubDir,
+                    mesh,
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE,
+                    false
+                )
+            );
+            const_cast<word&>(IOPtrList<entry>::typeName) = oldTypeName;
+            // Fake type back to what was in field
+            const_cast<word&>(dictList.type()) = dictList.headerClassName();
+
+            // Temporary convert to dictionary
+            dictionary fieldDict;
+            forAll(dictList, i)
+            {
+                fieldDict.add(dictList[i].keyword(), dictList[i].dict());
+            }
+
+            Info<< "Loaded dictionary " << fieldName
+                << " with entries " << fieldDict.toc() << endl;
+
+            // Get the replacement dictionary for the field
+            const dictionary& replaceDict = fieldIter().dict();
+            Info<< "Merging entries from " << replaceDict.toc() << endl;
+
+            // Merge the replacements in
+            fieldDict.merge(replaceDict);
+
+            Info<< "fieldDict:" << fieldDict << endl;
+
+            // Convert back into dictList
+            wordList doneKeys(dictList.size());
+
+            label nEntries = fieldDict.size();
+            forAll(dictList, i)
+            {
+                doneKeys[i] = dictList[i].keyword();
+                dictList.set(i, fieldDict.lookupEntry(doneKeys[i]).clone());
+                fieldDict.remove(doneKeys[i]);
+            }
+            // Add remaining entries
+            label sz = dictList.size();
+            dictList.setSize(nEntries);
+            forAllConstIter(dictionary, fieldDict, iter)
+            {
+                dictList.set(sz, iter().clone());
+            }
+
+            Info<< "Writing modified fieldDict " << fieldName << endl;
+            dictList.write();
+        }
+        else
+        {
+            // Read dictionary. (disable class type checking so we can load
+            // field)
+            Info<< "Loading dictionary " << fieldName << endl;
+            const word oldTypeName = IOdictionary::typeName;
+            const_cast<word&>(IOdictionary::typeName) = word::null;
+            IOdictionary fieldDict
             (
-                fieldName,
-                runTime.timeName(),
-                mesh,
-                IOobject::MUST_READ,
-                IOobject::NO_WRITE,
-                false
-            )
-        );
-        const_cast<word&>(IOdictionary::typeName) = oldTypeName;
-        // Fake type back to what was in field
-        const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
-
-        Info<< "Loaded dictionary " << fieldName
-            << " with entries " << fieldDict.toc() << endl;
-
-        // Get the replacement dictionary for the field
-        const dictionary& replaceDict = fieldIter().dict();
-        Info<< "Merging entries from " << replaceDict.toc() << endl;
-
-        // Merge the replacements in
-        fieldDict.merge(replaceDict);
-
-        Info<< "Writing modified fieldDict " << fieldName << endl;
-        fieldDict.regIOobject::write();
+                IOobject
+                (
+                    fieldName,
+                    runTime.timeName(),
+                    mesh,
+                    IOobject::MUST_READ,
+                    IOobject::NO_WRITE,
+                    false
+                )
+            );
+            const_cast<word&>(IOdictionary::typeName) = oldTypeName;
+            // Fake type back to what was in field
+            const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
+
+            Info<< "Loaded dictionary " << fieldName
+                << " with entries " << fieldDict.toc() << endl;
+
+            // Get the replacement dictionary for the field
+            const dictionary& replaceDict = fieldIter().dict();
+            Info<< "Merging entries from " << replaceDict.toc() << endl;
+
+            // Merge the replacements in
+            fieldDict.merge(replaceDict);
+
+            Info<< "Writing modified fieldDict " << fieldName << endl;
+            fieldDict.regIOobject::write();
+        }
     }
 
     Info<< endl;
diff --git a/src/meshTools/Make/files b/src/meshTools/Make/files
index e9a79be0b5b6a6504919722b57969e410062f4c8..3a3d2aff830ff305ddb6e6057dc244bcfa7e93f6 100644
--- a/src/meshTools/Make/files
+++ b/src/meshTools/Make/files
@@ -67,6 +67,7 @@ $(cellSources)/fieldToCell/fieldToCell.C
 $(cellSources)/pointToCell/pointToCell.C
 $(cellSources)/shapeToCell/shapeToCell.C
 $(cellSources)/boxToCell/boxToCell.C
+$(cellSources)/regionToCell/regionToCell.C
 $(cellSources)/rotatedBoxToCell/rotatedBoxToCell.C
 $(cellSources)/labelToCell/labelToCell.C
 $(cellSources)/surfaceToCell/surfaceToCell.C