diff --git a/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C b/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C
index daece06c1dfe20b0c93411ad46adc8ac837d9e9c..f245e4088bcb300b122f19e5ec5a6ddf2ceb97d9 100644
--- a/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C
+++ b/applications/utilities/surface/surfaceMeshConvertTesting/surfaceMeshConvertTesting.C
@@ -278,6 +278,14 @@ int main(int argc, char *argv[])
             Info<< "runTime.timeName() = " << runTime.timeName() << endl;
 
 
+            Info<< "write MeshedSurface 'yetAnother' via proxy as surfMesh"
+                << endl;
+            surf.write
+            (
+                runTime,
+                "yetAnother"
+            );
+
             surfMesh surfIn
             (
                 IOobject
@@ -291,7 +299,16 @@ int main(int argc, char *argv[])
             );
 
 
-            Info<< "surfIn = " << surfIn.nFaces() << endl;
+            MeshedSurface<face> surfIn2(runTime, "foobar");
+
+            Info<<"surfIn2 = " << surfIn2.size() << endl;
+
+            Info<< "surfIn = " << surfIn.size() << endl;
+
+
+            Info<< "writing surfMesh as obj = oldSurfIn.obj" << endl;
+            surfIn.write("oldSurfIn.obj");
+
 
             Info<< "runTime.instance() = " << runTime.instance() << endl;
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.C b/src/surfMesh/MeshedSurface/MeshedSurface.C
index 0a1440ff1fc26db09b51c9803a69cbd268a11cf4..8bcab42089f7936519567d3e0c9ce922decee5cc 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.C
@@ -28,8 +28,6 @@ License
 #include "UnsortedMeshedSurface.H"
 #include "MeshedSurfaceProxy.H"
 #include "mergePoints.H"
-#include "IFstream.H"
-#include "OFstream.H"
 #include "Time.H"
 #include "ListOps.H"
 #include "polyBoundaryMesh.H"
@@ -140,12 +138,7 @@ void Foam::MeshedSurface<Face>::write
 
         if (supported.found(ext))
         {
-            MeshedSurfaceProxy<Face>
-            (
-                surf.points(),
-                surf.faces(),
-                surf.surfZones()
-            ).write(name);
+            MeshedSurfaceProxy<Face>(surf).write(name);
         }
         else
         {
@@ -367,11 +360,37 @@ Foam::MeshedSurface<Face>::MeshedSurface(const fileName& name)
 
 
 template<class Face>
-Foam::MeshedSurface<Face>::MeshedSurface(const Time& d, const word& surfName)
+Foam::MeshedSurface<Face>::MeshedSurface
+(
+    const Time& t,
+    const word& surfName
+)
 :
     ParentType(List<Face>(), pointField())
 {
-    read(this->findMeshFile(d, surfName));
+    surfMesh mesh
+    (
+        IOobject
+        (
+            "dummyName",
+            t.timeName(),
+            t,
+            IOobject::MUST_READ,
+            IOobject::NO_WRITE,
+            false
+        ),
+        surfName
+    );
+
+    // same face type as surfMesh
+    MeshedSurface<face> surf
+    (
+        xferMove(mesh.storedPoints()),
+        xferMove(mesh.storedFaces()),
+        xferMove(mesh.storedZones())
+    );
+
+    this->transcribe(surf);
 }
 
 
@@ -1133,11 +1152,11 @@ bool Foam::MeshedSurface<Face>::read
 template<class Face>
 void Foam::MeshedSurface<Face>::write
 (
-    const Time& d,
+    const Time& t,
     const word& surfName
 ) const
 {
-    write(findMeshFile(d, surfName));
+    MeshedSurfaceProxy<Face>(*this).write(t, surfName);
 }
 
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
@@ -1153,6 +1172,18 @@ void Foam::MeshedSurface<Face>::operator=(const MeshedSurface& surf)
 }
 
 
