diff --git a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
index 910732fa7ac2415857d2274c102f52f3356257dc..bcdd1638345c49d41a3d0f122546517732d057c7 100644
--- a/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
+++ b/applications/utilities/mesh/generation/cvMesh/conformalVoronoiMesh/backgroundMeshDecomposition/backgroundMeshDecomposition.H
@@ -78,10 +78,8 @@ SourceFiles
 namespace Foam
 {
 
-typedef treeDataPrimitivePatch<face, List, const pointField, point>
-    treeDataBPatch;
-
 typedef PrimitivePatch<face, List, const pointField, point> bPatch;
+typedef treeDataPrimitivePatch<bPatch> treeDataBPatch;
 
 /*---------------------------------------------------------------------------*\
                   Class backgroundMeshDecomposition Declaration
diff --git a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
index 395ee77cbebfeac6951b6e8cf86a9c78e706e5ad..e64f6cb78ffd432c3c521de2b0c997003b05856a 100644
--- a/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
+++ b/applications/utilities/mesh/manipulation/renumberMesh/renumberMesh.C
@@ -1018,6 +1018,11 @@ int main(int argc, char *argv[])
 
     // Update proc maps
     if (cellProcAddressing.headerOk())
+    if
+    (
+        cellProcAddressing.headerOk()
+     && cellProcAddressing.size() == mesh.nCells()
+    )
     {
         Info<< "Renumbering processor cell decomposition map "
             << cellProcAddressing.name() << endl;
@@ -1028,6 +1033,11 @@ int main(int argc, char *argv[])
         );
     }
     if (faceProcAddressing.headerOk())
+    if
+    (
+        faceProcAddressing.headerOk()
+     && faceProcAddressing.size() == mesh.nFaces()
+    )
     {
         Info<< "Renumbering processor face decomposition map "
             << faceProcAddressing.name() << endl;
@@ -1054,6 +1064,11 @@ int main(int argc, char *argv[])
         }
     }
     if (pointProcAddressing.headerOk())
+    if
+    (
+        pointProcAddressing.headerOk()
+     && pointProcAddressing.size() == mesh.nPoints()
+    )
     {
         Info<< "Renumbering processor point decomposition map "
             << pointProcAddressing.name() << endl;
@@ -1173,21 +1188,41 @@ int main(int argc, char *argv[])
 
     mesh.write();
     if (cellProcAddressing.headerOk())
+    if
+    (
+        cellProcAddressing.headerOk()
+     && cellProcAddressing.size() == mesh.nCells()
+    )
     {
         cellProcAddressing.instance() = mesh.facesInstance();
         cellProcAddressing.write();
     }
     if (faceProcAddressing.headerOk())
+    if
+    (
+        faceProcAddressing.headerOk()
+     && faceProcAddressing.size() == mesh.nFaces()
+    )
     {
         faceProcAddressing.instance() = mesh.facesInstance();
         faceProcAddressing.write();
     }
     if (pointProcAddressing.headerOk())
+    if
+    (
+        pointProcAddressing.headerOk()
+     && pointProcAddressing.size() == mesh.nPoints()
+    )
     {
         pointProcAddressing.instance() = mesh.facesInstance();
         pointProcAddressing.write();
     }
     if (boundaryProcAddressing.headerOk())
+    if
+    (
+        boundaryProcAddressing.headerOk()
+     && boundaryProcAddressing.size() == mesh.boundaryMesh().size()
+    )
     {
         boundaryProcAddressing.instance() = mesh.facesInstance();
         boundaryProcAddressing.write();
diff --git a/applications/utilities/preProcessing/setFields/setFields.C b/applications/utilities/preProcessing/setFields/setFields.C
index 7b690d46f201584b069f49fb5e86200a11271201..dfde514992d607d36f62079b8c21e2f9b70f5f30 100644
--- a/applications/utilities/preProcessing/setFields/setFields.C
+++ b/applications/utilities/preProcessing/setFields/setFields.C
@@ -92,7 +92,15 @@ bool setCellFieldType
                 field.boundaryField()[patchi].patchInternalField();
         }
 
-        field.write();
+        if (!field.write())
+        {
+            FatalErrorIn
+            (
+                "void setCellFieldType"
+                "(const fvMesh& mesh, const labelList& selectedCells,"
+                "Istream& fieldValueStream)"
+            ) << "Failed writing field " << fieldName << endl;
+        }
     }
     else
     {
@@ -260,7 +268,15 @@ bool setFaceFieldType
             }
         }
 
-        field.write();
+        if (!field.write())
+        {
+            FatalErrorIn
+            (
+                "void setFaceFieldType"
+                "(const fvMesh& mesh, const labelList& selectedFaces,"
+                "Istream& fieldValueStream)"
+            )   << "Failed writing field " << field.name() << exit(FatalError);
+        }
     }
     else
     {
diff --git a/src/dynamicMesh/boundaryMesh/boundaryMesh.C b/src/dynamicMesh/boundaryMesh/boundaryMesh.C
index 51be127dd7108068e68c055ea2ed60d6bff1c2bd..4a705acead25c92bca38130fd1b0c0189dd173b4 100644
--- a/src/dynamicMesh/boundaryMesh/boundaryMesh.C
+++ b/src/dynamicMesh/boundaryMesh/boundaryMesh.C
@@ -924,10 +924,10 @@ Foam::labelList Foam::boundaryMesh::getNearest
     // Create the octrees
     indexedOctree
     <
-        treeDataPrimitivePatch<face, UIndirectList, const pointField&>
+        treeDataPrimitivePatch<uindirectPrimitivePatch>
     > leftTree
     (
-        treeDataPrimitivePatch<face, UIndirectList, const pointField&>
+        treeDataPrimitivePatch<uindirectPrimitivePatch>
         (
             false,          // cacheBb
             leftPatch
@@ -939,10 +939,10 @@ Foam::labelList Foam::boundaryMesh::getNearest
     );
     indexedOctree
     <
-        treeDataPrimitivePatch<face, UIndirectList, const pointField&>
+        treeDataPrimitivePatch<uindirectPrimitivePatch>
     > rightTree
     (
-        treeDataPrimitivePatch<face, UIndirectList, const pointField&>
+        treeDataPrimitivePatch<uindirectPrimitivePatch>
         (
             false,          // cacheBb
             rightPatch
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H
index 2e908b73180fbb85017ae176e7492f11eb311c12..35d0822d2a8f7d9f8452162e761466f7dc33bf08 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriver.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -249,9 +249,10 @@ class autoSnapDriver
                     const indirectPrimitivePatch& pp,
                     const scalarField& snapDist,
 
-                    const List<List<point> >& pointFaceNormals,
+                    const List<List<point> >& pointFaceSurfNormals,
                     const List<List<point> >& pointFaceDisp,
                     const List<List<point> >& pointFaceCentres,
+                    const labelListList& pointFacePatchID,
 
                     vectorField& patchAttraction,
                     List<pointConstraint>& patchConstraints
diff --git a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriverFeature.C b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriverFeature.C
index 6347d5dd16e65d359dd3eb2793857d0011fed803..950849e15ecf080e954f95aa5df36046c8d619af 100644
--- a/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriverFeature.C
+++ b/src/mesh/autoMesh/autoHexMesh/autoHexMeshDriver/autoSnapDriverFeature.C
@@ -71,14 +71,15 @@ namespace Foam
         }
     };
 
+    template<class T>
     class listPlusEqOp
     {
     public:
 
         void operator()
         (
-            List<point>& x,
-            const List<point>& y
+            List<T>& x,
+            const List<T>& y
         ) const
         {
             label sz = x.size();
@@ -486,7 +487,7 @@ void Foam::autoSnapDriver::binFeatureFaces
 
     const label pointI,
 
-    const List<List<point> >& pointFaceNormals,
+    const List<List<point> >& pointFaceSurfNormals,
     const List<List<point> >& pointFaceDisp,
     const List<List<point> >& pointFaceCentres,
 
@@ -495,7 +496,7 @@ void Foam::autoSnapDriver::binFeatureFaces
     DynamicList<label>& surfaceCount
 ) const
 {
-    const List<point>& pfNormals = pointFaceNormals[pointI];
+    const List<point>& pfNormals = pointFaceSurfNormals[pointI];
     const List<point>& pfDisp = pointFaceDisp[pointI];
     const List<point>& pfCentres = pointFaceCentres[pointI];
 
@@ -531,7 +532,7 @@ void Foam::autoSnapDriver::featureAttractionUsingReconstruction
     const indirectPrimitivePatch& pp,
     const scalarField& snapDist,
 
-    const List<List<point> >& pointFaceNormals,
+    const List<List<point> >& pointFaceSurfNormals,
     const List<List<point> >& pointFaceDisp,
     const List<List<point> >& pointFaceCentres,
 
@@ -590,7 +591,7 @@ void Foam::autoSnapDriver::featureAttractionUsingReconstruction
             snapDist,
             pointI,
 
-            pointFaceNormals,
+            pointFaceSurfNormals,
             pointFaceDisp,
             pointFaceCentres,
 
@@ -720,7 +721,7 @@ void Foam::autoSnapDriver::determineAllFeatures
     const indirectPrimitivePatch& pp,
     const scalarField& snapDist,
 
-    const List<List<point> >& pointFaceNormals,
+    const List<List<point> >& pointFaceSurfNormals,
     const List<List<point> >& pointFaceDisp,
     const List<List<point> >& pointFaceCentres,
 
@@ -873,7 +874,7 @@ void Foam::autoSnapDriver::determineFeatures
     //const vectorField& faceSurfaceNormal,
     //const vectorField& faceDisp,
     //const vectorField& faceRotation,
-    const List<List<point> >& pointFaceNormals,
+    const List<List<point> >& pointFaceSurfNormals,
     const List<List<point> >& pointFaceDisp,
     const List<List<point> >& pointFaceCentres,
 
@@ -955,7 +956,7 @@ void Foam::autoSnapDriver::determineFeatures
 
                 //faceSurfaceNormal,
                 //faceDisp,
-                pointFaceNormals,
+                pointFaceSurfNormals,
                 pointFaceDisp,
                 pointFaceCentres,
 
@@ -1132,9 +1133,10 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
     //const vectorField& faceSurfaceNormal,
     //const vectorField& faceDisp,
     //const vectorField& faceRotation,
-    const List<List<point> >& pointFaceNormals,
+    const List<List<point> >& pointFaceSurfNormals,
     const List<List<point> >& pointFaceDisp,
     const List<List<point> >& pointFaceCentres,
+    const labelListList& pointFacePatchID,
 
     vectorField& patchAttraction,
     List<pointConstraint>& patchConstraints
@@ -1181,7 +1183,7 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
         pp,
         snapDist,
 
-        pointFaceNormals,
+        pointFaceSurfNormals,
         pointFaceDisp,
         pointFaceCentres,
 
@@ -1340,6 +1342,131 @@ void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
     }
 
 
+
+    //MEJ: any faces that have multi-patch points only keep the multi-patch
+    //     points.
+    {
+        autoPtr<OFstream> multiPatchStr;
+        if (debug&meshRefinement::OBJINTERSECTIONS)
+        {
+            multiPatchStr.reset
+            (
+                new OFstream
+                (
+                    meshRefiner_.mesh().time().path()
+                  / "multiPatch_" + name(iter) + ".obj"
+                )
+            );
+            Pout<< nl << "Dumping removed constraints due to same-face"
+                << " multi-patch points to "
+                << multiPatchStr().name() << endl;
+        }
+
+
+        // 1. Mark points on multiple patches
+        PackedBoolList isMultiPatchPoint(pp.size());
+
+        forAll(pointFacePatchID, pointI)
+        {
+            const labelList& patches = pointFacePatchID[pointI];
+            label patch0 = patches[0];
+            for (label i = 1; i < patches.size(); i++)
+            {
+                if (patch0 != patches[i])
+                {
+                    isMultiPatchPoint[pointI] = 1u;
+                    break;
+                }
+            }
+        }
+
+        // 2. Make sure multi-patch points are also attracted
+        forAll(isMultiPatchPoint, pointI)
+        {
+            if (isMultiPatchPoint[pointI])
+            {
+                if
+                (
+                    patchConstraints[pointI].first() == 0
+                 && allPatchConstraints[pointI].first() > 0
+                )
+                {
+                    patchAttraction[pointI] = allPatchAttraction[pointI];
+                    patchConstraints[pointI] = allPatchConstraints[pointI];
+
+                    if (multiPatchStr.valid())
+                    {
+                        Pout<< "Adding constraint on multiPatchPoint:"
+                            << pp.localPoints()[pointI]
+                            << " constraint:" << patchConstraints[pointI]
+                            << " attraction:" << patchAttraction[pointI]
+                            << endl;
+                    }
+                }
+            }
+        }
+
+        // Up to here it is all parallel ok.
+
+
+        // 3. Knock out any attraction on faces with multi-patch points
+        label nChanged = 0;
+        forAll(pp.localFaces(), faceI)
+        {
+            const face& f = pp.localFaces()[faceI];
+
+            label nMultiPatchPoints = 0;
+            forAll(f, fp)
+            {
+                label pointI = f[fp];
+                if
+                (
+                    isMultiPatchPoint[pointI]
+                 && patchConstraints[pointI].first() != 0
+                )
+                {
+                    nMultiPatchPoints++;
+                }
+            }
+
+            if (nMultiPatchPoints > 0)
+            {
+                forAll(f, fp)
+                {
+                    label pointI = f[fp];
+                    if
+                    (
+                       !isMultiPatchPoint[pointI]
+                     && patchConstraints[pointI].first() != 0
+                    )
+                    {
+                        //Pout<< "Knocking out constraint"
+                        //    << " on non-multiPatchPoint:"
+                        //    << pp.localPoints()[pointI] << endl;
+                        patchAttraction[pointI] = vector::zero;
+                        patchConstraints[pointI] = pointConstraint();
+                        nChanged++;
+
+                        if (multiPatchStr.valid())
+                        {
+                            meshTools::writeOBJ
+                            (
+                                multiPatchStr(),
+                                pp.localPoints()[pointI]
+                            );
+                        }
+                    }
+                }
+            }
+        }
+
+        reduce(nChanged, sumOp<label>());
+        Info<< "Removing constraints near multi-patch points : changed "
+            << nChanged << " points" << endl;
+    }
+
+
+
     // Dump
     if (debug&meshRefinement::OBJINTERSECTIONS)
     {
@@ -1753,8 +1880,12 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
     const pointField& localPoints = pp.localPoints();
     const fvMesh& mesh = meshRefiner_.mesh();
 
-    // Displacement and orientation per pp face.
+    // Displacement and orientation per pp face
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    // vector from point on surface back to face centre
     vectorField faceDisp(pp.size(), vector::zero);
+    // normal of surface at point on surface
     vectorField faceSurfaceNormal(pp.size(), vector::zero);
     vectorField faceRotation(pp.size(), vector::zero);
 
@@ -1771,34 +1902,42 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
     vectorField patchDisp = nearestDisp;
 
 
-    // Collect (possibly remote) face-wise data on coupled points.
+    // Collect (possibly remote) per point data of all surrounding faces
+    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     // - faceSurfaceNormal
     // - faceDisp
     // - faceRotation
-    // - faceCentres
+    // - faceCentres&faceNormal
 
     // For now just get all surrounding face data. Expensive - should just
     // store and sync data on coupled points only (see e.g PatchToolsNormals.C)
 
-    List<List<point> > pointFaceNormals(pp.nPoints());
+    List<List<point> > pointFaceSurfNormals(pp.nPoints());
     List<List<point> > pointFaceDisp(pp.nPoints());
     List<List<point> > pointFaceCentres(pp.nPoints());
+    List<labelList>    pointFacePatchID(pp.nPoints());
 
     // Fill local data
     forAll(pp.pointFaces(), pointI)
     {
         const labelList& pFaces = pp.pointFaces()[pointI];
-        List<point>& pNormals = pointFaceNormals[pointI];
+        List<point>& pNormals = pointFaceSurfNormals[pointI];
         pNormals.setSize(pFaces.size());
         List<point>& pDisp = pointFaceDisp[pointI];
         pDisp.setSize(pFaces.size());
         List<point>& pFc = pointFaceCentres[pointI];
         pFc.setSize(pFaces.size());
+        labelList& pFid = pointFacePatchID[pointI];
+        pFid.setSize(pFaces.size());
+
         forAll(pFaces, i)
         {
-            pNormals[i] = faceSurfaceNormal[pFaces[i]];
-            pDisp[i] = faceDisp[pFaces[i]];
-            pFc[i] = pp.faceCentres()[pFaces[i]];
+            label faceI = pFaces[i];
+            pNormals[i] = faceSurfaceNormal[faceI];
+            pDisp[i] = faceDisp[faceI];
+            pFc[i] = pp.faceCentres()[faceI];
+            label meshFaceI = pp.addressing()[faceI];
+            pFid[i] = mesh.boundaryMesh().whichPatch(meshFaceI);
         }
     }
 
@@ -1806,8 +1945,8 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
     (
         mesh,
         pp.meshPoints(),
-        pointFaceNormals,
-        listPlusEqOp(),
+        pointFaceSurfNormals,
+        listPlusEqOp<point>(),
         List<point>(),
         listTransform()
     );
@@ -1816,7 +1955,7 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
         mesh,
         pp.meshPoints(),
         pointFaceDisp,
-        listPlusEqOp(),
+        listPlusEqOp<point>(),
         List<point>(),
         listTransform()
     );
@@ -1825,12 +1964,26 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
         mesh,
         pp.meshPoints(),
         pointFaceCentres,
-        listPlusEqOp(),
+        listPlusEqOp<point>(),
         List<point>(),
         listTransform()
     );
+    syncTools::syncPointList
+    (
+        mesh,
+        pp.meshPoints(),
+        pointFacePatchID,
+        listPlusEqOp<label>(),
+        List<label>()
+    );
+
 
 
+    // Main calculation
+    // ~~~~~~~~~~~~~~~~
+    // This is the main intelligence which calculates per point the vector to
+    // attract it to the nearest surface. There are lots of possibilities
+    // here.
 
     // Nearest feature
     vectorField patchAttraction(localPoints.size(), vector::zero);
@@ -1845,9 +1998,10 @@ Foam::vectorField Foam::autoSnapDriver::calcNearestSurfaceFeature
         pp,
         snapDist,
 
-        pointFaceNormals,
+        pointFaceSurfNormals,
         pointFaceDisp,
         pointFaceCentres,
+        pointFacePatchID,
 
         patchAttraction,
         patchConstraints
diff --git a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
index 2664719b26057ba262ec76a5edf99989e0f44866..e1b76c44e12692c1fbfd55b1c79439b06c8dc291 100644
--- a/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
+++ b/src/mesh/autoMesh/autoHexMesh/meshRefinement/meshRefinementRefine.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -272,7 +272,11 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
     // Find all start cells of features. Is done by tracking from keepPoint.
     Cloud<trackedParticle> cloud(mesh_, IDLList<trackedParticle>());
 
-    // Create particles on whichever processor holds the keepPoint.
+
+    // Features are identical on all processors. Number them so we know
+    // what to seed. Do this on only the processor that
+    // holds the keepPoint.
+
     label cellI = -1;
     label tetFaceI = -1;
     label tetPtI = -1;
@@ -281,13 +285,25 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
 
     if (cellI != -1)
     {
+        // I am the processor that holds the keepPoint
+
         forAll(features_, featI)
         {
             const featureEdgeMesh& featureMesh = features_[featI];
             const label featureLevel = features_.levels()[featI];
-
             const labelListList& pointEdges = featureMesh.pointEdges();
 
+            // Find regions on edgeMesh
+            labelList edgeRegion;
+            label nRegions = featureMesh.regions(edgeRegion);
+
+
+            PackedBoolList regionVisited(nRegions);
+
+
+            // 1. Seed all 'knots' in edgeMesh
+
+
             forAll(pointEdges, pointI)
             {
                 if (pointEdges[pointI].size() != 2)
@@ -316,6 +332,50 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
                             pointI                          // end point
                         )
                     );
+
+                    // Mark
+                    if (pointEdges[pointI].size() > 0)
+                    {
+                        label e0 = pointEdges[pointI][0];
+                        label regionI = edgeRegion[e0];
+                        regionVisited[regionI] = 1u;
+                    }
+                }
+            }
+
+
+            // 2. Any regions that have not been visited at all? These can
+            //    only be circular regions!
+            forAll(featureMesh.edges(), edgeI)
+            {
+                if (regionVisited.set(edgeRegion[edgeI], 1u))
+                {
+                    const edge& e = featureMesh.edges()[edgeI];
+                    label pointI = e.start();
+                    if (debug)
+                    {
+                        Pout<< "Adding particle from point:" << pointI
+                            << " coord:" << featureMesh.points()[pointI]
+                            << " on circular region:" << edgeRegion[edgeI]
+                            << endl;
+                    }
+
+                    // Non-manifold point. Create particle.
+                    cloud.addParticle
+                    (
+                        new trackedParticle
+                        (
+                            mesh_,
+                            keepPoint,
+                            cellI,
+                            tetFaceI,
+                            tetPtI,
+                            featureMesh.points()[pointI],   // endpos
+                            featureLevel,                   // level
+                            featI,                          // featureMesh
+                            pointI                          // end point
+                        )
+                    );
                 }
             }
         }
@@ -329,6 +389,8 @@ Foam::label Foam::meshRefinement::markFeatureRefinement
     trackedParticle::trackingData td(cloud, maxFeatureLevel);
 
     // Track all particles to their end position (= starting feature point)
+    // Note that the particle might have started on a different processor
+    // so this will transfer across nicely until we can start tracking proper.
     cloud.move(td, GREAT);
 
     // Reset level
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
index 3962697845a4489e8536007b20fbb9110f33ecca..5acc8dfa4c4925ef0998cc515394d4cbf14f018c 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.C
@@ -1164,50 +1164,36 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::normaliseWeights
     const word& patchName,
     const labelListList& addr,
     scalarListList& wght,
+    scalarField& wghtSum,
     const bool output
 )
 {
-    scalar minBound = VGREAT;
-    scalar maxBound = -VGREAT;
-
-    scalar tSum = 0.0;
-
     // Normalise the weights
+    wghtSum.setSize(wght.size());
     forAll(wght, faceI)
     {
         scalar s = sum(wght[faceI]);
         scalar t = s/patchAreas[faceI];
 
-        tSum += t;
-
-        if (t < minBound)
-        {
-            minBound = t;
-        }
-
-        if (t > maxBound)
-        {
-            maxBound = t;
-        }
-
         forAll(addr[faceI], i)
         {
             wght[faceI][i] /= s;
         }
+
+        wghtSum[faceI] = t;
     }
 
 
     if (output)
     {
-        const label nFace = returnReduce(wght.size(), sumOp<scalar>());
-        reduce(tSum, sumOp<scalar>());
+        const label nFace = returnReduce(wght.size(), sumOp<label>());
 
         if (nFace)
         {
             Info<< "AMI: Patch " << patchName << " weights min/max/average = "
-                << returnReduce(minBound, minOp<scalar>()) << ", "
-                << returnReduce(maxBound, maxOp<scalar>()) << ", "
-                << tSum/nFace << endl;
+                << gMin(wghtSum) << ", "
+                << gMax(wghtSum) << ", "
+                << gAverage(wghtSum) << endl;
         }
     }
 }
@@ -1227,6 +1213,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate
     scalarField& srcMagSf,
     labelListList& srcAddress,
     scalarListList& srcWeights,
+    scalarField& srcWeightsSum,
     autoPtr<mapDistribute>& tgtMap
 )
 {
@@ -1468,6 +1455,7 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::agglomerate
         "source",
         srcAddress,
         srcWeights,
+        srcWeightsSum,
         false
     );
 }
@@ -1488,9 +1476,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     singlePatchProc_(-999),
     srcAddress_(),
     srcWeights_(),
+    srcWeightsSum_(),
     srcNonOverlap_(),
     tgtAddress_(),
     tgtWeights_(),
+    tgtWeightsSum_(),
     treePtr_(NULL),
     triMode_(triMode),
     srcMapPtr_(NULL),
@@ -1521,9 +1511,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     singlePatchProc_(-999),
     srcAddress_(),
     srcWeights_(),
+    srcWeightsSum_(),
     srcNonOverlap_(),
     tgtAddress_(),
     tgtWeights_(),
+    tgtWeightsSum_(),
     treePtr_(NULL),
     triMode_(triMode),
     srcMapPtr_(NULL),
@@ -1609,9 +1601,11 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
     singlePatchProc_(fineAMI.singlePatchProc_),
     srcAddress_(),
     srcWeights_(),
+    srcWeightsSum_(),
     srcNonOverlap_(),
     tgtAddress_(),
     tgtWeights_(),
+    tgtWeightsSum_(),
     treePtr_(NULL),
     triMode_(fineAMI.triMode_),
     srcMapPtr_(NULL),
@@ -1681,6 +1675,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
         srcMagSf_,
         srcAddress_,
         srcWeights_,
+        srcWeightsSum_,
         tgtMapPtr_
     );
 
@@ -1706,6 +1701,7 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::AMIInterpolation
         tgtMagSf_,
         tgtAddress_,
         tgtWeights_,
+        tgtWeightsSum_,
         srcMapPtr_
     );
 
@@ -1857,8 +1853,24 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
         );
 
         // weights normalisation
-        normaliseWeights(srcMagSf_, "source", srcAddress_, srcWeights_, true);
-        normaliseWeights(tgtMagSf_, "target", tgtAddress_, tgtWeights_, true);
+        normaliseWeights
+        (
+            srcMagSf_,
+            "source",
+            srcAddress_,
+            srcWeights_,
+            srcWeightsSum_,
+            true
+        );
+        normaliseWeights
+        (
+            tgtMagSf_,
+            "target",
+            tgtAddress_,
+            tgtWeights_,
+            tgtWeightsSum_,
+            true
+        );
 
         // cache maps and reset addresses
         List<Map<label> > cMap;
@@ -1877,8 +1889,24 @@ void Foam::AMIInterpolation<SourcePatch, TargetPatch>::update
 
         calcAddressing(srcPatch, tgtPatch);
 
-        normaliseWeights(srcMagSf_, "source", srcAddress_, srcWeights_, true);
-        normaliseWeights(tgtMagSf_, "target", tgtAddress_, tgtWeights_, true);
+        normaliseWeights
+        (
+            srcMagSf_,
+            "source",
+            srcAddress_,
+            srcWeights_,
+            srcWeightsSum_,
+            true
+        );
+        normaliseWeights
+        (
+            tgtMagSf_,
+            "target",
+            tgtAddress_,
+            tgtWeights_,
+            tgtWeightsSum_,
+            true
+        );
     }
 
     if (debug)
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
index 36cd661175b5b25356287922c78c3f9c624cb943..b3930308235cd683803a4e56a90f32dabea11573 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolation.H
@@ -82,7 +82,7 @@ class AMIInterpolation
     public AMIInterpolationName
 {
     //- local typedef to octree tree-type
-    typedef treeDataPrimitivePatch<face, SubList, const pointField&> treeType;
+    typedef treeDataPrimitivePatch<TargetPatch> treeType;
 
 
     // Private data
@@ -106,6 +106,9 @@ class AMIInterpolation
             //- Weights of target faces per source face
             scalarListList srcWeights_;
 
+            //- Sum of weights of target faces per source face
+            scalarField srcWeightsSum_;
+
             //- Labels of faces that are not overlapped by any target faces
             //  (should be empty for correct functioning)
             labelList srcNonOverlap_;
@@ -122,6 +125,9 @@ class AMIInterpolation
             //- Weights of source faces per target face
             scalarListList tgtWeights_;
 
+            //- Sum of weights of source faces per target face
+            scalarField tgtWeightsSum_;
+
 
         //- Octree used to find face seeds
         autoPtr<indexedOctree<treeType> > treePtr_;
@@ -285,6 +291,7 @@ class AMIInterpolation
                 const word& patchName,
                 const labelListList& addr,
                 scalarListList& wght,
+                scalarField& wghtSum,
                 const bool output
             );
 
@@ -304,6 +311,7 @@ class AMIInterpolation
                 scalarField& srcMagSf,
                 labelListList& srcAddress,
                 scalarListList& srcWeights,
+                scalarField& srcWeightsSum,
                 autoPtr<mapDistribute>& tgtMap
             );
 
@@ -365,11 +373,14 @@ public:
                 //- Return const access to source patch weights
                 inline const scalarListList& srcWeights() const;
 
+                //- Return const access to normalisation factor of source
+                //  patch weights (i.e. the sum before normalisation)
+                inline const scalarField& srcWeightsSum() const;
+
                 //- Labels of faces that are not overlapped by any target faces
                 //  (should be empty for correct functioning)
                 inline const labelList& srcNonOverlap() const;
 
-
                 //- Source map pointer - valid only if singlePatchProc = -1
                 //  This gets source data into a form to be consumed by
                 //  tgtAddress, tgtWeights
@@ -387,7 +398,11 @@ public:
                 //- Return const access to target patch weights
                 inline const scalarListList& tgtWeights() const;
 
-                //- Target map pointer - valid only if singlePatchProc = -1
+                //- Return const access to normalisation factor of target
+                //  patch weights (i.e. the sum before normalisation)
+                inline const scalarField& tgtWeightsSum() const;
+
+                //- Target map pointer -  valid only if singlePatchProc=-1.
                 //  This gets target data into a form to be consumed by
                 //  srcAddress, srcWeights
                 inline const mapDistribute& tgtMap() const;
diff --git a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H
index 3dd21b5aa3a8642c6d98a75b2be2840d06626413..f2782bad886aef725f81f9b1fb74c6694b085092 100644
--- a/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H
+++ b/src/meshTools/AMIInterpolation/AMIInterpolation/AMIInterpolationI.H
@@ -63,6 +63,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcNonOverlap() const
 }
 
 
+template<class SourcePatch, class TargetPatch>
+inline const Foam::scalarField&
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcWeightsSum() const
+{
+    return srcWeightsSum_;
+}
+
+
 template<class SourcePatch, class TargetPatch>
 inline const Foam::mapDistribute&
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::srcMap() const
@@ -95,6 +103,14 @@ Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeights() const
 }
 
 
+template<class SourcePatch, class TargetPatch>
+inline const Foam::scalarField&
+Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtWeightsSum() const
+{
+    return tgtWeightsSum_;
+}
+
+
 template<class SourcePatch, class TargetPatch>
 inline const Foam::mapDistribute&
 Foam::AMIInterpolation<SourcePatch, TargetPatch>::tgtMap() const
diff --git a/src/meshTools/indexedOctree/treeDataPrimitivePatch.C b/src/meshTools/indexedOctree/treeDataPrimitivePatch.C
index 6927cbaa509d59a87b4b16c9ac46c387d0de5b12..4cd29682323df7d68cb1259cdb9836ac7325749f 100644
--- a/src/meshTools/indexedOctree/treeDataPrimitivePatch.C
+++ b/src/meshTools/indexedOctree/treeDataPrimitivePatch.C
@@ -29,30 +29,14 @@ License
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::scalar
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-tolSqr = sqr(1e-6);
+template<class PatchType>
+Foam::scalar Foam::treeDataPrimitivePatch<PatchType>::tolSqr = sqr(1e-6);
 
 
 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::treeBoundBox
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-calcBb
+template<class PatchType>
+Foam::treeBoundBox Foam::treeDataPrimitivePatch<PatchType>::calcBb
 (
     const pointField& points,
     const face& f
@@ -71,15 +55,8 @@ calcBb
 }
 
 
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-update()
+template<class PatchType>
+void Foam::treeDataPrimitivePatch<PatchType>::update()
 {
     if (cacheBb_)
     {
@@ -96,18 +73,11 @@ update()
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 // Construct from components
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-treeDataPrimitivePatch
+template<class PatchType>
+Foam::treeDataPrimitivePatch<PatchType>::treeDataPrimitivePatch
 (
     const bool cacheBb,
-    const PrimitivePatch<Face, FaceList, PointField, PointType>& patch
+    const PatchType& patch
 )
 :
     patch_(patch),
@@ -119,16 +89,8 @@ treeDataPrimitivePatch
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::pointField
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-shapePoints() const
+template<class PatchType>
+Foam::pointField Foam::treeDataPrimitivePatch<PatchType>::shapePoints() const
 {
     pointField cc(patch_.size());
 
@@ -143,27 +105,10 @@ shapePoints() const
 
 //- Get type (inside,outside,mixed,unknown) of point w.r.t. surface.
 //  Only makes sense for closed surfaces.
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-Foam::label
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-getVolumeType
+template<class PatchType>
+Foam::label Foam::treeDataPrimitivePatch<PatchType>:: getVolumeType
 (
-    const indexedOctree
-    <
-        treeDataPrimitivePatch
-        <
-            Face,
-            FaceList,
-            PointField,
-            PointType
-        >
-    >& oc,
+    const indexedOctree<treeDataPrimitivePatch<PatchType> >& oc,
     const point& sample
 ) const
 {
@@ -396,16 +341,8 @@ getVolumeType
 
 
 // Check if any point on shape is inside cubeBb.
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-bool
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-overlaps
+template<class PatchType>
+bool Foam::treeDataPrimitivePatch<PatchType>::overlaps
 (
     const label index,
     const treeBoundBox& cubeBb
@@ -462,16 +399,8 @@ overlaps
 
 
 // Check if any point on shape is inside sphere.
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-bool
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-overlaps
+template<class PatchType>
+bool Foam::treeDataPrimitivePatch<PatchType>::overlaps
 (
     const label index,
     const point& centre,
@@ -512,16 +441,8 @@ overlaps
 
 // Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex,
 // nearestPoint.
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-void
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-findNearest
+template<class PatchType>
+void Foam::treeDataPrimitivePatch<PatchType>::findNearest
 (
     const labelUList& indices,
     const point& sample,
@@ -552,16 +473,8 @@ findNearest
 }
 
 
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType
->
-bool
-Foam::treeDataPrimitivePatch<Face, FaceList, PointField, PointType>::
-intersects
+template<class PatchType>
+bool Foam::treeDataPrimitivePatch<PatchType>::intersects
 (
     const label index,
     const point& start,
diff --git a/src/meshTools/indexedOctree/treeDataPrimitivePatch.H b/src/meshTools/indexedOctree/treeDataPrimitivePatch.H
index 44f76d2c75ff76fdf732e52f076f5c9cfeec4787..bbb3c749562c49d99ce168a8e76cbc0fc2988a01 100644
--- a/src/meshTools/indexedOctree/treeDataPrimitivePatch.H
+++ b/src/meshTools/indexedOctree/treeDataPrimitivePatch.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -59,13 +59,7 @@ TemplateName(treeDataPrimitivePatch);
                    Class treeDataPrimitivePatch Declaration
 \*---------------------------------------------------------------------------*/
 
-template
-<
-    class Face,
-    template<class> class FaceList,
-    class PointField,
-    class PointType=point
->
+template<class PatchType>
 class treeDataPrimitivePatch
 :
     public treeDataPrimitivePatchName
@@ -78,7 +72,7 @@ class treeDataPrimitivePatch
     // Private data
 
         //- Underlying geometry
-        const PrimitivePatch<Face, FaceList, PointField, PointType>& patch_;
+        const PatchType& patch_;
 
         //- Whether to precalculate and store face bounding box
         const bool cacheBb_;
@@ -103,7 +97,7 @@ public:
         treeDataPrimitivePatch
         (
             const bool cacheBb,
-            const PrimitivePatch<Face, FaceList, PointField, PointType>&
+            const PatchType&
         );
 
 
@@ -121,8 +115,7 @@ public:
             pointField shapePoints() const;
 
             //- Return access to the underlying patch
-            const PrimitivePatch<Face, FaceList, PointField, PointType>&
-            patch() const
+            const PatchType& patch() const
             {
                 return patch_;
             }
@@ -134,16 +127,7 @@ public:
             //  Only makes sense for closed surfaces.
             label getVolumeType
             (
-                const indexedOctree
-                <
-                    treeDataPrimitivePatch
-                    <
-                        Face,
-                        FaceList,
-                        PointField,
-                        PointType
-                    >
-                >&,
+                const indexedOctree<treeDataPrimitivePatch<PatchType> >&,
                 const point&
             ) const;
 
diff --git a/src/meshTools/searchableSurface/searchableSurface.C b/src/meshTools/searchableSurface/searchableSurface.C
index b586ca191db14034649859780a9882d5ba82fbd0..decd4c7259ab41d187d438985f5517c2a40527e6 100644
--- a/src/meshTools/searchableSurface/searchableSurface.C
+++ b/src/meshTools/searchableSurface/searchableSurface.C
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -95,4 +95,21 @@ Foam::searchableSurface::~searchableSurface()
 {}
 
 
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+void Foam::searchableSurface::findNearest
+(
+    const pointField& sample,
+    const scalarField& nearestDistSqr,
+    List<pointIndexHit>& info,
+    vectorField& normal,
+    labelList& region
+) const
+{
+    findNearest(sample, nearestDistSqr, info);
+    getNormal(info, normal);
+    getRegion(info, region);
+}
+
+
 // ************************************************************************* //
diff --git a/src/meshTools/searchableSurface/searchableSurface.H b/src/meshTools/searchableSurface/searchableSurface.H
index 535997e90018063470a92519f2daf87d4e341b52..94713fbf386461e6f467bacd66b82dbe8ae0c4d6 100644
--- a/src/meshTools/searchableSurface/searchableSurface.H
+++ b/src/meshTools/searchableSurface/searchableSurface.H
@@ -2,7 +2,7 @@
   =========                 |
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
-    \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
+    \\  /    A nd           | Copyright (C) 2011-2012 OpenFOAM Foundation
      \\/     M anipulation  |
 -------------------------------------------------------------------------------
 License
@@ -323,6 +323,17 @@ public:
                 List<volumeType>&
             ) const = 0;
 
