diff --git a/applications/utilities/mesh/advanced/refineHexMesh/Make/files b/applications/utilities/mesh/advanced/refineHexMesh/Make/files
new file mode 100644
index 0000000000000000000000000000000000000000..824d6b0cd0334fe7688cf5fdaee6bba352c94ed1
--- /dev/null
+++ b/applications/utilities/mesh/advanced/refineHexMesh/Make/files
@@ -0,0 +1,3 @@
+refineHexMesh.C
+EXE = $(FOAM_APPBIN)/refineHexMesh
+
diff --git a/applications/utilities/mesh/advanced/refineHexMesh/Make/options b/applications/utilities/mesh/advanced/refineHexMesh/Make/options
new file mode 100644
index 0000000000000000000000000000000000000000..376f4dff51d6c32550bd7c1a13421daab764823c
--- /dev/null
+++ b/applications/utilities/mesh/advanced/refineHexMesh/Make/options
@@ -0,0 +1,10 @@
+EXE_INC = \
+    -I$(LIB_SRC)/finiteVolume/lnInclude \
+    -I$(LIB_SRC)/dynamicMesh/lnInclude \
+    -I$(LIB_SRC)/meshTools/lnInclude
+
+
+EXE_LIBS = \
+    -ldynamicMesh \
+    -lmeshTools \
+    -lfiniteVolume
diff --git a/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
new file mode 100644
index 0000000000000000000000000000000000000000..4bed4c059cbbbb047ac7b34f0e4610f82c6579dd
--- /dev/null
+++ b/applications/utilities/mesh/advanced/refineHexMesh/refineHexMesh.C
@@ -0,0 +1,185 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2007 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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Description
+    Hex 2x2x2 refiner
+
+\*---------------------------------------------------------------------------*/
+
+#include "fvMesh.H"
+#include "pointMesh.H"
+#include "argList.H"
+#include "Time.H"
+#include "hexRef8.H"
+#include "cellSet.H"
+#include "OFstream.H"
+#include "meshTools.H"
+#include "IFstream.H"
+#include "polyTopoChange.H"
+#include "mapPolyMesh.H"
+#include "volMesh.H"
+#include "surfaceMesh.H"
+#include "volFields.H"
+#include "surfaceFields.H"
+#include "pointFields.H"
+#include "ReadFields.H"
+
+using namespace Foam;
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+// Main program:
+int main(int argc, char *argv[])
+{
+    argList::validArgs.append("cellSet");
+#   include "setRootCase.H"
+#   include "createTime.H"
+#   include "createMesh.H"
+    pointMesh pMesh(mesh);
+
+    word cellSetName(args.args()[1]);
+
+    Info<< "Reading cells to refine from cellSet " << cellSetName
+        << nl << endl;
+
+    cellSet cellsToRefine(mesh, cellSetName);
+
+    Info<< "Read " << returnReduce(cellsToRefine.size(), sumOp<label>())
+        << " cells to refine from cellSet " << cellSetName << nl
+        << endl;
+
+
+    // Read objects in time directory
+    IOobjectList objects(mesh, runTime.timeName());
+
+    // Read vol fields.
+
+    PtrList<volScalarField> vsFlds;
+    ReadFields(mesh, objects, vsFlds);
+
+    PtrList<volVectorField> vvFlds;
+    ReadFields(mesh, objects, vvFlds);
+
+    PtrList<volSphericalTensorField> vstFlds;
+    ReadFields(mesh, objects, vstFlds);
+
+    PtrList<volSymmTensorField> vsymtFlds;
+    ReadFields(mesh, objects, vsymtFlds);
+
+    PtrList<volTensorField> vtFlds;
+    ReadFields(mesh, objects, vtFlds);
+
+    // Read surface fields.
+
+    PtrList<surfaceScalarField> ssFlds;
+    ReadFields(mesh, objects, ssFlds);
+
+    PtrList<surfaceVectorField> svFlds;
+    ReadFields(mesh, objects, svFlds);
+
+    PtrList<surfaceSphericalTensorField> sstFlds;
+    ReadFields(mesh, objects, sstFlds);
+
+    PtrList<surfaceSymmTensorField> ssymtFlds;
+    ReadFields(mesh, objects, ssymtFlds);
+
+    PtrList<surfaceTensorField> stFlds;
+    ReadFields(mesh, objects, stFlds);
+
+    // Read point fields
+    PtrList<pointScalarField> psFlds;
+    ReadFields(pMesh, objects, psFlds);
+    
+    PtrList<pointVectorField> pvFlds;
+    ReadFields(pMesh, objects, pvFlds);
+
+
+
+    // Construct refiner without unrefinement. Read existing point/cell level.
+    hexRef8 meshCutter(mesh);
+
+    // Some stats
+    Info<< "Read mesh:" << nl
+        << "    cells:" << mesh.globalData().nTotalCells() << nl
+        << "    faces:" << mesh.globalData().nTotalFaces() << nl
+        << "    points:" << mesh.globalData().nTotalPoints() << nl
+        << "    cellLevel :"
+        << " min:" << gMin(meshCutter.cellLevel())
+        << " max:" << gMax(meshCutter.cellLevel()) << nl
+        << "    pointLevel :"
+        << " min:" << gMin(meshCutter.pointLevel())
+        << " max:" << gMax(meshCutter.pointLevel()) << nl
+        << endl;
+
+
+    // Maintain 2:1 ratio
+    labelList newCellsToRefine
+    (
+        meshCutter.consistentRefinement
+        (
+            cellsToRefine.toc(),
+            true                  // extend set
+        )
+    );
+
+    // Mesh changing engine.
+    polyTopoChange meshMod(mesh);
+
+    // Play refinement commands into mesh changer.
+    meshCutter.setRefinement(newCellsToRefine, meshMod);
+
+    runTime++;
+
+    // Create mesh, return map from old to new mesh.
+    autoPtr<mapPolyMesh> map = meshMod.changeMesh(mesh, false);
+
+    // Update fields
+    mesh.updateMesh(map);
+    pMesh.updateMesh(map);
+
+    // Update numbering of cells/vertices.
+    meshCutter.updateMesh(map);
+
+    // Optionally inflate mesh
+    if (map().hasMotionPoints())
+    {
+        mesh.movePoints(map().preMotionPoints());
+        pMesh.movePoints(map().preMotionPoints());
+    }
+
+    Pout<< "Refined from " << returnReduce(map().nOldCells(), sumOp<label>())
+        << " to " << mesh.globalData().nTotalCells() << " cells." << nl << endl;
+
+    Info<< "Writing mesh to " << runTime.timeName() << endl;
+
+    mesh.write();
+    meshCutter.write();
+
+    Info<< "End\n" << endl;
+
+    return 0;
+}
+
+
+// ************************************************************************* //