diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
index 37868113d8925aaa26bf1e5a68141c22ea54e3be..f15c61b36315f0d3bd89dcdb14334c7bbc6d7e70 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.C
@@ -66,17 +66,13 @@ void Foam::sampledSurfaces::writeGeometry() const
 
         if (Pstream::parRun())
         {
-            if (Pstream::master() && mergeList_[surfI].faces.size())
+            if (Pstream::master() && mergedList_[surfI].size())
             {
                 formatter_->write
                 (
                     outputDir,
                     s.name(),
-                    meshedSurfRef
-                    (
-                        mergeList_[surfI].points,
-                        mergeList_[surfI].faces
-                    )
+                    mergedList_[surfI]
                 );
             }
         }
@@ -104,7 +100,7 @@ Foam::sampledSurfaces::sampledSurfaces
     outputPath_(fileName::null),
     fieldSelection_(),
     interpolationScheme_(word::null),
-    mergeList_(),
+    mergedList_(),
     formatter_(nullptr)
 {
     if (Pstream::parRun())
@@ -135,7 +131,7 @@ Foam::sampledSurfaces::sampledSurfaces
     outputPath_(fileName::null),
     fieldSelection_(),
     interpolationScheme_(word::null),
-    mergeList_(),
+    mergedList_(),
     formatter_(nullptr)
 {
     read(dict);
@@ -236,7 +232,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
 
         if (Pstream::parRun())
         {
-            mergeList_.setSize(size());
+            mergedList_.setSize(size());
         }
 
         // Ensure all surfaces and merge information are expired
@@ -326,7 +322,7 @@ bool Foam::sampledSurfaces::expire()
         // Clear merge information
         if (Pstream::parRun())
         {
-            mergeList_[surfI].clear();
+            mergedList_[surfI].clear();
         }
     }
 
@@ -374,24 +370,8 @@ bool Foam::sampledSurfaces::update()
         if (s.update())
         {
             updated = true;
+            mergedList_[surfI].merge(s, mergeDim);
         }
-        else
-        {
-            continue;
-        }
-
-        PatchTools::gatherAndMerge
-        (
-            mergeDim,
-            primitivePatch
-            (
-                SubList<face>(s.faces(), s.faces().size()),
-                s.points()
-            ),
-            mergeList_[surfI].points,
-            mergeList_[surfI].faces,
-            mergeList_[surfI].pointsMap
-        );
     }
 
     return updated;
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
index dffb6589664e8c893c195861851dac5e0405b774..1d9c9e730b91a668999fa9b5292804f22c0d2128 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfaces.H
@@ -40,6 +40,7 @@ SourceFiles
 #include "regionFunctionObject.H"
 #include "sampledSurface.H"
 #include "surfaceWriter.H"
+#include "mergedSurf.H"
 #include "volFieldsFwd.H"
 #include "surfaceFieldsFwd.H"
 #include "wordReList.H"
@@ -64,26 +65,6 @@ class sampledSurfaces
     public functionObjects::regionFunctionObject,
     public PtrList<sampledSurface>
 {
-    // Private classes
-
-        //- Class used for surface merging information
-        class mergeInfo
-        {
-        public:
-            pointField points;
-            faceList   faces;
-            labelList  pointsMap;
-
-            //- Clear all storage
-            void clear()
-            {
-                points.clear();
-                faces.clear();
-                pointsMap.clear();
-            }
-        };
-
-
     // Static data members
 
         //- Output verbosity
@@ -116,8 +97,8 @@ class sampledSurfaces
 
         // surfaces
 
-            //- Information for merging surfaces
-            List<mergeInfo> mergeList_;
+            //- Merged meshed surfaces (parallel only)
+            List<mergedSurf> mergedList_;
 
 
         // Calculated
diff --git a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
index db19cb0825d23161901d7598c4b70c00a8d67728..ba39848aad2bd0d809c3e56b2d0a0e615f43b679 100644
--- a/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
+++ b/src/sampling/sampledSurface/sampledSurfaces/sampledSurfacesTemplates.C
@@ -65,25 +65,21 @@ void Foam::sampledSurfaces::writeSurface
             );
 
             // Renumber (point data) to correspond to merged points
-            if (mergeList_[surfI].pointsMap.size() == allValues.size())
+            if (mergedList_[surfI].pointsMap().size() == allValues.size())
             {
-                inplaceReorder(mergeList_[surfI].pointsMap, allValues);
-                allValues.setSize(mergeList_[surfI].points.size());
+                inplaceReorder(mergedList_[surfI].pointsMap(), allValues);
+                allValues.setSize(mergedList_[surfI].points().size());
             }
 
             // Write to time directory under outputPath_
             // skip surface without faces (eg, a failed cut-plane)