+            //- Find nearest, normal and region. Can be overridden with
+            //  optimised implementation
+            virtual void findNearest
+            (
+                const pointField& sample,
+                const scalarField& nearestDistSqr,
+                List<pointIndexHit>&,
+                vectorField& normal,
+                labelList& region
+            ) const;
+
 
         // Other
 
diff --git a/src/meshTools/searchableSurface/triSurfaceMesh.C b/src/meshTools/searchableSurface/triSurfaceMesh.C
index 6bbfd229600591f6d9a937714606645e66507ae2..86fcd5889bc8e587223c27375f04ca19d604f3c4 100644
--- a/src/meshTools/searchableSurface/triSurfaceMesh.C
+++ b/src/meshTools/searchableSurface/triSurfaceMesh.C
@@ -827,6 +827,8 @@ void Foam::triSurfaceMesh::getNormal
     vectorField& normal
 ) const
 {
+    const triSurface& s = static_cast<const triSurface&>(*this);
+
     normal.setSize(info.size());
 
     if (minQuality_ >= 0)
@@ -834,7 +836,6 @@ void Foam::triSurfaceMesh::getNormal
         // Make sure we don't use triangles with low quality since
         // normal is not reliable.
 
-        const triSurface& s = static_cast<const triSurface&>(*this);
         const labelListList& faceFaces = s.faceFaces();
 
         forAll(info, i)
@@ -842,6 +843,7 @@ void Foam::triSurfaceMesh::getNormal
             if (info[i].hit())
             {
                 label faceI = info[i].index();
+                normal[i] = s[faceI].normal(points());
 
                 scalar qual = s[faceI].tri(points()).quality();
 
@@ -861,11 +863,8 @@ void Foam::triSurfaceMesh::getNormal
                         }
                     }
                 }
-                else
-                {
-                    normal[i] = s[faceI].normal(points());
-                }
-                normal[i] /= mag(normal[i]);
+
+                normal[i] /= mag(normal[i]) + VSMALL;
             }
             else
             {
@@ -885,7 +884,7 @@ void Foam::triSurfaceMesh::getNormal
                 //normal[i] = faceNormals()[faceI];
 
                 //- Uncached
-                normal[i] = triSurface::operator[](faceI).normal(points());
+                normal[i] = s[faceI].normal(points());
                 normal[i] /= mag(normal[i]) + VSMALL;
             }
             else