+template<class Face>
+Foam::MeshedSurface<Face>::operator
+Foam::MeshedSurfaceProxy<Face>() const
+{
+    return MeshedSurfaceProxy<Face>
+    (
+        this->points(),
+        this->faces(),
+        this->surfZones()
+    );
+}
+
 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
 
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
diff --git a/src/surfMesh/MeshedSurface/MeshedSurface.H b/src/surfMesh/MeshedSurface/MeshedSurface.H
index 51701bc499fa9d33f090f27971209d72352d5e00..5677233e0bcf8fb35056a81c04b1fcc0d82a507d 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurface.H
+++ b/src/surfMesh/MeshedSurface/MeshedSurface.H
@@ -85,14 +85,9 @@ class MeshedSurface
     public PrimitivePatch<Face, ::Foam::List, pointField, point>,
     public fileFormats::surfaceFormatsCore
 {
-    // friends despite different faces
-    template<class Face2>
-    friend class MeshedSurface;
-
-    // friends despite different faces
-    template<class Face2>
-    friend class UnsortedMeshedSurface;
-
+    // friends - despite different face representationsx
+    template<class Face2> friend class MeshedSurface;
+    template<class Face2> friend class UnsortedMeshedSurface;
     friend class surfMesh;
 
 private:
@@ -232,7 +227,7 @@ public:
         //- Construct from file name (uses extension to determine type)
         MeshedSurface(const fileName&, const word& ext);
 
-        //- Construct from objectRegistry
+        //- Construct from database
         MeshedSurface(const Time&, const word& surfName="");
 
     // Declare run-time constructor selection table
@@ -437,6 +432,9 @@ public:
 
         void operator=(const MeshedSurface<Face>&);
 
+        //- Conversion operator to MeshedSurfaceProxy
+        operator MeshedSurfaceProxy<Face>() const;
+
 };
 
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
index bdf7c28c80211f9584788b34778c8d22cd4b251e..93069a5d8c64b240b9fa29d41293c570f0f24b3d 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceIO.C
@@ -34,7 +34,7 @@ template<class Face>
 void Foam::MeshedSurface<Face>::writeStats(Ostream& os) const
 {
     os  << "points      : " << this->points().size() << nl;
-    if (this->isTri())
+    if (MeshedSurface<Face>::isTri())
     {
         os << "triangles   : " << this->size() << nl;
     }
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
index cd3f238c62fe767b4212a1cf9596961083a1b458..bdaae876a1cff71ad5ae5604d32cca7949a6a812 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceNew.C
@@ -51,7 +51,7 @@ Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
         if (supported.found(ext))
         {
             // create indirectly
-            autoPtr<MeshedSurface<Face> > surf(new MeshedSurface<Face>);
+            autoPtr< MeshedSurface<Face> > surf(new MeshedSurface<Face>);
             surf().transfer(FriendType::New(name, ext)());
 
             return surf;
@@ -70,7 +70,7 @@ Foam::MeshedSurface<Face>::New(const fileName& name, const word& ext)
             << exit(FatalError);
     }
 
-    return autoPtr<MeshedSurface<Face> >(cstrIter()(name));
+    return autoPtr< MeshedSurface<Face> >(cstrIter()(name));
 }
 
 
diff --git a/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C b/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C
index 6b5915070f9ba42e530fdb206bd4ca3e5844d2e1..a31e8d6314ee75d921e8a340a04a0836b8596fc8 100644
--- a/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C
+++ b/src/surfMesh/MeshedSurface/MeshedSurfaceZones.C
@@ -26,11 +26,6 @@ License
 
 #include "MeshedSurface.H"
 
-// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
-// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
-// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
-// * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
-// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
 
 template<class Face>
@@ -38,7 +33,7 @@ void Foam::MeshedSurface<Face>::checkZones()
 {
     // extra safety, ensure we have at some zones
     // and they cover all the faces - fix start silently
-    surfZoneList& zones = storedZones();
+    surfZoneList& zones = this->storedZones();
     if (zones.size())
     {
         label count = 0;
@@ -48,25 +43,25 @@ void Foam::MeshedSurface<Face>::checkZones()
             count += zones[zoneI].size();
         }
 
-        if (count < size())
+        if (count < this->size())
         {
             WarningIn
             (
                 "MeshedSurface::checkZones()\n"
             )
-                << "more faces " << size() << " than zones " << count
+                << "more faces " << this->size() << " than zones " << count
                 << " ... extending final zone"
                 << endl;
 
-            zones[zones.size()-1].size() += count - size();
+            zones[zones.size()-1].size() += count - this->size();
         }
-        else if (count > size())
+        else if (count > this->size())
         {
             FatalErrorIn
             (
                 "MeshedSurface::checkZones()\n"
             )
-                << "more zones " << count << " than faces " << size()
+                << "more zones " << count << " than faces " << this->size()
                 << exit(FatalError);
         }
     }
@@ -101,7 +96,7 @@ void Foam::MeshedSurface<Face>::sortFacesAndStore
         List<Face> newFaces(faceMap.size());
         forAll(faceMap, faceI)
         {
-            // use transfer to recover memory if possible
+            // use transfer to recover memory where possible
             newFaces[faceI].transfer(oldFaces[faceMap[faceI]]);
         }
         this->storedFaces().transfer(newFaces);
@@ -205,10 +200,4 @@ void Foam::MeshedSurface<Face>::removeZones()
 }
 
 
-// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
-// * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
-// * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
-
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
 // ************************************************************************* //
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
index 95b7bb911cdfbee98fdc90caf07ccd17265161c3..0246b40dcff8c42f32341654c98f21352bf8c61a 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.C
@@ -25,9 +25,11 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "MeshedSurfaceProxy.H"
+#include "MeshedSurface.H"
 #include "Time.H"
 #include "surfMesh.H"
-#include "MeshedSurface.H"
+#include "OFstream.H"
+#include "ListOps.H"
 
 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
 
@@ -86,6 +88,127 @@ void Foam::MeshedSurfaceProxy<Face>::write
 }
 
 
+template<class Face>
+void Foam::MeshedSurfaceProxy<Face>::write
+(
+    const Time& t,
+    const word& surfName
+) const
+{
+    // the surface name to be used
+    word name(surfName.size() ? surfName : surfaceRegistry::defaultName);
+
+    if (debug)
+    {
+        Info<< "MeshedSurfaceProxy::write"
+            "(const Time&, const word&) : "
+            "writing to " << name
+            << endl;
+    }
+
+
+    // the local location
+    const fileName objectDir
+    (
+        t.timePath()/surfaceRegistry::subInstance/name/surfMesh::meshSubDir
+    );
+
+    if (!isDir(objectDir))
+    {
+        mkDir(objectDir);
+    }
+
+
+    // write surfMesh/points
+    {
+        pointIOField io
+        (
+            IOobject
+            (
+                "points",
+                t.timeName(),
+                surfMesh::meshSubDir,
+                t,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+
+        OFstream os(objectDir/io.name());
+        io.writeHeader(os);
+
+        os  << this->points();
+
+        os  << "\n\n"
+            "// ************************************************************************* //\n";
+    }
+
+
+    // write surfMesh/faces
+    {
+        faceIOList io
+        (
+            IOobject
+            (
+                "faces",
+                t.timeName(),
+                surfMesh::meshSubDir,
+                t,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+
+        OFstream os(objectDir/io.name());
+        io.writeHeader(os);
+
+        if (this->useFaceMap())
+        {
+            // this is really a bit annoying (and wasteful) but no other way
+            os  << reorder(this->faceMap(), this->faces());
+        }
+        else
+        {
+            os  << this->faces();
+        }
+
+        os  << "\n\n"
+            "// ************************************************************************* //\n";
+    }
+
+
+    // write surfMesh/surfZones
+    {
+        surfZoneIOList io
+        (
+            IOobject
+            (
+                "surfZones",
+                t.timeName(),
+                surfMesh::meshSubDir,
+                t,
+                IOobject::NO_READ,
+                IOobject::NO_WRITE,
+                false
+            )
+        );
+
+        OFstream os(objectDir/io.name());
+        io.writeHeader(os);
+
+        os  << this->surfZones();
+
+        os  << "\n\n"
+            "// ************************************************************************* //"
+            << endl;
+    }
+
+}
+
+
+
 // * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
 
 template<class Face>
@@ -104,19 +227,6 @@ Foam::MeshedSurfaceProxy<Face>::MeshedSurfaceProxy
 {}
 
 
-template<class Face>
-Foam::MeshedSurfaceProxy<Face>::MeshedSurfaceProxy
-(
-    const MeshedSurface<Face>& surf
-)
-:
-    points_(surf.points()),
-    faces_(surf.faces()),
-    zones_(surf.surfZones()),
-    faceMap_(List<label>())
-{}
-
-
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
 
 template<class Face>
@@ -131,16 +241,6 @@ Foam::MeshedSurfaceProxy<Face>::~MeshedSurfaceProxy()
 
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
-// template<class Face>
-// void Foam::MeshedSurfaceProxy<Face>::write
-// (
-//     const Time& d,
-//     const word& surfName
-// ) const
-// {
-//     write(findMeshFile(d, surfName)());
-// }
-
 // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
 
 
diff --git a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
index 69b65fdeceac23a294fbdc7e10243903392e6301..2d05856f9c4cce7e5919b72081a34dabe1a98c98 100644
--- a/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
+++ b/src/surfMesh/MeshedSurfaceProxy/MeshedSurfaceProxy.H
@@ -76,15 +76,6 @@ class MeshedSurfaceProxy
 
         const List<label>& faceMap_;
 
-
-    // Private Member Functions
-
-        //- Disallow default bitwise copy construct
-        MeshedSurfaceProxy(const MeshedSurfaceProxy&);
-
-        //- Disallow default bitwise assignment
-        void operator=(const MeshedSurfaceProxy&);
-
 public:
 
         //- Runtime type information
@@ -108,12 +99,6 @@ public:
             const List<label>& faceMap = List<label>()
         );
 
-        //- Construct from MeshedSurface
-        explicit MeshedSurfaceProxy
-        (
-            const MeshedSurface<Face>&
-        );
-
     // Destructor
 
         virtual ~MeshedSurfaceProxy();
@@ -176,8 +161,6 @@ public:
 
     // Write
 
-//??        void writeStats(Ostream& os) const;
-
         //- Generic write routine. Chooses writer based on extension.
         virtual void write(const fileName& name) const
         {
@@ -185,7 +168,9 @@ public:
         }
 
         //- Write to database
-//??        void write(const Time&, const word& surfName="") const;
+        virtual void write(const Time&, const word& surfName = "") const;
+
+    //??        void writeStats(Ostream& os) const;
 
 };
 
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
index 2268448a107d80cbbf49dd83a0804c28cdd8e64a..881f73ebae3b2cdcd1be8da080c92caeca0b323a 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.C
@@ -26,6 +26,7 @@ License
 
 #include "MeshedSurface.H"
 #include "UnsortedMeshedSurface.H"
+#include "MeshedSurfaceProxy.H"
 #include "IFstream.H"
 #include "OFstream.H"
 #include "Time.H"
@@ -127,16 +128,7 @@ void Foam::UnsortedMeshedSurface<Face>::write
 
         if (supported.found(ext))
         {
-            labelList faceMap;
-            List<surfZone> zoneLst = surf.sortedZones(faceMap);
-
-            MeshedSurfaceProxy<Face>
-            (
-                surf.points(),
-                surf.faces(),
-                zoneLst,
-                faceMap
-            ).write(name);
+            MeshedSurfaceProxy<Face>(surf).write(name);
         }
         else
         {
@@ -291,13 +283,14 @@ Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface(const fileName& name)
 template<class Face>
 Foam::UnsortedMeshedSurface<Face>::UnsortedMeshedSurface
 (
-    const Time& d,
+    const Time& t,
     const word& surfName
 )
 :
     ParentType()
 {
-    read(this->findMeshFile(d, surfName));
+    MeshedSurface<Face> surf(t, surfName);
+    transfer(surf);
 }
 
 
@@ -473,7 +466,75 @@ Foam::surfZoneList Foam::UnsortedMeshedSurface<Face>::sortedZones
         zoneNames.insert(zoneI, zoneToc_[zoneI].name());
     }
 
-    return this->sortedZonesById(zoneIds_, zoneNames, faceMap);
+    // std::sort() really seems to mix up the order.
+    // and std::stable_sort() might take too long / too much memory
+
+    // Assuming that we have relatively fewer zones compared to the
+    // number of items, just do it ourselves
+
+    // step 1: get zone sizes and store (origId => zoneI)
+    Map<label> lookup;
+    forAll(zoneIds_, faceI)
+    {
+        const label origId = zoneIds_[faceI];
+
+        Map<label>::iterator fnd = lookup.find(origId);
+        if (fnd != lookup.end())
+        {
+            fnd()++;
+        }
+        else
+        {
+            lookup.insert(origId, 1);
+        }
+    }
+
+    // step 2: assign start/size (and name) to the newZones
+    // re-use the lookup to map (zoneId => zoneI)
+    surfZoneList zoneLst(lookup.size());
+    label start = 0;
+    label zoneI = 0;
+    forAllIter(Map<label>, lookup, iter)
+    {
+        label origId = iter.key();
+
+        word name;
+        Map<word>::const_iterator fnd = zoneNames.find(origId);
+        if (fnd != zoneNames.end())
+        {
+            name = fnd();
+        }
+        else
+        {
+            name = word("zone") + ::Foam::name(zoneI);
+        }
+
+        zoneLst[zoneI] = surfZone
+        (
+            name,
+            0,           // initialize with zero size
+            start,
+            zoneI
+        );
+
+        // increment the start for the next zone
+        // and save the (zoneId => zoneI) mapping
+        start += iter();
+        iter() = zoneI++;
+    }
+
+
+    // step 3: build the re-ordering
+    faceMap.setSize(zoneIds_.size());
+
+    forAll(zoneIds_, faceI)
+    {
+        label zoneI = lookup[zoneIds_[faceI]];
+        faceMap[faceI] = zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
+    }
+
+    // with reordered faces registered in faceMap
+    return zoneLst;
 }
 
 
@@ -670,11 +731,11 @@ bool Foam::UnsortedMeshedSurface<Face>::read
 template<class Face>
 void Foam::UnsortedMeshedSurface<Face>::write
 (
-    const Time& d,
+    const Time& t,
     const word& surfName
 ) const
 {
-    write(OFstream(this->findMeshFile(d, surfName))());
+    MeshedSurfaceProxy<Face>(*this).write(t, surfName);
 }
 
 
@@ -695,6 +756,24 @@ void Foam::UnsortedMeshedSurface<Face>::operator=
 }
 
 
+template<class Face>
+Foam::UnsortedMeshedSurface<Face>::operator
+Foam::MeshedSurfaceProxy<Face>() const
+{
+    labelList faceMap;
+    List<surfZone> zoneLst = this->sortedZones(faceMap);
+
+    return MeshedSurfaceProxy<Face>
+    (
+        this->points(),
+        this->faces(),
+        zoneLst,
+        faceMap
+    );
+}
+
+
+
 // * * * * * * * * * * * * * * * Friend Functions  * * * * * * * * * * * * * //
 
 // * * * * * * * * * * * * * * * IOstream Operators  * * * * * * * * * * * * //
diff --git a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
index 4056384db3cd74bc4182d71dba31b12a70564ea8..7a272240d15a50abbcb0842878779bdf024e9ec8 100644
--- a/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
+++ b/src/surfMesh/UnsortedMeshedSurface/UnsortedMeshedSurface.H
@@ -78,15 +78,10 @@ class UnsortedMeshedSurface
 :
     public MeshedSurface<Face>
 {
-    // friends despite different faces
-    template<class Face2>
-    friend class MeshedSurface;
-
-    // friends despite different faces
-    template<class Face2>
-    friend class UnsortedMeshedSurface;
-
-    friend class MeshedSurface<Face>;
+    // friends - despite different face representationsx
+    template<class Face2> friend class MeshedSurface;
+    template<class Face2> friend class UnsortedMeshedSurface;
+    friend class surfMesh;
 
 private:
 
@@ -200,7 +195,7 @@ public:
         //- Construct from Istream
         UnsortedMeshedSurface(Istream&);
 
-        //- Construct from objectRegistry
+        //- Construct from objectRegistry and a named surface
         UnsortedMeshedSurface(const Time&, const word& surfName="");
 
     // Declare run-time constructor selection table
@@ -277,7 +272,7 @@ public:
             return zoneToc_;
         }
 
-        //- Sort faces according to zone.
+        //- Sort faces according to zoneIds
         //  Returns a surfZoneList and sets faceMap to index within faces()
         surfZoneList sortedZones(labelList& faceMap) const;
 
@@ -365,6 +360,8 @@ public:
 
         void operator=(const UnsortedMeshedSurface<Face>&);
 
+        //- Conversion operator to MeshedSurfaceProxy
+        operator MeshedSurfaceProxy<Face>() const;
 
 };
 
diff --git a/src/surfMesh/surfMesh/surfMesh.H b/src/surfMesh/surfMesh/surfMesh.H
index 7f41b7a95e06cb6fcf1f760d4635013be0f9fbe0..234971788a1409cfa8330130b5b675deac0b6bb9 100644
--- a/src/surfMesh/surfMesh/surfMesh.H
+++ b/src/surfMesh/surfMesh/surfMesh.H
@@ -60,6 +60,9 @@ class surfMesh
     private MeshedSurfaceIOAllocator,
     public  PrimitivePatch<face, ::Foam::UList, ::Foam::SubField<point>, point>
 {
+    // friends
+    template<class Face> friend class MeshedSurface;
+    template<class Face> friend class UnsortedMeshedSurface;
 
 public:
 
@@ -259,17 +262,15 @@ public:
             void transfer(MeshedSurface<face>&);
 
 
-
+        //- Avoid masking the normal objectRegistry write
         using surfaceRegistry::write;
 
-
         //- Write to file
         static void write(const fileName&, const surfMesh&);
 
         //- Write to file
         void write(const fileName&);
 
-
         //  Storage management
 
             //- Transfer contents to the Xfer container as a MeshedSurface
diff --git a/src/surfMesh/surfaceFormats/surfaceFormatsCore.C b/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
index 1e957ed672d679375ccc0fe654edc6f0d96d45a1..65d71b252b2d9a1f889635f0658f2853e75bb336 100644
--- a/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
+++ b/src/surfMesh/surfaceFormats/surfaceFormatsCore.C
@@ -25,9 +25,10 @@ License
 \*---------------------------------------------------------------------------*/
 
 #include "surfaceFormatsCore.H"
+
+#include "Time.H"
 #include "IFstream.H"
 #include "OFstream.H"
-#include "Time.H"
 #include "SortableList.H"
 #include "surfMesh.H"
 
@@ -37,13 +38,6 @@ Foam::word Foam::fileFormats::surfaceFormatsCore::nativeExt("ofs");
 
 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
 
-bool
-Foam::fileFormats::surfaceFormatsCore::isNative(const word& ext)
-{
-    return (ext == nativeExt);
-}
-
-
 Foam::string
 Foam::fileFormats::surfaceFormatsCore::getLineNoComment
 (
@@ -60,7 +54,7 @@ Foam::fileFormats::surfaceFormatsCore::getLineNoComment
     return line;
 }
 
-
+#if 0
 Foam::fileName
 Foam::fileFormats::surfaceFormatsCore::localMeshFileName(const word& surfName)
 {
@@ -79,7 +73,7 @@ Foam::fileFormats::surfaceFormatsCore::localMeshFileName(const word& surfName)
 Foam::fileName
 Foam::fileFormats::surfaceFormatsCore::findMeshInstance
 (
-    const Time& d,
+    const Time& t,
     const word& surfName
 )
 {
@@ -88,12 +82,12 @@ Foam::fileFormats::surfaceFormatsCore::findMeshInstance
     // Search back through the time directories list to find the time
     // closest to and lower than current time
 
-    instantList ts = d.times();
+    instantList ts = t.times();
     label instanceI;
 
     for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
     {
-        if (ts[instanceI].value() <= d.timeOutputValue())
+        if (ts[instanceI].value() <= t.timeOutputValue())
         {
             break;
         }
@@ -106,7 +100,7 @@ Foam::fileFormats::surfaceFormatsCore::findMeshInstance
     {
         for (label i = instanceI; i >= 0; --i)
         {
-            if (isFile(d.path()/ts[i].name()/localName))
+            if (isFile(t.path()/ts[i].name()/localName))
             {
                 return ts[i].name();
             }
@@ -120,7 +114,7 @@ Foam::fileFormats::surfaceFormatsCore::findMeshInstance
 Foam::fileName
 Foam::fileFormats::surfaceFormatsCore::findMeshFile
 (
-    const Time& d,
+    const Time& t,
     const word& surfName
 )
 {
@@ -129,12 +123,12 @@ Foam::fileFormats::surfaceFormatsCore::findMeshFile
     // Search back through the time directories list to find the time
     // closest to and lower than current time
 
-    instantList ts = d.times();
+    instantList ts = t.times();
     label instanceI;
 
     for (instanceI = ts.size()-1; instanceI >= 0; --instanceI)
     {
-        if (ts[instanceI].value() <= d.timeOutputValue())
+        if (ts[instanceI].value() <= t.timeOutputValue())
         {
             break;
         }
@@ -147,7 +141,7 @@ Foam::fileFormats::surfaceFormatsCore::findMeshFile
     {
         for (label i = instanceI; i >= 0; --i)
         {
-            fileName testName(d.path()/ts[i].name()/localName);
+            fileName testName(t.path()/ts[i].name()/localName);
 
             if (isFile(testName))
             {
@@ -157,94 +151,9 @@ Foam::fileFormats::surfaceFormatsCore::findMeshFile
     }
 
     // fallback to "constant"
-    return d.path()/"constant"/localName;
-}
-
-
-// Returns zone info.
-// Sets faceMap to the indexing according to zone numbers.
-// Zone numbers start at 0.
-Foam::surfZoneList
-Foam::fileFormats::surfaceFormatsCore::sortedZonesById
-(
-    const UList<label>& zoneIds,
-    const Map<word>& zoneNames,
-    labelList& faceMap
-)
-{
-    // determine sort order according to zone numbers
-
-    // std::sort() really seems to mix up the order.
-    // and std::stable_sort() might take too long / too much memory
-
-    // Assuming that we have relatively fewer zones compared to the
-    // number of items, just do it ourselves
-
-    // step 1: get zone sizes and store (origId => zoneI)
-    Map<label> lookup;
-    forAll(zoneIds, faceI)
-    {
-        const label origId = zoneIds[faceI];
-
-        Map<label>::iterator fnd = lookup.find(origId);
-        if (fnd != lookup.end())
-        {
-            fnd()++;
-        }
-        else
-        {
-            lookup.insert(origId, 1);
-        }
-    }
-
-    // step 2: assign start/size (and name) to the newZones
-    // re-use the lookup to map (zoneId => zoneI)
-    surfZoneList zoneLst(lookup.size());
-    label start = 0;
-    label zoneI = 0;
-    forAllIter(Map<label>, lookup, iter)
-    {
-        label origId = iter.key();
-
-        word name;
-        Map<word>::const_iterator fnd = zoneNames.find(origId);
-        if (fnd != zoneNames.end())
-        {
-            name = fnd();
-        }
-        else
-        {
-            name = word("zone") + ::Foam::name(zoneI);
-        }
-
-        zoneLst[zoneI] = surfZone
-        (
-            name,
-            0,           // initialize with zero size
-            start,
-            zoneI
-        );
-
-        // increment the start for the next zone
-        // and save the (zoneId => zoneI) mapping
-        start += iter();
-        iter() = zoneI++;
-    }
-
-
-    // step 3: build the re-ordering
-    faceMap.setSize(zoneIds.size());
-
-    forAll(zoneIds, faceI)
-    {
-        label zoneI = lookup[zoneIds[faceI]];
-        faceMap[faceI] =
-            zoneLst[zoneI].start() + zoneLst[zoneI].size()++;
-    }
-
-    // with reordered faces registered in faceMap
-    return zoneLst;
+    return t.path()/"constant"/localName;
 }
+#endif
 
 
 bool
@@ -291,6 +200,7 @@ Foam::fileFormats::surfaceFormatsCore::surfaceFormatsCore()
 Foam::fileFormats::surfaceFormatsCore::~surfaceFormatsCore()
 {}
 
+
 // * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * * //
 
 // * * * * * * * * * * * * Protected Member Functions  * * * * * * * * * * * //
diff --git a/src/surfMesh/surfaceFormats/surfaceFormatsCore.H b/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
index 3e69ddb150954a0a7e5e660f05f69f33d825edf1..b23ff267191650effebdb247a9d0377d1b6589d7 100644
--- a/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
+++ b/src/surfMesh/surfaceFormats/surfaceFormatsCore.H
@@ -75,15 +75,6 @@ protected:
             return List<surfZone>(1, surfZone(name, container.size(), 0, 0));
         }
 
-        //- Determine the sort order from the zone ids.
-        //  Returns zone list and sets faceMap to indices within faceLst
-        static surfZoneList sortedZonesById
-        (
-            const UList<label>& zoneIds,
-            const Map<word>& zoneNames,
-            labelList& faceMap
-        );
-
         //- Read non-comment line
         static string getLineNoComment(IFstream&);
 
@@ -97,27 +88,27 @@ public:
 
     // Static Member Functions
 
-        //- Check if file extension corresponds to 'native' surface format
-        static bool isNative(const word&);
+        static bool checkSupport
+        (
+            const wordHashSet& available,
+            const word& ext,
+            const bool verbose,
+            const word& functionName
+        );
+
 
         //- Return the local file name (within time directory)
+        //  NEEDS FIXING
         static fileName localMeshFileName(const word& surfName="");
 
         //- Find instance with surfName
+        //  NEEDS FIXING
         static fileName findMeshInstance(const Time&, const word& surfName="");
 
         //- Find mesh file with surfName
+        //  NEEDS FIXING
         static fileName findMeshFile(const Time&, const word& surfName="");
 
-        static bool checkSupport
-        (
-            const wordHashSet& available,
-            const word& ext,
-            const bool verbose,
-            const word& functionName
-        );
-
-
     // Constructors
 
         //- Construct null