diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H
index acfebc54d150a15d504c904c5ce8ddd6b567a19f..44b317ca934312c63efbef4878bb92605423cb91 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndex.H
@@ -33,7 +33,9 @@ Description
 
 
 SourceFiles
+    globalIndexI.H
     globalIndex.C
+    globalIndexTemplates.C
 
 \*---------------------------------------------------------------------------*/
 
@@ -71,6 +73,8 @@ public:
 
     // Constructors
 
+        //- Construct null
+        inline globalIndex();
 
         //- Construct from local max size
         globalIndex(const label localSize);
@@ -87,12 +91,21 @@ public:
         //- Construct from components
         globalIndex(const labelList& offsets);
 
+        //- Construct from components
+        inline globalIndex(const Xfer<labelList>& offsets);
+
         //- Construct from Istream
         globalIndex(Istream& is);
 
 
     // Member Functions
 
+        // Edit
+
+            //- Change after construction
+            inline labelList& offsets();
+
+
         // Queries relating to my processor (using world communicator)
 
             //- my local size
@@ -133,6 +146,31 @@ public:
             inline label offset(const label procI) const;
 
 
+        // Other
+
+            //- Collect data in processor order on master (== procIDs[0]).
+            //  Needs offsets only on master.
+            template<class Type>
+            void gather
+            (
+                const label comm,
+                const labelList& procIDs,
+                const UList<Type>& fld,
+                List<Type>& allFld,
+                const int tag = UPstream::msgType()
+            ) const;
+
+            //- Distribute data in processor order. Requires fld to be sized!
+            template<class Type>
+            void scatter
+            (
+                const label comm,
+                const labelList& procIDs,
+                const UList<Type>& allFld,
+                UList<Type>& fld,
+                const int tag = UPstream::msgType()
+            ) const;
+
 
     // IOstream Operators
 
@@ -147,6 +185,12 @@ public:
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
+#ifdef NoRepository
+#   include "globalIndexTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
 #include "globalIndexI.H"
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H
index d85816f1b4cabff927f8481e6ee6573dffe26180..fcdb56cfc13b1567f3f9bbd382f3427f4798b2a8 100644
--- a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexI.H
@@ -25,8 +25,26 @@ License
 
 #include "ListOps.H"
 
+// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //
+
+Foam::globalIndex::globalIndex()
+{}
+
+
+Foam::globalIndex::globalIndex(const Xfer<labelList>& offsets)
+:
+    offsets_(offsets)
+{}
+
+
 // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
 
+inline Foam::labelList& Foam::globalIndex::offsets()
+{
+    return offsets_;
+}
+
+
 inline Foam::label Foam::globalIndex::offset(const label procI) const
 {
     return offsets_[procI];
diff --git a/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexTemplates.C b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexTemplates.C
new file mode 100644
index 0000000000000000000000000000000000000000..9712f5c41c49568ea4b771f693ad4023ff672146
--- /dev/null
+++ b/src/OpenFOAM/meshes/polyMesh/globalMeshData/globalIndexTemplates.C
@@ -0,0 +1,198 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 2013 OpenFOAM Foundation
+     \\/     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 "globalIndex.H"
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+template<class Type>
+void Foam::globalIndex::gather
+(
+    const label comm,
+    const labelList& procIDs,
+    const UList<Type>& fld,
+    List<Type>& allFld,
+    const int tag
+) const
+{
+    if (Pstream::myProcNo(comm) == procIDs[0])
+    {
+        allFld.setSize(size());
+
+        // Assign my local data
+        SubList<Type>(allFld, fld.size(), 0).assign(fld);
+
+        for (label i = 1; i < procIDs.size(); i++)
+        {
+            SubList<Type> procSlot
+            (
+                allFld,
+                offsets_[i+1]-offsets_[i],
+                offsets_[i]
+            );
+
+            if (contiguous<Type>())
+            {
+                IPstream::read
+                (
+                    Pstream::scheduled,
+                    procIDs[i],
+                    reinterpret_cast<char*>(procSlot.begin()),
+                    procSlot.byteSize(),
+                    tag,
+                    comm
+                );
+            }
+            else
+            {
+                IPstream fromSlave
+                (
+                    Pstream::scheduled,
+                    procIDs[i],
+                    0,
+                    tag,
+                    comm
+                );
+                fromSlave >> procSlot;
+            }
+        }
+    }
+    else
+    {
+        if (contiguous<Type>())
+        {
+            OPstream::write
+            (
+                Pstream::scheduled,
+                procIDs[0],
+                reinterpret_cast<const char*>(fld.begin()),
+                fld.byteSize(),
+                tag,
+                comm
+            );
+        }
+        else
+        {
+            OPstream toMaster
+            (
+                Pstream::scheduled,
+                procIDs[0],
+                0,
+                tag,
+                comm
+            );
+            toMaster << fld;
+        }
+    }
+}
+
+
+template<class Type>
+void Foam::globalIndex::scatter
+(
+    const label comm,
+    const labelList& procIDs,
+    const UList<Type>& allFld,
+    UList<Type>& fld,
+    const int tag
+) const
+{
+    if (Pstream::myProcNo(comm) == procIDs[0])
+    {
+        fld.assign
+        (
+            SubList<Type>
+            (
+                allFld,
+                offsets_[1]-offsets_[0]
+            )
+        );
+
+        for (label i = 1; i < procIDs.size(); i++)
+        {
+            const SubList<Type> procSlot
+            (
+                allFld,
+                offsets_[i+1]-offsets_[i],
+                offsets_[i]
+            );
+
+            if (contiguous<Type>())
+            {
+                OPstream::write
+                (
+                    Pstream::scheduled,
+                    procIDs[i],
+                    reinterpret_cast<const char*>(procSlot.begin()),
+                    procSlot.byteSize(),
+                    tag,
+                    comm
+                );
+            }
+            else
+            {
+                OPstream toSlave
+                (
+                    Pstream::scheduled,
+                    procIDs[i],
+                    0,
+                    tag,
+                    comm
+                );
+                toSlave << procSlot;
+            }
+        }
+    }
+    else
+    {
+        if (contiguous<Type>())
+        {
+            IPstream::read
+            (
+                Pstream::scheduled,
+                procIDs[0],
+                reinterpret_cast<char*>(fld.begin()),
+                fld.byteSize(),
+                tag,
+                comm
+            );
+        }
+        else
+        {
+            IPstream fromMaster
+            (
+                Pstream::scheduled,
+                procIDs[0],
+                0,
+                tag,
+                comm
+            );
+            fromMaster >> fld;
+        }
+    }
+}
+
+
+// ************************************************************************* //