-            if (mergeList_[surfI].faces.size())
+            if (mergedList_[surfI].size())
             {
                 sampleFile = formatter_->write
                 (
                     outputDir,
                     s.name(),
-                    meshedSurfRef
-                    (
-                        mergeList_[surfI].points,
-                        mergeList_[surfI].faces
-                    ),
+                    mergedList_[surfI],
                     fieldName,
                     allValues,
                     s.interpolate()
diff --git a/src/surfMesh/Make/files b/src/surfMesh/Make/files
index f86024310449ba7bf2207d713c716b92fd4cb7e0..5e19af861366c32dac7299078654198d27636264 100644
--- a/src/surfMesh/Make/files
+++ b/src/surfMesh/Make/files
@@ -10,6 +10,8 @@ UnsortedMeshedSurface/UnsortedMeshedSurfaces.C
 
 MeshedSurfaceProxy/MeshedSurfaceProxyCore.C
 
+mergedSurf/mergedSurf.C
+
 surfaceRegistry/surfaceRegistry.C
 surfMesh/surfMesh.C
 surfMesh/surfMeshClear.C
diff --git a/src/surfMesh/mergedSurf/mergedSurf.C b/src/surfMesh/mergedSurf/mergedSurf.C
new file mode 100644
index 0000000000000000000000000000000000000000..d5c5f3dc8e8ab835ae861c899e0da54ca7c8419a
--- /dev/null
+++ b/src/surfMesh/mergedSurf/mergedSurf.C
@@ -0,0 +1,122 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 3 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, see <http://www.gnu.org/licenses/>.
+
+\*---------------------------------------------------------------------------*/
+
+#include "mergedSurf.H"
+#include "PatchTools.H"
+#include "ListListOps.H"
+
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::mergedSurf::mergedSurf()
+:
+    points_(),
+    faces_(),
+    zones_(),
+    pointsMap_()
+{}
+
+
+Foam::mergedSurf::mergedSurf
+(
+    const meshedSurf& surf,
+    const scalar mergeDim
+)
+:
+    mergedSurf()
+{
+    merge(surf, mergeDim);
+}
+
+
+// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
+
+Foam::mergedSurf::~mergedSurf()
+{}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+bool Foam::mergedSurf::use()
+{
+    return Pstream::parRun();
+}
+
+
+void Foam::mergedSurf::clear()
+{
+    points_.clear();
+    faces_.clear();
+    zones_.clear();
+    pointsMap_.clear();
+}
+
+
+bool Foam::mergedSurf::merge
+(
+    const meshedSurf& surf,
+    const scalar mergeDim
+)
+{
+    // needed for extra safety?
+    // clear();
+
+    if (!use())
+    {
+        return false;
+    }
+
+    PatchTools::gatherAndMerge
+    (
+        mergeDim,
+        primitivePatch
+        (
+            SubList<face>(surf.faces(), surf.faces().size()),
+            surf.points()
+        ),
+        points_,
+        faces_,
+        pointsMap_
+    );
+
+    // Now handle zone/region information
+    List<labelList> allZones(Pstream::nProcs());
+    allZones[Pstream::myProcNo()] = surf.zoneIds();
+    Pstream::gatherList(allZones);
+
+    if (Pstream::master())
+    {
+        zones_ = ListListOps::combine<labelList>
+        (
+            allZones,
+            accessOp<labelList>()
+        );
+    }
+    allZones.clear();
+
+    return true;
+}
+
+
+// ************************************************************************* //
diff --git a/src/surfMesh/mergedSurf/mergedSurf.H b/src/surfMesh/mergedSurf/mergedSurf.H
new file mode 100644
index 0000000000000000000000000000000000000000..dae03660ee95fcf6797b986d75a6e2f989d71387
--- /dev/null
+++ b/src/surfMesh/mergedSurf/mergedSurf.H
@@ -0,0 +1,133 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2016 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Class
+    Foam::mergedSurf
+
+Description
+    Simple class to manage surface merging information
+
+SourceFiles
+    mergedSurf.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef mergedSurf_H
+#define mergedSurf_H
+
+#include "meshedSurf.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+/*---------------------------------------------------------------------------*\
+                         Class mergedSurf Declaration
+\*---------------------------------------------------------------------------*/
+
+class mergedSurf
+:
+    public meshedSurf
+{
+    pointField points_;
+    faceList   faces_;
+    labelList  zones_;
+    labelList  pointsMap_;
+
+    //- Disallow default bitwise copy construct
+    mergedSurf(const mergedSurf&) = delete;
+
+    // Assignment is needed for lists
+
+public:
+
+    // Constructors
+
+        //- Construct null
+        mergedSurf();
+
+        //- Construct and merge meshed surfaces immediately (in parallel only).
+        mergedSurf(const meshedSurf&, const scalar mergeDim);
+
+
+    //- Destructor
+    virtual ~mergedSurf();
+
+
+    // Access Member Functions
+
+        //- Can use (parallel only)
+        static bool use();
+
+        //- Number of faces
+        label size() const
+        {
+            return faces_.size();
+        }
+
+        //- Const access to (global) points used for the surface
+        virtual const pointField& points() const
+        {
+            return points_;
+        }
+
+        //- Const access to the surface faces
+        virtual const faceList& faces() const
+        {
+            return faces_;
+        }
+
+        //- Const access to per-face zone/region information
+        virtual const labelList& zoneIds() const
+        {
+            return zones_;
+        }
+
+        //- Map for reordered points (old-to-new)
+        const labelList& pointsMap() const
+        {
+            return pointsMap_;
+        }
+
+
+    // Edit
+
+        //- Clear all storage
+        void clear();
+
+        //- Merge meshed surfaces (in parallel only).
+        bool merge(const meshedSurf&, const scalar mergeDim);
+
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //