[xdmf] 17/38: Merge missing xdmf3 files

Alastair McKinstry mckinstry at moszumanska.debian.org
Thu Apr 13 15:16:34 UTC 2017


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to branch debian/master
in repository xdmf.

commit 09f75f49c30bcdc406bd7d23160c3309f589e3cf
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Sun Aug 14 19:45:14 2016 +0100

    Merge missing xdmf3 files
---
 CMake/FindExodus.cmake                             |    21 +
 CMake/FindMPI4PY.cmake                             |    34 +
 CMake/FindMetis.cmake                              |    16 +
 CMake/FindNetCDF.cmake                             |    29 +
 CMake/TestingSuite/AddTestsC.cmake                 |   175 +
 CMake/TestingSuite/AddTestsCxx.cmake               |   183 +
 CMake/TestingSuite/AddTestsFortran.cmake           |   191 +
 CMake/TestingSuite/AddTestsJava.cmake              |   171 +
 CMake/TestingSuite/AddTestsPython.cmake            |   247 +
 CMake/TestingSuite/TestDriverC.cmake.in            |    37 +
 CMake/TestingSuite/TestDriverCxx.cmake.in          |    37 +
 CMake/TestingSuite/TestDriverFortran.cmake.in      |    37 +
 CMake/TestingSuite/TestDriverJava.cmake.in         |    33 +
 CMake/TestingSuite/TestDriverPython.cmake.in       |    37 +
 CMake/TestingSuite/TestDriverPythonScript.cmake.in |    41 +
 CMake/TestingSuite/TestingSetup.cmake              |    91 +
 CMake/UseDoxygen.cmake                             |   101 +
 CMake/VersionSuite/ProjectVersion.hpp              |   152 +
 CMake/VersionSuite/SetUpVersion.cmake              |    83 +
 CMake/XdmfFunctions.cmake                          |    16 +
 Copyright.txt                                      |    32 +
 README.md                                          |    43 +
 Xdmf.dtd                                           |    85 +
 Xdmf.hpp                                           |   185 +
 Xdmf.i                                             |  1269 ++
 XdmfAggregate.cpp                                  |   272 +
 XdmfAggregate.hpp                                  |   214 +
 XdmfAttribute.cpp                                  |   275 +
 XdmfAttribute.hpp                                  |   290 +
 XdmfAttributeCenter.cpp                            |   154 +
 XdmfAttributeCenter.hpp                            |   141 +
 XdmfAttributeType.cpp                              |   182 +
 XdmfAttributeType.hpp                              |   149 +
 XdmfConfig.cmake.in                                |     5 +
 XdmfConfig.hpp.in                                  |    32 +
 XdmfCurvilinearGrid.cpp                            |   465 +
 XdmfCurvilinearGrid.hpp                            |   344 +
 XdmfDomain.cpp                                     |   483 +
 XdmfDomain.hpp                                     |   428 +
 XdmfGeometry.cpp                                   |   353 +
 XdmfGeometry.hpp                                   |   260 +
 XdmfGeometryType.cpp                               |   239 +
 XdmfGeometryType.hpp                               |   190 +
 XdmfGraph.cpp                                      |   175 +
 XdmfGraph.hpp                                      |   141 +
 XdmfGrid.cpp                                       |   518 +
 XdmfGrid.hpp                                       |   649 +
 XdmfGridCollection.cpp                             |   405 +
 XdmfGridCollection.hpp                             |   220 +
 XdmfGridCollectionType.cpp                         |   129 +
 XdmfGridCollectionType.hpp                         |   133 +
 XdmfGridController.cpp                             |   195 +
 XdmfGridController.hpp                             |   226 +
 XdmfGridTemplate.cpp                               |   975 ++
 XdmfGridTemplate.hpp                               |   224 +
 XdmfItemFactory.cpp                                |   390 +
 XdmfItemFactory.hpp                                |   102 +
 XdmfMap.cpp                                        |   707 +
 XdmfMap.hpp                                        |   481 +
 XdmfReader.cpp                                     |    83 +
 XdmfReader.hpp                                     |   115 +
 XdmfRectilinearGrid.cpp                            |   677 +
 XdmfRectilinearGrid.hpp                            |   439 +
 XdmfRegularGrid.cpp                                |   673 +
 XdmfRegularGrid.hpp                                |   482 +
 XdmfSet.cpp                                        |   251 +
 XdmfSet.hpp                                        |   257 +
 XdmfSetType.cpp                                    |   153 +
 XdmfSetType.hpp                                    |   117 +
 XdmfTemplate.cpp                                   |  1244 ++
 XdmfTemplate.hpp                                   |   218 +
 XdmfTime.cpp                                       |   124 +
 XdmfTime.hpp                                       |   165 +
 XdmfTopology.cpp                                   |   605 +
 XdmfTopology.hpp                                   |   231 +
 XdmfTopologyType.cpp                               |  1266 ++
 XdmfTopologyType.hpp                               |   506 +
 XdmfUnstructuredGrid.cpp                           |   401 +
 XdmfUnstructuredGrid.hpp                           |   267 +
 core/CMakeLists.txt                                |   285 +
 core/XdmfArray.cpp                                 |  2612 ++++
 core/XdmfArray.hpp                                 |  2008 +++
 core/XdmfArray.tpp                                 |   812 ++
 core/XdmfArrayReference.cpp                        |   156 +
 core/XdmfArrayReference.hpp                        |   262 +
 core/XdmfArrayType.cpp                             |   615 +
 core/XdmfArrayType.hpp                             |   293 +
 core/XdmfBinaryController.cpp                      |   404 +
 core/XdmfBinaryController.hpp                      |   247 +
 core/XdmfConfig.hpp.in                             |    31 +
 core/XdmfCore.hpp                                  |    73 +
 core/XdmfCore.i                                    |  1382 ++
 core/XdmfCoreConfig.hpp.in                         |    37 +
 core/XdmfCoreItemFactory.cpp                       |   756 ++
 core/XdmfCoreItemFactory.hpp                       |   118 +
 core/XdmfCoreReader.cpp                            |   416 +
 core/XdmfCoreReader.hpp                            |   269 +
 core/XdmfError.cpp                                 |   207 +
 core/XdmfError.hpp                                 |   326 +
 core/XdmfFunction.cpp                              |  1827 +++
 core/XdmfFunction.hpp                              |  1398 ++
 core/XdmfHDF5Controller.cpp                        |   460 +
 core/XdmfHDF5Controller.hpp                        |   270 +
 core/XdmfHDF5Writer.cpp                            |  1701 +++
 core/XdmfHDF5Writer.hpp                            |   420 +
 core/XdmfHeavyDataController.cpp                   |   398 +
 core/XdmfHeavyDataController.hpp                   |   559 +
 core/XdmfHeavyDataDescription.cpp                  |    88 +
 core/XdmfHeavyDataDescription.hpp                  |   104 +
 core/XdmfHeavyDataWriter.cpp                       |   254 +
 core/XdmfHeavyDataWriter.hpp                       |   640 +
 core/XdmfInformation.cpp                           |   277 +
 core/XdmfInformation.hpp                           |   275 +
 core/XdmfItem.cpp                                  |   155 +
 core/XdmfItem.hpp                                  |   515 +
 core/XdmfItemProperty.cpp                          |    83 +
 core/XdmfItemProperty.hpp                          |    92 +
 core/XdmfPlaceholder.cpp                           |   224 +
 core/XdmfPlaceholder.hpp                           |   156 +
 core/XdmfSharedPtr.hpp                             |    61 +
 core/XdmfSparseMatrix.cpp                          |   387 +
 core/XdmfSparseMatrix.hpp                          |   555 +
 core/XdmfSubset.cpp                                |   489 +
 core/XdmfSubset.hpp                                |   437 +
 core/XdmfSystemUtils.cpp                           |    80 +
 core/XdmfSystemUtils.hpp                           |    93 +
 core/XdmfTIFFController.cpp                        |   617 +
 core/XdmfTIFFController.hpp                        |   187 +
 core/XdmfVisitor.cpp                               |    40 +
 core/XdmfVisitor.hpp                               |    81 +
 core/XdmfWriter.cpp                                |   842 ++
 core/XdmfWriter.hpp                                |   629 +
 core/dsm/CMakeLists.txt                            |   216 +
 core/dsm/XdmfDSM.hpp                               |    66 +
 core/dsm/XdmfDSM.i                                 |   374 +
 core/dsm/XdmfDSMBuffer.cpp                         |  3030 +++++
 core/dsm/XdmfDSMBuffer.hpp                         |  2949 +++++
 core/dsm/XdmfDSMCommMPI.cpp                        |  1196 ++
 core/dsm/XdmfDSMCommMPI.hpp                        |  1548 +++
 core/dsm/XdmfDSMDescription.cpp                    |   115 +
 core/dsm/XdmfDSMDescription.hpp                    |   113 +
 core/dsm/XdmfDSMDriver.cpp                         |  1333 ++
 core/dsm/XdmfDSMDriver.hpp                         |   147 +
 core/dsm/XdmfDSMItemFactory.cpp                    |   391 +
 core/dsm/XdmfDSMItemFactory.hpp                    |   114 +
 core/dsm/XdmfHDF5ControllerDSM.cpp                 |  1016 ++
 core/dsm/XdmfHDF5ControllerDSM.hpp                 |   749 ++
 core/dsm/XdmfHDF5WriterDSM.cpp                     |  1235 ++
 core/dsm/XdmfHDF5WriterDSM.hpp                     |   923 ++
 core/dsm/tests/C/CConnectTest.sh                   |     7 +
 core/dsm/tests/C/CDSMLoopTest.c                    |   310 +
 core/dsm/tests/C/CDSMLoopTest.sh                   |     1 +
 core/dsm/tests/C/CMakeLists.txt                    |    37 +
 core/dsm/tests/C/CXdmfAcceptTest.c                 |    56 +
 core/dsm/tests/C/CXdmfConnectTest.c                |   234 +
 core/dsm/tests/C/CXdmfConnectTest2.c               |   229 +
 core/dsm/tests/CMakeLists.txt                      |     6 +
 core/dsm/tests/Cxx/CMakeLists.txt                  |    61 +
 core/dsm/tests/Cxx/ConnectTest.sh                  |     7 +
 core/dsm/tests/Cxx/ConnectTestPaged.sh             |     7 +
 core/dsm/tests/Cxx/CrayConnectTest.sh              |     3 +
 core/dsm/tests/Cxx/DSMLoopTest.cpp                 |   376 +
 core/dsm/tests/Cxx/DSMLoopTest.sh                  |     1 +
 core/dsm/tests/Cxx/DSMLoopTestPaged.cpp            |   376 +
 core/dsm/tests/Cxx/DSMLoopTestPaged.sh             |     1 +
 core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.cpp  |   162 +
 core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.sh   |     1 +
 core/dsm/tests/Cxx/TestXdmfHDF5WriterDSM.cpp       |   117 +
 core/dsm/tests/Cxx/XdmfAcceptTest.cpp              |   118 +
 core/dsm/tests/Cxx/XdmfAcceptTestPaged.cpp         |   117 +
 core/dsm/tests/Cxx/XdmfConnectTest.cpp             |   320 +
 core/dsm/tests/Cxx/XdmfConnectTest2.cpp            |   244 +
 core/dsm/tests/Cxx/XdmfConnectTest2Paged.cpp       |   236 +
 core/dsm/tests/Cxx/XdmfConnectTestPaged.cpp        |   315 +
 core/dsm/tests/Python/CMakeLists.txt               |    51 +
 core/dsm/tests/Python/CrayPythonConnect.sh         |     5 +
 core/dsm/tests/Python/PythonConnect.sh             |     7 +
 core/dsm/tests/Python/PythonDSM.sh                 |     3 +
 core/dsm/tests/Python/XdmfExampleAcceptTest.py     |    82 +
 core/dsm/tests/Python/XdmfExampleConnectTest.py    |   212 +
 core/dsm/tests/Python/XdmfExampleConnectTest2.py   |   160 +
 core/dsm/tests/Python/XdmfExampleDsmTest.py        |   621 +
 core/loki/EmptyType.h                              |    49 +
 core/loki/HierarchyGenerators.h                    |   291 +
 core/loki/NullType.h                               |    34 +
 core/loki/Sequence.h                               |    49 +
 core/loki/TypeManip.h                              |   284 +
 core/loki/TypeTraits.h                             |  2228 ++++
 core/loki/Typelist.h                               |   459 +
 core/loki/TypelistMacros.h                         |   353 +
 core/loki/Visitor.h                                |   427 +
 core/tests/C/CMakeLists.txt                        |    47 +
 core/tests/C/CTestXdmfArray.c                      |   343 +
 core/tests/C/CTestXdmfArrayType.c                  |   161 +
 core/tests/C/CTestXdmfError.c                      |   100 +
 core/tests/C/CTestXdmfFunction.c                   |   393 +
 core/tests/C/CTestXdmfHDF5Controller.c             |   194 +
 core/tests/C/CTestXdmfInformation.c                |    71 +
 core/tests/C/CTestXdmfSparseMatrix.c               |   170 +
 core/tests/C/CTestXdmfSubset.c                     |   174 +
 core/tests/C/CTestXdmfWriter.c                     |    21 +
 core/tests/CMakeLists.txt                          |    10 +
 core/tests/Cxx/CMakeLists.txt                      |    59 +
 core/tests/Cxx/TestXdmfArray.cpp                   |   476 +
 core/tests/Cxx/TestXdmfArrayInsert.cpp             |    79 +
 .../Cxx/TestXdmfArrayMultiDimensionalInsert.cpp    |    52 +
 core/tests/Cxx/TestXdmfArrayMultidimensional.cpp   |    94 +
 core/tests/Cxx/TestXdmfArrayWriteRead.cpp          |   100 +
 .../tests/Cxx/TestXdmfArrayWriteReadHyperSlabs.cpp |    68 +
 core/tests/Cxx/TestXdmfError.cpp                   |   188 +
 core/tests/Cxx/TestXdmfHDF5Controller.cpp          |    27 +
 core/tests/Cxx/TestXdmfHDF5Writer.cpp              |   130 +
 core/tests/Cxx/TestXdmfHDF5WriterTree.cpp          |    75 +
 core/tests/Cxx/TestXdmfInformation.cpp             |    71 +
 core/tests/Cxx/TestXdmfSparseMatrix.cpp            |    34 +
 core/tests/Cxx/TestXdmfVersion.cpp                 |     8 +
 core/tests/Java/CMakeLists.txt                     |    36 +
 core/tests/Java/TestXdmfArray.java                 |    32 +
 core/tests/Java/TestXdmfEquals.java                |    39 +
 core/tests/Python/CMakeLists.txt                   |    42 +
 core/tests/Python/TestXdmfArray.py                 |   107 +
 core/tests/Python/TestXdmfArrayMultidimensional.py |    86 +
 core/tests/Python/TestXdmfEquals.py                |    13 +
 core/tests/Python/TestXdmfError.py                 |    47 +
 core/tests/Python/TestXdmfVersion.py               |     5 +
 doc/CMakeLists.txt                                 |     1 +
 doc/Doxyfile.in                                    |  1516 +++
 examples/Cxx/DSMLoopTest.cpp                       |   297 +
 examples/Cxx/ExampleXdmfAggregate.cpp              |    53 +
 examples/Cxx/ExampleXdmfArray.cpp                  |   468 +
 examples/Cxx/ExampleXdmfArrayType.cpp              |    47 +
 examples/Cxx/ExampleXdmfAttribute.cpp              |    61 +
 examples/Cxx/ExampleXdmfBinaryController.cpp       |    76 +
 examples/Cxx/ExampleXdmfCoreItemFactory.cpp        |    22 +
 examples/Cxx/ExampleXdmfCoreReader.cpp             |    53 +
 examples/Cxx/ExampleXdmfCurvilinearGrid.cpp        |    96 +
 examples/Cxx/ExampleXdmfDSM.cpp                    |   700 +
 examples/Cxx/ExampleXdmfDSMNoThread.cpp            |   953 ++
 examples/Cxx/ExampleXdmfDSMSelfcontained.cpp       |   285 +
 examples/Cxx/ExampleXdmfDomain.cpp                 |    12 +
 examples/Cxx/ExampleXdmfEdit.cpp                   |   826 ++
 examples/Cxx/ExampleXdmfError.cpp                  |    75 +
 examples/Cxx/ExampleXdmfFunction.cpp               |   522 +
 examples/Cxx/ExampleXdmfGeometry.cpp               |    49 +
 examples/Cxx/ExampleXdmfGeometryType.cpp           |    33 +
 examples/Cxx/ExampleXdmfGraph.cpp                  |    12 +
 examples/Cxx/ExampleXdmfGrid.cpp                   |    85 +
 examples/Cxx/ExampleXdmfGridCollection.cpp         |    44 +
 examples/Cxx/ExampleXdmfHDF5Controller.cpp         |    84 +
 examples/Cxx/ExampleXdmfHDF5Writer.cpp             |    57 +
 examples/Cxx/ExampleXdmfHeavyDataController.cpp    |   110 +
 examples/Cxx/ExampleXdmfHeavyDataWriter.cpp        |   127 +
 examples/Cxx/ExampleXdmfInformation.cpp            |    51 +
 examples/Cxx/ExampleXdmfItem.cpp                   |    60 +
 examples/Cxx/ExampleXdmfItemFactory.cpp            |    12 +
 examples/Cxx/ExampleXdmfItemProperty.cpp           |    14 +
 examples/Cxx/ExampleXdmfMap.cpp                    |   228 +
 examples/Cxx/ExampleXdmfPlaceholder.cpp            |    40 +
 examples/Cxx/ExampleXdmfRead.cpp                   |   676 +
 examples/Cxx/ExampleXdmfReader.cpp                 |    12 +
 examples/Cxx/ExampleXdmfRectilinearGrid.cpp        |   121 +
 examples/Cxx/ExampleXdmfRegularGrid.cpp            |   124 +
 examples/Cxx/ExampleXdmfSet.cpp                    |    43 +
 examples/Cxx/ExampleXdmfSparseMatrix.cpp           |    98 +
 examples/Cxx/ExampleXdmfSubset.cpp                 |   120 +
 examples/Cxx/ExampleXdmfSystemUtils.cpp            |    13 +
 examples/Cxx/ExampleXdmfTIFFController.cpp         |    56 +
 examples/Cxx/ExampleXdmfTime.cpp                   |    29 +
 examples/Cxx/ExampleXdmfTopology.cpp               |    31 +
 examples/Cxx/ExampleXdmfTopologyType.cpp           |    71 +
 examples/Cxx/ExampleXdmfUnstructuredGrid.cpp       |    74 +
 examples/Cxx/ExampleXdmfWrite.cpp                  |   242 +
 examples/Cxx/ExampleXdmfWriter.cpp                 |   155 +
 examples/Cxx/XdmfAcceptTest.cpp                    |   115 +
 examples/Cxx/XdmfConnectTest.cpp                   |   286 +
 examples/Cxx/XdmfConnectTest2.cpp                  |   199 +
 examples/Python/XdmfExampleAcceptTest.py           |    85 +
 examples/Python/XdmfExampleAggregate.py            |    40 +
 examples/Python/XdmfExampleArray.py                |   364 +
 examples/Python/XdmfExampleArrayType.py            |    43 +
 examples/Python/XdmfExampleAttribute.py            |    52 +
 examples/Python/XdmfExampleBinaryController.py     |    72 +
 examples/Python/XdmfExampleConnectTest.py          |   222 +
 examples/Python/XdmfExampleConnectTest2.py         |   166 +
 examples/Python/XdmfExampleCoreItemFactory.py      |    15 +
 examples/Python/XdmfExampleCoreReader.py           |    41 +
 examples/Python/XdmfExampleCurvilinearGrid.py      |    70 +
 examples/Python/XdmfExampleDSMNoThread.py          |   705 +
 examples/Python/XdmfExampleDSMStandalone.py        |   283 +
 examples/Python/XdmfExampleDomain.py               |     9 +
 examples/Python/XdmfExampleEdit.py                 |   568 +
 examples/Python/XdmfExampleError.py                |    72 +
 examples/Python/XdmfExampleFunction.py             |   410 +
 examples/Python/XdmfExampleGeometry.py             |    29 +
 examples/Python/XdmfExampleGeometryType.py         |    26 +
 examples/Python/XdmfExampleGraph.py                |     9 +
 examples/Python/XdmfExampleGrid.py                 |    75 +
 examples/Python/XdmfExampleGridCollection.py       |    36 +
 examples/Python/XdmfExampleHDF5Controller.py       |    81 +
 examples/Python/XdmfExampleHDF5Writer.py           |    53 +
 examples/Python/XdmfExampleHeavyDataController.py  |   104 +
 examples/Python/XdmfExampleHeavyDataWriter.py      |   117 +
 examples/Python/XdmfExampleInformation.py          |    46 +
 examples/Python/XdmfExampleItem.py                 |    52 +
 examples/Python/XdmfExampleItemFactory.py          |     9 +
 examples/Python/XdmfExampleItemProperty.py         |    11 +
 examples/Python/XdmfExampleMap.py                  |   205 +
 examples/Python/XdmfExamplePlaceholder.py          |    36 +
 examples/Python/XdmfExampleRead.py                 |   461 +
 examples/Python/XdmfExampleReader.py               |     9 +
 examples/Python/XdmfExampleRectilinearGrid.py      |    83 +
 examples/Python/XdmfExampleRegularGrid.py          |    87 +
 examples/Python/XdmfExampleSet.py                  |    36 +
 examples/Python/XdmfExampleSparseMatrix.py         |    93 +
 examples/Python/XdmfExampleSubset.py               |   109 +
 examples/Python/XdmfExampleSystemUtils.py          |     9 +
 examples/Python/XdmfExampleTIFFController.py       |    52 +
 examples/Python/XdmfExampleTime.py                 |    25 +
 examples/Python/XdmfExampleTopology.py             |    26 +
 examples/Python/XdmfExampleTopologyType.py         |    59 +
 examples/Python/XdmfExampleUnstructuredGrid.py     |    67 +
 examples/Python/XdmfExampleWrite.py                |   196 +
 examples/Python/XdmfExampleWriter.py               |   131 +
 tests/C/CMakeLists.txt                             |   102 +
 tests/C/CTestXdmfAggregate.c                       |    98 +
 tests/C/CTestXdmfAttribute.c                       |    88 +
 tests/C/CTestXdmfBinaryController.c                |    92 +
 tests/C/CTestXdmfCurvilinearGrid.c                 |   133 +
 tests/C/CTestXdmfDomain.c                          |   817 ++
 tests/C/CTestXdmfGeometry.c                        |    91 +
 tests/C/CTestXdmfGraph.c                           |   279 +
 tests/C/CTestXdmfGridCollection.c                  |  1204 ++
 tests/C/CTestXdmfGridController.c                  |   377 +
 tests/C/CTestXdmfMap.c                             |   307 +
 tests/C/CTestXdmfRectilinearGrid.c                 |   144 +
 tests/C/CTestXdmfRegularGrid.c                     |   138 +
 tests/C/CTestXdmfSet.c                             |    73 +
 tests/C/CTestXdmfTIFFReadWriteCompressed.c         |    83 +
 tests/C/CTestXdmfTopology.c                        |   101 +
 tests/C/CTestXdmfUnstructuredGrid.c                |   124 +
 tests/C/CTestXdmfWriter.c                          |   302 +
 tests/CMakeLists.txt                               |     9 +
 tests/Cxx/CMakeLists.txt                           |   163 +
 tests/Cxx/DSMFileTest.sh                           |     6 +
 tests/Cxx/ExampleXdmfEdit.cpp                      |   826 ++
 tests/Cxx/ExampleXdmfRead.cpp                      |   677 +
 tests/Cxx/ExampleXdmfWrite.cpp                     |   244 +
 tests/Cxx/HugeReadArray.cpp                        |    14 +
 tests/Cxx/HugeWriteArray.cpp                       |    96 +
 tests/Cxx/ReadArray.cpp                            |    61 +
 tests/Cxx/ReadFunctionArray.cpp                    |    61 +
 tests/Cxx/TestXdmfAggregate.cpp                    |    88 +
 tests/Cxx/TestXdmfAttribute.cpp                    |    23 +
 tests/Cxx/TestXdmfBinaryController.cpp             |    86 +
 tests/Cxx/TestXdmfCurvilinearGrid.cpp              |    78 +
 tests/Cxx/TestXdmfFunction.cpp                     |   349 +
 tests/Cxx/TestXdmfGeometry.cpp                     |    33 +
 tests/Cxx/TestXdmfGraph.cpp                        |    69 +
 tests/Cxx/TestXdmfGridCollection.cpp               |   112 +
 tests/Cxx/TestXdmfGridController.cpp               |   411 +
 tests/Cxx/TestXdmfGridTemplate.cpp                 |   306 +
 tests/Cxx/TestXdmfHDF5Hyperslab.cpp                |   233 +
 tests/Cxx/TestXdmfHDF5Visit.cpp                    |   114 +
 tests/Cxx/TestXdmfMap.cpp                          |   169 +
 tests/Cxx/TestXdmfMultiOpen.cpp                    |   110 +
 tests/Cxx/TestXdmfMultiXPath.cpp                   |    49 +
 tests/Cxx/TestXdmfReader.cpp                       |    72 +
 tests/Cxx/TestXdmfRectilinearGrid.cpp              |   114 +
 tests/Cxx/TestXdmfRegularGrid.cpp                  |   151 +
 tests/Cxx/TestXdmfSet.cpp                          |    52 +
 tests/Cxx/TestXdmfSubset.cpp                       |   131 +
 tests/Cxx/TestXdmfTIFFReadWriteCompressed.cpp      |   359 +
 tests/Cxx/TestXdmfTemplate.cpp                     |   569 +
 tests/Cxx/TestXdmfTime.cpp                         |    16 +
 tests/Cxx/TestXdmfTopology.cpp                     |    59 +
 tests/Cxx/TestXdmfTopologyMixed.cpp                |    81 +
 tests/Cxx/TestXdmfUnstructuredGrid.cpp             |    98 +
 tests/Cxx/TestXdmfVisitorValueCounter.cpp          |    67 +
 tests/Cxx/TestXdmfWriter.cpp                       |    31 +
 tests/Cxx/TestXdmfWriterHDF5ThenXML.cpp            |    34 +
 tests/Cxx/TestXdmfXPath.cpp                        |    93 +
 tests/Cxx/TestXdmfXPointerReference.cpp            |    57 +
 tests/Cxx/WriteArray.cpp                           |    42 +
 tests/Cxx/XdmfExampleCollect.cpp                   |    42 +
 tests/Cxx/XdmfFileAcceptTest.cpp                   |   166 +
 tests/Cxx/XdmfFileConnectTest.cpp                  |   118 +
 tests/Cxx/XdmfFortranExample.f90                   |   104 +
 tests/Cxx/XdmfPostFixCalc.cpp                      |  1215 ++
 tests/Cxx/XdmfTestCompareFiles.hpp                 |    35 +
 tests/Cxx/XdmfTestDataGenerator.hpp                |   102 +
 tests/Java/CMakeLists.txt                          |    44 +
 tests/Java/TestXdmfEquals.java                     |   149 +
 tests/Java/TestXdmfGC.java                         |    17 +
 tests/Java/TestXdmfJava.java                       |    17 +
 tests/Python/CMakeLists.txt                        |    65 +
 tests/Python/ReadArray.py                          |    76 +
 tests/Python/ReadTypeTest.py                       |    28 +
 tests/Python/SplitTime.py                          |    41 +
 tests/Python/TestXdmfEquals.py                     |    59 +
 tests/Python/TestXdmfFunction.py                   |    84 +
 tests/Python/TestXdmfFunctionRead.py               |    82 +
 tests/Python/TestXdmfHDF5Writer.py                 |    39 +
 tests/Python/TestXdmfRead.py                       |    58 +
 tests/Python/TestXdmfSet.py                        |    24 +
 tests/Python/TestXdmfWriter.py                     |   163 +
 tests/Python/TestXdmfXPointerReference.py          |    47 +
 tests/Python/WriteArray.py                         |    15 +
 tests/Python/WriteTime.py                          |    93 +
 tests/Python/XdmfExampleWrite.py                   |   106 +
 utils/CMakeLists.txt                               |   178 +
 utils/Xdmf.f                                       |   203 +
 utils/XdmfDiff.cpp                                 |   333 +
 utils/XdmfDiff.hpp                                 |   127 +
 utils/XdmfExodusConverter.cpp                      |   181 +
 utils/XdmfExodusReader.cpp                         |   698 +
 utils/XdmfExodusReader.hpp                         |   102 +
 utils/XdmfExodusWriter.cpp                         |   964 ++
 utils/XdmfExodusWriter.hpp                         |   116 +
 utils/XdmfFortran.cpp                              | 13022 +++++++++++++++++++
 utils/XdmfFortran.hpp                              |  3934 ++++++
 utils/XdmfGeometryConverter.cpp                    |   357 +
 utils/XdmfGeometryConverter.hpp                    |   155 +
 utils/XdmfPartitioner.cpp                          |  1426 ++
 utils/XdmfPartitioner.hpp                          |   176 +
 utils/XdmfTopologyConverter.cpp                    |  2122 +++
 utils/XdmfTopologyConverter.hpp                    |   172 +
 utils/XdmfUtils.hpp                                |    77 +
 utils/XdmfUtils.i                                  |   246 +
 utils/tests/C/CMakeLists.txt                       |    40 +
 utils/tests/C/CTestXdmfDiff.c                      |   140 +
 utils/tests/C/CTestXdmfExodusIO.c                  |   126 +
 utils/tests/C/CTestXdmfGeometryConverter.c         |   129 +
 utils/tests/C/CTestXdmfTopologyConverter.c         |   178 +
 utils/tests/CMakeLists.txt                         |    10 +
 utils/tests/Cxx/CMakeLists.txt                     |    38 +
 utils/tests/Cxx/TestXdmfDiff.cpp                   |   149 +
 utils/tests/Cxx/TestXdmfExodusIO.cpp               |    51 +
 utils/tests/Cxx/TestXdmfGeometryConverter.cpp      |   110 +
 utils/tests/Cxx/TestXdmfTopologyConverter.cpp      |   163 +
 utils/tests/Fortran/AcceptDSMFortran.f90           |    64 +
 utils/tests/Fortran/CMakeLists.txt                 |    70 +
 utils/tests/Fortran/ConnectDSMFortran.f90          |   124 +
 utils/tests/Fortran/ConnectDSMFortran.sh           |    11 +
 utils/tests/Fortran/ConnectDSMFortran2.f90         |    90 +
 utils/tests/Fortran/EditTestXdmfFortran.f90        |   333 +
 utils/tests/Fortran/FixedOutputTestXdmfFortran.f90 |   202 +
 utils/tests/Fortran/FunctionTestXdmfFortran.f90    |   144 +
 utils/tests/Fortran/NestedInfoFortran.f90          |    41 +
 utils/tests/Fortran/OutputTestXdmfFortran.f90      |   196 +
 utils/tests/Fortran/SubsetTestXdmfFortran.f90      |   169 +
 utils/tests/Fortran/TestXdmfFortran.f90            |   318 +
 utils/tests/Python/CMakeLists.txt                  |    31 +
 utils/tests/Python/XdmfTestDiff.py                 |   122 +
 utils/tests/Python/XdmfTestGeometryConverter.py    |    84 +
 utils/tests/Python/XdmfTestTopologyConverter.py    |   142 +
 455 files changed, 132095 insertions(+)

diff --git a/CMake/FindExodus.cmake b/CMake/FindExodus.cmake
new file mode 100644
index 0000000..4a82dc9
--- /dev/null
+++ b/CMake/FindExodus.cmake
@@ -0,0 +1,21 @@
+#
+# Find the Exodus finite element data model library from Sandia
+#
+#  EXODUS_FOUND - System has Exodus
+#  EXODUS_INCLUDE_DIR - The LibXml2 include directory
+#  EXODUS_LIBRARIES - The libraries needed to use LibXml2
+
+FIND_PACKAGE(NetCDF REQUIRED)
+
+FIND_PATH(EXODUS_INCLUDE_DIR NAMES exodusII.h)
+
+FIND_LIBRARY(EXODUS_LIBRARIES NAMES exodusii exodusIIv2c)
+
+INCLUDE(FindPackageHandleStandardArgs)
+
+# handle the QUIETLY and REQUIRED arguments and set EXODUS_FOUND to TRUE if 
+# all listed variables are TRUE
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Exodus DEFAULT_MSG EXODUS_LIBRARIES EXODUS_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(EXODUS_INCLUDE_DIR EXODUS_LIBRARIES)
+
diff --git a/CMake/FindMPI4PY.cmake b/CMake/FindMPI4PY.cmake
new file mode 100644
index 0000000..dc28ddf
--- /dev/null
+++ b/CMake/FindMPI4PY.cmake
@@ -0,0 +1,34 @@
+# - FindMPI4PY
+# Find mpi4py includes and library
+# This module defines:
+# MPI4PY_INCLUDE_DIR, where to find mpi4py.h, etc.
+# MPI4PY_FOUND
+
+# https://compacc.fnal.gov/projects/repositories/entry/synergia2/CMake/FindMPI4PY.cmake?rev=c147eafb60728606af4fe7b1b161a660df142e9a
+
+if(NOT MPI4PY_INCLUDE_DIR)
+    execute_process(COMMAND
+      "${PYTHON_EXECUTABLE}" "-c" "import mpi4py; print mpi4py.get_include()"
+      OUTPUT_VARIABLE MPI4PY_INCLUDE_DIR
+      RESULT_VARIABLE MPI4PY_COMMAND_RESULT
+      OUTPUT_STRIP_TRAILING_WHITESPACE)
+    if(MPI4PY_COMMAND_RESULT)
+        message("jfa: mpi4py not found")
+        set(MPI4PY_FOUND FALSE)
+    else(MPI4PY_COMMAND_RESULT)
+        if (MPI4PY_INCLUDE_DIR MATCHES "Traceback")
+            message("jfa: mpi4py matches traceback")
+            ## Did not successfully include MPI4PY
+            set(MPI4PY_FOUND FALSE)
+        else (MPI4PY_INCLUDE_DIR MATCHES "Traceback")
+            ## successful
+            set(MPI4PY_FOUND TRUE)
+            set(MPI4PY_INCLUDE_DIR ${MPI4PY_INCLUDE_DIR} CACHE STRING "mpi4py include path")
+        endif (MPI4PY_INCLUDE_DIR MATCHES "Traceback")
+    endif(MPI4PY_COMMAND_RESULT)
+else(NOT MPI4PY_INCLUDE_DIR)
+    set(MPI4PY_FOUND TRUE)
+endif(NOT MPI4PY_INCLUDE_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(MPI4PY DEFAULT_MSG MPI4PY_INCLUDE_DIR)
diff --git a/CMake/FindMetis.cmake b/CMake/FindMetis.cmake
new file mode 100644
index 0000000..9fd5745
--- /dev/null
+++ b/CMake/FindMetis.cmake
@@ -0,0 +1,16 @@
+# - Try to find the Metis graph partitioning library
+# Once done this will define
+#
+#  METIS_FOUND - System has metis
+#  METIS_INCLUDE_DIR - The metis include directory
+#  METIS_LIBRARIES - The libraries needed to use metis
+
+FIND_PATH(METIS_INCLUDE_DIR NAMES metis.h)
+
+FIND_LIBRARY(METIS_LIBRARIES NAMES metis)
+
+INCLUDE(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Metis DEFAULT_MSG METIS_LIBRARIES METIS_INCLUDE_DIR)
+
+MARK_AS_ADVANCED(METIS_INCLUDE_DIR METIS_LIBRARIES)
diff --git a/CMake/FindNetCDF.cmake b/CMake/FindNetCDF.cmake
new file mode 100644
index 0000000..e5e457b
--- /dev/null
+++ b/CMake/FindNetCDF.cmake
@@ -0,0 +1,29 @@
+#
+# Find NetCDF include directories and libraries
+#
+# NetCDF_FOUND - System has NetCDF
+# NetCDF_INCLUDE_DIR - The NetCDF include directory
+# NetCDF_LIBRARIES - The libraries needed to use NetCDF
+
+FIND_PATH(NetCDF_INCLUDE_DIR netcdf.h)
+
+FIND_LIBRARY(NetCDF_LIBRARIES
+  NAMES netcdf
+  ${NetCDF_PREFIX}
+  ${NetCDF_PREFIX}/lib64
+  ${NetCDF_PREFIX}/lib
+  /usr/local/lib64
+  /usr/lib64
+  /usr/lib64/netcdf-3
+  /usr/local/lib
+  /usr/lib
+  /usr/lib/netcdf-3
+)
+
+INCLUDE(FindPackageHandleStandardArgs)
+
+# handle the QUIETLY and REQUIRED arguments and set EXODUS_FOUND to TRUE if 
+# all listed variables are TRUE
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(NetCDF DEFAULT_MSG NetCDF_INCLUDE_DIR NetCDF_LIBRARIES)
+
+MARK_AS_ADVANCED(NetCDF_INCLUDE_DIR NetCDF_LIBRARIES)
diff --git a/CMake/TestingSuite/AddTestsC.cmake b/CMake/TestingSuite/AddTestsC.cmake
new file mode 100644
index 0000000..0de25bc
--- /dev/null
+++ b/CMake/TestingSuite/AddTestsC.cmake
@@ -0,0 +1,175 @@
+INCLUDE(TestingSetup)
+
+# We should have one place that points to the c source directory and the c
+# binary directory
+SET(c_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+SET(c_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+
+# C Add Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the c test dependencies.
+# 	  Note: The tests already depend on their own file
+# Parameters:         
+#              dependencies         = any dependencies needed for c tests
+MACRO(ADD_TEST_C_DEPENDENCIES dependencies)
+    IF(NOT ("${dependencies}" STREQUAL ""))
+        SET_PROPERTY(GLOBAL APPEND PROPERTY C_TEST_DEPENDENCIES
+            "${dependencies}"
+ 	)
+    ENDIF()
+ENDMACRO()
+
+# C Add LDPath  Macro
+# Author: Brian Panneton
+# Description: This macro adds the c test ldpaths.
+# Parameters:         
+#               ld  = any ldpaths needed for c tests
+MACRO(ADD_TEST_C_LDPATH ld)
+    GET_PROPERTY(ldpath GLOBAL PROPERTY C_TEST_LDPATH)
+    IF("${ld}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY C_TEST_LDPATH 
+                "${ldpath}${sep}${ld}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# C Add Path  Macro
+# Author: Brian Panneton
+# Description: This macro adds the c test paths.
+# Parameters:         
+#               p  = any paths needed for c tests
+MACRO(ADD_TEST_C_PATH p)
+    GET_PROPERTY(path GLOBAL PROPERTY C_TEST_PATH)
+    IF("${p}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY C_TEST_PATH 
+                "${path}${sep}${p}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# C Test Macro
+# Author: Brian Panneton
+# Description: This macro builds and add the c test in one shot.
+# Parameters:         
+#		executable      = executable name
+#		dup		= duplicate number
+#		tdep		= test dependency (Full Test Name with Prefix)
+#             	${ARGN}         = any arguments for the executable
+MACRO(ADD_TEST_C executable)
+    PARSE_TEST_ARGS("${ARGN}")
+    
+    IF(EXISTS ${c_source_dir}/${executable}.c)
+        ADD_EXECUTABLE(${executable}${dup} ${c_source_dir}/${executable}.c)
+    ENDIF()
+
+    GET_PROPERTY(c_dependencies GLOBAL PROPERTY C_TEST_DEPENDENCIES)
+    GET_PROPERTY(c_ldpath GLOBAL PROPERTY C_TEST_LDPATH)
+    GET_PROPERTY(c_path GLOBAL PROPERTY C_TEST_PATH)
+    TARGET_LINK_LIBRARIES(${executable}${dup} ${c_dependencies})
+ 
+    # Take care of windowisims
+    IF(WIN32)
+        SET_TARGET_PROPERTIES(${executable}${dup} PROPERTIES 
+            PREFIX ../
+            RUNTIME_OUTPUT_DIRECTORY ${c_binary_dir}
+            LIBRARY_OUTPUT_DIRECTORY ${c_binary_dir}
+            ARCHIVE_OUTPUT_DIRECTORY ${c_binary_dir})
+
+        IF("${c_path}" STREQUAL "")
+            SET(c_path ${c_ldpath})
+        ENDIF()
+    ENDIF()
+
+    SET_CORE("${c_binary_dir}")
+    ADD_TEST(C${is_core}_${executable}${dup} ${CMAKE_COMMAND}
+            -D "EXECUTABLE=${executable}${dup}"
+            -D "ARGUMENTS=${arguments}"
+            -D "LDPATH=${c_ldpath}"
+            -D "PATH=${c_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${c_binary_dir}/TestDriverC.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+	    SET_TESTS_PROPERTIES(C${is_core}_${executable}${dup}
+            PROPERTIES DEPENDS ${tdep})
+    ENDIF()
+ENDMACRO()
+
+# C MPI Test Macro
+# Author: Andrew Burns
+# Description: This macro builds and adds a script to execute MPI tests.
+# Parameters:
+#               executable      = script name
+#               files           = code to be compiled and executed by the script
+#               tdep            = test dependency (Full Test Name with Prefix)
+#               ${ARGN}         = any arguments for the executable
+MACRO(ADD_MPI_TEST_C script files)
+    PARSE_TEST_ARGS("${ARGN}")
+
+    set(tempfiles ${files})
+
+    WHILE(NOT "${tempfiles}" STREQUAL "")
+        # ${executable}
+        STRING(REGEX MATCH "([^ ,])+,|([^ ,])+" executable "${tempfiles}")
+        STRING(REGEX REPLACE "," "" executable "${executable}")
+        STRING(REGEX REPLACE "${executable},|${executable}" "" trimmed "${tempfiles}")
+
+        set(tempfiles ${trimmed})
+
+        IF(EXISTS ${c_source_dir}/${executable}.c)
+            ADD_EXECUTABLE(${executable} ${c_source_dir}/${executable}.c)
+        ENDIF()
+
+        GET_PROPERTY(c_dependencies GLOBAL PROPERTY C_TEST_DEPENDENCIES)
+        GET_PROPERTY(c_ldpath GLOBAL PROPERTY C_TEST_LDPATH)
+        GET_PROPERTY(c_path GLOBAL PROPERTY C_TEST_PATH)
+        TARGET_LINK_LIBRARIES(${executable} ${c_dependencies})
+
+        # Take care of windowisims
+        IF(WIN32)
+            SET_TARGET_PROPERTIES(${executable} PROPERTIES
+                PREFIX ../
+                RUNTIME_OUTPUT_DIRECTORY ${c_binary_dir}
+                LIBRARY_OUTPUT_DIRECTORY ${c_binary_dir}
+                ARCHIVE_OUTPUT_DIRECTORY ${c_binary_dir})
+
+            IF("${c_path}" STREQUAL "")
+                SET(c_path ${c_ldpath})
+            ENDIF()
+        ENDIF()
+    ENDWHILE()
+
+    SET_CORE("${c_binary_dir}")
+    ADD_TEST(C${is_core}_${script} ${CMAKE_COMMAND}
+            -D "EXECUTABLE='./${script}'"
+            -D "ARGUMENTS=${arguments}"
+            -D "LDPATH=${c_ldpath}"
+            -D "PATH=${c_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${c_binary_dir}/TestDriverC.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+            SET_TESTS_PROPERTIES(C${is_core}_${script}
+            PROPERTIES DEPENDS ${tdep} ${script})
+    ENDIF()
+    file(COPY
+        ${c_source_dir}/${script}
+        DESTINATION ${c_binary_dir}/
+    )
+ENDMACRO()
+
+# C Clean Macro
+# Author: Brian Panneton
+# Description: This macro sets up the c test for a make clean.
+# Parameters:         
+#		executable      = executable name
+#             	${ARGN}         = files that the executable created
+MACRO(CLEAN_TEST_C executable)
+    set_property(DIRECTORY APPEND PROPERTY 
+        ADDITIONAL_MAKE_CLEAN_FILES ${ARGN} 
+    )
+ENDMACRO()
+
+ # Configure the c 'driver' file
+CONFIGURE_FILE(${TESTING_SUITE_DIR}/TestingSuite/TestDriverC.cmake.in ${c_binary_dir}/TestDriverC.cmake @ONLY)
+
diff --git a/CMake/TestingSuite/AddTestsCxx.cmake b/CMake/TestingSuite/AddTestsCxx.cmake
new file mode 100644
index 0000000..4ba2aea
--- /dev/null
+++ b/CMake/TestingSuite/AddTestsCxx.cmake
@@ -0,0 +1,183 @@
+INCLUDE(TestingSetup)
+
+# We should have one place that points to the cxx source directory and the cxx
+# binary directory
+SET(cxx_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+SET(cxx_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+
+# CXX Add Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the cxx test dependencies.
+# 	  Note: The tests already depend on their own file
+# Parameters:         
+#              dependencies         = any dependencies needed for cxx tests
+MACRO(ADD_TEST_CXX_DEPENDENCIES dependencies)
+    IF(NOT ("${dependencies}" STREQUAL ""))
+        SET_PROPERTY(GLOBAL APPEND PROPERTY CXX_TEST_DEPENDENCIES
+            "${dependencies}"
+ 	)
+    ENDIF()
+ENDMACRO()
+
+# Cxx Add LDPath  Macro
+# Author: Brian Panneton
+# Description: This macro adds the cxx test ldpaths.
+# Parameters:         
+#               ld  = any ldpaths needed for cxx tests
+MACRO(ADD_TEST_CXX_LDPATH ld)
+    GET_PROPERTY(ldpath GLOBAL PROPERTY CXX_TEST_LDPATH)
+    IF("${ld}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY CXX_TEST_LDPATH 
+                "${ldpath}${sep}${ld}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# Cxx Add Path  Macro
+# Author: Brian Panneton
+# Description: This macro adds the cxx test paths.
+# Parameters:         
+#               p  = any paths needed for cxx tests
+MACRO(ADD_TEST_CXX_PATH p)
+    GET_PROPERTY(path GLOBAL PROPERTY CXX_TEST_PATH)
+    IF("${p}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY CXX_TEST_PATH 
+                "${path}${sep}${p}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# CXX Test Macro
+# Author: Brian Panneton
+# Description: This macro builds and add the cxx test in one shot.
+# Parameters:         
+#		executable      = executable name
+#		dup		= duplicate number
+#		tdep		= test dependency (Full Test Name with Prefix)
+#             	${ARGN}         = any arguments for the executable
+MACRO(ADD_TEST_CXX executable)
+    PARSE_TEST_ARGS("${ARGN}")
+    
+    IF(EXISTS ${cxx_source_dir}/${executable}.cpp)
+        ADD_EXECUTABLE(${executable}${dup} ${cxx_source_dir}/${executable}.cpp)
+    ENDIF()
+
+    IF(EXISTS ${cxx_source_dir}/${executable}.cxx)
+        ADD_EXECUTABLE(${executable}${dup} ${cxx_source_dir}/${executable}.cxx)
+    ENDIF()
+	
+    GET_PROPERTY(cxx_dependencies GLOBAL PROPERTY CXX_TEST_DEPENDENCIES)
+    GET_PROPERTY(cxx_ldpath GLOBAL PROPERTY CXX_TEST_LDPATH)
+    GET_PROPERTY(cxx_path GLOBAL PROPERTY CXX_TEST_PATH)
+    TARGET_LINK_LIBRARIES(${executable}${dup} ${cxx_dependencies})
+ 
+    # Take care of windowisims
+    IF(WIN32)
+        SET_TARGET_PROPERTIES(${executable}${dup} PROPERTIES 
+            PREFIX ../
+            RUNTIME_OUTPUT_DIRECTORY ${cxx_binary_dir}
+            LIBRARY_OUTPUT_DIRECTORY ${cxx_binary_dir}
+            ARCHIVE_OUTPUT_DIRECTORY ${cxx_binary_dir})
+
+        IF("${cxx_path}" STREQUAL "")
+            SET(cxx_path ${cxx_ldpath})
+        ENDIF()
+    ENDIF()
+
+    SET_CORE("${cxx_binary_dir}")
+    ADD_TEST(Cxx${is_core}_${executable}${dup} ${CMAKE_COMMAND}
+            -D "EXECUTABLE=${executable}${dup}"
+            -D "ARGUMENTS=${arguments}"
+            -D "LDPATH=${cxx_ldpath}"
+            -D "PATH=${cxx_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${cxx_binary_dir}/TestDriverCxx.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+	    SET_TESTS_PROPERTIES(Cxx${is_core}_${executable}${dup}
+            PROPERTIES DEPENDS ${tdep})
+    ENDIF()
+ENDMACRO()
+
+# CXX MPI Test Macro
+# Author: Andrew Burns
+# Description: This macro builds and adds a script to execute MPI tests.
+# Parameters:
+#               executable      = script name
+#               files           = code to be compiled and executed by the script
+#               tdep            = test dependency (Full Test Name with Prefix)
+#               ${ARGN}         = any arguments for the executable
+MACRO(ADD_MPI_TEST_CXX script files)
+    PARSE_TEST_ARGS("${ARGN}")
+
+    set(tempfiles ${files})
+
+    WHILE(NOT "${tempfiles}" STREQUAL "")
+        # ${executable}
+        STRING(REGEX MATCH "([^ ,])+,|([^ ,])+" executable "${tempfiles}")
+        STRING(REGEX REPLACE "," "" executable "${executable}")
+        STRING(REGEX REPLACE "${executable},|${executable}" "" trimmed "${tempfiles}")
+
+        set(tempfiles ${trimmed})
+
+        IF(EXISTS ${cxx_source_dir}/${executable}.cpp)
+            ADD_EXECUTABLE(${executable} ${cxx_source_dir}/${executable}.cpp)
+        ENDIF()
+
+        IF(EXISTS ${cxx_source_dir}/${executable}.cxx)
+            ADD_EXECUTABLE(${executable} ${cxx_source_dir}/${executable}.cxx)
+        ENDIF()
+
+        GET_PROPERTY(cxx_dependencies GLOBAL PROPERTY CXX_TEST_DEPENDENCIES)
+        GET_PROPERTY(cxx_ldpath GLOBAL PROPERTY CXX_TEST_LDPATH)
+        GET_PROPERTY(cxx_path GLOBAL PROPERTY CXX_TEST_PATH)
+        TARGET_LINK_LIBRARIES(${executable} ${cxx_dependencies})
+
+        # Take care of windowisims
+        IF(WIN32)
+            SET_TARGET_PROPERTIES(${executable} PROPERTIES
+                PREFIX ../
+                RUNTIME_OUTPUT_DIRECTORY ${cxx_binary_dir}
+                LIBRARY_OUTPUT_DIRECTORY ${cxx_binary_dir}
+                ARCHIVE_OUTPUT_DIRECTORY ${cxx_binary_dir})
+
+            IF("${cxx_path}" STREQUAL "")
+                SET(cxx_path ${cxx_ldpath})
+            ENDIF()
+        ENDIF()
+    ENDWHILE()
+
+    SET_CORE("${cxx_binary_dir}")
+    ADD_TEST(Cxx${is_core}_${script} ${CMAKE_COMMAND}
+            -D "EXECUTABLE='./${script}'"
+            -D "ARGUMENTS=${arguments}"
+            -D "LDPATH=${cxx_ldpath}"
+            -D "PATH=${cxx_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${cxx_binary_dir}/TestDriverCxx.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+            SET_TESTS_PROPERTIES(Cxx${is_core}_${script}
+            PROPERTIES DEPENDS ${tdep} ${script})
+    ENDIF()
+    file(COPY
+        ${cxx_source_dir}/${script}
+        DESTINATION ${cxx_binary_dir}/
+    )
+ENDMACRO()
+
+# CXX Clean Macro
+# Author: Brian Panneton
+# Description: This macro sets up the cxx test for a make clean.
+# Parameters:         
+#		executable      = executable name
+#             	${ARGN}         = files that the executable created
+MACRO(CLEAN_TEST_CXX executable)
+    set_property(DIRECTORY APPEND PROPERTY 
+        ADDITIONAL_MAKE_CLEAN_FILES ${ARGN} 
+    )
+ENDMACRO()
+
+ # Configure the cxx 'driver' file
+CONFIGURE_FILE(${TESTING_SUITE_DIR}/TestingSuite/TestDriverCxx.cmake.in ${cxx_binary_dir}/TestDriverCxx.cmake @ONLY)
+
diff --git a/CMake/TestingSuite/AddTestsFortran.cmake b/CMake/TestingSuite/AddTestsFortran.cmake
new file mode 100644
index 0000000..3468992
--- /dev/null
+++ b/CMake/TestingSuite/AddTestsFortran.cmake
@@ -0,0 +1,191 @@
+INCLUDE(TestingSetup)
+
+# We should have one place that points to the fortran source directory and the fortran
+# binary directory
+SET(fortran_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+SET(fortran_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+
+# Fortran Add Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the fortran test dependencies.
+# 	  Note: The tests already depend on their own file
+# Parameters:         
+#              dependencies         = any dependencies needed for fortran tests
+MACRO(ADD_TEST_FORTRAN_DEPENDENCIES dependencies)
+    IF(NOT ("${dependencies}" STREQUAL ""))
+        SET_PROPERTY(GLOBAL APPEND PROPERTY FORTRAN_TEST_DEPENDENCIES
+            "${dependencies}"
+ 	)
+    ENDIF()
+ENDMACRO()
+
+# Fortran Add LDPath  Macro
+# Author: Brian Panneton
+# Description: This macro adds the fortran test ldpaths.
+# Parameters:         
+#               ld  = any ldpaths needed for fortran tests
+MACRO(ADD_TEST_FORTRAN_LDPATH ld)
+    GET_PROPERTY(ldpath GLOBAL PROPERTY FORTRAN_TEST_LDPATH)
+    IF("${ld}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY FORTRAN_TEST_LDPATH 
+                "${ldpath}${sep}${ld}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# Fortran Add Path  Macro
+# Author: Brian Panneton
+# Description: This macro adds the fortran test paths.
+# Parameters:         
+#               p  = any paths needed for fortran tests
+MACRO(ADD_TEST_FORTRAN_PATH p)
+    GET_PROPERTY(path GLOBAL PROPERTY FORTRAN_TEST_PATH)
+    IF("${p}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY FORTRAN_TEST_PATH 
+                "${path}${sep}${p}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# Fortran Test Macro
+# Author: Brian Panneton
+# Description: This macro builds and add the fortran test in one shot.
+# Parameters:         
+#		executable      = executable name
+#		dup		= duplicate number
+#		tdep		= test dependency (Full Test Name with Prefix)
+#             	${ARGN}         = any arguments for the executable
+MACRO(ADD_TEST_FORTRAN executable)
+    PARSE_TEST_ARGS("${ARGN}")
+
+    IF(EXISTS ${fortran_source_dir}/${executable}.f)
+        ADD_EXECUTABLE(${executable} ${fortran_source_dir}/${executable}.f)
+    ENDIF()
+
+    IF(EXISTS ${fortran_source_dir}/${executable}.f90)
+        ADD_EXECUTABLE(${executable} ${fortran_source_dir}/${executable}.f90)
+    ENDIF()
+
+    IF(EXISTS ${fortran_source_dir}/${executable}.F90)
+        ADD_EXECUTABLE(${executable} ${fortran_source_dir}/${executable}.F90)
+    ENDIF()
+    
+    GET_PROPERTY(fortran_dependencies GLOBAL PROPERTY FORTRAN_TEST_DEPENDENCIES)
+    GET_PROPERTY(fortran_ldpath GLOBAL PROPERTY FORTRAN_TEST_LDPATH)
+    GET_PROPERTY(fortran_path GLOBAL PROPERTY FORTRAN_TEST_PATH)
+    TARGET_LINK_LIBRARIES(${executable}${dup} ${fortran_dependencies})
+ 
+    # Take care of windowisims
+    IF(WIN32)
+        SET_TARGET_PROPERTIES(${executable}${dup} PROPERTIES 
+            PREFIX ../
+            RUNTIME_OUTPUT_DIRECTORY ${fortran_binary_dir}
+            LIBRARY_OUTPUT_DIRECTORY ${fortran_binary_dir}
+            ARCHIVE_OUTPUT_DIRECTORY ${fortran_binary_dir})
+
+        IF("${fortran_path}" STREQUAL "")
+            SET(fortran_path ${fortran_ldpath})
+        ENDIF()
+    ENDIF()
+
+    SET_CORE("${fortran_binary_dir}")
+    ADD_TEST(FORTRAN${is_core}_${executable}${dup} ${CMAKE_COMMAND}
+            -D "EXECUTABLE=${executable}${dup}"
+            -D "ARGUMENTS=${arguments}"
+            -D "LDPATH=${fortran_ldpath}"
+            -D "PATH=${fortran_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${fortran_binary_dir}/TestDriverFortran.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+	    SET_TESTS_PROPERTIES(FORTRAN${is_core}_${executable}${dup}
+            PROPERTIES DEPENDS ${tdep})
+    ENDIF()
+ENDMACRO()
+
+# Fortran MPI Test Macro
+# Author: Andrew Burns
+# Description: This macro builds and adds a script to execute MPI tests.
+# Parameters:
+#               executable      = script name
+#               files           = code to be compiled and executed by the script
+#               tdep            = test dependency (Full Test Name with Prefix)
+#               ${ARGN}         = any arguments for the executable
+MACRO(ADD_MPI_TEST_FORTRAN script files)
+    PARSE_TEST_ARGS("${ARGN}")
+
+    set(tempfiles ${files})
+
+    WHILE(NOT "${tempfiles}" STREQUAL "")
+        # ${executable}
+        STRING(REGEX MATCH "([^ ,])+,|([^ ,])+" executable "${tempfiles}")
+        STRING(REGEX REPLACE "," "" executable "${executable}")
+        STRING(REGEX REPLACE "${executable},|${executable}" "" trimmed "${tempfiles}")
+
+        set(tempfiles ${trimmed})
+
+        IF(EXISTS ${fortran_source_dir}/${executable}.f)
+            ADD_EXECUTABLE(${executable} ${fortran_source_dir}/${executable}.f)
+        ENDIF()
+
+        IF(EXISTS ${fortran_source_dir}/${executable}.f90)
+            ADD_EXECUTABLE(${executable} ${fortran_source_dir}/${executable}.f90)
+        ENDIF()
+
+        IF(EXISTS ${fortran_source_dir}/${executable}.F90)
+            ADD_EXECUTABLE(${executable} ${fortran_source_dir}/${executable}.F90)
+        ENDIF()
+
+        GET_PROPERTY(fortran_dependencies GLOBAL PROPERTY FORTRAN_TEST_DEPENDENCIES)
+        GET_PROPERTY(fortran_ldpath GLOBAL PROPERTY FORTRAN_TEST_LDPATH)
+        GET_PROPERTY(fortran_path GLOBAL PROPERTY FORTRAN_TEST_PATH)
+        TARGET_LINK_LIBRARIES(${executable} ${fortran_dependencies})
+
+        # Take care of windowisims
+        IF(WIN32)
+            SET_TARGET_PROPERTIES(${executable} PROPERTIES
+                PREFIX ../
+                RUNTIME_OUTPUT_DIRECTORY ${fortran_binary_dir}
+                LIBRARY_OUTPUT_DIRECTORY ${fortran_binary_dir}
+                ARCHIVE_OUTPUT_DIRECTORY ${fortran_binary_dir})
+
+            IF("${fortran_path}" STREQUAL "")
+                SET(fortran_path ${fortran_ldpath})
+            ENDIF()
+        ENDIF()
+    ENDWHILE()
+
+    SET_CORE("${fortran_binary_dir}")
+    ADD_TEST(FORTRAN${is_core}_${script} ${CMAKE_COMMAND}
+            -D "EXECUTABLE='./${script}'"
+            -D "ARGUMENTS=${arguments}"
+            -D "LDPATH=${fortran_ldpath}"
+            -D "PATH=${fortran_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${fortran_binary_dir}/TestDriverFortran.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+            SET_TESTS_PROPERTIES(FORTRAN${is_core}_${script}
+            PROPERTIES DEPENDS ${tdep} ${script})
+    ENDIF()
+    file(COPY
+        ${fortran_source_dir}/${script}
+        DESTINATION ${fortran_binary_dir}/
+    )
+ENDMACRO()
+
+# Fortran Clean Macro
+# Author: Brian Panneton
+# Description: This macro sets up the fortran test for a make clean.
+# Parameters:         
+#		executable      = executable name
+#             	${ARGN}         = files that the executable created
+MACRO(CLEAN_TEST_FORTRAN executable)
+    set_property(DIRECTORY APPEND PROPERTY 
+        ADDITIONAL_MAKE_CLEAN_FILES ${ARGN} 
+    )
+ENDMACRO()
+
+ # Configure the Fortran 'driver' file
+CONFIGURE_FILE(${TESTING_SUITE_DIR}/TestingSuite/TestDriverFortran.cmake.in ${fortran_binary_dir}/TestDriverFortran.cmake @ONLY)
+
diff --git a/CMake/TestingSuite/AddTestsJava.cmake b/CMake/TestingSuite/AddTestsJava.cmake
new file mode 100644
index 0000000..5c7ff37
--- /dev/null
+++ b/CMake/TestingSuite/AddTestsJava.cmake
@@ -0,0 +1,171 @@
+INCLUDE(TestingSetup)
+
+# Variables that are set externally
+SET(java_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+SET(java_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+
+# Java Add Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the java test dependencies.
+# Parameters:         
+#              dependencies     = any target dependencies needed for java tests
+MACRO(ADD_TEST_JAVA_DEPENDENCIES dependencies)
+	IF(NOT ("${dependencies}" STREQUAL ""))
+		SET_PROPERTY(GLOBAL APPEND PROPERTY JAVA_TEST_DEPENDENCIES 
+        		"${dependencies}"
+		)
+	ENDIF()
+ENDMACRO()
+
+# Java Add File Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the java test file dependencies.
+#        Note: The tests already depend on their own file
+# Parameters:         
+#              dependencies     = any dependencies needed for java tests
+MACRO(ADD_TEST_JAVA_FILE_DEPENDENCIES dependencies)
+	IF(NOT ("${dependencies}" STREQUAL ""))
+		SET_PROPERTY(GLOBAL APPEND PROPERTY JAVA_TEST_FILE_DEPENDENCIES 
+        		"${dependencies}"
+		)
+	ENDIF()
+ENDMACRO()
+
+# Java Add Classpath Macro
+# Author: Brian Panneton
+# Description: This macro adds the java test classpaths.
+# Parameters:         
+#              cp   = any classpaths needed for java tests
+MACRO(ADD_TEST_JAVA_CLASSPATH cp)
+        GET_PROPERTY(classpath GLOBAL PROPERTY JAVA_TEST_CLASSPATH)
+        IF(NOT ("${cp}" STREQUAL ""))
+                SET_PROPERTY(GLOBAL PROPERTY JAVA_TEST_CLASSPATH 
+                        "${classpath}${sep}${cp}" 
+                )
+        ENDIF()
+ENDMACRO()
+
+# Java Add LDPath  Macro
+# Author: Brian Panneton
+# Description: This macro adds the java test ldpaths.
+# Parameters:         
+#               ld  = any ldpaths needed for java tests
+MACRO(ADD_TEST_JAVA_LDPATH ld)
+	GET_PROPERTY(ldpath GLOBAL PROPERTY JAVA_TEST_LDPATH)
+	IF("${ld}" STRGREATER "")
+		SET_PROPERTY(GLOBAL PROPERTY JAVA_TEST_LDPATH 
+        		"${ldpath}${sep}${ld}" 
+		)
+	ENDIF()
+ENDMACRO()
+
+# Java Add Path Macro
+# Author: Brian Panneton
+# Description: This macro adds the java test paths.
+# Parameters:         
+#               p = any paths needed for java tests
+MACRO(ADD_TEST_JAVA_PATH p)
+    GET_PROPERTY(path GLOBAL PROPERTY JAVA_TEST_PATH)
+    IF("${p}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY JAVA_TEST_PATH 
+                "${path}${sep}${p}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# Add Java Test Macro
+# Author: Brian Panneton
+# Description:	This macro builds and adds the java test in one shot. There is
+#		no need to build a test separately, because there isn't a case 
+#		that you don't want to run it.
+# Parameters: 
+#		executable 	= executable name 
+#		${ARGN}		= any arguments for the executable
+#
+MACRO(ADD_TEST_JAVA executable)
+
+	PARSE_TEST_ARGS("${ARGN}")	
+
+	GET_PROPERTY(java_file_dependencies GLOBAL PROPERTY 
+                    JAVA_TEST_FILE_DEPENDENCIES)
+	GET_PROPERTY(java_classpath GLOBAL PROPERTY JAVA_TEST_CLASSPATH)
+	GET_PROPERTY(java_ldpath GLOBAL PROPERTY JAVA_TEST_LDPATH)
+    GET_PROPERTY(java_path GLOBAL PROPERTY JAVA_TEST_PATH)
+	
+	ADD_CUSTOM_COMMAND(
+		OUTPUT ${java_binary_dir}/${executable}.class
+		WORKING_DIRECTORY ${java_binary_dir}
+		DEPENDS	${java_source_dir}/${executable}.java
+			${java_file_dependencies}
+		COMMAND ${JAVA_COMPILE}
+		ARGS	-cp	"\"${java_classpath}\""
+			-d	"\"${java_binary_dir}\""
+			${java_source_dir}/${executable}.java
+	)
+	
+	SET_PROPERTY(GLOBAL APPEND PROPERTY JAVA_TEST_TARGETS "${java_binary_dir}/${executable}.class")
+	
+    # Dlls need to be in the path dir for java
+    IF(WIN32)
+        IF("${java_path}" STREQUAL "")
+            SET(java_path ${java_ldpath})
+        ENDIF()
+    ENDIF()
+
+	SET_CORE("${java_binary_dir}")
+    ADD_TEST(Java${is_core}_${executable}${dup} ${CMAKE_COMMAND}
+            -D "EXECUTABLE=${executable}"
+            -D "ARGUMENTS=${arguments}"
+            -D "CLASSPATH=${java_classpath}"
+            -D "LDPATH=${java_ldpath}"
+            -D "PATH=${java_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${java_binary_dir}/TestDriverJava.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+        SET_TESTS_PROPERTIES(Java${is_core}_${executable}${dup}
+            PROPERTIES DEPENDS ${tdep})
+    ENDIF()
+ENDMACRO()
+
+# Java Clean Macro
+# Author: Brian Panneton
+# Description: This macro sets up the java test for a make clean.
+# Parameters:         
+#              executable      = executable name
+#              ${ARGN}         = files that the executable created
+MACRO(CLEAN_TEST_JAVA executable)
+       set_property(DIRECTORY APPEND PROPERTY 
+                ADDITIONAL_MAKE_CLEAN_FILES ${ARGN}
+       )
+ENDMACRO()
+
+# Java Create Target Macro
+# Author: Brian Panneton
+# Description: This macro sets up the java test target
+# Parameters:   none
+MACRO(CREATE_TARGET_TEST_JAVA)
+    IF(EXISTS JavaCore_ALLTEST)
+        SET(JavaCore_ALLTEST JavaCore_ALLTEST)
+    ENDIF()
+
+    GET_PROPERTY(java_dependencies GLOBAL PROPERTY JAVA_TEST_DEPENDENCIES)
+
+	SET_CORE("${java_binary_dir}")
+	GET_PROPERTY(targets GLOBAL PROPERTY JAVA_TEST_TARGETS)
+    ADD_CUSTOM_TARGET(Java${is_core}_ALLTEST ALL DEPENDS 
+            ${JavaCore_ALLTEST} ${targets})
+   
+    IF(NOT ("${java_dependencies}" STREQUAL ""))
+        ADD_DEPENDENCIES(Java${is_core}_ALLTEST ${java_dependencies})
+    ENDIF()
+
+	IF(NOT ("${is_core}" STREQUAL ""))
+        SET_PROPERTY(GLOBAL PROPERTY JAVA_TEST_TARGETS "")
+    ENDIF()
+
+ENDMACRO()
+
+
+# Configure the java 'driver' file
+CONFIGURE_FILE(${TESTING_SUITE_DIR}/TestingSuite/TestDriverJava.cmake.in ${java_binary_dir}/TestDriverJava.cmake @ONLY)
diff --git a/CMake/TestingSuite/AddTestsPython.cmake b/CMake/TestingSuite/AddTestsPython.cmake
new file mode 100644
index 0000000..1376f95
--- /dev/null
+++ b/CMake/TestingSuite/AddTestsPython.cmake
@@ -0,0 +1,247 @@
+INCLUDE(TestingSetup)
+
+# Variables that are set externally
+SET(python_binary_dir ${CMAKE_CURRENT_BINARY_DIR})
+SET(python_source_dir ${CMAKE_CURRENT_SOURCE_DIR})
+
+# Python Add Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the python test dependencies.
+#        Note: The tests already depend on their own file
+# Parameters:         
+#              dependencies         = any dependencies needed for python tests
+MACRO(ADD_TEST_PYTHON_DEPENDENCIES dependencies)
+	IF(NOT ("${dependencies}" STREQUAL ""))
+	        SET_PROPERTY(GLOBAL APPEND PROPERTY PYTHON_TEST_DEPENDENCIES 
+        	        "${dependencies}"
+	        )
+	ENDIF()
+ENDMACRO()
+
+# Python Add Dependencies Macro
+# Author: Brian Panneton
+# Description: This macro adds the python test dependencies.
+#        Note: The tests already depend on their own file
+# Parameters:         
+#              dependencies         = any dependencies needed for python tests
+MACRO(ADD_TEST_PYTHON_FILE_DEPENDENCIES dependencies)
+	IF(NOT ("${dependencies}" STREQUAL ""))
+	        SET_PROPERTY(GLOBAL APPEND PROPERTY PYTHON_TEST_FILE_DEPENDENCIES 
+        	        "${dependencies}"
+	        )
+	ENDIF()
+ENDMACRO()
+
+# Python Add PythonPath Macro
+# Author: Brian Panneton
+# Description: This macro adds the python test pythonpaths.
+# Parameters:         
+#              pyp         = any pythonpaths needed for python tests
+MACRO(ADD_TEST_PYTHON_PYTHONPATH pyp)
+        GET_PROPERTY(pythonpath GLOBAL PROPERTY PYTHON_TEST_PYTHONPATH)
+        IF(NOT ("${pyp}" STREQUAL ""))
+                SET_PROPERTY(GLOBAL PROPERTY PYTHON_TEST_PYTHONPATH 
+                        "${pythonpath}${sep}${pyp}" 
+                )
+        ENDIF()
+ENDMACRO()
+
+# Python Add LDPath  Macro
+# Author: Brian Panneton
+# Description: This macro adds the python test ldpaths.
+# Parameters:         
+#               ld  = any ldpaths needed for python tests
+MACRO(ADD_TEST_PYTHON_LDPATH ld)
+    GET_PROPERTY(ldpath GLOBAL PROPERTY PYTHON_TEST_LDPATH)
+    IF("${ld}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY PYTHON_TEST_LDPATH 
+                "${ldpath}${sep}${ld}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# Python Add Path Macro
+# Author: Brian Panneton
+# Description: This macro adds the python test paths.
+# Parameters:         
+#               p = any paths needed for python tests
+MACRO(ADD_TEST_PYTHON_PATH p)
+    GET_PROPERTY(path GLOBAL PROPERTY PYTHON_TEST_PATH)
+    IF("${p}" STRGREATER "")
+        SET_PROPERTY(GLOBAL PROPERTY PYTHON_TEST_PATH 
+                "${path}${sep}${p}" 
+        )
+    ENDIF()
+ENDMACRO()
+
+# Add Python Test Macro
+# Author: Brian Panneton
+# Description:	This macro compiles and adds the python test in one shot. There is
+#		no need to build a test separately, because there isn't a case 
+#		that you don't want to run it.
+# Parameters: 
+#		executable 	= executable name 
+#		${ARGN}		= any arguments for the executable
+#
+MACRO(ADD_TEST_PYTHON executable)
+	
+	PARSE_TEST_ARGS("${ARGN}")
+
+	GET_PROPERTY(python_file_dependencies GLOBAL 
+			PROPERTY PYTHON_TEST_FILE_DEPENDENCIES)
+	GET_PROPERTY(python_pythonpath GLOBAL PROPERTY PYTHON_TEST_PYTHONPATH)
+    GET_PROPERTY(python_ldpath GLOBAL PROPERTY PYTHON_TEST_LDPATH)
+    GET_PROPERTY(python_path GLOBAL PROPERTY PYTHON_TEST_PATH)
+	
+	ADD_CUSTOM_COMMAND(
+		OUTPUT ${python_binary_dir}/${executable}.pyc
+		WORKING_DIRECTORY ${python_binary_dir} 
+		COMMAND ${CMAKE_COMMAND}
+		ARGS 	-E copy
+			${python_source_dir}/${executable}.py
+			${python_binary_dir}/${executable}.py
+		COMMAND ${PYTHON_EXECUTABLE} 
+		ARGS	-mpy_compile
+			${python_binary_dir}/${executable}.py
+		DEPENDS ${python_source_dir}/${executable}.py
+			${python_file_dependencies}
+	)
+	
+	SET_PROPERTY(GLOBAL APPEND PROPERTY PYTHON_TEST_TARGETS "${python_binary_dir}/${executable}.pyc")
+
+    # Dlls need to be in the path dir for java
+    IF(WIN32)
+        IF("${python_path}" STREQUAL "")
+            SET(python_path ${java_ldpath})
+        ENDIF()
+    ENDIF()
+
+	SET_CORE("${python_binary_dir}")
+    ADD_TEST(Python${is_core}_${executable}${dup} ${CMAKE_COMMAND}
+            -D "EXECUTABLE=${executable}"
+            -D "ARGUMENTS=${arguments}"
+            -D "PYTHONPATH=${python_pythonpath}"
+            -D "LDPATH=${python_ldpath}"
+            -D "PATH=${python_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${python_binary_dir}/TestDriverPython.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+        SET_TESTS_PROPERTIES(Python${is_core}_${executable}${dup}
+            PROPERTIES DEPENDS ${tdep})
+    ENDIF()
+
+ENDMACRO()
+
+
+
+# PYTHON MPI Test Macro
+# Author: Andrew Burns
+# Description: This macro builds and adds a script to execute MPI tests.
+# Parameters:
+#               executable      = script name
+#               files           = code to be compiled and executed by the script
+#               tdep            = test dependency (Full Test Name with Prefix)
+#               ${ARGN}         = any arguments for the executable
+MACRO(ADD_MPI_TEST_PYTHON script files)
+    PARSE_TEST_ARGS("${ARGN}")
+
+    GET_PROPERTY(python_file_dependencies GLOBAL
+                 PROPERTY PYTHON_TEST_FILE_DEPENDENCIES)
+    GET_PROPERTY(python_pythonpath GLOBAL PROPERTY PYTHON_TEST_PYTHONPATH)
+    GET_PROPERTY(python_ldpath GLOBAL PROPERTY PYTHON_TEST_LDPATH)
+    GET_PROPERTY(python_path GLOBAL PROPERTY PYTHON_TEST_PATH)
+
+    IF(WIN32)
+        IF("${python_path}" STREQUAL "")
+            SET(python_path ${python_ldpath})
+        ENDIF()
+    ENDIF()
+
+    set(tempfiles ${files})
+
+    WHILE(NOT "${tempfiles}" STREQUAL "")
+        # ${executable}
+        STRING(REGEX MATCH "([^ ,])+,|([^ ,])+" executable "${tempfiles}")
+        STRING(REGEX REPLACE "," "" executable "${executable}")
+        STRING(REGEX REPLACE "${executable},|${executable}" "" trimmed "${tempfiles}")
+
+        set(tempfiles ${trimmed})
+
+        IF(EXISTS ${python_source_dir}/${executable}.py)
+                file(COPY
+                    ${python_source_dir}/${executable}.py
+                    DESTINATION ${python_binary_dir}/
+                )
+        ENDIF()
+
+    ENDWHILE()
+
+    SET_CORE("${python_binary_dir}")
+    ADD_TEST(Python${is_core}_${script} ${CMAKE_COMMAND}
+            -D "EXECUTABLE='./${script}'"
+            -D "ARGUMENTS=${arguments}"
+            -D "PYTHONPATH=${python_pythonpath}"
+            -D "LDPATH=${python_ldpath}"
+            -D "PATH=${python_path}"
+            -D "SEPARATOR=${sep}"
+            -P "${python_binary_dir}/TestDriverPythonScript.cmake"
+    )
+    IF(NOT "${tdep}" STREQUAL "")
+        SET_TESTS_PROPERTIES(Python${is_core}_${script}}
+            PROPERTIES DEPENDS ${tdep})
+    ENDIF()
+    file(COPY
+        ${python_source_dir}/${script}
+        DESTINATION ${python_binary_dir}/
+    )
+ENDMACRO()
+
+
+
+
+# Python Clean Macro
+# Author: Brian Panneton
+# Description: This macro sets up the python test for a make clean.
+# Parameters:         
+#              executable      = executable name
+#              ${ARGN}         = files that the executable created
+MACRO(CLEAN_TEST_PYTHON executable)
+	set_property(DIRECTORY APPEND PROPERTY
+		ADDITIONAL_MAKE_CLEAN_FILES ${ARGN}
+		${executable}.py
+	)
+ENDMACRO()
+
+
+# Python Create Target Macro
+# Author: Brian Panneton
+# Description: This macro sets up the python test target
+# Parameters:	none
+MACRO(CREATE_TARGET_TEST_PYTHON)
+	IF(EXISTS PythonCore_ALLTEST)
+        	SET(PythonCore_ALLTEST PythonCore_ALLTEST)
+	ENDIF()
+
+    GET_PROPERTY(python_dependencies GLOBAL PROPERTY PYTHON_TEST_DEPENDENCIES)	
+
+	SET_CORE("${python_binary_dir}")
+	GET_PROPERTY(targets GLOBAL PROPERTY PYTHON_TEST_TARGETS)
+	ADD_CUSTOM_TARGET(Python${is_core}_ALLTEST ALL DEPENDS 
+		${PythonCore_ALLTEST} ${targets})
+
+    IF(NOT ("${python_dependencies}" STREQUAL ""))
+        ADD_DEPENDENCIES(Python${is_core}_ALLTEST ${python_dependencies})
+	ENDIF()
+
+	IF(NOT ("${is_core}" STREQUAL ""))
+		SET_PROPERTY(GLOBAL PROPERTY PYTHON_TEST_TARGETS "")
+	ENDIF()
+
+ENDMACRO()
+
+
+# Configure the python 'driver' file
+CONFIGURE_FILE(${TESTING_SUITE_DIR}/TestingSuite/TestDriverPython.cmake.in ${python_binary_dir}/TestDriverPython.cmake @ONLY)
+CONFIGURE_FILE(${TESTING_SUITE_DIR}/TestingSuite/TestDriverPythonScript.cmake.in ${python_binary_dir}/TestDriverPythonScript.cmake @ONLY)
+
diff --git a/CMake/TestingSuite/TestDriverC.cmake.in b/CMake/TestingSuite/TestDriverC.cmake.in
new file mode 100644
index 0000000..d2c9b4a
--- /dev/null
+++ b/CMake/TestingSuite/TestDriverC.cmake.in
@@ -0,0 +1,37 @@
+SET(ENV{PATH} "${PATH}${SEPARATOR}$ENV{PATH}")
+
+set(XDMF_DSM_IS_CRAY "@XDMF_DSM_IS_CRAY@")
+if (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}${SEPARATOR}${LDPATH}")
+else (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "${LDPATH}${SEPARATOR}$ENV{LD_LIBRARY_PATH}")
+endif (XDMF_DSM_IS_CRAY)
+
+SET(ENV{MPIEXEC} "@MPIEXEC@")
+
+MESSAGE("| Calling:\t${EXECUTABLE} ${ARGUMENTS}")
+EXECUTE_PROCESS(
+       COMMAND ${EXECUTABLE} ${ARGUMENTS} 
+			RESULT_VARIABLE c_result
+            OUTPUT_VARIABLE c_output
+            ERROR_VARIABLE  c_error
+)
+
+MESSAGE("| Call Result:\t${c_result}")
+MESSAGE("| Call Output: Begin\n${c_output}")
+MESSAGE("| Call Output: End")
+IF(c_error)
+	MESSAGE("| Call Error: Begin\n${c_error}")
+	MESSAGE("| Call Error: End")
+ENDIF()
+MESSAGE("| Call Ended")
+MESSAGE("----------------------------------------------------------")
+
+# Let's make sure that if the test failed, it failed with CTest too
+IF(c_error)
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
+
+IF(NOT ${c_result} EQUAL "0")
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
diff --git a/CMake/TestingSuite/TestDriverCxx.cmake.in b/CMake/TestingSuite/TestDriverCxx.cmake.in
new file mode 100644
index 0000000..10c19bd
--- /dev/null
+++ b/CMake/TestingSuite/TestDriverCxx.cmake.in
@@ -0,0 +1,37 @@
+SET(ENV{PATH} "${PATH}${SEPARATOR}$ENV{PATH}")
+
+set(XDMF_DSM_IS_CRAY "@XDMF_DSM_IS_CRAY@")
+if (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}${SEPARATOR}${LDPATH}")
+else (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "${LDPATH}${SEPARATOR}$ENV{LD_LIBRARY_PATH}")
+endif (XDMF_DSM_IS_CRAY)
+
+SET(ENV{MPIEXEC} "@MPIEXEC@")
+
+MESSAGE("| Calling:\t${EXECUTABLE} ${ARGUMENTS}")
+EXECUTE_PROCESS(
+       COMMAND ${EXECUTABLE} ${ARGUMENTS} 
+			RESULT_VARIABLE cxx_result
+            OUTPUT_VARIABLE cxx_output
+            ERROR_VARIABLE  cxx_error
+)
+
+MESSAGE("| Call Result:\t${cxx_result}")
+MESSAGE("| Call Output: Begin\n${cxx_output}")
+MESSAGE("| Call Output: End")
+IF(cxx_error)
+	MESSAGE("| Call Error: Begin\n${cxx_error}")
+	MESSAGE("| Call Error: End")
+ENDIF()
+MESSAGE("| Call Ended")
+MESSAGE("----------------------------------------------------------")
+
+# Let's make sure that if the test failed, it failed with CTest too
+IF(cxx_error)
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
+
+IF(NOT ${cxx_result} EQUAL "0")
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
diff --git a/CMake/TestingSuite/TestDriverFortran.cmake.in b/CMake/TestingSuite/TestDriverFortran.cmake.in
new file mode 100644
index 0000000..30dfa6a
--- /dev/null
+++ b/CMake/TestingSuite/TestDriverFortran.cmake.in
@@ -0,0 +1,37 @@
+SET(ENV{PATH} "${PATH}${SEPARATOR}$ENV{PATH}")
+
+set(XDMF_DSM_IS_CRAY "@XDMF_DSM_IS_CRAY@")
+if (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}${SEPARATOR}${LDPATH}")
+else (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "${LDPATH}${SEPARATOR}$ENV{LD_LIBRARY_PATH}")
+endif (XDMF_DSM_IS_CRAY)
+
+SET(ENV{MPIEXEC} "@MPIEXEC@")
+
+MESSAGE("| Calling:\t${EXECUTABLE} ${ARGUMENTS}")
+EXECUTE_PROCESS(
+       COMMAND ${EXECUTABLE} ${ARGUMENTS} 
+			RESULT_VARIABLE fortran_result
+            OUTPUT_VARIABLE fortran_output
+            ERROR_VARIABLE  fortran_error
+)
+
+MESSAGE("| Call Result:\t${fortran_result}")
+MESSAGE("| Call Output: Begin\n${fortran_output}")
+MESSAGE("| Call Output: End")
+IF(fortran_error)
+	MESSAGE("| Call Error: Begin\n${fortran_error}")
+	MESSAGE("| Call Error: End")
+ENDIF()
+MESSAGE("| Call Ended")
+MESSAGE("----------------------------------------------------------")
+
+# Let's make sure that if the test failed, it failed with CTest too
+IF(fortran_error)
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
+
+IF(NOT ${fortran_result} EQUAL "0")
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
diff --git a/CMake/TestingSuite/TestDriverJava.cmake.in b/CMake/TestingSuite/TestDriverJava.cmake.in
new file mode 100644
index 0000000..ac75c3e
--- /dev/null
+++ b/CMake/TestingSuite/TestDriverJava.cmake.in
@@ -0,0 +1,33 @@
+SET(java_runtime "@JAVA_RUNTIME@")
+SET(java_binary_dir "@CMAKE_CURRENT_BINARY_DIR@")
+
+SET(ENV{PATH} "${PATH}${SEPARATOR}$ENV{PATH}")
+SET(ENV{LD_LIBRARY_PATH} "${LDPATH}${SEPARATOR}$ENV{LD_LIBRARY_PATH}")
+SET(ENV{CLASSPATH} "${CLASSPATH}${SEPARATOR}$ENV{CLASSPATH}")
+
+MESSAGE("| Calling:\t${java_runtime} ${EXECUTABLE} ${ARGUMENTS}")
+EXECUTE_PROCESS(
+       COMMAND "${java_runtime}" "${EXECUTABLE}" ${ARGUMENTS} 
+               	WORKING_DIRECTORY "${java_binary_dir}"
+        		RESULT_VARIABLE java_result
+               	OUTPUT_VARIABLE java_output
+               	ERROR_VARIABLE  java_error
+)
+
+MESSAGE("| Call Result:\t${java_result}")
+MESSAGE("| Call Output: Begin\n${java_output}")
+MESSAGE("| Call Output: End")
+IF(java_error)
+	MESSAGE("| Call Error: Begin\n${java_error}")
+	MESSAGE("| Call Error: End")
+ENDIF()
+MESSAGE("| Call Ended")
+MESSAGE("----------------------------------------------------------")
+
+# Let's make sure that if the test failed, it failed with CTest too
+IF(java_error)
+	MESSAGE(SEND_ERROR "Test Failed.")
+ENDIF()
+IF(NOT "${java_result}" STREQUAL "0")
+    MESSAGE(SEND_ERROR "Result not zero.")
+ENDIF()
diff --git a/CMake/TestingSuite/TestDriverPython.cmake.in b/CMake/TestingSuite/TestDriverPython.cmake.in
new file mode 100644
index 0000000..1d7dd7b
--- /dev/null
+++ b/CMake/TestingSuite/TestDriverPython.cmake.in
@@ -0,0 +1,37 @@
+SET(python_runtime "@PYTHON_EXECUTABLE@")
+SET(python_binary_dir "@CMAKE_CURRENT_BINARY_DIR@")
+
+SET(ENV{PYTHONPATH} "${PYTHONPATH}${SEPARATOR}$ENV{PYTHONPATH}")
+SET(ENV{PATH} "${PATH}${SEPARATOR}$ENV{PATH}")
+
+set(XDMF_DSM_IS_CRAY "@XDMF_DSM_IS_CRAY@")
+if (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}${SEPARATOR}${LDPATH}")
+else (XDMF_DSM_IS_CRAY)
+  SET(ENV{LD_LIBRARY_PATH} "${LDPATH}${SEPARATOR}$ENV{LD_LIBRARY_PATH}")
+endif (XDMF_DSM_IS_CRAY)
+
+MESSAGE("| Calling:\t${python_runtime} ${EXECUTABLE} ${ARGUMENTS}")
+EXECUTE_PROCESS(
+    	COMMAND "${python_runtime}" "${EXECUTABLE}.pyc" ${ARGUMENTS}
+		WORKING_DIRECTORY "${python_binary_dir}"
+    		RESULT_VARIABLE python_result
+    		OUTPUT_VARIABLE python_output
+ 		ERROR_VARIABLE python_error
+)
+
+MESSAGE("| Call Result:\t${python_result}")
+MESSAGE("| Call Output: Begin\n${python_output}")
+MESSAGE("| Call Output: End")
+IF(python_error)
+	MESSAGE("Call Error: Begin\n${python_error}")
+	MESSAGE("Call Error: End")
+ENDIF()
+MESSAGE("| Call Ended")
+MESSAGE("----------------------------------------------------------")
+
+# Let's make sure that if the test failed, it failed with CTest too
+IF(python_result)
+	MESSAGE(SEND_ERROR "${python_result}")
+ENDIF()
+
diff --git a/CMake/TestingSuite/TestDriverPythonScript.cmake.in b/CMake/TestingSuite/TestDriverPythonScript.cmake.in
new file mode 100644
index 0000000..5996f03
--- /dev/null
+++ b/CMake/TestingSuite/TestDriverPythonScript.cmake.in
@@ -0,0 +1,41 @@
+SET(python_runtime "@PYTHON_EXECUTABLE@")
+SET(python_binary_dir "@CMAKE_CURRENT_BINARY_DIR@")
+
+SET(ENV{PYTHONPATH} "${PYTHONPATH}${SEPARATOR}$ENV{PYTHONPATH}")
+SET(ENV{PATH} "${PATH}${SEPARATOR}$ENV{PATH}")
+
+set(XDMF_DSM_IS_CRAY "@XDMF_DSM_IS_CRAY@")
+if (XDMF_DSM_IS_CRAY)
+#  message("Cray Style")
+  SET(ENV{LD_LIBRARY_PATH} "$ENV{LD_LIBRARY_PATH}${SEPARATOR}${LDPATH}")
+else (XDMF_DSM_IS_CRAY)
+#  message("Normal Style")
+  SET(ENV{LD_LIBRARY_PATH} "${LDPATH}${SEPARATOR}$ENV{LD_LIBRARY_PATH}")
+endif (XDMF_DSM_IS_CRAY)
+
+SET(ENV{PYTHON_EXECUTABLE} "${python_runtime}")
+SET(ENV{MPIEXEC} "@MPIEXEC@")
+
+MESSAGE("| Calling:\t ${EXECUTABLE} ${ARGUMENTS}")
+EXECUTE_PROCESS(
+        COMMAND "${EXECUTABLE}" ${ARGUMENTS}
+                WORKING_DIRECTORY "${python_binary_dir}"
+                RESULT_VARIABLE python_result
+                OUTPUT_VARIABLE python_output
+                ERROR_VARIABLE python_error
+)
+
+MESSAGE("| Call Result:\t${python_result}")
+MESSAGE("| Call Output: Begin\n${python_output}")
+MESSAGE("| Call Output: End")
+IF(python_error)
+        MESSAGE("Call Error: Begin\n${python_error}")
+        MESSAGE("Call Error: End")
+ENDIF()
+MESSAGE("| Call Ended")
+MESSAGE("----------------------------------------------------------")
+
+# Let's make sure that if the test failed, it failed with CTest too
+IF(python_result)
+        MESSAGE(SEND_ERROR "${python_result}")
+ENDIF()
diff --git a/CMake/TestingSuite/TestingSetup.cmake b/CMake/TestingSuite/TestingSetup.cmake
new file mode 100644
index 0000000..68977f5
--- /dev/null
+++ b/CMake/TestingSuite/TestingSetup.cmake
@@ -0,0 +1,91 @@
+# List of global variables needed by tests
+SET(defines 
+    JAVA_TEST_DEPENDENCIES
+    JAVA_TEST_FILE_DEPENDENCIES
+    JAVA_TEST_CLASSPATH
+    JAVA_TEST_LDPATH
+    JAVA_TEST_PATH
+    JAVA_TEST_TARGETS
+    PYTHON_TEST_DEPENDENCIES
+    PYTHON_TEST_FILE_DEPENDENCIES
+    PYTHON_TEST_PYTHONPATH
+    PYTHON_TEST_LDPATH
+    PYTHON_TEST_PATH
+    CXX_TEST_DEPENDENCIES
+    CXX_TEST_LDPATH
+    CXX_TEST_PATH
+)
+
+# Take care of Windows Path Seperators
+IF(WIN32)
+    SET(sep ";")
+ELSE()
+    SET(sep ":")
+ENDIF()
+
+# Make sure they are defined
+FOREACH(def IN LISTS defines)
+    GET_PROPERTY(is_defined GLOBAL PROPERTY ${def} DEFINED)
+    IF(NOT is_defined)
+        DEFINE_PROPERTY(GLOBAL PROPERTY ${def}
+			BRIEF_DOCS "${def}"
+			FULL_DOCS "${def} No Documentation"
+        )
+    ENDIF()
+ENDFOREACH()
+
+# Set the testing suite dir
+SET(TESTING_SUITE_DIR "${CMAKE_SOURCE_DIR}/CMake" CACHE PATH 
+    "Testing Suite CMake Dir")
+MARK_AS_ADVANCED(TESTING_SUITE_DIR)
+
+# Argument Parsing Macro
+# Author: Brian Panneton
+# Description: This macro parses the provided argument string and sets the vars
+# Parameters:         
+#        	${test_args}    = the argument string for the test
+# Output:	
+#		${arguments}	= whatever is left after stripping the arguments
+#		${dup}		= number or string to append to a duplicate test
+#		${tdep}		= test dependencies (comma seperated list)
+MACRO(PARSE_TEST_ARGS test_args)
+    STRING(COMPARE NOTEQUAL "${test_args}" "" check)
+    IF(${check})
+        SET(arguments "${test_args}")
+	# Here we strip out any arguments for the testing suite
+        
+	# ${dup}
+        STRING(REGEX MATCH "dup=([^ ;])+" dup "${test_args}")
+        STRING(REGEX REPLACE "dup=" "" dup "${dup}")
+        STRING(REGEX REPLACE ";" "" dup "${dup}")
+        STRING(REGEX REPLACE "dup=([^ ;])+" "" arguments "${arguments}")
+        
+	# ${tdep}
+        STRING(REGEX MATCH "tdep=([^ ;])+" tdep "${test_args}")
+        STRING(REGEX REPLACE "tdep=" "" tdep "${tdep}")
+        STRING(REGEX REPLACE ";" "" tdep "${tdep}")
+	STRING(REGEX REPLACE "tdep=([^ ;])+" "" arguments "${arguments}")
+	STRING(REGEX REPLACE "," ";" tdep "${tdep}")
+    ELSE()
+        SET(arguments "") # Sanity Check	
+    ENDIF()
+ENDMACRO()
+
+# Set Core Macro
+# Author: Brian Panneton
+# Description: This macro checks the directory provided to see if it is a core
+# Parameters:         
+#               dir    	= the directory to be checked
+# Output:     
+#		is_core	= variable is set to 'Core' is core was found in dir
+MACRO(SET_CORE dir)
+    STRING(REGEX MATCH "core" is_core "${dir}")
+    IF(EXISTS ${is_core})
+        SET(is_core "Core")
+    ELSE(EXISTS ${is_core})
+      STRING(REGEX MATCH "utils" is_core "${dir}")
+      IF(EXISTS ${is_core})
+          SET(is_core "Util")
+      ENDIF(EXISTS ${is_core})
+    ENDIF(EXISTS ${is_core})
+ENDMACRO(SET_CORE dir)
diff --git a/CMake/UseDoxygen.cmake b/CMake/UseDoxygen.cmake
new file mode 100644
index 0000000..c5af2de
--- /dev/null
+++ b/CMake/UseDoxygen.cmake
@@ -0,0 +1,101 @@
+# - Run Doxygen
+# 
+# Adds a doxygen target that runs doxygen to generate the html and
+# optionally the LaTeX API documentation.  The doxygen target is added
+# to the doc target as dependency.  i.e.: the API documentation is
+# built with: make doc
+# 
+# USAGE: GLOBAL INSTALL
+# 
+# Install it with: cmake ./ && sudo make install Add the following to
+# the CMakeLists.txt of your project: include(UseDoxygen OPTIONAL)
+# Optionally copy Doxyfile.in in the directory of CMakeLists.txt and
+# edit it.
+# 
+# USAGE: INCLUDE IN PROJECT
+# 
+# set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+# include(UseDoxygen) Add the Doxyfile.in and UseDoxygen.cmake files
+# to the projects source directory.
+# 
+# 
+# Variables you may define are: DOXYFILE_OUTPUT_DIR - Path where the
+# Doxygen output is stored. Defaults to "doc".
+# 
+# DOXYFILE_LATEX_DIR - Directory where the Doxygen LaTeX output is
+# stored. Defaults to "latex".
+# 
+# DOXYFILE_HTML_DIR - Directory where the Doxygen html output is
+# stored. Defaults to "html".
+
+#
+#  Copyright (c) 2009, 2010 Tobias Rautenkranz <tobias at rautenkranz.ch>
+#
+#  Redistribution and use is allowed according to the terms of the New
+#  BSD license.
+#  For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+#
+
+macro(usedoxygen_set_default name value)
+  if(NOT DEFINED "${name}")
+    set("${name}" "${value}")
+  endif()
+endmacro()
+
+mark_as_advanced(CLEAR DOXYGEN_EXECUTABLE)
+find_package(Doxygen REQUIRED)
+
+if(DOXYGEN_FOUND)
+  mark_as_advanced(FORCE DOXYGEN_EXECUTABLE)
+  find_file(DOXYFILE_IN "Doxyfile.in"
+    PATHS "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_ROOT}/Modules/"
+    NO_DEFAULT_PATH)
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(DOXYFILE_IN DEFAULT_MSG "DOXYFILE_IN")
+endif()
+
+if(DOXYGEN_FOUND AND DOXYFILE_IN_FOUND)
+  add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
+
+  usedoxygen_set_default(DOXYFILE_OUTPUT_DIR "${CMAKE_BINARY_DIR}/doc")
+  usedoxygen_set_default(DOXYFILE_HTML_DIR "html")
+
+  set_property(DIRECTORY APPEND PROPERTY
+    ADDITIONAL_MAKE_CLEAN_FILES "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_HTML_DIR}")
+
+  set(DOXYFILE_LATEX "NO")
+  set(DOXYFILE_PDFLATEX "NO")
+  set(DOXYFILE_DOT "NO")
+
+  find_package(LATEX)
+  if(LATEX_COMPILER AND MAKEINDEX_COMPILER)
+    set(DOXYFILE_LATEX "YES")
+    usedoxygen_set_default(DOXYFILE_LATEX_DIR "latex")
+
+    set_property(DIRECTORY APPEND PROPERTY
+      ADDITIONAL_MAKE_CLEAN_FILES
+      "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
+
+    if(PDFLATEX_COMPILER)
+      set(DOXYFILE_PDFLATEX "YES")
+    endif()
+    if(DOXYGEN_DOT_EXECUTABLE)
+      set(DOXYFILE_DOT "YES")
+    endif()
+
+    add_custom_command(TARGET doxygen
+      POST_BUILD
+      COMMAND ${CMAKE_MAKE_PROGRAM}
+      WORKING_DIRECTORY "${DOXYFILE_OUTPUT_DIR}/${DOXYFILE_LATEX_DIR}")
+  endif()
+
+
+  configure_file(${DOXYFILE_IN} Doxyfile ESCAPE_QUOTES IMMEDIATE @ONLY)
+
+  get_target_property(DOC_TARGET doc TYPE)
+  if(NOT DOC_TARGET)
+    add_custom_target(doc)
+  endif()
+
+  add_dependencies(doc doxygen)
+endif()
diff --git a/CMake/VersionSuite/ProjectVersion.hpp b/CMake/VersionSuite/ProjectVersion.hpp
new file mode 100644
index 0000000..4458e10
--- /dev/null
+++ b/CMake/VersionSuite/ProjectVersion.hpp
@@ -0,0 +1,152 @@
+#ifndef PROJECT_VERSION_HPP
+#define PROJECT_VERSION_HPP
+
+/* Version Suite Class
+ * Author: Brian Panneton
+ */
+#include <string>
+#include <sstream>
+
+/**
+ * @brief Version Suite to assist in adding versioning to your project
+ *
+ * A simple way to have the library contain its own version.
+ */
+class ProjectVersion {
+	public:
+	/**
+     * Create a Version class object
+     *
+     * @param name of the project
+     */
+    ProjectVersion(std::string iProjectName, int iMajor, int iMinor, int iPatch) { 
+      setProjectName(iProjectName);
+      setMajor(iMajor);
+      setMinor(iMinor);
+      setPatch(iPatch);
+    }
+
+    ProjectVersion(std::string iProjectName, 
+                   std::string iMajor, std::string iMinor, std::string iPatch) { 
+      setProjectName(iProjectName);
+      setMajorStr(iMajor);
+      setMinorStr(iMinor);
+      setPatchStr(iPatch);
+    }
+
+    /**
+     * Get the version string
+     *
+     * @return the Version in "ProjectName Major.Minor.Patch" string format
+     */	
+    std::string getFull() {
+      return getProjectName()+std::string(" ")+
+             getMajorStr()+std::string(".")+
+             getMinorStr()+std::string(".")+
+             getPatchStr();
+    }
+
+    /**
+     * Get the shorter version string
+     *
+     * @return the Version in "Major.Minor" string format
+     */  
+    std::string getShort() {
+      return getMajorStr()+std::string(".")+
+             getMinorStr();
+    }
+	
+    /**
+     * Get the version objects project name
+     *
+     * @return the project name in string format
+     */	
+    std::string getProjectName() { return ProjectName; }
+                
+    /**
+     * Get the Version Major
+     *
+     * @return the Version Major in string format
+     */
+    std::string getMajorStr() 
+    { 
+      if(Major != -1) return IntToStr(Major);
+      return("X");
+    }
+		
+    /**
+     * Get the Version Minor
+     *
+     * @return the Version Minor in string format
+     */
+    std::string getMinorStr() 
+    { 
+      if(Minor != -1) return IntToStr(Minor); 
+      return("X");
+    }
+
+    /**
+     * Get the Version Patch
+     *
+     * @return the Version Patch in string format
+     */
+    std::string getPatchStr()
+    {
+      if(Patch != -1) return IntToStr(Patch);
+      return("X");
+    }
+
+    /**
+     * Get the Version Major
+     *
+     * @return the Version Major in int format
+     */
+    int getMajor() { return Major; }
+	
+    /**
+     * Get the Version Minor
+     *
+     * @return the Version Minor in int format
+     */
+    int getMinor() { return Minor; }
+
+    /**
+     * Get the Version Patch
+     *
+     * @return the Version Patch in int format
+     */
+    int getPatch() { return Patch; }
+
+private:
+    std::string ProjectName;
+	int Major, Minor, Patch;
+
+    std::string IntToStr(int number) {
+      std::stringstream s;
+      s << number;
+      return s.str();
+    }
+    int StrToInt(std::string string) {
+      int i = 0;
+      std::stringstream s(string);
+      if(!(s >> i)) return -1;
+      return i;
+    }
+    void setProjectName(std::string iProjectName)
+      { ProjectName = iProjectName; }
+
+    void setMajor(int iMajor) { Major = iMajor; }
+    void setMajorStr(std::string iMajor) {
+      Major = StrToInt(iMajor);
+    }
+    void setMinor(int iMinor) { Minor = iMinor; }
+    void setMinorStr(std::string iMinor) {
+      Minor = StrToInt(iMinor);
+    }
+    void setPatch(int iPatch) { Patch = iPatch; }
+    void setPatchStr(std::string iPatch) {
+      Patch = StrToInt(iPatch);
+    }
+};
+
+#endif //PROJECT_VERSION_HPP
diff --git a/CMake/VersionSuite/SetUpVersion.cmake b/CMake/VersionSuite/SetUpVersion.cmake
new file mode 100644
index 0000000..67f46dd
--- /dev/null
+++ b/CMake/VersionSuite/SetUpVersion.cmake
@@ -0,0 +1,83 @@
+# Version Suite
+# Author: Brian Panneton
+# Descrition:   This small suite allows you to add support
+#               for versioning in your projects
+
+# This allows you to turn on and off the auto
+# update of the (project name)Version.hpp file
+SET(VERSION_CONTROL_AUTOUPDATE OFF CACHE BOOL "Automaticaly Update The Version")
+MARK_AS_ADVANCED(VERSION_CONTROL_AUTOUPDATE)
+
+# We need to make sure we have the header file
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/CMake/VersionSuite)
+
+# Default incase CalculateVerison is not called
+SET(vMajor "0")
+SET(vMinor "0")
+SET(vPatch "0")
+
+# This Macro allows you to set up the Version in a one liner
+MACRO(VersionCreate versionName versionMajor versionMinor versionPatch export_name)
+    VersionMajorSet(${versionMajor})
+    VersionMinorSet(${versionMinor})
+    VersionPatchSet(${versionPatch})
+    
+# Manually generating minor version
+#   VersionCalculate()
+    VersionWrite(${versionName} ${export_name} "${ARGN}")
+ENDMACRO()
+
+# This Macro allows you to set the rewrite number
+MACRO(VersionMajorSet versionMajor)
+        SET(vMajor ${versionMajor})
+ENDMACRO()
+
+MACRO(VersionMinorSet versionMinor)
+        SET(vMinor ${versionMinor})
+ENDMACRO(VersionMinorSet)
+
+MACRO(VersionPatchSet versionPatch)
+        SET(vPatch ${versionPatch})
+ENDMACRO(VersionPatchSet)
+
+# This Macro calculates the number of tags from your git repo
+MACRO(VersionCalculate)
+    FIND_PACKAGE(Git)
+    IF(GIT_FOUND)
+        EXEC_PROGRAM(${GIT_EXECUTABLE} ${CMAKE_SOURCE_DIR} ARGS tag OUTPUT_VARIABLE return)
+        STRING(REGEX REPLACE "\n" ";" return "${return}")
+        SET(count 0)
+        FOREACH(r ${return})
+            MATH(EXPR count "${count} + 1")
+        ENDFOREACH()
+        SET(vMinor ${count})
+    ELSE()
+        SET(vMinor "X")
+    ENDIF()
+ENDMACRO()
+
+# This Macro writes your hpp/cpp files
+MACRO(VersionWrite vProjectName export_name)
+    SET(include_list "${ARGN}")
+    FOREACH(il ${include_list})
+        SET(includes "${includes}\n\#include \"${il}\"")
+    ENDFOREACH()
+    FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${vProjectName}Version.hpp
+"/* Current Version of ${vProjectName}
+ * Major is: ${vMajor}
+ * Minor is: ${vMinor}
+ * Patch is: ${vPatch}
+ */
+${includes}
+\#include \"ProjectVersion.hpp\"
+extern ${export_name} ProjectVersion ${vProjectName}Version;\n"
+    )
+
+        FILE(WRITE ${CMAKE_CURRENT_BINARY_DIR}/${vProjectName}Version.cpp
+"/* Current Version of ${vProjectName}
+ * Make sure to include this file in your built sources
+ */
+\#include \"${vProjectName}Version.hpp\"
+ProjectVersion ${vProjectName}Version = ProjectVersion(\"${vProjectName}\", \"${vMajor}\", \"${vMinor}\", \"${vPatch}\");\n"
+        )
+ENDMACRO()
diff --git a/CMake/XdmfFunctions.cmake b/CMake/XdmfFunctions.cmake
new file mode 100644
index 0000000..a22ffd0
--- /dev/null
+++ b/CMake/XdmfFunctions.cmake
@@ -0,0 +1,16 @@
+function(xdmf_create_config_file name)
+  get_cmake_property(ALL_VARS VARIABLES)
+  set(XDMF_VARS "")
+  foreach(var ${ALL_VARS})
+    if (NOT "x${${var}}" STREQUAL "x")
+      string(REGEX REPLACE "\\\\" "\\\\\\\\" ${var} "${${var}}")
+      if (var MATCHES "^(XDMF).*$")
+        set(XDMF_VARS "${XDMF_VARS}\nset(${var}\t\t\"${${var}}\")")
+      else()
+        set(XDMF_VARS "${XDMF_VARS}\nset(XDMF_${var}\t\t\"${${var}}\")")
+      endif()
+    endif()
+  endforeach()
+  configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/${name}Config.cmake.in
+    ${CMAKE_CURRENT_BINARY_DIR}/${name}Config.cmake @ONLY)
+endfunction()
diff --git a/Copyright.txt b/Copyright.txt
new file mode 100644
index 0000000..7759f17
--- /dev/null
+++ b/Copyright.txt
@@ -0,0 +1,32 @@
+Copyright (c) 2011 U.S. Army Research Laboratory 
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice,
+   this list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+   this list of conditions and the following disclaimer in the documentation
+   and/or other materials provided with the distribution.
+
+ * Neither the name of the U.S. Army Research Laboratory nor the names
+   of any contributors may be used to endorse or promote products derived
+   from this software without specific prior written permission.
+
+ * Modified source versions must be plainly marked as such, and must not be
+   misrepresented as being the original software.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..b911ab5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,43 @@
+Installing XDMF
+===============
+
+Brief instructions for building XDMF from source code: 
+
+* Clone the git repository:
+
+  ```sh
+  git clone git://xdmf.org/Xdmf.git
+  ```
+
+* Create a directory for building the code:
+
+  ```sh
+  cd Xdmf
+  mkdir build 
+  cd build
+  ```
+
+* Prepare the CMake-based build. There are two options:
+
+  1. Use the following command and select options using a menu.
+
+     ```sh
+     ccmake ..
+     ```
+
+  2. Set options on the command line. A typical command line for building 
+     XDMF with Python bindings may look like the following:
+
+     ```sh
+     export XDMF_INSTALL_DIR=/opt/Xdmf/
+     cmake .. -DCMAKE_INSTALL_PREFIX=${XDMF_INSTALL_DIR} \
+              -DBUILD_SHARED_LIBS=1 -DXDMF_WRAP_PYTHON=1 -Wno-dev
+     ```
+
+* Build and install XDMF:
+
+  ```sh
+  make 
+  make install
+  ```
+   
diff --git a/Xdmf.dtd b/Xdmf.dtd
new file mode 100644
index 0000000..3e39e64
--- /dev/null
+++ b/Xdmf.dtd
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--Root element of dataset-->
+<!ELEMENT Xdmf (Information*, Domain+)>
+<!ATTLIST Xdmf
+    Version CDATA #IMPLIED
+>
+<!--Contains domain data information-->
+<!ELEMENT Domain (Information*, Grid+)>
+<!ATTLIST Domain
+	Name CDATA #IMPLIED
+>
+<!--Contains a collection of homogeneous elements-->
+<!ELEMENT Grid (Information*, Time*, Grid*, Topology*, Geometry*, Attribute*)>
+<!ATTLIST Grid
+	Name CDATA #IMPLIED
+	GridType (Uniform | Collection) "Uniform"
+        CollectionType   (Spatial | Temporal) "Spatial"
+>
+<!--Contains a graph of points-->
+<!ELEMENT Graph (Information*, Time*, Attribute*)>
+<!ATTLIST Graph
+        Name CDATA #IMPLIED
+        NumberColumns CDATA #REQUIRED
+        NumberRows CDATA #REQUIRED
+>
+<!-- Described Temporal Relationship -->
+<!ELEMENT Time (Information*)>
+<!ATTLIST Time
+    Value CDATA #IMPLIED
+>
+<!--Describes the general organization of the data-->
+<!ELEMENT Topology (Information*, DataItem*)>
+<!ATTLIST Topology
+        TopologyType (NoTopologyType | Polyvertex | Polyline | Polygon | Triangle | Quadrilateral | Tetrahedron | Wedge | Hexahedron | Edge_3 | Triangle_6 | Quadrilateral_8 | Quadrilateral_9 | Tetrahedron_10 | Pyramid_13 | Wedge_15 | Wedge_18 | Hexahedron_20 | Hexahedron_24 | Hexahedron_27 | Hexahedron_64 | Hexahedron_125 | Hexahedron_216 | Hexahedron_343 | Hexahedron_512 | Hexahedron_729 | Hexahedron_1000 | Hexahedron_1331 | Hexahedron_Spectral_64 | Hexahedron_Spectral_125 | Hexahedron_ [...]
+	Dimensions CDATA #IMPLIED
+	Order CDATA #IMPLIED
+	NodesPerElement CDATA #IMPLIED
+>
+<!--Describes the XYZ values of the mesh-->
+<!ELEMENT Geometry (Information*, DataItem+)>
+<!ATTLIST Geometry
+	Name CDATA #IMPLIED
+	GeometryType (XYZ | XY | X_Y_Z | VXVYVZ | ORIGIN_DXDYDZ) "XYZ"
+>
+<!--Lowest level element, describes the data that is present in the XDMF dataset-->
+<!ELEMENT DataItem (#PCDATA | DataItem)*>
+<!ATTLIST DataItem
+	Name CDATA #IMPLIED
+        ItemType (Uniform | HyperSlab | Function) "Uniform"
+	Dimensions CDATA #REQUIRED
+	NumberType (Char | UChar | Float | Int | UInt) "Float"
+	Precision (1 | 4 | 8) "4"
+	Reference CDATA #IMPLIED
+        Endian (Big | Little | Native) "Native"
+	Format (XML | HDF | Binary | TIFF) "XML"
+>
+<!--Describes the values on the mesh-->
+<!ELEMENT Attribute (Information*, DataItem)>
+<!ATTLIST Attribute
+	Name CDATA #IMPLIED
+	Center (Node | Cell | Grid | Face | Edge) "Node"
+	AttributeType (Scalar | Vector | Tensor | Tensor6 | Matrix) "Scalar"
+>
+<!--Describes subsections of a grid-->
+<!ELEMENT Set (Information*, DataItem)>
+<!ATTLIST Set
+        Name CDATA #IMPLIED
+        Type (NoSetType | Node | Cell | Face | Edge) "Node"
+>
+<!--Describes a node maping-->
+<!ELEMENT Map (Information*, DataItem*)>
+<!ATTLIST Map
+        Name CDATA #IMPLIED
+>
+<!-- Application Dependent -->
+<!ELEMENT Information (#PCDATA | Information | EMPTY)*>
+<!ATTLIST Information 
+	Name CDATA #IMPLIED
+	Value CDATA #IMPLIED
+>
+
+<!--The Definitions of these three items are extremely loose-->
+<!ELEMENT Aggregate ANY>
+<!ELEMENT Subset ANY>
+<!ELEMENT Function ANY>
diff --git a/Xdmf.hpp b/Xdmf.hpp
new file mode 100644
index 0000000..db71bfa
--- /dev/null
+++ b/Xdmf.hpp
@@ -0,0 +1,185 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : Xdmf.hpp                                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef _XDMF_HPP
+#define _XDMF_HPP
+
+/*! \mainpage XDMF API
+*
+* \section intro Introduction
+*
+* The eXtensible Data Model and Format (XDMF) is a distributed data
+* hub for accessing scientific data in High Performance Computing
+* (HPC) applications. XDMF defines a data model and format as well as
+* facilities for accessing the data in a distributed environment.
+*
+* XDMF differs from other data model and format efforts in that the
+* "light data" is logically (and possibly physically) separated from
+* the "heavy data". Light data is considered to be both "data about
+* the data" such as dimensions and name, as well as small quantities
+* of computed data. Heavy data is considered to be large amounts of
+* data. For example, in a three dimensional structural mechanics
+* calculation, the size and dimensions of the computational grid are
+* light data while the actual X, Y, and Z values for the grid are
+* heavy data. Calculated values like "Pressure at a node" are heavy,
+* while "Total Residual Mass" for the entire calculation is light.
+* Light data is stored on disk in a machine parsable language like
+* XML. Heavy data is stored in a format suitable for large amounts of
+* data like HDF5.
+*
+* While use of the XDMF API is not necessary to produce or consume
+* valid datasets, it is extremely useful for handling the wide variety
+* of files that are possible and its use is highly recommended. The
+* XDMF API is written in C++ and is wrapped for access from other
+* languages including Python and Java.
+*
+* XDMF utilizes reference counting shared pointers to handle ownership
+* of XDMF objects. This allows multiple objects to reference a single
+* XDMF object. An object is deleted and memory is reclaimed when no
+* other XDMF objects hold a reference to the object. This allows
+* flexibility in constructing XDMF structures, as simple structures
+* can be shared instead of copied.
+*
+* All XDMF objects are constructed by calling New(), which returns a
+* shared pointer to a newly constructed object. All default
+* constructors in the XDMF API are protected, ensuring that only
+* shared pointers can be created. These pointers are freed
+* automatically by the shared pointer reference counting mechanism.
+*
+*
+* Structure:
+*
+* Xdmf2 is structured in a tree format with an XdmfDomain serving
+* as the base. The Domain contains multiple grid collections or
+* grids; each with their own geometries, topologies, attributes,
+* and/or sets. With the inclusion of shared pointers in Xdmf2
+* a topology could be shared across multiple grids or a grid
+* could be included in multiple grid collections and/or the domain.
+*
+* Comparing objects is done by comparing pointer addresses,
+* a deep copy will not produce an equivalent object.
+*
+*
+* C++ Examples:
+*
+* \subpage cppwrite "C++ Example of Xdmf Creation"
+*
+* \subpage cppread "C++ Example of Reading Xdmf"
+*
+* \subpage cppedit "C++ Example of Reading and Modifying Xdmf"
+*
+* Python Examples:
+*
+* \subpage pywrite "Python Example of Xdmf Creation"
+*
+* \subpage pyread "Python Example of Reading Xdmf"
+*
+* \subpage pyedit "Python Example of Reading and Modifying Xdmf"
+*
+*/
+
+/*!
+* \page cppwrite Example of Xdmf Creation
+* \include ExampleXdmfWrite.cpp
+*/
+
+/*!
+* \page cppread Example of Reading Xdmf
+* \include ExampleXdmfRead.cpp
+*/
+
+/*!
+* \page cppedit Example of Reading and Modifying
+* \include ExampleXdmfEdit.cpp
+*/
+
+/*!
+* \page pywrite Example of Xdmf Creation
+* \include XdmfExampleWrite.py
+*/
+
+/*!
+* \page pyread Example of Reading Xdmf
+* \include XdmfExampleRead.py
+*/
+
+/*!
+* \page pyedit Example of Reading and Modifying
+* \include XdmfExampleEdit.py
+*/
+
+#include "XdmfConfig.hpp"
+
+
+/* Keep all our Win32 Conversions here */
+#ifdef _WIN32
+#ifdef XDMFSTATIC
+# define XDMFCORE_EXPORT
+# define XDMFDSM_EXPORT
+# define XDMF_EXPORT
+# define XDMFCORE_TEMPLATE
+# define XDMFDSM_TEMPLATE
+# define XDMF_TEMPLATE
+#else
+/* Used to export/import from the dlls */
+# undef XDMFCORE_EXPORT
+# define XDMFCORE_EXPORT __declspec(dllimport)
+# undef XDMFCORE_TEMPLATE
+# define XDMFCORE_TEMPLATE extern
+
+# undef XDMFDSM_EXPORT
+# define XDMFDSM_EXPORT __declspec(dllimport)
+# undef XDMFDSM_TEMPLATE
+# define XDMFDSM_TEMPLATE extern
+
+# ifdef XDMF_EXPORTS
+# define XDMF_EXPORT __declspec(dllexport)
+# define XDMF_TEMPLATE
+# else /* XDMF_EXPORTS */
+# define XDMF_EXPORT __declspec(dllimport)
+# define XDMF_TEMPLATE extern
+# endif /* XDMF_EXPORTS */
+#endif
+
+/* Compiler Warnings */
+#ifndef XDMF_DEBUG
+#pragma warning( disable : 4231 ) /* nonstandard extension used : 'extern' before template explicit instantiation */
+#pragma warning( disable : 4251 ) /* needs to have dll-interface to be used by clients (Most of these guys are in private */
+#pragma warning( disable : 4275 ) /* non dll-interface class 'std::_Container_base_aux' used as base for dll-interface class */
+#pragma warning( disable : 4373 ) /* virtual function overrides,  parameters only differed by const/volatile qualifiers */
+#pragma warning( disable : 4748 ) /* /GS can not protect parameters and local variables from local buffer overrun (turned off op)*/
+#endif /* XDMF_DEBUG */
+
+/* Compiler Optimizations will result in an 'internal compiler error', so turn them off */
+#pragma optimize("g", off)
+
+#else /* _WIN32 */
+/* We don't need to export/import since there are no dlls */
+#define XDMFCORE_EXPORT
+#define XDMFDSM_EXPORT
+#define XDMF_EXPORT
+#define XDMFCORE_TEMPLATE
+#define XDMFDSM_TEMPLATE
+#define XDMF_TEMPLATE
+#endif /* _WIN32 */
+#endif /* _XDMF_HPP */
diff --git a/Xdmf.i b/Xdmf.i
new file mode 100644
index 0000000..b86fb7c
--- /dev/null
+++ b/Xdmf.i
@@ -0,0 +1,1269 @@
+/*
+XdmfPython.cpp:
+swig -v -c++ -python -o XdmfPython.cpp Xdmf.i
+*/
+
+%{
+#include <cstddef>
+#include <iostream>
+#if PY_VERSION_HEX >= 0x03020000
+    #define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
+#else
+    #define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
+#endif
+%}
+
+#ifdef XDMF_BUILD_DSM
+
+%module Xdmf
+%{
+    // MPI Includes
+    #include <mpi.h>
+
+    // XdmfCore Includes
+    #include <Xdmf.hpp>
+    #include <XdmfArray.hpp>
+    #include <XdmfArrayReference.hpp>
+    #include <XdmfArrayType.hpp>
+    #include <XdmfCoreItemFactory.hpp>
+    #include <XdmfCoreReader.hpp>
+    #include <XdmfDSMBuffer.hpp>
+    #include <XdmfDSMCommMPI.hpp>
+    #include <XdmfDSMItemFactory.hpp>
+    #include <XdmfError.hpp>
+    #include <XdmfFunction.hpp>
+    #include <XdmfHDF5Controller.hpp>
+    #include <XdmfHDF5Writer.hpp>
+    #include <XdmfHDF5ControllerDSM.hpp>
+    #include <XdmfHDF5WriterDSM.hpp>
+    #include <XdmfHeavyDataController.hpp>
+    #include <XdmfHeavyDataWriter.hpp>
+    #include <XdmfInformation.hpp>
+    #include <XdmfItem.hpp>
+    #include <XdmfItemProperty.hpp>
+    #include <XdmfSharedPtr.hpp>
+    #include <XdmfSparseMatrix.hpp>
+    #include <XdmfSubset.hpp>
+    #include <XdmfSystemUtils.hpp>
+    #include <XdmfTIFFController.hpp>
+    #include <XdmfVisitor.hpp>
+    #include <XdmfWriter.hpp>
+
+    // Xdmf Includes
+    #include <XdmfAggregate.hpp>
+    #include <XdmfAttribute.hpp>
+    #include <XdmfAttributeCenter.hpp>
+    #include <XdmfAttributeType.hpp>
+    #include <XdmfCurvilinearGrid.hpp>
+    #include <XdmfDomain.hpp>
+    #include <XdmfGeometry.hpp>
+    #include <XdmfGeometryType.hpp>
+    #include <XdmfGraph.hpp>
+    #include <XdmfGrid.hpp>
+    #include <XdmfGridCollection.hpp>
+    #include <XdmfGridCollectionType.hpp>
+    #include <XdmfItemFactory.hpp>
+    #include <XdmfMap.hpp>
+    #include <XdmfReader.hpp>
+    #include <XdmfRectilinearGrid.hpp>
+    #include <XdmfRegularGrid.hpp>
+    #include <XdmfSet.hpp>
+    #include <XdmfSetType.hpp>
+    #include <XdmfTime.hpp>
+    #include <XdmfTopology.hpp>
+    #include <XdmfTopologyType.hpp>
+    #include <XdmfUnstructuredGrid.hpp>
+
+%}
+
+#else
+%module Xdmf
+%{
+    // XdmfCore Includes
+    #include <Xdmf.hpp>
+    #include <XdmfArray.hpp>
+    #include <XdmfArrayReference.hpp>
+    #include <XdmfArrayType.hpp>
+    #include <XdmfCoreItemFactory.hpp>
+    #include <XdmfCoreReader.hpp>
+    #include <XdmfError.hpp>
+    #include <XdmfFunction.hpp>
+    #include <XdmfHDF5Controller.hpp>
+    #include <XdmfHDF5Writer.hpp>
+    #include <XdmfHeavyDataController.hpp>
+    #include <XdmfHeavyDataWriter.hpp>
+    #include <XdmfInformation.hpp>
+    #include <XdmfItem.hpp>
+    #include <XdmfItemProperty.hpp>
+    #include <XdmfSharedPtr.hpp>
+    #include <XdmfSparseMatrix.hpp>
+    #include <XdmfSubset.hpp>
+    #include <XdmfSystemUtils.hpp>
+    #include <XdmfTIFFController.hpp>
+    #include <XdmfVisitor.hpp>
+    #include <XdmfWriter.hpp>
+
+    // Xdmf Includes
+    #include <XdmfAggregate.hpp>
+    #include <XdmfAttribute.hpp>
+    #include <XdmfAttributeCenter.hpp>
+    #include <XdmfAttributeType.hpp>
+    #include <XdmfCurvilinearGrid.hpp>
+    #include <XdmfDomain.hpp>
+    #include <XdmfGeometry.hpp>
+    #include <XdmfGeometryType.hpp>
+    #include <XdmfGraph.hpp>
+    #include <XdmfGrid.hpp>
+    #include <XdmfGridCollection.hpp>
+    #include <XdmfGridCollectionType.hpp>
+    #include <XdmfItemFactory.hpp>
+    #include <XdmfMap.hpp>
+    #include <XdmfReader.hpp>
+    #include <XdmfRectilinearGrid.hpp>
+    #include <XdmfRegularGrid.hpp>
+    #include <XdmfSet.hpp>
+    #include <XdmfSetType.hpp>
+    #include <XdmfTime.hpp>
+    #include <XdmfTopology.hpp>
+    #include <XdmfTopologyType.hpp>
+    #include <XdmfUnstructuredGrid.hpp>
+%}
+
+#endif
+
+%import XdmfCore.i
+
+// Ignoring C Wrappers
+
+// XdmfAggregate
+
+%ignore XdmfAggregateNew();
+%ignore XdmfAggregateGetArray(XDMFAGGREGATE * aggregate, unsigned int index);
+%ignore XdmfAggregateGetArrayByName(XDMFAGGREGATE * aggregate, char * name);
+%ignore XdmfAggregateGetNumberArrays(XDMFAGGREGATE * aggregate);
+%ignore XdmfAggregateInsertArray(XDMFAGGREGATE * aggregate, XDMFARRAY * array, int transferOwnership);
+%ignore XdmfAggregateRemoveArray(XDMFAGGREGATE * aggregate, unsigned int index);
+%ignore XdmfAggregateRemoveArrayByName(XDMFAGGREGATE * aggregate, char * name);
+
+// XdmfAttributeCenter
+
+%ignore XdmfAttributeCenterGrid();
+%ignore XdmfAttributeCenterCell();
+%ignore XdmfAttributeCenterFace();
+%ignore XdmfAttributeCenterEdge();
+%ignore XdmfAttributeCenterNode();
+
+// XdmfAttribute
+
+%ignore XdmfAttributeNew();
+%ignore XdmfAttributeGetCenter(XDMFATTRIBUTE * attribute);
+%ignore XdmfAttributeGetType(XDMFATTRIBUTE * attribute);
+%ignore XdmfAttributeSetCenter(XDMFATTRIBUTE * attribute, int center, int * status);
+%ignore XdmfAttributeSetType(XDMFATTRIBUTE * attribute, int type, int * status);
+// XdmfAttribute inherited from XdmfArray
+%ignore XdmfAttributeNew();
+%ignore XdmfAttributeClear(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeErase(XDMFATTRIBUTE * array, unsigned int index);
+%ignore XdmfAttributeGetArrayType(XDMFATTRIBUTE * array, int * status);
+%ignore XdmfAttributeGetCapacity(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetDimensions(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetDimensionsString(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetHeavyDataController(XDMFATTRIBUTE * array, unsigned int index);
+%ignore XdmfAttributeGetReadMode(XDMFATTRIBUTE * array, int * status);
+%ignore XdmfAttributeGetName(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetNumberDimensions(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetNumberHeavyDataControllers(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetSize(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetReference(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetValue(XDMFATTRIBUTE * array, unsigned int index, int arrayType, int * status);
+%ignore XdmfAttributeGetValues(XDMFATTRIBUTE * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfAttributeGetValuesInternal(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeGetValuesString(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeInitialize(XDMFATTRIBUTE * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfAttributeInsertDataFromPointer(XDMFATTRIBUTE * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfAttributeInsertDataFromXdmfArray(XDMFATTRIBUTE * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status);
+%ignore XdmfAttributeInsertHeavyDataController(XDMFATTRIBUTE * array, XDMFHEAVYDATACONTROLLER * controller, int passControl);
+%ignore XdmfAttributeInsertValue(XDMFATTRIBUTE * array, unsigned int index, void * value, int arrayType, int * status);
+%ignore XdmfAttributeIsInitialized(XDMFATTRIBUTE * array);
+%ignore XdmfAttributePushBack(XDMFATTRIBUTE * array, void * value, int arrayType, int * status);
+%ignore XdmfAttributeRead(XDMFATTRIBUTE * array, int * status);
+%ignore XdmfAttributeReadController(XDMFATTRIBUTE * array, int * status);
+%ignore XdmfAttributeReadReference(XDMFATTRIBUTE * array, int * status);
+%ignore XdmfAttributeRelease(XDMFATTRIBUTE * array);
+%ignore XdmfAttributeRemoveHeavyDataController(XDMFATTRIBUTE * array, unsigned int index);
+%ignore XdmfAttributeReserve(XDMFATTRIBUTE * array, int size);
+%ignore XdmfAttributeResize(XDMFATTRIBUTE * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfAttributeSetReadMode(XDMFATTRIBUTE * array, int readMode, int * status);
+%ignore XdmfAttributeSetReference(XDMFATTRIBUTE * array, XDMFARRAYREFERENCE * reference, int passControl);
+%ignore XdmfAttributeSetName(XDMFATTRIBUTE * array, char * name, int * status);
+%ignore XdmfAttributeSetValuesInternal(XDMFATTRIBUTE * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status);
+%ignore XdmfAttributeSwapWithXdmfArray(XDMFATTRIBUTE * array, XDMFARRAY * swapArray);
+%ignore XdmfAttributeSwapWithArray(XDMFATTRIBUTE * array, void ** pointer, int numValues, int arrayType, int * status);
+// XdmfAttribute inherited from XdmfItem
+%ignore XdmfAttributeAccept(XDMFATTRIBUTE * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfAttributeFree(void * item);
+%ignore XdmfAttributeGetInformation(XDMFATTRIBUTE * item, unsigned int index);
+%ignore XdmfAttributeGetInformationByKey(XDMFATTRIBUTE * item, char * key);
+%ignore XdmfAttributeGetNumberInformations(XDMFATTRIBUTE * item);
+%ignore XdmfAttributeInsertInformation(XDMFATTRIBUTE * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfAttributeRemoveInformation(XDMFATTRIBUTE * item, unsigned int index);
+%ignore XdmfAttributeRemoveInformationByKey(XDMFATTRIBUTE * item, char * key);
+%ignore XdmfAttributeGetItemTag(XDMFATTRIBUTE * item);
+
+// XdmfAttributeType
+
+%ignore XdmfAttributeTypeScalar();
+%ignore XdmfAttributeTypeVector();
+%ignore XdmfAttributeTypeTensor();
+%ignore XdmfAttributeTypeMatrix();
+%ignore XdmfAttributeTypeTensor6();
+%ignore XdmfAttributeTypeGlobalId();
+%ignore XdmfAttributeTypeNoAttributeType();
+
+// XdmfCurvilinearGrid
+
+%ignore XdmfCurvilinearGridNew2D(unsigned int xNumPoints,
+                                 unsigned int yNumPoints);
+%ignore XdmfCurvilinearGridNew3D(unsigned int xNumPoints,
+                                 unsigned int yNumPoints,
+                                 unsigned int zNumPoints);
+%ignore XdmfCurvilinearGridNew(XDMFARRAY * numPoints, int * status);
+%ignore XdmfCurvilinearGridGetDimensions(XDMFCURVILINEARGRID * grid, int * status);
+%ignore XdmfCurvilinearGridGetGeometry(XDMFCURVILINEARGRID * grid);
+%ignore XdmfCurvilinearGridSetDimensions(XDMFCURVILINEARGRID * grid,
+                                         XDMFARRAY * dimensions,
+                                         int passControl,
+                                         int * status);
+%ignore XdmfCurvilinearGridSetGeometry(XDMFCURVILINEARGRID * grid,
+                                       XDMFGEOMETRY * geometry,
+                                       int passControl);
+// XdmfCurvilinearGrid inherited from XdmfItem
+%ignore XdmfCurvilinearGridAccept(XDMFCURVILINEARGRID * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfCurvilinearGridFree(void * item);
+%ignore XdmfCurvilinearGridGetInformation(XDMFCURVILINEARGRID * item, unsigned int index);
+%ignore XdmfCurvilinearGridGetInformationByKey(XDMFCURVILINEARGRID * item, char * key);
+%ignore XdmfCurvilinearGridGetNumberInformations(XDMFCURVILINEARGRID * item);
+%ignore XdmfCurvilinearGridInsertInformation(XDMFCURVILINEARGRID * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfCurvilinearGridRemoveInformation(XDMFCURVILINEARGRID * item, unsigned int index);
+%ignore XdmfCurvilinearGridRemoveInformationByKey(XDMFCURVILINEARGRID * item, char * key);
+%ignore XdmfCurvilinearGridGetItemTag(XDMFCURVILINEARGRID * item);
+// XdmfCurvilinearGrid inherited from XdmfGrid
+%ignore XdmfCurvilinearGridGetAttribute(XDMFCURVILINEARGRID * grid, unsigned int index);
+%ignore XdmfCurvilinearGridGetAttributeByName(XDMFCURVILINEARGRID * grid, char * Name);
+%ignore XdmfCurvilinearGridGetNumberAttributes(XDMFCURVILINEARGRID * grid);
+%ignore XdmfCurvilinearGridInsertAttribute(XDMFCURVILINEARGRID * grid, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfCurvilinearGridRemoveAttribute(XDMFCURVILINEARGRID * grid, unsigned int index);
+%ignore XdmfCurvilinearGridRemoveAttributeByName(XDMFCURVILINEARGRID * grid, char * Name);
+%ignore XdmfCurvilinearGridGetSet(XDMFCURVILINEARGRID * grid, unsigned int index);
+%ignore XdmfCurvilinearGridGetSetByName(XDMFCURVILINEARGRID * grid, char * Name);
+%ignore XdmfCurvilinearGridGetNumberSets(XDMFCURVILINEARGRID * grid);
+%ignore XdmfCurvilinearGridInsertSet(XDMFCURVILINEARGRID * grid, XDMFSET * Set, int passControl);
+%ignore XdmfCurvilinearGridRemoveSet(XDMFCURVILINEARGRID * grid, unsigned int index);
+%ignore XdmfCurvilinearGridRemoveSetByName(XDMFCURVILINEARGRID * grid, char * Name);
+%ignore XdmfCurvilinearGridGetMap(XDMFCURVILINEARGRID * grid, unsigned int index);
+%ignore XdmfCurvilinearGridGetMapByName(XDMFCURVILINEARGRID * grid, char * Name);
+%ignore XdmfCurvilinearGridGetNumberMaps(XDMFCURVILINEARGRID * grid);
+%ignore XdmfCurvilinearGridInsertMap(XDMFCURVILINEARGRID * grid, XDMFMAP * Map, int passControl);
+%ignore XdmfCurvilinearGridRemoveMap(XDMFCURVILINEARGRID * grid, unsigned int index);
+%ignore XdmfCurvilinearGridRemoveMapByName(XDMFCURVILINEARGRID * grid, char * Name);
+%ignore XdmfCurvilinearGridGetName(XDMFCURVILINEARGRID * grid);
+%ignore XdmfCurvilinearGridGetTime(XDMFCURVILINEARGRID * grid);
+%ignore XdmfCurvilinearGridSetName(XDMFCURVILINEARGRID * grid, char * name, int * status);
+%ignore XdmfCurvilinearGridSetTime(XDMFCURVILINEARGRID * grid, XDMFTIME * time, int passControl);
+
+// XdmfDomain
+
+%ignore XdmfDomainNew();
+%ignore XdmfDomainGetGridCollection(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainGetGridCollectionByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetNumberGridCollections(XDMFDOMAIN * domain);
+%ignore XdmfDomainInsertGridCollection(XDMFDOMAIN * domain,
+                                       XDMFGRIDCOLLECTION * GridCollection,
+                                       int passControl);
+%ignore XdmfDomainRemoveGridCollection(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainRemoveGridCollectionByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetGraph(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainGetGraphByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetNumberGraphs(XDMFDOMAIN * domain);
+%ignore XdmfDomainInsertGraph(XDMFDOMAIN * domain, XDMFGRAPH * graph, int passControl);
+%ignore XdmfDomainRemoveGraph(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainRemoveGraphByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetCurvilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainGetCurvilinearGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetNumberCurvilinearGrids(XDMFDOMAIN * domain);
+%ignore XdmfDomainInsertCurvilinearGrid(XDMFDOMAIN * domain,
+                                        XDMFCURVILINEARGRID * CurvilinearGrid,
+                                        int passControl);
+%ignore XdmfDomainRemoveCurvilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainRemoveCurvilinearGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetRectilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainGetRectilinearGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetNumberRectilinearGrids(XDMFDOMAIN * domain);
+%ignore XdmfDomainInsertRectilinearGrid(XDMFDOMAIN * domain,
+                                        XDMFRECTILINEARGRID * RectilinearGrid,
+                                        int passControl);
+%ignore XdmfDomainRemoveRectilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainRemoveRectilinearGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetRegularGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainGetRegularGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetNumberRegularGrids(XDMFDOMAIN * domain);
+%ignore XdmfDomainInsertRegularGrid(XDMFDOMAIN * domain,
+                                    XDMFREGULARGRID * RegularGrid,
+                                    int passControl);
+%ignore XdmfDomainRemoveRegularGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainRemoveRegularGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetUnstructuredGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainGetUnstructuredGridByName(XDMFDOMAIN * domain, char * Name);
+%ignore XdmfDomainGetNumberUnstructuredGrids(XDMFDOMAIN * domain);
+%ignore XdmfDomainInsertUnstructuredGrid(XDMFDOMAIN * domain,
+                                         XDMFUNSTRUCTUREDGRID * UnstructuredGrid,
+                                         int passControl);
+%ignore XdmfDomainRemoveUnstructuredGrid(XDMFDOMAIN * domain, unsigned int index);
+%ignore XdmfDomainRemoveUnstructuredGridByName(XDMFDOMAIN * domain, char * Name);
+// XdmfDomain inherited from XdmfItem
+%ignore XdmfDomainAccept(XDMFDOMAIN * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfDomainFree(void * item);
+%ignore XdmfDomainGetInformation(XDMFDOMAIN * item, unsigned int index);
+%ignore XdmfDomainGetInformationByKey(XDMFDOMAIN * item, char * key);
+%ignore XdmfDomainGetNumberInformations(XDMFDOMAIN * item);
+%ignore XdmfDomainInsertInformation(XDMFDOMAIN * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfDomainRemoveInformation(XDMFDOMAIN * item, unsigned int index);
+%ignore XdmfDomainRemoveInformationByKey(XDMFDOMAIN * item, char * key);
+%ignore XdmfDomainGetItemTag(XDMFDOMAIN * item);
+
+// XdmfGeometry
+
+%ignore XdmfGeometryNew();
+%ignore XdmfGeometryGetNumberPoints(XDMFGEOMETRY * geometry);
+%ignore XdmfGeometryGetOrigin(XDMFGEOMETRY * geometry);
+%ignore XdmfGeometryGetOriginSize(XDMFGEOMETRY * geometry);
+%ignore XdmfGeometryGetType(XDMFGEOMETRY * geometry);
+%ignore XdmfGeometrySetOrigin(XDMFGEOMETRY * geometry, double newX, double newY, double newZ);
+%ignore XdmfGeometrySetOriginArray(XDMFGEOMETRY * geometry, double * originVals, unsigned int numDims);
+%ignore XdmfGeometrySetType(XDMFGEOMETRY * geometry, int type, int * status);
+// XdmfGeometry inherited from XdmfArray
+%ignore XdmfGeometryNew();
+%ignore XdmfGeometryClear(XDMFGEOMETRY * array);
+%ignore XdmfGeometryErase(XDMFGEOMETRY * array, unsigned int index);
+%ignore XdmfGeometryGetArrayType(XDMFGEOMETRY * array, int * status);
+%ignore XdmfGeometryGetCapacity(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetDimensions(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetDimensionsString(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetHeavyDataController(XDMFGEOMETRY * array, unsigned int index);
+%ignore XdmfGeometryGetReadMode(XDMFGEOMETRY * array, int * status);
+%ignore XdmfGeometryGetName(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetNumberDimensions(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetNumberHeavyDataControllers(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetSize(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetReference(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetValue(XDMFGEOMETRY * array, unsigned int index, int arrayType, int * status);
+%ignore XdmfGeometryGetValues(XDMFGEOMETRY * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfGeometryGetValuesInternal(XDMFGEOMETRY * array);
+%ignore XdmfGeometryGetValuesString(XDMFGEOMETRY * array);
+%ignore XdmfGeometryInitialize(XDMFGEOMETRY * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfGeometryInsertDataFromPointer(XDMFGEOMETRY * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfGeometryInsertDataFromXdmfArray(XDMFGEOMETRY * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status);
+%ignore XdmfGeometryInsertHeavyDataController(XDMFGEOMETRY * array, XDMFHEAVYDATACONTROLLER * controller, int passControl);
+%ignore XdmfGeometryInsertValue(XDMFGEOMETRY * array, unsigned int index, void * value, int arrayType, int * status);
+%ignore XdmfGeometryIsInitialized(XDMFGEOMETRY * array);
+%ignore XdmfGeometryPushBack(XDMFGEOMETRY * array, void * value, int arrayType, int * status);
+%ignore XdmfGeometryRead(XDMFGEOMETRY * array, int * status);
+%ignore XdmfGeometryReadController(XDMFGEOMETRY * array, int * status);
+%ignore XdmfGeometryReadReference(XDMFGEOMETRY * array, int * status);
+%ignore XdmfGeometryRelease(XDMFGEOMETRY * array);
+%ignore XdmfGeometryRemoveHeavyDataController(XDMFGEOMETRY * array, unsigned int index);
+%ignore XdmfGeometryReserve(XDMFGEOMETRY * array, int size);
+%ignore XdmfGeometryResize(XDMFGEOMETRY * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfGeometrySetReadMode(XDMFGEOMETRY * array, int readMode, int * status);
+%ignore XdmfGeometrySetReference(XDMFGEOMETRY * array, XDMFARRAYREFERENCE * reference, int passControl);
+%ignore XdmfGeometrySetName(XDMFGEOMETRY * array, char * name, int * status);
+%ignore XdmfGeometrySetValuesInternal(XDMFGEOMETRY * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status);
+%ignore XdmfGeometrySwapWithXdmfArray(XDMFGEOMETRY * array, XDMFARRAY * swapArray);
+%ignore XdmfGeometrySwapWithArray(XDMFGEOMETRY * array, void ** pointer, int numValues, int arrayType, int * status);
+// XdmfGeometry inherited from XdmfItem
+%ignore XdmfGeometryAccept(XDMFGEOMETRY * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfGeometryFree(void * item);
+%ignore XdmfGeometryGetInformation(XDMFGEOMETRY * item, unsigned int index);
+%ignore XdmfGeometryGetInformationByKey(XDMFGEOMETRY * item, char * key);
+%ignore XdmfGeometryGetNumberInformations(XDMFGEOMETRY * item);
+%ignore XdmfGeometryInsertInformation(XDMFGEOMETRY * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfGeometryRemoveInformation(XDMFGEOMETRY * item, unsigned int index);
+%ignore XdmfGeometryRemoveInformationByKey(XDMFGEOMETRY * item, char * key);
+%ignore XdmfGeometryGetItemTag(XDMFGEOMETRY * item);
+
+// XdmfGeometryType
+
+%ignore XdmfGeometryTypeNoGeometryType();
+%ignore XdmfGeometryTypeXYZ();
+%ignore XdmfGeometryTypeXY();
+%ignore XdmfGeometryTypeGetDimensions(int type, int * status);
+%ignore XdmfGeometryTypeGetName(int type);
+
+// XdmfGraph
+
+%ignore XdmfGraphNew(unsigned int numberNodes);
+%ignore XdmfGraphGetAttribute(XDMFGRAPH * graph, unsigned int index);
+%ignore XdmfGraphGetAttributeByName(XDMFGRAPH * graph, char * Name);
+%ignore XdmfGraphGetNumberAttributes(XDMFGRAPH * graph);
+%ignore XdmfGraphInsertAttribute(XDMFGRAPH * graph, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfGraphRemoveAttribute(XDMFGRAPH * graph, unsigned int index);
+%ignore XdmfGraphRemoveAttributeByName(XDMFGRAPH * graph, char * Name);
+%ignore XdmfGraphGetNumberNodes(XDMFGRAPH * graph);
+// XdmfGraph inherited from XdmfSparseMatrix
+%ignore XdmfGraphNew(unsigned int numberRows, unsigned int numberColumns);
+%ignore XdmfGraphGetColumnIndex(XDMFGRAPH * matrix, int * status);
+%ignore XdmfGraphGetName(XDMFGRAPH * matrix);
+%ignore XdmfGraphGetNumberColumns(XDMFGRAPH * matrix);
+%ignore XdmfGraphGetNumberRows(XDMFGRAPH * matrix);
+%ignore XdmfGraphGetRowPointer(XDMFGRAPH * matrix, int * status);
+%ignore XdmfGraphGetValues(XDMFGRAPH * matrix, int * status);
+%ignore XdmfGraphGetValuesString(XDMFGRAPH * matrix, int * status);
+%ignore XdmfGraphSetColumnIndex(XDMFGRAPH * matrix,
+                                XDMFARRAY * columnIndex,
+                                int passControl,
+                                int * status);
+%ignore XdmfGraphSetName(XDMFGRAPH * matrix, char * name, int * status);
+%ignore XdmfGraphSetRowPointer(XDMFGRAPH * matrix,
+                               XDMFARRAY * rowPointer,
+                               int passControl,
+                               int * status);
+%ignore XdmfGraphSetValues(XDMFGRAPH * matrix,
+                           XDMFARRAY * values,
+                           int passControl,
+                           int * status);
+// XdmfGraph inherited from XdmfItem
+%ignore XdmfGraphAccept(XDMFGRAPH * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfGraphFree(void * item);
+%ignore XdmfGraphGetInformation(XDMFGRAPH * item, unsigned int index);
+%ignore XdmfGraphGetInformationByKey(XDMFGRAPH * item, char * key);
+%ignore XdmfGraphGetNumberInformations(XDMFGRAPH * item);
+%ignore XdmfGraphInsertInformation(XDMFGRAPH * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfGraphRemoveInformation(XDMFGRAPH * item, unsigned int index);
+%ignore XdmfGraphRemoveInformationByKey(XDMFGRAPH * item, char * key);
+%ignore XdmfGraphGetItemTag(XDMFGRAPH * item);
+
+// XdmfGridCollection
+
+%ignore XdmfGridCollectionNew();
+%ignore XdmfGridCollectionGetType(XDMFGRIDCOLLECTION * collection, int * status);
+%ignore XdmfGridCollectionSetType(XDMFGRIDCOLLECTION * collection, int type, int * status);
+// XdmfGridCollection inherited from XdmfDomain
+%ignore XdmfGridCollectionGetGridCollection(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionGetGridCollectionByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetNumberGridCollections(XDMFGRIDCOLLECTION * domain);
+%ignore XdmfGridCollectionInsertGridCollection(XDMFGRIDCOLLECTION * domain,
+                                       XDMFGRIDCOLLECTION * GridCollection,
+                                       int passControl);
+%ignore XdmfGridCollectionRemoveGridCollection(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionRemoveGridCollectionByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetGraph(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionGetGraphByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetNumberGraphs(XDMFGRIDCOLLECTION * domain);
+%ignore XdmfGridCollectionInsertGraph(XDMFGRIDCOLLECTION * domain, XDMFGRAPH * graph, int passControl);
+%ignore XdmfGridCollectionRemoveGraph(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionRemoveGraphByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetCurvilinearGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionGetCurvilinearGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetNumberCurvilinearGrids(XDMFGRIDCOLLECTION * domain);
+%ignore XdmfGridCollectionInsertCurvilinearGrid(XDMFGRIDCOLLECTION * domain,
+                                        XDMFCURVILINEARGRID * CurvilinearGrid,
+                                        int passControl);
+%ignore XdmfGridCollectionRemoveCurvilinearGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionRemoveCurvilinearGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetRectilinearGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionGetRectilinearGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetNumberRectilinearGrids(XDMFGRIDCOLLECTION * domain);
+%ignore XdmfGridCollectionInsertRectilinearGrid(XDMFGRIDCOLLECTION * domain,
+                                        XDMFRECTILINEARGRID * RectilinearGrid,
+                                        int passControl);
+%ignore XdmfGridCollectionRemoveRectilinearGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionRemoveRectilinearGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetRegularGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionGetRegularGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetNumberRegularGrids(XDMFGRIDCOLLECTION * domain);
+%ignore XdmfGridCollectionInsertRegularGrid(XDMFGRIDCOLLECTION * domain,
+                                    XDMFREGULARGRID * RegularGrid,
+                                    int passControl);
+%ignore XdmfGridCollectionRemoveRegularGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionRemoveRegularGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetUnstructuredGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionGetUnstructuredGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+%ignore XdmfGridCollectionGetNumberUnstructuredGrids(XDMFGRIDCOLLECTION * domain);
+%ignore XdmfGridCollectionInsertUnstructuredGrid(XDMFGRIDCOLLECTION * domain,
+                                         XDMFUNSTRUCTUREDGRID * UnstructuredGrid,
+                                         int passControl);
+%ignore XdmfGridCollectionRemoveUnstructuredGrid(XDMFGRIDCOLLECTION * domain, unsigned int index);
+%ignore XdmfGridCollectionRemoveUnstructuredGridByName(XDMFGRIDCOLLECTION * domain, char * Name);
+// XdmfGridCollection inherited from XdmfGrid
+%ignore XdmfGridCollectionGetAttribute(XDMFGRIDCOLLECTION * grid, unsigned int index);
+%ignore XdmfGridCollectionGetAttributeByName(XDMFGRIDCOLLECTION * grid, char * Name);
+%ignore XdmfGridCollectionGetNumberAttributes(XDMFGRIDCOLLECTION * grid);
+%ignore XdmfGridCollectionInsertAttribute(XDMFGRIDCOLLECTION * grid, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfGridCollectionRemoveAttribute(XDMFGRIDCOLLECTION * grid, unsigned int index);
+%ignore XdmfGridCollectionRemoveAttributeByName(XDMFGRIDCOLLECTION * grid, char * Name);
+%ignore XdmfGridCollectionGetSet(XDMFGRIDCOLLECTION * grid, unsigned int index);
+%ignore XdmfGridCollectionGetSetByName(XDMFGRIDCOLLECTION * grid, char * Name);
+%ignore XdmfGridCollectionGetNumberSets(XDMFGRIDCOLLECTION * grid);
+%ignore XdmfGridCollectionInsertSet(XDMFGRIDCOLLECTION * grid, XDMFSET * Set, int passControl);
+%ignore XdmfGridCollectionRemoveSet(XDMFGRIDCOLLECTION * grid, unsigned int index);
+%ignore XdmfGridCollectionRemoveSetByName(XDMFGRIDCOLLECTION * grid, char * Name);
+%ignore XdmfGridCollectionGetMap(XDMFGRIDCOLLECTION * grid, unsigned int index);
+%ignore XdmfGridCollectionGetMapByName(XDMFGRIDCOLLECTION * grid, char * Name);
+%ignore XdmfGridCollectionGetNumberMaps(XDMFGRIDCOLLECTION * grid);
+%ignore XdmfGridCollectionInsertMap(XDMFGRIDCOLLECTION * grid, XDMFMAP * Map, int passControl);
+%ignore XdmfGridCollectionRemoveMap(XDMFGRIDCOLLECTION * grid, unsigned int index);
+%ignore XdmfGridCollectionRemoveMapByName(XDMFGRIDCOLLECTION * grid, char * Name);
+%ignore XdmfGridCollectionGetName(XDMFGRIDCOLLECTION * grid);
+%ignore XdmfGridCollectionGetTime(XDMFGRIDCOLLECTION * grid);
+%ignore XdmfGridCollectionSetName(XDMFGRIDCOLLECTION * grid, char * name, int * status);
+%ignore XdmfGridCollectionSetTime(XDMFGRIDCOLLECTION * grid, XDMFTIME * time, int passControl);
+// XdmfGridCollection inherited from XdmfItem
+%ignore XdmfGridCollectionAccept(XDMFGRIDCOLLECTION * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfGridCollectionFree(void * item);
+%ignore XdmfGridCollectionGetInformation(XDMFGRIDCOLLECTION * item, unsigned int index);
+%ignore XdmfGridCollectionGetInformationByKey(XDMFGRIDCOLLECTION * item, char * key);
+%ignore XdmfGridCollectionGetNumberInformations(XDMFGRIDCOLLECTION * item);
+%ignore XdmfGridCollectionInsertInformation(XDMFGRIDCOLLECTION * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfGridCollectionRemoveInformation(XDMFGRIDCOLLECTION * item, unsigned int index);
+%ignore XdmfGridCollectionRemoveInformationByKey(XDMFGRIDCOLLECTION * item, char * key);
+%ignore XdmfGridCollectionGetItemTag(XDMFGRIDCOLLECTION * item);
+
+// XdmfGrid
+
+// XdmfGrid inherited from XdmfGrid
+%ignore XdmfGridGetAttribute(XDMFGRID * grid, unsigned int index);
+%ignore XdmfGridGetAttributeByName(XDMFGRID * grid, char * Name);
+%ignore XdmfGridGetNumberAttributes(XDMFGRID * grid);
+%ignore XdmfGridInsertAttribute(XDMFGRID * grid, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfGridRemoveAttribute(XDMFGRID * grid, unsigned int index);
+%ignore XdmfGridRemoveAttributeByName(XDMFGRID * grid, char * Name);
+%ignore XdmfGridGetSet(XDMFGRID * grid, unsigned int index);
+%ignore XdmfGridGetSetByName(XDMFGRID * grid, char * Name);
+%ignore XdmfGridGetNumberSets(XDMFGRID * grid);
+%ignore XdmfGridInsertSet(XDMFGRID * grid, XDMFSET * Set, int passControl);
+%ignore XdmfGridRemoveSet(XDMFGRID * grid, unsigned int index);
+%ignore XdmfGridRemoveSetByName(XDMFGRID * grid, char * Name);
+%ignore XdmfGridGetMap(XDMFGRID * grid, unsigned int index);
+%ignore XdmfGridGetMapByName(XDMFGRID * grid, char * Name);
+%ignore XdmfGridGetNumberMaps(XDMFGRID * grid);
+%ignore XdmfGridInsertMap(XDMFGRID * grid, XDMFMAP * Map, int passControl);
+%ignore XdmfGridRemoveMap(XDMFGRID * grid, unsigned int index);
+%ignore XdmfGridRemoveMapByName(XDMFGRID * grid, char * Name);
+%ignore XdmfGridGetName(XDMFGRID * grid);
+%ignore XdmfGridGetTime(XDMFGRID * grid);
+%ignore XdmfGridSetName(XDMFGRID * grid, char * name, int * status);
+%ignore XdmfGridSetTime(XDMFGRID * grid, XDMFTIME * time, int passControl);
+// XdmfGrid inherited from XdmfItem
+%ignore XdmfGridAccept(XDMFGRID * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfGridFree(void * item);
+%ignore XdmfGridGetInformation(XDMFGRID * item, unsigned int index);
+%ignore XdmfGridGetInformationByKey(XDMFGRID * item, char * key);
+%ignore XdmfGridGetNumberInformations(XDMFGRID * item);
+%ignore XdmfGridInsertInformation(XDMFGRID * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfGridRemoveInformation(XDMFGRID * item, unsigned int index);
+%ignore XdmfGridRemoveInformationByKey(XDMFGRID * item, char * key);
+%ignore XdmfGridGetItemTag(XDMFGRID * item);
+
+// XdmfMap
+
+%ignore XdmfMapNew();
+%ignore XdmfMapNewFromIdVector(int ** globalNodeIds, int * numIdsOnNode, int numIds);
+%ignore XdmfMapGetName(XDMFMAP * map);
+%ignore XdmfMapInsert(XDMFMAP * map, int remoteTaskId, int localNodeId, int remoteLocalNodeId);
+%ignore XdmfMapIsInitialized(XDMFMAP * map);
+%ignore XdmfMapRead(XDMFMAP * map, int * status);
+%ignore XdmfMapRelease(XDMFMAP * map);
+%ignore XdmfMapRetrieveLocalNodeIds(XDMFMAP * map, int remoteTaskId);
+%ignore XdmfMapRetrieveNumberLocalNodeIds(XDMFMAP * map, int remoteTaskId);
+%ignore XdmfMapRetrieveNumberRemoteTaskIds(XDMFMAP * map);
+%ignore XdmfMapRetrieveNumberRemoteNodeIds(XDMFMAP * map, int remoteTaskId, int localNodeId);
+%ignore XdmfMapRetrieveRemoteTaskIds(XDMFMAP * map);
+%ignore XdmfMapRetrieveRemoteNodeIds(XDMFMAP * map, int remoteTaskId, int localNodeId);
+%ignore XdmfMapSetHeavyDataControllers(XDMFMAP * map,
+                                       XDMFHEAVYDATACONTROLLER ** remoteTaskControllers,
+                                       int numRemoteTaskControllers,
+                                       XDMFHEAVYDATACONTROLLER ** localNodeControllers,
+                                       int numberLocalNodeControllers,
+                                       XDMFHEAVYDATACONTROLLER ** remoteLocalNodeControllers,
+                                       int numRemoteLocalNodeControllers,
+                                       int passControl,
+                                       int * status);
+%ignore XdmfMapSetName(XDMFMAP * map, char * newName);
+// XdmfMap inherited from XdmfItem
+%ignore XdmfMapAccept(XDMFMAP * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfMapFree(void * item);
+%ignore XdmfMapGetInformation(XDMFMAP * item, unsigned int index);
+%ignore XdmfMapGetInformationByKey(XDMFMAP * item, char * key);
+%ignore XdmfMapGetNumberInformations(XDMFMAP * item);
+%ignore XdmfMapInsertInformation(XDMFMAP * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfMapRemoveInformation(XDMFMAP * item, unsigned int index);
+%ignore XdmfMapRemoveInformationByKey(XDMFMAP * item, char * key);
+%ignore XdmfMapGetItemTag(XDMFMAP * item);
+
+// XdmfReader
+
+%ignore XdmfReaderNew();
+%ignore XdmfReaderFree(XDMFREADER * item);
+// XdmfReader inherited from XdmfCoreReader
+%ignore XdmfReaderRead(XDMFREADER * reader, char * filePath, int * status);
+
+// XdmfRectilinearGrid
+
+%ignore XdmfRectilinearGridNew(XDMFARRAY ** axesCoordinates,
+                               unsigned int numCoordinates,
+                               int passControl);
+%ignore XdmfRectilinearGridNew2D(XDMFARRAY * xCoordinates,
+                                 XDMFARRAY * yCoordinates,
+                                 int passControl);
+%ignore XdmfRectilinearGridNew3D(XDMFARRAY * xCoordinates,
+                                 XDMFARRAY * yCoordinates,
+                                 XDMFARRAY * zCoordinates,
+                                 int passControl);
+%ignore XdmfRectilinearGridGetCoordinatesByIndex(XDMFRECTILINEARGRID * grid,
+                                                 unsigned int axisIndex,
+                                                 int * status);
+%ignore XdmfRectilinearGridGetCoordinates(XDMFRECTILINEARGRID * grid, int * status);
+%ignore XdmfRectilinearGridGetNumberCoordinates(XDMFRECTILINEARGRID * grid, int * status);
+%ignore XdmfRectilinearGridGetDimensions(XDMFRECTILINEARGRID * grid, int * status);
+%ignore XdmfRectilinearGridSetCoordinates(XDMFRECTILINEARGRID * grid,
+                                          XDMFARRAY ** axesCoordinates,
+                                          unsigned int numCoordinates,
+                                          int passControl,
+                                          int * status);
+%ignore XdmfRectilinearGridSetCoordinatesByIndex(XDMFRECTILINEARGRID * grid,
+                                                 unsigned int index,
+                                                 XDMFARRAY * coordinates,
+                                                 int passControl,
+                                                 int * status);
+// XdmfRectilinearGrid inherited from XdmfItem
+%ignore XdmfRectilinearGridAccept(XDMFRECTILINEARGRID * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfRectilinearGridFree(void * item);
+%ignore XdmfRectilinearGridGetInformation(XDMFRECTILINEARGRID * item, unsigned int index);
+%ignore XdmfRectilinearGridGetInformationByKey(XDMFRECTILINEARGRID * item, char * key);
+%ignore XdmfRectilinearGridGetNumberInformations(XDMFRECTILINEARGRID * item);
+%ignore XdmfRectilinearGridInsertInformation(XDMFRECTILINEARGRID * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfRectilinearGridRemoveInformation(XDMFRECTILINEARGRID * item, unsigned int index);
+%ignore XdmfRectilinearGridRemoveInformationByKey(XDMFRECTILINEARGRID * item, char * key);
+%ignore XdmfRectilinearGridGetItemTag(XDMFRECTILINEARGRID * item);
+// XdmfRectilinearGrid inherited from XdmfGrid
+%ignore XdmfRectilinearGridGetAttribute(XDMFRECTILINEARGRID * grid, unsigned int index);
+%ignore XdmfRectilinearGridGetAttributeByName(XDMFRECTILINEARGRID * grid, char * Name);
+%ignore XdmfRectilinearGridGetNumberAttributes(XDMFRECTILINEARGRID * grid);
+%ignore XdmfRectilinearGridInsertAttribute(XDMFRECTILINEARGRID * grid, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfRectilinearGridRemoveAttribute(XDMFRECTILINEARGRID * grid, unsigned int index);
+%ignore XdmfRectilinearGridRemoveAttributeByName(XDMFRECTILINEARGRID * grid, char * Name);
+%ignore XdmfRectilinearGridGetSet(XDMFRECTILINEARGRID * grid, unsigned int index);
+%ignore XdmfRectilinearGridGetSetByName(XDMFRECTILINEARGRID * grid, char * Name);
+%ignore XdmfRectilinearGridGetNumberSets(XDMFRECTILINEARGRID * grid);
+%ignore XdmfRectilinearGridInsertSet(XDMFRECTILINEARGRID * grid, XDMFSET * Set, int passControl);
+%ignore XdmfRectilinearGridRemoveSet(XDMFRECTILINEARGRID * grid, unsigned int index);
+%ignore XdmfRectilinearGridRemoveSetByName(XDMFRECTILINEARGRID * grid, char * Name);
+%ignore XdmfRectilinearGridGetMap(XDMFRECTILINEARGRID * grid, unsigned int index);
+%ignore XdmfRectilinearGridGetMapByName(XDMFRECTILINEARGRID * grid, char * Name);
+%ignore XdmfRectilinearGridGetNumberMaps(XDMFRECTILINEARGRID * grid);
+%ignore XdmfRectilinearGridInsertMap(XDMFRECTILINEARGRID * grid, XDMFMAP * Map, int passControl);
+%ignore XdmfRectilinearGridRemoveMap(XDMFRECTILINEARGRID * grid, unsigned int index);
+%ignore XdmfRectilinearGridRemoveMapByName(XDMFRECTILINEARGRID * grid, char * Name);
+%ignore XdmfRectilinearGridGetName(XDMFRECTILINEARGRID * grid);
+%ignore XdmfRectilinearGridGetTime(XDMFRECTILINEARGRID * grid);
+%ignore XdmfRectilinearGridSetName(XDMFRECTILINEARGRID * grid, char * name, int * status);
+%ignore XdmfRectilinearGridSetTime(XDMFRECTILINEARGRID * grid, XDMFTIME * time, int passControl);
+
+// XdmfRegularGrid
+
+%ignore XdmfRegularGridNew2D(double xBrickSize,
+                             double yBrickSize,
+                             unsigned int xNumPoints,
+                             unsigned int yNumPoints,
+                             double xOrigin,
+                             double yOrigin);
+%ignore XdmfRegularGridNew3D(double xBrickSize,
+                             double yBrickSize,
+                             double zBrickSize,
+                             unsigned int xNumPoints,
+                             unsigned int yNumPoints,
+                             unsigned int zNumPoints,
+                             double xOrigin,
+                             double yOrigin,
+                             double zOrigin);
+%ignore XdmfRegularGridNew(XDMFARRAY * brickSize,
+                           XDMFARRAY * numPoints,
+                           XDMFARRAY * origin,
+                           int passControl);
+%ignore XdmfRegularGridGetBrickSize(XDMFREGULARGRID * grid, int * status);
+%ignore XdmfRegularGridGetDimensions(XDMFREGULARGRID * grid, int * status);
+%ignore XdmfRegularGridGetOrigin(XDMFREGULARGRID * grid, int * status);
+%ignore XdmfRegularGridSetBrickSize(XDMFREGULARGRID * grid,
+                                    XDMFARRAY * brickSize,
+                                    int passControl,
+                                    int * status);
+%ignore XdmfRegularGridSetDimensions(XDMFREGULARGRID * grid,
+                                     XDMFARRAY * dimensions,
+                                     int passControl,
+                                     int * status);
+%ignore XdmfRegularGridSetOrigin(XDMFREGULARGRID * grid,
+                                 XDMFARRAY * origin,
+                                 int passControl,
+                                 int * status);
+// XdmfRegularGrid inherited from XdmfItem
+%ignore XdmfRegularGridAccept(XDMFREGULARGRID * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfRegularGridFree(void * item);
+%ignore XdmfRegularGridGetInformation(XDMFREGULARGRID * item, unsigned int index);
+%ignore XdmfRegularGridGetInformationByKey(XDMFREGULARGRID * item, char * key);
+%ignore XdmfRegularGridGetNumberInformations(XDMFREGULARGRID * item);
+%ignore XdmfRegularGridInsertInformation(XDMFREGULARGRID * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfRegularGridRemoveInformation(XDMFREGULARGRID * item, unsigned int index);
+%ignore XdmfRegularGridRemoveInformationByKey(XDMFREGULARGRID * item, char * key);
+%ignore XdmfRegularGridGetItemTag(XDMFREGULARGRID * item);
+// XdmfRegularGrid inherited from XdmfGrid
+%ignore XdmfRegularGridGetAttribute(XDMFREGULARGRID * grid, unsigned int index);
+%ignore XdmfRegularGridGetAttributeByName(XDMFREGULARGRID * grid, char * Name);
+%ignore XdmfRegularGridGetNumberAttributes(XDMFREGULARGRID * grid);
+%ignore XdmfRegularGridInsertAttribute(XDMFREGULARGRID * grid, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfRegularGridRemoveAttribute(XDMFREGULARGRID * grid, unsigned int index);
+%ignore XdmfRegularGridRemoveAttributeByName(XDMFREGULARGRID * grid, char * Name);
+%ignore XdmfRegularGridGetSet(XDMFREGULARGRID * grid, unsigned int index);
+%ignore XdmfRegularGridGetSetByName(XDMFREGULARGRID * grid, char * Name);
+%ignore XdmfRegularGridGetNumberSets(XDMFREGULARGRID * grid);
+%ignore XdmfRegularGridInsertSet(XDMFREGULARGRID * grid, XDMFSET * Set, int passControl);
+%ignore XdmfRegularGridRemoveSet(XDMFREGULARGRID * grid, unsigned int index);
+%ignore XdmfRegularGridRemoveSetByName(XDMFREGULARGRID * grid, char * Name);
+%ignore XdmfRegularGridGetMap(XDMFREGULARGRID * grid, unsigned int index);
+%ignore XdmfRegularGridGetMapByName(XDMFREGULARGRID * grid, char * Name);
+%ignore XdmfRegularGridGetNumberMaps(XDMFREGULARGRID * grid);
+%ignore XdmfRegularGridInsertMap(XDMFREGULARGRID * grid, XDMFMAP * Map, int passControl);
+%ignore XdmfRegularGridRemoveMap(XDMFREGULARGRID * grid, unsigned int index);
+%ignore XdmfRegularGridRemoveMapByName(XDMFREGULARGRID * grid, char * Name);
+%ignore XdmfRegularGridGetName(XDMFREGULARGRID * grid);
+%ignore XdmfRegularGridGetTime(XDMFREGULARGRID * grid);
+%ignore XdmfRegularGridSetName(XDMFREGULARGRID * grid, char * name, int * status);
+%ignore XdmfRegularGridSetTime(XDMFREGULARGRID * grid, XDMFTIME * time, int passControl);
+
+// XdmfSet
+
+%ignore XdmfSetNew();
+%ignore XdmfSetGetAttribute(XDMFSET * set, unsigned int index);
+%ignore XdmfSetGetAttributeByName(XDMFSET * set, char * Name);
+%ignore XdmfSetGetNumberAttributes(XDMFSET * set);
+%ignore XdmfSetGetType(XDMFSET * set);
+%ignore XdmfSetInsertAttribute(XDMFSET * set, XDMFATTRIBUTE * Attribute, int passControl);
+vXdmfSetRemoveAttribute(XDMFSET * set, unsigned int index);
+%ignore XdmfSetRemoveAttributeByName(XDMFSET * set, char * Name);
+%ignore XdmfSetSetType(XDMFSET * set, int type, int * status);
+// XdmfSet inherited from XdmfArray
+%ignore XdmfSetNew();
+%ignore XdmfSetClear(XDMFSET * array);
+%ignore XdmfSetErase(XDMFSET * array, unsigned int index);
+%ignore XdmfSetGetArrayType(XDMFSET * array, int * status);
+%ignore XdmfSetGetCapacity(XDMFSET * array);
+%ignore XdmfSetGetDimensions(XDMFSET * array);
+%ignore XdmfSetGetDimensionsString(XDMFSET * array);
+%ignore XdmfSetGetHeavyDataController(XDMFSET * array, unsigned int index);
+%ignore XdmfSetGetReadMode(XDMFSET * array, int * status);
+%ignore XdmfSetGetName(XDMFSET * array);
+%ignore XdmfSetGetNumberDimensions(XDMFSET * array);
+%ignore XdmfSetGetNumberHeavyDataControllers(XDMFSET * array);
+%ignore XdmfSetGetSize(XDMFSET * array);
+%ignore XdmfSetGetReference(XDMFSET * array);
+%ignore XdmfSetGetValue(XDMFSET * array, unsigned int index, int arrayType, int * status);
+%ignore XdmfSetGetValues(XDMFSET * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfSetGetValuesInternal(XDMFSET * array);
+%ignore XdmfSetGetValuesString(XDMFSET * array);
+%ignore XdmfSetInitialize(XDMFSET * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfSetInsertDataFromPointer(XDMFSET * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfSetInsertDataFromXdmfArray(XDMFSET * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status);
+%ignore XdmfSetInsertHeavyDataController(XDMFSET * array, XDMFHEAVYDATACONTROLLER * controller, int passControl);
+%ignore XdmfSetInsertValue(XDMFSET * array, unsigned int index, void * value, int arrayType, int * status);
+%ignore XdmfSetIsInitialized(XDMFSET * array);
+%ignore XdmfSetPushBack(XDMFSET * array, void * value, int arrayType, int * status);
+%ignore XdmfSetRead(XDMFSET * array, int * status);
+%ignore XdmfSetReadController(XDMFSET * array, int * status);
+%ignore XdmfSetReadReference(XDMFSET * array, int * status);
+%ignore XdmfSetRelease(XDMFSET * array);
+%ignore XdmfSetRemoveHeavyDataController(XDMFSET * array, unsigned int index);
+%ignore XdmfSetReserve(XDMFSET * array, int size);
+%ignore XdmfSetResize(XDMFSET * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfSetSetReadMode(XDMFSET * array, int readMode, int * status);
+%ignore XdmfSetSetReference(XDMFSET * array, XDMFARRAYREFERENCE * reference, int passControl);
+%ignore XdmfSetSetName(XDMFSET * array, char * name, int * status);
+%ignore XdmfSetSetValuesInternal(XDMFSET * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status);
+%ignore XdmfSetSwapWithXdmfArray(XDMFSET * array, XDMFARRAY * swapArray);
+%ignore XdmfSetSwapWithArray(XDMFSET * array, void ** pointer, int numValues, int arrayType, int * status);
+// XdmfSet inherited from XdmfItem
+%ignore XdmfSetAccept(XDMFSET * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfSetFree(void * item);
+%ignore XdmfSetGetInformation(XDMFSET * item, unsigned int index);
+%ignore XdmfSetGetInformationByKey(XDMFSET * item, char * key);
+%ignore XdmfSetGetNumberInformations(XDMFSET * item);
+%ignore XdmfSetInsertInformation(XDMFSET * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfSetRemoveInformation(XDMFSET * item, unsigned int index);
+%ignore XdmfSetRemoveInformationByKey(XDMFSET * item, char * key);
+%ignore XdmfSetGetItemTag(XDMFSET * item);
+
+// XdmfSetType
+
+%ignore XdmfSetTypeNoSetType();
+%ignore XdmfSetTypeNode();
+%ignore XdmfSetTypeCell();
+%ignore XdmfSetTypeFace();
+%ignore XdmfSetTypeEdge();
+
+// XdmfTime
+
+%ignore XdmfTimeNew(double value);
+%ignore XdmfTimeGetValue(XDMFTIME * timePointer);
+%ignore XdmfTimeSetValue(XDMFTIME * timePointer, double time);
+// XdmfTime inherited from XdmfItem
+%ignore XdmfTimeAccept(XDMFTIME * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfTimeFree(void * item);
+%ignore XdmfTimeGetInformation(XDMFTIME * item, unsigned int index);
+%ignore XdmfTimeGetInformationByKey(XDMFTIME * item, char * key);
+%ignore XdmfTimeGetNumberInformations(XDMFTIME * item);
+%ignore XdmfTimeInsertInformation(XDMFTIME * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfTimeRemoveInformation(XDMFTIME * item, unsigned int index);
+%ignore XdmfTimeRemoveInformationByKey(XDMFTIME * item, char * key);
+%ignore XdmfTimeGetItemTag(XDMFTIME * item);
+
+// XdmfTopology
+
+%ignore XdmfTopologyNew();
+%ignore XdmfTopologyGetNumberElements(XDMFTOPOLOGY * topology, int * status);
+%ignore XdmfTopologyGetType(XDMFTOPOLOGY * topology);
+%ignore XdmfTopologySetType(XDMFTOPOLOGY * topology, int type, int * status);
+%ignore XdmfTopologySetPolyType(XDMFTOPOLOGY * topology, int type, int nodes, int * status);
+// XdmfTopology inherited from XdmfArray
+%ignore XdmfTopologyNew();
+%ignore XdmfTopologyClear(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyErase(XDMFTOPOLOGY * array, unsigned int index);
+%ignore XdmfTopologyGetArrayType(XDMFTOPOLOGY * array, int * status);
+%ignore XdmfTopologyGetCapacity(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetDimensions(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetDimensionsString(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetHeavyDataController(XDMFTOPOLOGY * array, unsigned int index);
+%ignore XdmfTopologyGetReadMode(XDMFTOPOLOGY * array, int * status);
+%ignore XdmfTopologyGetName(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetNumberDimensions(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetNumberHeavyDataControllers(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetSize(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetReference(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetValue(XDMFTOPOLOGY * array, unsigned int index, int arrayType, int * status);
+%ignore XdmfTopologyGetValues(XDMFTOPOLOGY * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfTopologyGetValuesInternal(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyGetValuesString(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyInitialize(XDMFTOPOLOGY * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfTopologyInsertDataFromPointer(XDMFTOPOLOGY * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfTopologyInsertDataFromXdmfArray(XDMFTOPOLOGY * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status);
+%ignore XdmfTopologyInsertHeavyDataController(XDMFTOPOLOGY * array, XDMFHEAVYDATACONTROLLER * controller, int passControl);
+%ignore XdmfTopologyInsertValue(XDMFTOPOLOGY * array, unsigned int index, void * value, int arrayType, int * status);
+%ignore XdmfTopologyIsInitialized(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyPushBack(XDMFTOPOLOGY * array, void * value, int arrayType, int * status);
+%ignore XdmfTopologyRead(XDMFTOPOLOGY * array, int * status);
+%ignore XdmfTopologyReadController(XDMFTOPOLOGY * array, int * status);
+%ignore XdmfTopologyReadReference(XDMFTOPOLOGY * array, int * status);
+%ignore XdmfTopologyRelease(XDMFTOPOLOGY * array);
+%ignore XdmfTopologyRemoveHeavyDataController(XDMFTOPOLOGY * array, unsigned int index);
+%ignore XdmfTopologyReserve(XDMFTOPOLOGY * array, int size);
+%ignore XdmfTopologyResize(XDMFTOPOLOGY * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfTopologySetReadMode(XDMFTOPOLOGY * array, int readMode, int * status);
+%ignore XdmfTopologySetReference(XDMFTOPOLOGY * array, XDMFARRAYREFERENCE * reference, int passControl);
+%ignore XdmfTopologySetName(XDMFTOPOLOGY * array, char * name, int * status);
+%ignore XdmfTopologySetValuesInternal(XDMFTOPOLOGY * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status);
+%ignore XdmfTopologySwapWithXdmfArray(XDMFTOPOLOGY * array, XDMFARRAY * swapArray);
+%ignore XdmfTopologySwapWithArray(XDMFTOPOLOGY * array, void ** pointer, int numValues, int arrayType, int * status);
+// XdmfTopology inherited from XdmfItem
+%ignore XdmfTopologyAccept(XDMFTOPOLOGY * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfTopologyFree(void * item);
+%ignore XdmfTopologyGetInformation(XDMFTOPOLOGY * item, unsigned int index);
+%ignore XdmfTopologyGetInformationByKey(XDMFTOPOLOGY * item, char * key);
+%ignore XdmfTopologyGetNumberInformations(XDMFTOPOLOGY * item);
+%ignore XdmfTopologyInsertInformation(XDMFTOPOLOGY * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfTopologyRemoveInformation(XDMFTOPOLOGY * item, unsigned int index);
+%ignore XdmfTopologyRemoveInformationByKey(XDMFTOPOLOGY * item, char * key);
+%ignore XdmfTopologyGetItemTag(XDMFTOPOLOGY * item);
+
+// XdmfTopologyType
+
+%ignore XdmfTopologyTypePolyvertex();
+%ignore XdmfTopologyTypePolyline();
+%ignore XdmfTopologyTypePolygon();
+%ignore XdmfTopologyTypeTriangle();
+%ignore XdmfTopologyTypeQuadrilateral();
+%ignore XdmfTopologyTypeTetrahedron();
+%ignore XdmfTopologyTypePyramid();
+%ignore XdmfTopologyTypeWedge();
+%ignore XdmfTopologyTypeHexahedron();
+%ignore XdmfTopologyTypeEdge_3();
+%ignore XdmfTopologyTypeTriangle_6();
+%ignore XdmfTopologyTypeQuadrilateral_8();
+%ignore XdmfTopologyTypeQuadrilateral_9();
+%ignore XdmfTopologyTypeTetrahedron_10();
+%ignore XdmfTopologyTypePyramid_13();
+%ignore XdmfTopologyTypeWedge_15();
+%ignore XdmfTopologyTypeWedge_18();
+%ignore XdmfTopologyTypeHexahedron_20();
+%ignore XdmfTopologyTypeHexahedron_24();
+%ignore XdmfTopologyTypeHexahedron_27();
+%ignore XdmfTopologyTypeHexahedron_64();
+%ignore XdmfTopologyTypeHexahedron_125();
+%ignore XdmfTopologyTypeHexahedron_216();
+%ignore XdmfTopologyTypeHexahedron_343();
+%ignore XdmfTopologyTypeHexahedron_512();
+%ignore XdmfTopologyTypeHexahedron_729();
+%ignore XdmfTopologyTypeHexahedron_1000();
+%ignore XdmfTopologyTypeHexahedron_1331();
+%ignore XdmfTopologyTypeHexahedron_Spectral_64();
+%ignore XdmfTopologyTypeHexahedron_Spectral_125();
+%ignore XdmfTopologyTypeHexahedron_Spectral_216();
+%ignore XdmfTopologyTypeHexahedron_Spectral_343();
+%ignore XdmfTopologyTypeHexahedron_Spectral_512();
+%ignore XdmfTopologyTypeHexahedron_Spectral_729();
+%ignore XdmfTopologyTypeHexahedron_Spectral_1000();
+%ignore XdmfTopologyTypeHexahedron_Spectral_1331();
+%ignore XdmfTopologyTypeMixed();
+%ignore XdmfTopologyTypeGetCellType(int type);
+%ignore XdmfTopologyTypeGetEdgesPerElement(int type, int * status);
+%ignore XdmfTopologyTypeGetFacesPerElement(int type, int * status);
+%ignore XdmfTopologyTypeGetFaceType(int type);
+%ignore XdmfTopologyTypeGetID(int type);
+%ignore XdmfTopologyTypeGetName(int type);
+%ignore XdmfTopologyTypeGetNodesPerElement(int type);
+
+// XdmfUnstructuredGrid
+
+%ignore XdmfUnstructuredGridNew();
+%ignore XdmfUnstructuredGridNewFromRegularGrid(XDMFREGULARGRID * regularGrid, int * status);
+%ignore XdmfUnstructuredGridGetGeometry(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridGetTopology(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridSetGeometry(XDMFUNSTRUCTUREDGRID * grid,
+                                        XDMFGEOMETRY * geometry,
+                                        int passControl);
+%ignore XdmfUnstructuredGridSetTopology(XDMFUNSTRUCTUREDGRID * grid,
+                                        XDMFTOPOLOGY * topology,
+                                        int passControl);
+// XdmfUnstructuredGrid inherited from XdmfItem
+%ignore XdmfUnstructuredGridAccept(XDMFUNSTRUCTUREDGRID * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfUnstructuredGridFree(void * item);
+%ignore XdmfUnstructuredGridGetInformation(XDMFUNSTRUCTUREDGRID * item, unsigned int index);
+%ignore XdmfUnstructuredGridGetInformationByKey(XDMFUNSTRUCTUREDGRID * item, char * key);
+%ignore XdmfUnstructuredGridGetNumberInformations(XDMFUNSTRUCTUREDGRID * item);
+%ignore XdmfUnstructuredGridInsertInformation(XDMFUNSTRUCTUREDGRID * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfUnstructuredGridRemoveInformation(XDMFUNSTRUCTUREDGRID * item, unsigned int index);
+%ignore XdmfUnstructuredGridRemoveInformationByKey(XDMFUNSTRUCTUREDGRID * item, char * key);
+%ignore XdmfUnstructuredGridGetItemTag(XDMFUNSTRUCTUREDGRID * item);
+// XdmfUnstructuredGrid inherited from XdmfGrid
+%ignore XdmfUnstructuredGridGetAttribute(XDMFUNSTRUCTUREDGRID * grid, unsigned int index);
+%ignore XdmfUnstructuredGridGetAttributeByName(XDMFUNSTRUCTUREDGRID * grid, char * Name);
+%ignore XdmfUnstructuredGridGetNumberAttributes(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridInsertAttribute(XDMFUNSTRUCTUREDGRID * grid, XDMFATTRIBUTE * Attribute, int passControl);
+%ignore XdmfUnstructuredGridRemoveAttribute(XDMFUNSTRUCTUREDGRID * grid, unsigned int index);
+%ignore XdmfUnstructuredGridRemoveAttributeByName(XDMFUNSTRUCTUREDGRID * grid, char * Name);
+%ignore XdmfUnstructuredGridGetSet(XDMFUNSTRUCTUREDGRID * grid, unsigned int index);
+%ignore XdmfUnstructuredGridGetSetByName(XDMFUNSTRUCTUREDGRID * grid, char * Name);
+%ignore XdmfUnstructuredGridGetNumberSets(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridInsertSet(XDMFUNSTRUCTUREDGRID * grid, XDMFSET * Set, int passControl);
+%ignore XdmfUnstructuredGridRemoveSet(XDMFUNSTRUCTUREDGRID * grid, unsigned int index);
+%ignore XdmfUnstructuredGridRemoveSetByName(XDMFUNSTRUCTUREDGRID * grid, char * Name);
+%ignore XdmfUnstructuredGridGetMap(XDMFUNSTRUCTUREDGRID * grid, unsigned int index);
+%ignore XdmfUnstructuredGridGetMapByName(XDMFUNSTRUCTUREDGRID * grid, char * Name);
+%ignore XdmfUnstructuredGridGetNumberMaps(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridInsertMap(XDMFUNSTRUCTUREDGRID * grid, XDMFMAP * Map, int passControl);
+%ignore XdmfUnstructuredGridRemoveMap(XDMFUNSTRUCTUREDGRID * grid, unsigned int index);
+%ignore XdmfUnstructuredGridRemoveMapByName(XDMFUNSTRUCTUREDGRID * grid, char * Name);
+%ignore XdmfUnstructuredGridGetName(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridGetTime(XDMFUNSTRUCTUREDGRID * grid);
+%ignore XdmfUnstructuredGridSetName(XDMFUNSTRUCTUREDGRID * grid, char * name, int * status);
+%ignore XdmfUnstructuredGridSetTime(XDMFUNSTRUCTUREDGRID * grid, XDMFTIME * time, int passControl);
+
+#ifdef SWIGJAVA
+
+// Typemaps that work for Java
+
+%typemap(out) shared_ptr<XdmfItem> {
+    if(shared_ptr<XdmfAttribute> value = shared_dynamic_cast<XdmfAttribute>($1)) {
+        *(shared_ptr< XdmfAttribute > **)&($result) = value ? new shared_ptr< XdmfAttribute >(value) : 0;
+    }
+    else if(shared_ptr<XdmfCurvilinearGrid> value = shared_dynamic_cast<XdmfCurvilinearGrid>($1)) {
+        *(shared_ptr< XdmfCurvilinearGrid > **)&($result) = value ? new shared_ptr< XdmfCurvilinearGrid >(value) : 0;
+    }
+    else if(shared_ptr<XdmfGridCollection> value = shared_dynamic_cast<XdmfGridCollection>($1)) {
+        *(shared_ptr< XdmfGridCollection > **)&($result) = value ? new shared_ptr< XdmfGridCollection >(value) : 0;
+    }
+    else if(shared_ptr<XdmfDomain> value = shared_dynamic_cast<XdmfDomain>($1)) {
+        *(shared_ptr< XdmfDomain > **)&($result) = value ? new shared_ptr< XdmfDomain >(value) : 0;
+    }
+    else if(shared_ptr<XdmfGeometry> value = shared_dynamic_cast<XdmfGeometry>($1)) {
+        *(shared_ptr< XdmfGeometry > **)&($result) = value ? new shared_ptr< XdmfGeometry >(value) : 0;
+    }
+    else if(shared_ptr<XdmfInformation> value = shared_dynamic_cast<XdmfInformation>($1)) {
+        *(shared_ptr< XdmfInformation > **)&($result) = value ? new shared_ptr< XdmfInformation >(value) : 0;
+    }
+    else if(shared_ptr<XdmfRectilinearGrid> value = shared_dynamic_cast<XdmfRectilinearGrid>($1)) {
+        *(shared_ptr< XdmfRectilinearGrid > **)&($result) = value ? new shared_ptr< XdmfRectilinearGrid >(value) : 0;
+    }
+    else if(shared_ptr<XdmfRegularGrid> value = shared_dynamic_cast<XdmfRegularGrid>($1)) {
+        *(shared_ptr< XdmfRegularGrid > **)&($result) = value ? new shared_ptr< XdmfRegularGrid >(value) : 0;
+    }
+    else if(shared_ptr<XdmfSet> value = shared_dynamic_cast<XdmfSet>($1)) {
+        *(shared_ptr< XdmfSet > **)&($result) = value ? new shared_ptr< XdmfSet >(value) : 0;
+    }
+    else if(shared_ptr<XdmfTime> value = shared_dynamic_cast<XdmfTime>($1)) {
+        *(shared_ptr< XdmfTime > **)&($result) = value ? new shared_ptr< XdmfTime >(value) : 0;
+    }
+    else if(shared_ptr<XdmfTopology> value = shared_dynamic_cast<XdmfTopology>($1)) {
+        *(shared_ptr< XdmfTopology > **)&($result) = value ? new shared_ptr< XdmfTopology >(value) : 0;
+    }
+    else if(shared_ptr<XdmfUnstructuredGrid> value = shared_dynamic_cast<XdmfUnstructuredGrid>($1)) {
+        *(shared_ptr< XdmfUnstructuredGrid > **)&($result) = value ? new shared_ptr< XdmfUnstructuredGrid >(value) : 0;
+    }
+    else {
+        *(shared_ptr< XdmfItem > **)&($result) = &($1);
+    }
+}
+
+// Ignore multiple inheritance warning
+#pragma SWIG nowarn=813
+
+// Ignore const overloaded methods
+%ignore XdmfCurvilinearGrid::getDimensions() const;
+%ignore XdmfDomain::getCurvilinearGrid(const unsigned int) const;
+%ignore XdmfDomain::getCurvilinearGrid(const std::string &) const;
+%ignore XdmfDomain::getGridCollection(const unsigned int) const;
+%ignore XdmfDomain::getGridCollection(const std::string &) const;
+%ignore XdmfDomain::getRectilinearGrid(const unsigned int) const;
+%ignore XdmfDomain::getRectilinearGrid(const std::string &) const;
+%ignore XdmfDomain::getRegularGrid(const unsigned int) const;
+%ignore XdmfDomain::getRegularGrid(const std::string &) const;
+%ignore XdmfDomain::getUnstructuredGrid(const unsigned int) const;
+%ignore XdmfDomain::getUnstructuredGrid(const std::string &) const;
+%ignore XdmfGrid::getAttribute(const unsigned int) const;
+%ignore XdmfGrid::getAttribute(const std::string &) const;
+%ignore XdmfGrid::getMap() const;
+%ignore XdmfGrid::getMap(unsigned int const) const;
+%ignore XdmfGrid::getMap(unsigned int const &) const;
+%ignore XdmfGrid::getMap(std::string const &) const;
+%ignore XdmfGrid::getSet(const unsigned int) const;
+%ignore XdmfGrid::getSet(const std::string &) const;
+%ignore XdmfGrid::getTime() const;
+%ignore XdmfRectilinearGrid::getCoordinates(const unsigned int) const;
+%ignore XdmfRectilinearGrid::getCoordinates() const;
+%ignore XdmfRectilinearGrid::getDimensions() const;
+%ignore XdmfRegularGrid::getBrickSize() const;
+%ignore XdmfRegularGrid::getDimensions() const;
+%ignore XdmfRegularGrid::getOrigin() const;
+%ignore XdmfSet::getAttribute(const unsigned int) const;
+%ignore XdmfSet::getAttribute(const std::string &) const;
+
+// Ignore ItemTags
+%ignore XdmfAttribute::ItemTag;
+%ignore XdmfCurvilinearGrid::ItemTag;
+%ignore XdmfDomain::ItemTag;
+%ignore XdmfGeometry::ItemTag;
+%ignore XdmfGraph::ItemTag;
+%ignore XdmfGrid::ItemTag;
+%ignore XdmfGridCollection::ItemTag;
+%ignore XdmfMap::ItemTag;
+%ignore XdmfRectilinearGrid::ItemTag;
+%ignore XdmfRegularGrid::ItemTag;
+%ignore XdmfSet::ItemTag;
+%ignore XdmfTime::ItemTag;
+%ignore XdmfTopology::ItemTag;
+%ignore XdmfUnstructuredGrid::ItemTag;
+
+%pragma(java) jniclasscode=%{
+    static {
+        try {
+            System.loadLibrary("XdmfJava");
+        }
+        catch (UnsatisfiedLinkError e) {
+            System.err.println("Native code library failed to load for" +
+                                "XdmfJava\n" + e);
+            System.exit(1);
+        }
+    }
+%}
+
+#endif /* SWIGJAVA */
+
+#ifdef SWIGPYTHON
+
+%include std_set.i
+%include std_map.i
+%include std_vector.i
+
+%template(XdmfMapNodeIdSet) std::set<int>;
+%template(XdmfMapNodeIdMap) std::map<int, std::set<int> >;
+%template(XdmfMapMap) std::map<int, std::map<int, std::set<int> > >;
+%template(AttributeVector) std::vector<shared_ptr<XdmfAttribute> >;
+%template(MapVector) std::vector<shared_ptr<XdmfMap> >;
+%template(ArrayVector) std::vector<shared_ptr<XdmfArray> >;
+
+#ifdef XDMF_BUILD_DSM
+
+%pythoncode {
+    import sys
+    from XdmfCore import *
+    if 'mpi4py' in sys.modules.keys():
+      from XdmfDSM import *
+}
+
+#else
+
+%pythoncode {
+    from XdmfCore import *
+}
+
+#endif /* XDMF_BUILD_DSM */
+
+
+%fragment("XdmfItemCast", "header") {
+    #include <XdmfSharedPtr.hpp>
+    PyObject * XdmfItemCast(shared_ptr<XdmfItem> obj) {
+        PyObject * result;
+        if(shared_ptr<XdmfAttribute> attribute = shared_dynamic_cast<XdmfAttribute>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfAttribute>(attribute)), SWIGTYPE_p_boost__shared_ptrT_XdmfAttribute_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfCurvilinearGrid> gridCurvilinear = shared_dynamic_cast<XdmfCurvilinearGrid>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfCurvilinearGrid>(gridCurvilinear)), SWIGTYPE_p_boost__shared_ptrT_XdmfCurvilinearGrid_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfGridCollection> gridCollection = shared_dynamic_cast<XdmfGridCollection>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfGridCollection>(gridCollection)), SWIGTYPE_p_boost__shared_ptrT_XdmfGridCollection_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfDomain> domain = shared_dynamic_cast<XdmfDomain>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfDomain>(domain)), SWIGTYPE_p_boost__shared_ptrT_XdmfDomain_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfGeometry> geometry = shared_dynamic_cast<XdmfGeometry>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfGeometry>(geometry)), SWIGTYPE_p_boost__shared_ptrT_XdmfGeometry_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfGraph> graph = shared_dynamic_cast<XdmfGraph>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfGraph>(graph)), SWIGTYPE_p_boost__shared_ptrT_XdmfGraph_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfInformation> information = shared_dynamic_cast<XdmfInformation>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfInformation>(information)), SWIGTYPE_p_boost__shared_ptrT_XdmfInformation_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfMap> map = shared_dynamic_cast<XdmfMap>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfMap>(map)), SWIGTYPE_p_boost__shared_ptrT_XdmfMap_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfRectilinearGrid> gridRectilinear = shared_dynamic_cast<XdmfRectilinearGrid>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfRectilinearGrid>(gridRectilinear)), SWIGTYPE_p_boost__shared_ptrT_XdmfRectilinearGrid_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfRegularGrid> gridRegular = shared_dynamic_cast<XdmfRegularGrid>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfRegularGrid>(gridRegular)), SWIGTYPE_p_boost__shared_ptrT_XdmfRegularGrid_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfSet> set = shared_dynamic_cast<XdmfSet>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfSet>(set)), SWIGTYPE_p_boost__shared_ptrT_XdmfSet_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfTime> time = shared_dynamic_cast<XdmfTime>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfTime>(time)), SWIGTYPE_p_boost__shared_ptrT_XdmfTime_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfTopology> topology = shared_dynamic_cast<XdmfTopology>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfTopology>(topology)), SWIGTYPE_p_boost__shared_ptrT_XdmfTopology_t, SWIG_POINTER_OWN);
+        }
+        else if(shared_ptr<XdmfUnstructuredGrid> gridUnstructured = shared_dynamic_cast<XdmfUnstructuredGrid>(obj)) {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfUnstructuredGrid>(gridUnstructured)), SWIGTYPE_p_boost__shared_ptrT_XdmfUnstructuredGrid_t, SWIG_POINTER_OWN);
+        }
+        else {
+            result = SWIG_NewPointerObj(SWIG_as_voidptr(new shared_ptr<XdmfItem>(obj)), SWIGTYPE_p_boost__shared_ptrT_XdmfItem_t, SWIG_POINTER_OWN);
+        }
+        return result;
+    }
+}
+
+%typemap(out, fragment="XdmfItemCast") shared_ptr<XdmfItem> {
+    $result = XdmfItemCast($1);
+}
+
+%typemap(out, fragment="XdmfItemCast") std::vector<shared_ptr<XdmfItem> > {
+    $result = PyList_New($1.size());
+    for(std::vector<shared_ptr<XdmfItem> >::size_type i = 0; i < $1.size(); ++i) {
+        PyList_SetItem($result, i, XdmfItemCast($1[i]));
+    } 
+}
+
+%extend XdmfAttributeCenter {
+    bool __eq__(const XdmfAttributeCenter * attributeCenter) {
+        return $self == attributeCenter;
+    }
+}
+
+%extend XdmfAttributeType {
+    bool __eq__(const XdmfAttributeType * attributeType) {
+   	return $self == attributeType;
+    }
+}
+
+%extend XdmfGeometryType {
+    bool __eq__(const XdmfGeometryType * geometryType) {
+   	return $self == geometryType;
+    }
+}
+
+%extend XdmfGridCollectionType {
+    bool __eq__(const XdmfGridCollectionType * gridCollectionType) {
+   	return $self == gridCollectionType;
+    }
+}
+
+%extend XdmfSetType {
+    bool __eq__(const XdmfSetType * setType) {
+   	return $self == setType;
+    }
+}
+
+%extend XdmfTopologyType {
+    bool __eq__(const XdmfTopologyType * topologyType) {
+   	return $self == topologyType;
+    }
+}
+
+#endif /* SWIGPYTHON */
+
+// Shared Pointer Templates
+%shared_ptr(XdmfAggregate)
+%shared_ptr(XdmfAttribute)
+%shared_ptr(XdmfAttributeCenter)
+%shared_ptr(XdmfAttributeType)
+%shared_ptr(XdmfCurvilinearGrid)
+%shared_ptr(XdmfDomain)
+%shared_ptr(XdmfGeometry)
+%shared_ptr(XdmfGeometryType)
+%shared_ptr(XdmfGraph)
+%shared_ptr(XdmfGrid)
+%shared_ptr(XdmfGridCollection)
+%shared_ptr(XdmfGridCollectionType)
+%shared_ptr(XdmfItemFactory)
+%shared_ptr(XdmfMap)
+%shared_ptr(XdmfReader)
+%shared_ptr(XdmfRectilinearGrid)
+%shared_ptr(XdmfRegularGrid)
+%shared_ptr(XdmfSet)
+%shared_ptr(XdmfSetType)
+%shared_ptr(XdmfTime)
+%shared_ptr(XdmfTopology)
+%shared_ptr(XdmfTopologyType)
+%shared_ptr(XdmfUnstructuredGrid)
+
+%include Xdmf.hpp
+%include XdmfGrid.hpp
+
+%include XdmfAggregate.hpp
+%include XdmfAttribute.hpp
+%include XdmfAttributeCenter.hpp
+%include XdmfAttributeType.hpp
+%include XdmfCurvilinearGrid.hpp
+%include XdmfDomain.hpp
+%include XdmfGeometry.hpp
+%include XdmfGeometryType.hpp
+%include XdmfGraph.hpp
+%include XdmfGridCollection.hpp
+%include XdmfGridCollectionType.hpp
+%include XdmfItemFactory.hpp
+%include XdmfMap.hpp
+%include XdmfReader.hpp
+%include XdmfRectilinearGrid.hpp
+%include XdmfRegularGrid.hpp
+%include XdmfSet.hpp
+%include XdmfSetType.hpp
+%include XdmfTime.hpp
+%include XdmfTopology.hpp
+%include XdmfTopologyType.hpp
+%include XdmfUnstructuredGrid.hpp
diff --git a/XdmfAggregate.cpp b/XdmfAggregate.cpp
new file mode 100644
index 0000000..c5cfdd9
--- /dev/null
+++ b/XdmfAggregate.cpp
@@ -0,0 +1,272 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAggregate.cpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <numeric>
+#include <functional>
+#include <boost/tokenizer.hpp>
+#include "XdmfArray.hpp"
+#include "XdmfError.hpp"
+#include "XdmfAggregate.hpp"
+#include "XdmfVisitor.hpp"
+#include "XdmfWriter.hpp"
+#include "string.h"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfAggregate, XdmfArray, Array, Name)
+
+XdmfAggregate::XdmfAggregate()
+{
+}
+
+XdmfAggregate::XdmfAggregate(XdmfAggregate & refAggregate) :
+  XdmfArrayReference(refAggregate)
+{
+}
+
+XdmfAggregate::~XdmfAggregate()
+{
+}
+
+const std::string XdmfAggregate::ItemTag = "Aggregate";
+
+shared_ptr<XdmfAggregate>
+XdmfAggregate::New()
+{
+  shared_ptr<XdmfAggregate> p(new XdmfAggregate());
+  return p;
+}
+
+std::vector<unsigned int> XdmfAggregate::getDimensions() const
+{
+  std::vector<unsigned int> testDims = mArrays[0]->getDimensions();
+
+  bool isSame = true;
+
+  for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
+        mArrays.begin();
+      iter != mArrays.end() && isSame;
+      ++iter) {
+    std::vector<unsigned int> compareDims = (*iter)->getDimensions();
+    if (compareDims.size() == testDims.size())
+    {
+      for (unsigned int i = 0; i < testDims.size(); ++i)
+      {
+        if (compareDims[i] != testDims[i])
+        {
+          isSame = false;
+          break;
+        }
+      }
+    }
+    else
+    {
+      isSame = false;
+      break;
+    }
+  }
+
+  if (isSame)
+  {
+    testDims.push_back(mArrays.size());
+    return testDims;
+  }
+  else
+  {
+    std::vector<unsigned int> returnDims;
+    returnDims.push_back(this->getSize());
+    return returnDims;
+  }
+}
+
+std::map<std::string, std::string>
+XdmfAggregate::getItemProperties() const
+{
+  std::map<std::string, std::string> aggregateMap = XdmfArrayReference::getItemProperties();
+
+  return aggregateMap;
+}
+
+std::string
+XdmfAggregate::getItemTag() const
+{
+  return ItemTag;
+}
+
+unsigned int
+XdmfAggregate::getSize() const
+{
+  unsigned int total = 0;
+  for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
+        mArrays.begin();
+      iter != mArrays.end();
+      ++iter) {
+    total += (*iter)->getSize();
+  }
+  return total;
+}
+
+void
+XdmfAggregate::populateItem(const std::map<std::string, std::string> & itemProperties,
+                            const std::vector<shared_ptr<XdmfItem> > & childItems,
+                            const XdmfCoreReader * const reader)
+{
+  bool placeholderFound = false;
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+      if (!placeholderFound) {
+        placeholderFound = true;
+      }
+      else {
+        this->insert(array);
+      }
+/*
+      this->swap(array);
+      if (array->getReference()) {
+        this->setReference(array->getReference());
+        this->setReadMode(XdmfArray::Reference);
+      }
+      break;
+*/
+    }
+  }
+}
+
+shared_ptr<XdmfArray>
+XdmfAggregate::read() const
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+
+  if (mArrays.size() > 0)
+  {
+    if (!mArrays[0]->isInitialized()) {
+      mArrays[0]->read();
+    }
+    returnArray->insert(0, mArrays[0], 0, mArrays[0]->getSize(),  1, 1);
+    if (mArrays.size() > 1)
+    {
+      unsigned int offset = mArrays[0]->getSize();
+      for (unsigned int i = 1; i < mArrays.size(); ++i)
+      {
+        if (!mArrays[i]->isInitialized()) {
+          mArrays[i]->read();
+        }
+        returnArray->insert(offset, mArrays[i], 0, mArrays[i]->getSize(), 1, 1);
+        offset += mArrays[i]->getSize();
+      }
+    }
+  }
+
+  return returnArray;
+}
+
+void
+XdmfAggregate::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+
+  bool originalXPath;
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+      originalXPath = writer->getWriteXPaths();
+      writer->setWriteXPaths(false);
+  }
+
+  shared_ptr<XdmfArray> spacerarray = XdmfArray::New();
+  spacerarray->pushBack((int)0);
+  spacerarray->accept(visitor);
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+      writer->setWriteXPaths(originalXPath);
+  }
+
+  for (unsigned int i = 0; i < mArrays.size(); ++i)
+  {
+    mArrays[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+XDMFAGGREGATE * XdmfAggregateNew()
+{
+  try
+  {
+    shared_ptr<XdmfAggregate> generatedAggregate = XdmfAggregate::New();
+    return (XDMFAGGREGATE *)((void *)(new XdmfAggregate(*generatedAggregate.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfAggregate> generatedAggregate = XdmfAggregate::New();
+    return (XDMFAGGREGATE *)((void *)(new XdmfAggregate(*generatedAggregate.get())));
+  }
+}
+
+XDMFARRAY *
+XdmfAggregateGetArray(XDMFAGGREGATE * aggregate, unsigned int index)
+{
+  return (XDMFARRAY *)((void *)(((XdmfAggregate *)(aggregate))->getArray(index).get()));
+}
+
+XDMFARRAY *
+XdmfAggregateGetArrayByName(XDMFAGGREGATE * aggregate, char * name)
+{
+  return (XDMFARRAY *)((void *)(((XdmfAggregate *)(aggregate))->getArray(name).get()));
+}
+
+unsigned int
+XdmfAggregateGetNumberArrays(XDMFAGGREGATE * aggregate)
+{
+  return ((XdmfAggregate *)(aggregate))->getNumberArrays();
+}
+
+void
+XdmfAggregateInsertArray(XDMFAGGREGATE * aggregate, XDMFARRAY * array, int transferOwnership)
+{
+  if (transferOwnership) {
+    ((XdmfAggregate *)(aggregate))->insert(shared_ptr<XdmfArray>((XdmfArray *)array));
+  }
+  else {
+    ((XdmfAggregate *)(aggregate))->insert(shared_ptr<XdmfArray>((XdmfArray *)array, XdmfNullDeleter()));
+  }
+}
+
+void
+XdmfAggregateRemoveArray(XDMFAGGREGATE * aggregate, unsigned int index)
+{
+  ((XdmfAggregate *)(aggregate))->removeArray(index);
+}
+
+void
+XdmfAggregateRemoveArrayByName(XDMFAGGREGATE * aggregate, char * name)
+{
+  ((XdmfAggregate *)(aggregate))->removeArray(name);
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfAggregate, XDMFAGGREGATE)
+XDMF_ARRAYREFERENCE_C_CHILD_WRAPPER(XdmfAggregate, XDMFAGGREGATE)
diff --git a/XdmfAggregate.hpp b/XdmfAggregate.hpp
new file mode 100644
index 0000000..e422bff
--- /dev/null
+++ b/XdmfAggregate.hpp
@@ -0,0 +1,214 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAggregate.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFAGGREGATE_HPP_
+#define XDMFAGGREGATE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfArrayReference.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+// Includes
+#include <vector>
+#include "XdmfItem.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Couples an XdmfArray with heavy data stored in another XdmfArray.
+ *
+ * This class serves to allow an array to retrieve data that is a subsection
+ * of an already existing array.
+ */
+class XDMF_EXPORT XdmfAggregate: public XdmfArrayReference {
+
+public:
+
+  /**
+   * Generates an XdmfAggregate object.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAggregate.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAggregate.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    A constructed XdmfAggregate object.
+   */
+  static shared_ptr<XdmfAggregate>
+  New();
+
+  virtual ~XdmfAggregate();
+
+  LOKI_DEFINE_VISITABLE(XdmfAggregate, XdmfItem)
+  XDMF_CHILDREN(XdmfAggregate, XdmfArray, Array, Name)
+
+  static const std::string ItemTag;
+
+  /**
+   * Get the dimensions of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAggregate.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAggregate.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    A vector containing the size in each dimension of the
+   *            set referenced by this subset.
+   */
+  std::vector<unsigned int> getDimensions() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the size of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAggregate.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getSize
+   * @until //#getSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAggregate.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getSize
+   * @until #//getSize
+   *
+   * @return    An int containing the size of the subset.
+   */
+  unsigned int getSize() const;
+
+  /**
+   * Read data reference by this subset and return as an XdmfArray.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAggregate.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAggregate.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//read
+   * @until #//read
+   *
+   * @return    An array filled with data based on the subset's parameters.
+   */
+  virtual shared_ptr<XdmfArray> read() const;
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfAggregate(XdmfAggregate&);
+
+protected:
+
+  XdmfAggregate();
+
+  void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfAggregate(const XdmfAggregate&);  // Not implemented.
+  void operator=(const XdmfAggregate&);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFAGGREGATE; // Simply as a typedef to ensure correct typing
+typedef struct XDMFAGGREGATE XDMFAGGREGATE;
+
+XDMF_EXPORT XDMFAGGREGATE * XdmfAggregateNew();
+
+XDMF_EXPORT XDMFARRAY * XdmfAggregateGetArray(XDMFAGGREGATE * aggregate, unsigned int index);
+
+XDMF_EXPORT XDMFARRAY * XdmfAggregateGetArrayByName(XDMFAGGREGATE * aggregate, char * name);
+
+XDMF_EXPORT unsigned int XdmfAggregateGetNumberArrays(XDMFAGGREGATE * aggregate);
+
+XDMF_EXPORT void XdmfAggregateInsertArray(XDMFAGGREGATE * aggregate, XDMFARRAY * array, int transferOwnership);
+
+XDMF_EXPORT void XdmfAggregateRemoveArray(XDMFAGGREGATE * aggregate, unsigned int index);
+
+XDMF_EXPORT void XdmfAggregateRemoveArrayByName(XDMFAGGREGATE * aggregate, char * name);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfAggregate, XDMFAGGREGATE, XDMF)
+XDMF_ARRAYREFERENCE_C_CHILD_DECLARE(XdmfAggregate, XDMFAGGREGATE, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFAGGREGATE_HPP_ */
diff --git a/XdmfAttribute.cpp b/XdmfAttribute.cpp
new file mode 100644
index 0000000..0c86abb
--- /dev/null
+++ b/XdmfAttribute.cpp
@@ -0,0 +1,275 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAttribute.cpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfError.hpp"
+
+shared_ptr<XdmfAttribute>
+XdmfAttribute::New()
+{
+  shared_ptr<XdmfAttribute> p(new XdmfAttribute());
+  return p;
+}
+
+XdmfAttribute::XdmfAttribute() :
+  mCenter(XdmfAttributeCenter::Grid()),
+  mName(""),
+  mType(XdmfAttributeType::NoAttributeType())
+{
+}
+
+XdmfAttribute::XdmfAttribute(XdmfAttribute & refAttribute) :
+  XdmfArray(refAttribute),
+  mCenter(refAttribute.mCenter),
+  mName(refAttribute.mName),
+  mType(refAttribute.mType)
+{
+}
+
+XdmfAttribute::~XdmfAttribute()
+{
+}
+
+const std::string XdmfAttribute::ItemTag = "Attribute";
+
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttribute::getCenter() const
+{
+  return mCenter;
+}
+
+std::map<std::string, std::string>
+XdmfAttribute::getItemProperties() const
+{
+  std::map<std::string, std::string> attributeProperties;
+  attributeProperties.insert(std::make_pair("Name", mName));
+  mType->getProperties(attributeProperties);
+  mCenter->getProperties(attributeProperties);
+  return attributeProperties;
+}
+
+std::string
+XdmfAttribute::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfAttribute::getName() const
+{
+  return mName;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttribute::getType() const
+{
+  return mType;
+}
+
+void
+XdmfAttribute::populateItem(const std::map<std::string, std::string> & itemProperties,
+                            const std::vector<shared_ptr<XdmfItem> > & childItems,
+                            const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+
+  std::map<std::string, std::string>::const_iterator name =
+    itemProperties.find("Name");
+  if(name != itemProperties.end()) {
+    mName = name->second;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "'Name' not found in itemProperties in "
+                       "XdmfAttribute::populateItem");
+  }
+
+  mCenter = XdmfAttributeCenter::New(itemProperties);
+  mType = XdmfAttributeType::New(itemProperties);
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter = 
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+      this->swap(array);
+      if (array->getReference()) {
+        this->setReference(array->getReference());
+        this->setReadMode(XdmfArray::Reference);
+      }
+      break;
+    }
+  }
+}
+
+void
+XdmfAttribute::setCenter(const shared_ptr<const XdmfAttributeCenter> center)
+{
+  mCenter = center;
+  this->setIsChanged(true);
+}
+
+void
+XdmfAttribute::setName(const std::string & name)
+{
+  mName = name;
+  this->setIsChanged(true);
+}
+
+void
+XdmfAttribute::setType(const shared_ptr<const XdmfAttributeType> type)
+{
+  mType = type;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFATTRIBUTE * XdmfAttributeNew()
+{
+  try
+  {
+    shared_ptr<XdmfAttribute> generatedAttribute = XdmfAttribute::New();
+    return (XDMFATTRIBUTE *)((void *)(new XdmfAttribute(*generatedAttribute.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfAttribute> generatedAttribute = XdmfAttribute::New();
+    return (XDMFATTRIBUTE *)((void *)(new XdmfAttribute(*generatedAttribute.get())));
+  }
+}
+
+int XdmfAttributeGetCenter(XDMFATTRIBUTE * attribute)
+{
+  if (((XdmfAttribute *)attribute)->getCenter() == XdmfAttributeCenter::Grid()) {
+    return XDMF_ATTRIBUTE_CENTER_GRID;
+  }
+  else if (((XdmfAttribute *)attribute)->getCenter() == XdmfAttributeCenter::Cell()) {
+    return XDMF_ATTRIBUTE_CENTER_CELL;
+  }
+  else if (((XdmfAttribute *)attribute)->getCenter() == XdmfAttributeCenter::Face()) {
+    return XDMF_ATTRIBUTE_CENTER_FACE;
+  }
+  else if (((XdmfAttribute *)attribute)->getCenter() == XdmfAttributeCenter::Edge()) {
+    return XDMF_ATTRIBUTE_CENTER_EDGE;
+  }
+  else if (((XdmfAttribute *)attribute)->getCenter() == XdmfAttributeCenter::Node()) {
+    return XDMF_ATTRIBUTE_CENTER_NODE;
+  }
+  else {
+    return -1;
+  }
+}
+
+int XdmfAttributeGetType(XDMFATTRIBUTE * attribute)
+{
+  if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::Scalar()) {
+    return XDMF_ATTRIBUTE_TYPE_SCALAR;
+  }
+  else if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::Vector()) {
+    return XDMF_ATTRIBUTE_TYPE_VECTOR;
+  }
+  else if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::Tensor()) {
+    return XDMF_ATTRIBUTE_TYPE_TENSOR;
+  }
+  else if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::Matrix()) {
+    return XDMF_ATTRIBUTE_TYPE_MATRIX;
+  }
+  else if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::Tensor6()) {
+    return XDMF_ATTRIBUTE_TYPE_TENSOR6;
+  }
+  else if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::GlobalId()) {
+    return XDMF_ATTRIBUTE_TYPE_GLOBALID;
+  }
+  else if (((XdmfAttribute *)attribute)->getType() == XdmfAttributeType::NoAttributeType()) {
+    return XDMF_ATTRIBUTE_TYPE_NOTYPE;
+  }
+  else {
+    return -1;
+  }
+}
+
+void XdmfAttributeSetCenter(XDMFATTRIBUTE * attribute, int center, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch(center) {
+    case XDMF_ATTRIBUTE_CENTER_GRID:
+      ((XdmfAttribute *)attribute)->setCenter(XdmfAttributeCenter::Grid());
+      break;
+    case XDMF_ATTRIBUTE_CENTER_CELL:
+      ((XdmfAttribute *)attribute)->setCenter(XdmfAttributeCenter::Cell());
+      break;
+    case XDMF_ATTRIBUTE_CENTER_FACE:
+      ((XdmfAttribute *)attribute)->setCenter(XdmfAttributeCenter::Face());
+      break;
+    case XDMF_ATTRIBUTE_CENTER_EDGE:
+      ((XdmfAttribute *)attribute)->setCenter(XdmfAttributeCenter::Edge());
+      break;
+    case XDMF_ATTRIBUTE_CENTER_NODE:
+      ((XdmfAttribute *)attribute)->setCenter(XdmfAttributeCenter::Node());
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Attribute Center: Code " + center);
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfAttributeSetType(XDMFATTRIBUTE * attribute, int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch(type) {
+    case XDMF_ATTRIBUTE_TYPE_SCALAR:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::Scalar());
+      break;
+    case XDMF_ATTRIBUTE_TYPE_VECTOR:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::Vector());
+      break;
+    case XDMF_ATTRIBUTE_TYPE_TENSOR:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::Tensor());
+      break;
+    case XDMF_ATTRIBUTE_TYPE_MATRIX:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::Matrix());
+      break;
+    case XDMF_ATTRIBUTE_TYPE_TENSOR6:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::Tensor6());
+      break;
+    case XDMF_ATTRIBUTE_TYPE_GLOBALID:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::GlobalId());
+      break;
+    case XDMF_ATTRIBUTE_TYPE_NOTYPE:
+      ((XdmfAttribute *)attribute)->setType(XdmfAttributeType::NoAttributeType());
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Attribute Type: Code " + type);
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfAttribute, XDMFATTRIBUTE)
+XDMF_ARRAY_C_CHILD_WRAPPER(XdmfAttribute, XDMFATTRIBUTE)
diff --git a/XdmfAttribute.hpp b/XdmfAttribute.hpp
new file mode 100644
index 0000000..ab07fd0
--- /dev/null
+++ b/XdmfAttribute.hpp
@@ -0,0 +1,290 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAttribute.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFATTRIBUTE_HPP_
+#define XDMFATTRIBUTE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfTime.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Holds values located at specific parts of an XdmfGrid.
+ *
+ * XdmfAttribute holds values centered at specific locations of an
+ * XdmfGrid. An attribute contains two properties that should be set,
+ * XdmfAttributeCenter, which describes where the values are centered,
+ * and XdmfAttributeType, which describes what types of values the
+ * attribute contains.
+ */
+class XDMF_EXPORT XdmfAttribute : public XdmfArray {
+
+public:
+
+  /**
+   * Create a new XdmfAttribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfAttribute.
+   */
+  static shared_ptr<XdmfAttribute> New();
+
+  virtual ~XdmfAttribute();
+
+  LOKI_DEFINE_VISITABLE(XdmfAttribute, XdmfArray)
+  static const std::string ItemTag;
+
+  /**
+   * Get the XdmfAttributeCenter associated with this attribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setCenter
+   * @until //#setCenter
+   * @skipline //#getCenter
+   * @until //#getCenter
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setCenter
+   * @until #//setCenter
+   * @skipline #//getCenter
+   * @until #//getCenter
+   *
+   * @return    XdmfAttributeCenter of the attribute.
+   */
+  shared_ptr<const XdmfAttributeCenter> getCenter() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the name of the attribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    A string containing the name of the attribute.
+   */
+  std::string getName() const;
+
+  /**
+   * Get the XdmfAttributeType associated with this attribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setType
+   * @until //#setType
+   * @skipline //#getType
+   * @until //#getType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setType
+   * @until #//setType
+   * @skipline #//getType
+   * @until #//getType
+   *
+   * @return    XdmfAttributeType of the attribute.
+   */
+  shared_ptr<const XdmfAttributeType> getType() const;
+
+  /**
+   * Set the XdmfAttributeCenter associated with this attribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setCenter
+   * @until //#setCenter
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setCenter
+   * @until #//setCenter
+   *
+   * @param     center  The XdmfAttributeCenter to set.
+   */
+  void setCenter(const shared_ptr<const XdmfAttributeCenter> center);
+
+  /**
+   * Set the name of the attribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   *
+   * @param     name    A string containing the name to set.
+   */
+  void setName(const std::string & name);
+
+  /**
+   * Set the XdmfAttributeType associated with this attribute.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfAttribute.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setType
+   * @until //#setType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAttribute.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setType
+   * @until #//setType
+   *
+   * @param     type    XdmfAttributeType to set.
+   */
+  void setType(const shared_ptr<const XdmfAttributeType> type);
+
+  XdmfAttribute(XdmfAttribute &);
+
+protected:
+
+  XdmfAttribute();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfAttribute(const XdmfAttribute &);  // Not implemented.
+  void operator=(const XdmfAttribute &);  // Not implemented.
+
+  shared_ptr<const XdmfAttributeCenter> mCenter;
+  std::string mName;
+  shared_ptr<const XdmfAttributeType> mType;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFATTRIBUTE; // Simply as a typedef to ensure correct typing
+typedef struct XDMFATTRIBUTE XDMFATTRIBUTE;
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfAttributeNew();
+
+XDMF_EXPORT int XdmfAttributeGetCenter(XDMFATTRIBUTE * attribute);
+
+XDMF_EXPORT int XdmfAttributeGetType(XDMFATTRIBUTE * attribute);
+
+XDMF_EXPORT void XdmfAttributeSetCenter(XDMFATTRIBUTE * attribute, int center, int * status);
+
+XDMF_EXPORT void XdmfAttributeSetType(XDMFATTRIBUTE * attribute, int type, int * status);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfAttribute, XDMFATTRIBUTE, XDMF)
+XDMF_ARRAY_C_CHILD_DECLARE(XdmfAttribute, XDMFATTRIBUTE, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFATTRIBUTE_HPP_ */
diff --git a/XdmfAttributeCenter.cpp b/XdmfAttributeCenter.cpp
new file mode 100644
index 0000000..0b7691e
--- /dev/null
+++ b/XdmfAttributeCenter.cpp
@@ -0,0 +1,154 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAttributeCenter.cpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfError.hpp"
+
+std::map<std::string, shared_ptr<const XdmfAttributeCenter>(*)()> XdmfAttributeCenter::mAttributeCenterDefinitions;
+
+// Supported XdmfAttributeCenters
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttributeCenter::Grid()
+{
+  static shared_ptr<const XdmfAttributeCenter>
+    p(new XdmfAttributeCenter("Grid"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttributeCenter::Cell()
+{
+  static shared_ptr<const XdmfAttributeCenter> 
+    p(new XdmfAttributeCenter("Cell"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttributeCenter::Face()
+{
+  static shared_ptr<const XdmfAttributeCenter>
+    p(new XdmfAttributeCenter("Face"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttributeCenter::Edge()
+{
+  static shared_ptr<const XdmfAttributeCenter>
+    p(new XdmfAttributeCenter("Edge"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttributeCenter::Node()
+{
+  static shared_ptr<const XdmfAttributeCenter>
+    p(new XdmfAttributeCenter("Node"));
+  return p;
+}
+
+void
+XdmfAttributeCenter::InitTypes()
+{
+  mAttributeCenterDefinitions["GRID"] = Grid;
+  mAttributeCenterDefinitions["CELL"] = Cell;
+  mAttributeCenterDefinitions["FACE"] = Face;
+  mAttributeCenterDefinitions["EDGE"] = Edge;
+  mAttributeCenterDefinitions["NODE"] = Node;
+}
+
+XdmfAttributeCenter::XdmfAttributeCenter(const std::string & name) :
+  mName(name)
+{
+}
+
+XdmfAttributeCenter::~XdmfAttributeCenter()
+{
+}
+
+shared_ptr<const XdmfAttributeCenter>
+XdmfAttributeCenter::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+  std::map<std::string, std::string>::const_iterator center =
+    itemProperties.find("Center");
+  if(center == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL, 
+                       "'Center' not found in itemProperties in "
+                       "XdmfAttributeCenter::New");
+  }
+
+  const std::string & centerVal = ConvertToUpper(center->second);
+
+  std::map<std::string, shared_ptr<const XdmfAttributeCenter>(*)()>::const_iterator returnType = mAttributeCenterDefinitions.find(centerVal);
+
+  if (returnType == mAttributeCenterDefinitions.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Center not of 'Grid','Cell','Face','Edge','Node' "
+                       "in XdmfAttributeCenter::New");
+  }
+  else {
+    return (*(returnType->second))();
+  }
+
+  XdmfError::message(XdmfError::FATAL, 
+                     "Center not of 'Grid','Cell','Face','Edge','Node' "
+                     "in XdmfAttributeCenter::New");
+
+  // unreachable
+  return shared_ptr<const XdmfAttributeCenter>();
+}
+
+void
+XdmfAttributeCenter::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("Center", mName));
+}
+
+// C Wrappers
+
+int XdmfAttributeCenterGrid()
+{
+  return XDMF_ATTRIBUTE_CENTER_GRID;
+}
+
+int XdmfAttributeCenterCell()
+{
+  return XDMF_ATTRIBUTE_CENTER_CELL;
+}
+
+int XdmfAttributeCenterFace()
+{
+  return XDMF_ATTRIBUTE_CENTER_FACE;
+}
+
+int XdmfAttributeCenterEdge()
+{
+  return XDMF_ATTRIBUTE_CENTER_EDGE;
+}
+
+int XdmfAttributeCenterNode()
+{
+  return XDMF_ATTRIBUTE_CENTER_NODE;
+}
diff --git a/XdmfAttributeCenter.hpp b/XdmfAttributeCenter.hpp
new file mode 100644
index 0000000..a0b7616
--- /dev/null
+++ b/XdmfAttributeCenter.hpp
@@ -0,0 +1,141 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAttributeCenter.hpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFATTRIBUTECENTER_HPP_
+#define XDMFATTRIBUTECENTER_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItemProperty.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Property describing where XdmfAttribute values are centered.
+ *
+ * XdmfAttributeCenter is a property used by XdmfAttribute to specify
+ * where its values are centered on an XdmfGrid. A specific
+ * XdmfAttributeCenter can be created by calling on of the static
+ * methods in the class, i.e.  XdmfAttributeCenter::Cell().
+ * Xdmf supports the following attribute centers:
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfAttribute.cpp
+ * @skipline //#initialization
+ * @until //#initialization
+ * @skipline //#setCenter
+ * @until //#setCenter
+ * @skipline //#getCenter
+ * @until //#getCenter
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleAttribute.py
+ * @skipline #//initialization
+ * @until #//initialization
+ * @skipline #//setCenter
+ * @until #//setCenter
+ * @skipline #//getCenter
+ * @until #//getCenter
+ *
+ *   Grid
+ *   Cell
+ *   Face
+ *   Edge
+ *   Node
+ */
+class XDMF_EXPORT XdmfAttributeCenter : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfAttributeCenter();
+
+  friend class XdmfAttribute;
+
+  // Supported Xdmf Attribute Centers
+  static shared_ptr<const XdmfAttributeCenter> Grid();
+  static shared_ptr<const XdmfAttributeCenter> Cell();
+  static shared_ptr<const XdmfAttributeCenter> Face();
+  static shared_ptr<const XdmfAttributeCenter> Edge();
+  static shared_ptr<const XdmfAttributeCenter> Node();
+
+  void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+
+protected:
+
+  /**
+   * Protected constructor for XdmfAttributeCenter.  The constructor
+   * is protected because all attribute centers supported by Xdmf
+   * should be accessed through more specific static methods that
+   * construct XdmfAttributeCenters -
+   * i.e. XdmfAttributeCenter::Node().
+   *
+   * @param     name    The name of the XdmfAttributeCenter to construct.
+   */
+  XdmfAttributeCenter(const std::string & name);
+
+  static std::map<std::string, shared_ptr<const XdmfAttributeCenter>(*)()> mAttributeCenterDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfAttributeCenter(const XdmfAttributeCenter &); // Not implemented.
+  void operator=(const XdmfAttributeCenter &); // Not implemented.
+
+  static shared_ptr<const XdmfAttributeCenter>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  std::string mName;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#define XDMF_ATTRIBUTE_CENTER_GRID 100
+#define XDMF_ATTRIBUTE_CENTER_CELL 101
+#define XDMF_ATTRIBUTE_CENTER_FACE 102
+#define XDMF_ATTRIBUTE_CENTER_EDGE 103
+#define XDMF_ATTRIBUTE_CENTER_NODE 104
+
+XDMF_EXPORT int XdmfAttributeCenterGrid();
+XDMF_EXPORT int XdmfAttributeCenterCell();
+XDMF_EXPORT int XdmfAttributeCenterFace();
+XDMF_EXPORT int XdmfAttributeCenterEdge();
+XDMF_EXPORT int XdmfAttributeCenterNode();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFATTRIBUTECENTER_HPP_ */
diff --git a/XdmfAttributeType.cpp b/XdmfAttributeType.cpp
new file mode 100644
index 0000000..c0729ab
--- /dev/null
+++ b/XdmfAttributeType.cpp
@@ -0,0 +1,182 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAttributeType.cpp                                               */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfAttributeType.hpp"
+#include "XdmfError.hpp"
+
+std::map<std::string, shared_ptr<const XdmfAttributeType>(*)()> XdmfAttributeType::mAttributeDefinitions;
+
+// Supported XdmfAttributeTypes
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::NoAttributeType()
+{
+  static shared_ptr<const XdmfAttributeType> 
+    p(new XdmfAttributeType("None"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::Scalar()
+{
+  static shared_ptr<const XdmfAttributeType> 
+    p(new XdmfAttributeType("Scalar"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::Vector()
+{
+  static shared_ptr<const XdmfAttributeType> 
+    p(new XdmfAttributeType("Vector"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::Tensor()
+{
+  static shared_ptr<const XdmfAttributeType>
+    p(new XdmfAttributeType("Tensor"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::Matrix()
+{
+  static shared_ptr<const XdmfAttributeType>
+    p(new XdmfAttributeType("Matrix"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::Tensor6()
+{
+  static shared_ptr<const XdmfAttributeType>
+    p(new XdmfAttributeType("Tensor6"));
+  return p;
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::GlobalId()
+{
+  static shared_ptr<const XdmfAttributeType>
+    p(new XdmfAttributeType("GlobalId"));
+  return p;
+}
+
+void
+XdmfAttributeType::InitTypes()
+{
+  mAttributeDefinitions["NONE"] = NoAttributeType;
+  mAttributeDefinitions["SCALAR"] = Scalar;
+  mAttributeDefinitions["VECTOR"] = Vector;
+  mAttributeDefinitions["TENSOR"] = Tensor;
+  mAttributeDefinitions["MATRIX"] = Matrix;
+  mAttributeDefinitions["TENSOR6"] = Tensor6;
+  mAttributeDefinitions["GLOBALID"] = GlobalId;
+}
+
+XdmfAttributeType::XdmfAttributeType(const std::string & name) :
+  mName(name)
+{
+}
+
+XdmfAttributeType::~XdmfAttributeType()
+{
+}
+
+shared_ptr<const XdmfAttributeType>
+XdmfAttributeType::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("Type");
+  if(type == itemProperties.end()) {
+    type = itemProperties.find("AttributeType");
+  }
+  if(type == itemProperties.end()) {
+    // to support old xdmf defaults, return Scalar()
+    return Scalar();
+  }
+
+
+  const std::string & typeVal = ConvertToUpper(type->second);
+
+  std::map<std::string, shared_ptr<const XdmfAttributeType>(*)()>::const_iterator returnType = mAttributeDefinitions.find(typeVal);
+
+  if (returnType == mAttributeDefinitions.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Type not of 'None','Scalar','Vector','Tensor', "
+                       "'Matrix','Tensor6', or 'GlobalId' in "
+                       "XdmfAttributeType::New");
+  }
+  else {
+    return (*(returnType->second))();
+  }
+
+  // unreachable
+  return shared_ptr<const XdmfAttributeType>();
+}
+
+void
+XdmfAttributeType::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("Type", mName));
+}
+
+// C Wrappers
+
+int XdmfAttributeTypeScalar()
+{
+  return XDMF_ATTRIBUTE_TYPE_SCALAR;
+}
+
+int XdmfAttributeTypeVector()
+{
+  return XDMF_ATTRIBUTE_TYPE_VECTOR;
+}
+
+int XdmfAttributeTypeTensor()
+{
+  return XDMF_ATTRIBUTE_TYPE_TENSOR;
+}
+
+int XdmfAttributeTypeMatrix()
+{
+  return XDMF_ATTRIBUTE_TYPE_MATRIX;
+}
+
+int XdmfAttributeTypeTensor6()
+{
+  return XDMF_ATTRIBUTE_TYPE_TENSOR6;
+}
+
+int XdmfAttributeTypeGlobalId()
+{
+  return XDMF_ATTRIBUTE_TYPE_GLOBALID;
+}
+
+int XdmfAttributeTypeNoAttributeType()
+{
+  return XDMF_ATTRIBUTE_TYPE_NOTYPE;
+}
diff --git a/XdmfAttributeType.hpp b/XdmfAttributeType.hpp
new file mode 100644
index 0000000..4ffa6ed
--- /dev/null
+++ b/XdmfAttributeType.hpp
@@ -0,0 +1,149 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfAttributeType.hpp                                               */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFATTRIBUTETYPE_HPP_
+#define XDMFATTRIBUTETYPE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+
+#ifdef __cplusplus
+
+#include "XdmfItemProperty.hpp"
+
+/**
+ * @brief Property describing the type of values an XdmfAttribute
+ * contains.
+ *
+ * XdmfAttributeType is a property used by XdmfAttribute to specify
+ * what type of values the XdmfAttribute contains. A specific
+ * XdmfAttributeType can be created by calling one of the static
+ * methods in the class, i.e. XdmfAttributeType::Scalar().
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfAttribute.cpp
+ * @skipline //#initialization
+ * @until //#initialization
+ * @skipline //#setType
+ * @until //#setType
+ * @skipline //#getType
+ * @until //#getType
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleAttribute.py
+ * @skipline #//initialization
+ * @until #//initialization
+ * @skipline #//setType
+ * @until #//setType
+ * @skipline #//getType
+ * @until #//getType
+ *
+ * Xdmf supports the following attribute types:
+ *   NoAttributeType
+ *   Scalar
+ *   Vector
+ *   Tensor
+ *   Matrix
+ *   Tensor6
+ *   GlobalId
+ */
+class XDMF_EXPORT XdmfAttributeType : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfAttributeType();
+
+  friend class XdmfAttribute;
+
+  // Supported Xdmf Attribute Types
+  static shared_ptr<const XdmfAttributeType> NoAttributeType();
+  static shared_ptr<const XdmfAttributeType> Scalar();
+  static shared_ptr<const XdmfAttributeType> Vector();
+  static shared_ptr<const XdmfAttributeType> Tensor();
+  static shared_ptr<const XdmfAttributeType> Matrix();
+  static shared_ptr<const XdmfAttributeType> Tensor6();
+  static shared_ptr<const XdmfAttributeType> GlobalId();
+
+  void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+protected:
+
+  /**
+   * Protected constructor for XdmfAttributeType.  The constructor is
+   * protected because all attribute types supported by Xdmf should be
+   * accessed through more specific static methods that construct
+   * XdmfAttributeTypes - i.e. XdmfAttributeType::Scalar().
+   *
+   * @param     name    The name of the XdmfAttributeType to construct.
+   */
+  XdmfAttributeType(const std::string & name);
+
+  static std::map<std::string, shared_ptr<const XdmfAttributeType>(*)()> mAttributeDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfAttributeType(const XdmfAttributeType &); // Not implemented.
+  void operator=(const XdmfAttributeType &); // Not implemented.
+
+  static shared_ptr<const XdmfAttributeType>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  std::string mName;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#define XDMF_ATTRIBUTE_TYPE_SCALAR                       200
+#define XDMF_ATTRIBUTE_TYPE_VECTOR                       201
+#define XDMF_ATTRIBUTE_TYPE_TENSOR                       202
+#define XDMF_ATTRIBUTE_TYPE_MATRIX                       203
+#define XDMF_ATTRIBUTE_TYPE_TENSOR6                      204
+#define XDMF_ATTRIBUTE_TYPE_GLOBALID                     205
+#define XDMF_ATTRIBUTE_TYPE_NOTYPE                       206
+
+XDMF_EXPORT int XdmfAttributeTypeScalar();
+XDMF_EXPORT int XdmfAttributeTypeVector();
+XDMF_EXPORT int XdmfAttributeTypeTensor();
+XDMF_EXPORT int XdmfAttributeTypeMatrix();
+XDMF_EXPORT int XdmfAttributeTypeTensor6();
+XDMF_EXPORT int XdmfAttributeTypeGlobalId();
+XDMF_EXPORT int XdmfAttributeTypeNoAttributeType();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFATTRIBUTETYPE_HPP_ */
diff --git a/XdmfConfig.cmake.in b/XdmfConfig.cmake.in
new file mode 100644
index 0000000..c0b22d9
--- /dev/null
+++ b/XdmfConfig.cmake.in
@@ -0,0 +1,5 @@
+#
+#	XdmfConfig.cmake
+#
+
+ at XDMF_VARS@
diff --git a/XdmfConfig.hpp.in b/XdmfConfig.hpp.in
new file mode 100644
index 0000000..bb3f95f
--- /dev/null
+++ b/XdmfConfig.hpp.in
@@ -0,0 +1,32 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfConfig.hpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFCONFIG_HPP_
+#define XDMFCONFIG_HPP_
+
+#cmakedefine BUILD_SHARED
+#ifndef BUILD_SHARED
+#  define XDMFSTATIC
+#endif
+
+#endif
diff --git a/XdmfCurvilinearGrid.cpp b/XdmfCurvilinearGrid.cpp
new file mode 100644
index 0000000..82f12d4
--- /dev/null
+++ b/XdmfCurvilinearGrid.cpp
@@ -0,0 +1,465 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCurviliniearGrid.cpp                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cmath>
+#include "XdmfArray.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfError.hpp"
+
+/**
+ * PIMPL
+ */
+class XdmfCurvilinearGrid::XdmfCurvilinearGridImpl : public XdmfGridImpl {
+
+public:
+
+  class XdmfTopologyCurvilinear : public XdmfTopology
+  {
+
+  public:
+
+    static shared_ptr<XdmfTopologyCurvilinear>
+    New(const XdmfCurvilinearGrid * const curvilinearGrid)
+    {
+      shared_ptr<XdmfTopologyCurvilinear> 
+        p(new XdmfTopologyCurvilinear(curvilinearGrid));
+      return p;
+    }
+
+    bool isInitialized() const
+    {
+      return true;
+    }
+
+    unsigned int
+    getNumberElements() const
+    {
+      const shared_ptr<const XdmfArray> dimensions = 
+        mCurvilinearGrid->getDimensions();
+      if(dimensions->getSize() == 0) {
+        return 0;
+      }
+      unsigned int toReturn = 1;
+      for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+        toReturn *= (dimensions->getValue<unsigned int>(i) - 1);
+      }
+      return toReturn;
+    }
+
+  private:
+
+    XdmfTopologyCurvilinear(const XdmfCurvilinearGrid * const curvilinearGrid) :
+      mCurvilinearGrid(curvilinearGrid)
+    {
+      this->setType(XdmfTopologyTypeCurvilinear::New(curvilinearGrid));
+    }
+
+    const XdmfCurvilinearGrid * const mCurvilinearGrid;
+  };
+
+  class XdmfTopologyTypeCurvilinear : public XdmfTopologyType
+  {
+
+  public:
+
+    static shared_ptr<const XdmfTopologyTypeCurvilinear>
+    New(const XdmfCurvilinearGrid * const curvilinearGrid)
+    {
+      shared_ptr<const XdmfTopologyTypeCurvilinear>
+        p(new XdmfTopologyTypeCurvilinear(curvilinearGrid));
+      return p;
+    }
+
+    unsigned int
+    getEdgesPerElement() const
+    {
+      return calculateHypercubeNumElements(mCurvilinearGrid->getDimensions()->getSize(), 1);
+/*
+      const unsigned int dimensions = 
+        mCurvilinearGrid->getDimensions()->getSize();
+      if (dimensions == 1) {
+        return 1;
+      }
+      if(dimensions == 2) {
+        return 4;
+      }
+      else if(dimensions >= 3) {
+        return 12;
+      }
+      else {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Grid dimensions not 2 or 3 in "
+                           "XdmfTopologyTypeCurvilinear::getEdgesPerElement");
+      }
+      return 0;
+*/
+    }
+
+    unsigned int
+    getFacesPerElement() const
+    {
+      return calculateHypercubeNumElements(mCurvilinearGrid->getDimensions()->getSize(), 2);
+/*
+      const unsigned int dimensions = 
+        mCurvilinearGrid->getDimensions()->getSize();
+      if (dimensions == 1) {
+        return 0;
+      }
+      else if(dimensions == 2) {
+        return 1;
+      }
+      else if(dimensions == 3) {
+        return 6;
+      }
+      else {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Grid dimensions not 2 or 3 in "
+                           "XdmfTopologyTypeCurvilinear::getFacesPerElement");
+      }
+      return 0;
+*/
+    }
+
+    unsigned int
+    getNodesPerElement() const
+    {
+      return calculateHypercubeNumElements(mCurvilinearGrid->getDimensions()->getSize(), 0);
+      // 2^Dimensions
+      // e.g. 1D = 2 nodes per element and 2D = 4 nodes per element.
+//      return (unsigned int)
+//        std::pow(2, (double)mCurvilinearGrid->getDimensions()->getSize());
+    }
+
+    void
+    getProperties(std::map<std::string, std::string> & collectedProperties) const
+    {
+      shared_ptr<const XdmfArray> dimensions =
+        mCurvilinearGrid->getDimensions();
+      if(dimensions->getSize() == 3) {
+        collectedProperties["Type"] = "3DSMesh";
+      }
+      else if(dimensions->getSize() == 2) {
+        collectedProperties["Type"] = "2DSMesh";
+      }
+      else {
+        collectedProperties["Type"] = "SMesh";
+//        XdmfError::message(XdmfError::FATAL, 
+//                           "Grid dimensions not 2 or 3 in "
+//                           "XdmfTopologyTypeCurvilinear::getProperties");
+      }
+      collectedProperties["Dimensions"] = dimensions->getValuesString();
+    }
+
+  private:
+
+    XdmfTopologyTypeCurvilinear(const XdmfCurvilinearGrid * const curvilinearGrid) :
+      XdmfTopologyType(0,
+                       0,
+                       std::vector<shared_ptr<const XdmfTopologyType> >(),
+                       0,
+                       "foo",
+                       XdmfTopologyType::Structured,
+                       0x1110),
+      mCurvilinearGrid(curvilinearGrid)
+    {
+    }
+
+    const XdmfCurvilinearGrid * const mCurvilinearGrid;
+
+  };
+
+  XdmfCurvilinearGridImpl(const shared_ptr<XdmfArray> numPoints) :
+    mDimensions(numPoints)
+  {
+     mGridType ="Curvilinear";
+  }
+
+  XdmfGridImpl * duplicate()
+  {
+    return new XdmfCurvilinearGridImpl(mDimensions);
+  }
+
+  shared_ptr<XdmfArray> mDimensions;
+};
+
+shared_ptr<XdmfCurvilinearGrid>
+XdmfCurvilinearGrid::New(const unsigned int xNumPoints,
+                         const unsigned int yNumPoints)
+{
+  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
+  numPoints->initialize<unsigned int>(2);
+  numPoints->insert(0, xNumPoints);
+  numPoints->insert(1, yNumPoints);
+  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
+  return p;
+}
+
+shared_ptr<XdmfCurvilinearGrid>
+XdmfCurvilinearGrid::New(const unsigned int xNumPoints,
+                         const unsigned int yNumPoints,
+                         const unsigned int zNumPoints)
+{
+  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
+  numPoints->initialize<unsigned int>(3);
+  numPoints->insert(0, xNumPoints);
+  numPoints->insert(1, yNumPoints);
+  numPoints->insert(2, zNumPoints);
+  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
+  return p;
+}
+
+shared_ptr<XdmfCurvilinearGrid>
+XdmfCurvilinearGrid::New(const shared_ptr<XdmfArray> numPoints)
+{
+  shared_ptr<XdmfCurvilinearGrid> p(new XdmfCurvilinearGrid(numPoints));
+  return p;
+}
+
+XdmfCurvilinearGrid::XdmfCurvilinearGrid(const shared_ptr<XdmfArray> numPoints) :
+  XdmfGrid(XdmfGeometry::New(),
+           XdmfCurvilinearGridImpl::XdmfTopologyCurvilinear::New(this))
+{
+  mImpl = new XdmfCurvilinearGridImpl(numPoints);
+}
+
+XdmfCurvilinearGrid::XdmfCurvilinearGrid(XdmfCurvilinearGrid & refGrid) :
+  XdmfGrid(refGrid)
+{
+  mTopology = XdmfCurvilinearGridImpl::XdmfTopologyCurvilinear::New(this);
+}
+
+XdmfCurvilinearGrid::~XdmfCurvilinearGrid()
+{
+  if (mImpl) {
+    delete mImpl;
+  }
+  mImpl = NULL;
+}
+
+const std::string XdmfCurvilinearGrid::ItemTag = "Grid";
+
+void
+XdmfCurvilinearGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
+{
+  XdmfGrid::copyGrid(sourceGrid);
+  if (shared_ptr<XdmfCurvilinearGrid> classedGrid = shared_dynamic_cast<XdmfCurvilinearGrid>(sourceGrid))
+  {
+    // Copy stucture from read grid to this grid
+    this->setGeometry(classedGrid->getGeometry());
+    this->setDimensions(classedGrid->getDimensions());
+  }
+}
+
+shared_ptr<XdmfArray>
+XdmfCurvilinearGrid::getDimensions()
+{
+  return boost::const_pointer_cast<XdmfArray>
+    (static_cast<const XdmfCurvilinearGrid &>(*this).getDimensions());
+}
+
+shared_ptr<const XdmfArray>
+XdmfCurvilinearGrid::getDimensions() const
+{
+  return ((XdmfCurvilinearGridImpl *)mImpl)->mDimensions;
+}
+
+shared_ptr<XdmfGeometry>
+XdmfCurvilinearGrid::getGeometry()
+{
+  return boost::const_pointer_cast<XdmfGeometry>
+    (static_cast<const XdmfGrid &>(*this).getGeometry());
+}
+
+void
+XdmfCurvilinearGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
+                                  const std::vector<shared_ptr<XdmfItem> > & childItems,
+                                  const XdmfCoreReader * const reader)
+{
+  XdmfGrid::populateItem(itemProperties, childItems, reader);
+
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfCurvilinearGrid> curvilinearGrid =
+       shared_dynamic_cast<XdmfCurvilinearGrid>(*iter)) {
+      ((XdmfCurvilinearGridImpl *)mImpl)->mDimensions = curvilinearGrid->getDimensions();
+    }
+  }
+}
+
+void
+XdmfCurvilinearGrid::read()
+{
+  if (mGridController)
+  {
+    if (shared_ptr<XdmfCurvilinearGrid> grid = shared_dynamic_cast<XdmfCurvilinearGrid>(mGridController->read()))
+    { 
+      // Copy stucture from read grid to this grid
+      copyGrid(grid);
+    }
+    else if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(mGridController->read()))
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
+    }
+    else
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
+    }
+  }
+}
+
+void
+XdmfCurvilinearGrid::release()
+{
+  XdmfGrid::release();
+  this->setGeometry(shared_ptr<XdmfGeometry>());
+  this->setDimensions(shared_ptr<XdmfArray>());
+}
+
+void
+XdmfCurvilinearGrid::setDimensions(const shared_ptr<XdmfArray> dimensions)
+{
+  ((XdmfCurvilinearGridImpl *)mImpl)->mDimensions = dimensions;
+  this->setIsChanged(true);
+}
+
+void
+XdmfCurvilinearGrid::setGeometry(const shared_ptr<XdmfGeometry> geometry)
+{
+  mGeometry = geometry;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFCURVILINEARGRID * XdmfCurvilinearGridNew2D(unsigned int xNumPoints,
+                                               unsigned int yNumPoints)
+{
+  try
+  {
+    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints);
+    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints);
+    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
+  }
+}
+
+XDMFCURVILINEARGRID * XdmfCurvilinearGridNew3D(unsigned int xNumPoints,
+                                               unsigned int yNumPoints,
+                                               unsigned int zNumPoints)
+{
+  try
+  {
+    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints, zNumPoints);
+    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(xNumPoints, yNumPoints, zNumPoints);
+    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
+  }
+}
+
+XDMFCURVILINEARGRID * XdmfCurvilinearGridNew(XDMFARRAY * numPoints, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    shared_ptr<XdmfArray> tempArray = shared_ptr<XdmfArray>((XdmfArray *)numPoints, XdmfNullDeleter());
+    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(tempArray);
+    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfArray> tempArray = shared_ptr<XdmfArray>((XdmfArray *)numPoints, XdmfNullDeleter());
+    shared_ptr<XdmfCurvilinearGrid> generatedGrid = XdmfCurvilinearGrid::New(tempArray);
+    return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*generatedGrid.get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfCurvilinearGridGetDimensions(XDMFCURVILINEARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
+    shared_ptr<XdmfArray> generatedArray = gridPointer->getDimensions();
+    return (XDMFARRAY *)((void *)generatedArray.get());
+  }
+  catch (...)
+  {
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
+    shared_ptr<XdmfArray> generatedArray = gridPointer->getDimensions();
+    return (XDMFARRAY *)((void *)generatedArray.get());
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFGEOMETRY * XdmfCurvilinearGridGetGeometry(XDMFCURVILINEARGRID * grid)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
+  shared_ptr<XdmfGeometry> generatedGeometry = gridPointer->getGeometry();
+  return (XDMFGEOMETRY *)((void *)generatedGeometry.get());
+}
+
+void XdmfCurvilinearGridSetDimensions(XDMFCURVILINEARGRID * grid, XDMFARRAY * dimensions, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setDimensions(shared_ptr<XdmfArray>((XdmfArray *)dimensions));
+  }
+  else {
+    gridPointer->setDimensions(shared_ptr<XdmfArray>((XdmfArray *)dimensions, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfCurvilinearGridSetGeometry(XDMFCURVILINEARGRID * grid, XDMFGEOMETRY * geometry, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfCurvilinearGrid * gridPointer = dynamic_cast<XdmfCurvilinearGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry));
+  }
+  else {
+    gridPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry, XdmfNullDeleter()));
+  }
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfCurvilinearGrid, XDMFCURVILINEARGRID)
+XDMF_GRID_C_CHILD_WRAPPER(XdmfCurvilinearGrid, XDMFCURVILINEARGRID)
diff --git a/XdmfCurvilinearGrid.hpp b/XdmfCurvilinearGrid.hpp
new file mode 100644
index 0000000..c65c944
--- /dev/null
+++ b/XdmfCurvilinearGrid.hpp
@@ -0,0 +1,344 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCurvilinearGrid.hpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFCURVILINEARGRID_HPP_
+#define XDMFCURVILINEARGRID_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfGrid.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+/**
+ * @brief A curvilinear (or structured) grid consisting of cells and
+ * points arranged on a regular lattice in space.
+ *
+ * XdmfCurvilinearGrid represents a mesh of cells and points arranged
+ * with regular topology and irregular geometry.
+ *
+ * In order to define a curvilinear grid, the dimensions of the grid
+ * must be supplied along with the coordinates of each point.
+ *
+ */
+class XDMF_EXPORT XdmfCurvilinearGrid : public XdmfGrid {
+
+public:
+
+  /**
+   * Create a new curvilinear grid (Two dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim2
+   * @until //#initializationdim2
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructor2
+   * @until #//constructor2
+   *
+   * @param     xNumPoints      The number of points in the x direction.
+   * @param     yNumPoints      The number of points in the y direction.
+   *
+   * @return                    Constructed curvilinear grid.
+   */
+  static shared_ptr<XdmfCurvilinearGrid>
+  New(const unsigned int xNumPoints,
+      const unsigned int yNumPoints);
+
+  /**
+   * Create a new curvilinear grid (Three dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim3
+   * @until //#initializationdim3
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructor3
+   * @until #//constructor3
+   *
+   * @param     xNumPoints      The number of points in the x direction.
+   * @param     yNumPoints      The number of points in the y direction.
+   * @param     zNumPoints      The number of points in the z direction.
+   *
+   * @return                    Constructed curvilinear grid.
+   */
+  static shared_ptr<XdmfCurvilinearGrid>
+  New(const unsigned int xNumPoints,
+      const unsigned int yNumPoints,
+      const unsigned int zNumPoints);
+
+  /**
+   * Create a new curvilinear grid (N dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructorvector
+   * @until #//constructorvector
+   *
+   * @param     numPoints       The number of points in each direction.
+   *
+   * @return                    Constructed curvilinear grid.
+   */
+  static shared_ptr<XdmfCurvilinearGrid>
+  New(const shared_ptr<XdmfArray> numPoints);
+
+  virtual ~XdmfCurvilinearGrid();
+
+  LOKI_DEFINE_VISITABLE(XdmfCurvilinearGrid, XdmfGrid)
+  static const std::string ItemTag;
+
+  /**
+   * Get the dimensions of the grid, the number of points in each
+   * direction.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim3
+   * @until //#initializationdim3
+   * @skipline //#setDimensions
+   * @until //#setDimensions
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructorvector
+   * @until #//constructorvector
+   * @skipline #//setDimensions
+   * @until #//setDimensions
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    XdmfArray containing dimensions of this grid.
+   */
+  shared_ptr<XdmfArray> getDimensions();
+
+  /**
+   * Get the dimensions of the grid, the number of points in each
+   * direction (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim3
+   * @until //#initializationdim3
+   * @skipline //#setDimensions
+   * @until //#setDimensions
+   * @skipline //#getDimensionsconst
+   * @until //#getDimensionsconst
+   *
+   * Python: Python doesn't have a constant version
+   *
+   * @return    XdmfArray containing the dimensions of this grid.
+   */
+  shared_ptr<const XdmfArray> getDimensions() const;
+
+  /**
+   * Get the geometry associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim3
+   * @until //#initializationdim3
+   * @skipline //#setGeometry
+   * @until //#setGeometry
+   * @skipline //#getGeometry
+   * @until //#getGeometry
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructorvector
+   * @until #//constructorvector
+   * @skipline #//setGeometry
+   * @until #//setGeometry
+   * @skipline #//getGeometry
+   * @until #//getGeometry
+   *
+   * @return    The geometry associated with this grid.
+   */
+  shared_ptr<XdmfGeometry> getGeometry();
+  using XdmfGrid::getGeometry;
+
+  virtual void read();
+
+  virtual void release();
+
+  /**
+   * Set the dimensions of the grid, the number of points in each
+   * direction.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim3
+   * @until //#initializationdim3
+   * @skipline //#setDimensions
+   * @until //#setDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructorvector
+   * @until #//constructorvector
+   * @skipline #//setDimensions
+   * @until #//setDimensions
+   *
+   * @param     dimensions      The dimension of the grid.
+   */
+  void setDimensions(const shared_ptr<XdmfArray> dimensions);
+
+  /**
+   * Set the geometry associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCurvilinearGrid.cpp
+   * @skipline //#initializationdim3
+   * @until //#initializationdim3
+   * @skipline //#setGeometry
+   * @until //#setGeometry
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCurvilinearGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//constructorvector
+   * @until #//constructorvector
+   * @skipline #//setGeometry
+   * @until #//setGeometry
+   *
+   * @param     geometry        An XdmfGeometry to associate with this grid.
+   */
+  void setGeometry(const shared_ptr<XdmfGeometry> geometry);
+
+  XdmfCurvilinearGrid(XdmfCurvilinearGrid &);
+
+protected:
+
+  XdmfCurvilinearGrid(const shared_ptr<XdmfArray> numPoints);
+
+  void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfCurvilinearGridImpl;
+  XdmfCurvilinearGrid(const XdmfCurvilinearGrid &); // Not implemented.
+  void operator=(const XdmfCurvilinearGrid &);  // Not implemented.
+
+  void
+  copyGrid(shared_ptr<XdmfGrid> sourceGrid);
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFCURVILINEARGRID; // Simply as a typedef to ensure correct typing
+typedef struct XDMFCURVILINEARGRID XDMFCURVILINEARGRID;
+
+XDMF_EXPORT XDMFCURVILINEARGRID * XdmfCurvilinearGridNew2D(unsigned int xNumPoints,
+                                                           unsigned int yNumPoints);
+
+XDMF_EXPORT XDMFCURVILINEARGRID * XdmfCurvilinearGridNew3D(unsigned int xNumPoints,
+                                                           unsigned int yNumPoints,
+                                                           unsigned int zNumPoints);
+
+XDMF_EXPORT XDMFCURVILINEARGRID * XdmfCurvilinearGridNew(XDMFARRAY * numPoints, int * status);
+
+XDMF_EXPORT XDMFARRAY * XdmfCurvilinearGridGetDimensions(XDMFCURVILINEARGRID * grid, int * status);
+
+XDMF_EXPORT XDMFGEOMETRY * XdmfCurvilinearGridGetGeometry(XDMFCURVILINEARGRID * grid);
+
+XDMF_EXPORT void XdmfCurvilinearGridSetDimensions(XDMFCURVILINEARGRID * grid, XDMFARRAY * dimensions, int passControl, int * status);
+
+XDMF_EXPORT void XdmfCurvilinearGridSetGeometry(XDMFCURVILINEARGRID * grid, XDMFGEOMETRY * geometry, int passControl);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfCurvilinearGrid, XDMFCURVILINEARGRID, XDMF)
+XDMF_GRID_C_CHILD_DECLARE(XdmfCurvilinearGrid, XDMFCURVILINEARGRID, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFCURVILINEARGRID_HPP_ */
diff --git a/XdmfDomain.cpp b/XdmfDomain.cpp
new file mode 100644
index 0000000..a2ba9ff
--- /dev/null
+++ b/XdmfDomain.cpp
@@ -0,0 +1,483 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDomain.cpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfDomain.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+#ifdef XDMF_BUILD_DSM
+  #include "XdmfDSMBuffer.hpp"
+  #include "XdmfDSMDriver.hpp"
+  #include "XdmfDSMDescription.hpp"
+#endif
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfDomain,
+                             XdmfGridCollection,
+                             GridCollection,
+                             Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfDomain,
+                             XdmfCurvilinearGrid,
+                             CurvilinearGrid,
+                             Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfDomain,
+                             XdmfGraph,
+                             Graph,
+                             Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfDomain,
+                             XdmfRectilinearGrid,
+                             RectilinearGrid,
+                             Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfDomain,
+                             XdmfRegularGrid,
+                             RegularGrid,
+                             Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfDomain,
+                             XdmfUnstructuredGrid,
+                             UnstructuredGrid,
+                             Name)
+
+shared_ptr<XdmfDomain>
+XdmfDomain::New()
+{
+  shared_ptr<XdmfDomain> p(new XdmfDomain());
+  return p;
+}
+
+XdmfDomain::XdmfDomain()
+{
+}
+
+XdmfDomain::XdmfDomain(XdmfDomain & refDomain) :
+  XdmfItem(refDomain),
+  mGridCollections(refDomain.mGridCollections),
+  mGraphs(refDomain.mGraphs),
+  mCurvilinearGrids(refDomain.mCurvilinearGrids),
+  mRectilinearGrids(refDomain.mRectilinearGrids),
+  mRegularGrids(refDomain.mRegularGrids),
+  mUnstructuredGrids(refDomain.mUnstructuredGrids)
+{
+}
+
+XdmfDomain::~XdmfDomain()
+{
+}
+
+const std::string XdmfDomain::ItemTag = "Domain";
+
+std::map<std::string, std::string>
+XdmfDomain::getItemProperties() const
+{
+  std::map<std::string, std::string> domainProperties;
+  return domainProperties;
+}
+
+std::string
+XdmfDomain::getItemTag() const
+{
+  return ItemTag;
+}
+
+void
+XdmfDomain::populateItem(const std::map<std::string, std::string> & itemProperties,
+                         const std::vector<shared_ptr<XdmfItem> > & childItems,
+                         const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfGridCollection> gridCollection =
+       shared_dynamic_cast<XdmfGridCollection>(*iter)) {
+      this->insert(gridCollection);
+    }
+    else if(shared_ptr<XdmfCurvilinearGrid> grid =
+            shared_dynamic_cast<XdmfCurvilinearGrid>(*iter)) {
+      this->insert(grid);
+    }
+    else if(shared_ptr<XdmfGraph> graph =
+            shared_dynamic_cast<XdmfGraph>(*iter)) {
+      this->insert(graph);
+    }
+    else if(shared_ptr<XdmfRectilinearGrid> grid =
+            shared_dynamic_cast<XdmfRectilinearGrid>(*iter)) {
+      this->insert(grid);
+    }
+    else if(shared_ptr<XdmfRegularGrid> grid =
+            shared_dynamic_cast<XdmfRegularGrid>(*iter)) {
+      this->insert(grid);
+    }
+    else if(shared_ptr<XdmfUnstructuredGrid> grid =
+            shared_dynamic_cast<XdmfUnstructuredGrid>(*iter)) {
+      this->insert(grid);
+    }
+  }
+}
+
+void
+XdmfDomain::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+#ifdef XDMF_BUILD_DSM
+  // Traverse Data Descriptions before anything
+  XdmfDSMBuffer * dsmBuffer = (XdmfDSMBuffer *)xdmf_dsm_get_manager();
+
+  if (dsmBuffer)
+  {
+    shared_ptr<XdmfDSMDescription> dsmDescription;
+    dsmDescription = XdmfDSMDescription::New();
+    dsmDescription->setPortDescription(dsmBuffer->GetComm()->GetDsmPortName());
+
+    dsmDescription->accept(visitor);
+  }
+#endif
+
+  XdmfItem::traverse(visitor);
+  for (unsigned int i = 0; i < mGridCollections.size(); ++i)
+  {
+    mGridCollections[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mCurvilinearGrids.size(); ++i)
+  {
+    mCurvilinearGrids[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mGraphs.size(); ++i)
+  {
+    mGraphs[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mRectilinearGrids.size(); ++i)
+  {
+    mRectilinearGrids[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mRegularGrids.size(); ++i)
+  {
+    mRegularGrids[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mUnstructuredGrids.size(); ++i)
+  {
+    mUnstructuredGrids[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+XDMFDOMAIN * XdmfDomainNew()
+{
+  try
+  {
+    shared_ptr<XdmfDomain> generatedDomain = XdmfDomain::New();
+    return (XDMFDOMAIN *)((void *)((XdmfItem *)(new XdmfDomain(*generatedDomain.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfDomain> generatedDomain = XdmfDomain::New();
+    return (XDMFDOMAIN *)((void *)((XdmfItem *)(new XdmfDomain(*generatedDomain.get()))));
+  }
+}
+
+XDMFGRIDCOLLECTION * XdmfDomainGetGridCollection(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFGRIDCOLLECTION *)((void *)((XdmfItem *)(domainPointer->getGridCollection(index).get())));
+}
+
+XDMFGRIDCOLLECTION * XdmfDomainGetGridCollectionByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFGRIDCOLLECTION *)((void *)((XdmfItem *)(domainPointer->getGridCollection(Name).get())));
+}
+
+unsigned int XdmfDomainGetNumberGridCollections(XDMFDOMAIN * domain)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return domainPointer->getNumberGridCollections();
+}
+
+void XdmfDomainInsertGridCollection(XDMFDOMAIN * domain, XDMFGRIDCOLLECTION * GridCollection, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  if (passControl) {
+    domainPointer->insert(shared_ptr<XdmfGridCollection>((XdmfGridCollection *)GridCollection));
+  }
+  else {
+    domainPointer->insert(shared_ptr<XdmfGridCollection>((XdmfGridCollection *)GridCollection, XdmfNullDeleter()));
+  }
+}
+
+void XdmfDomainRemoveGridCollection(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeGridCollection(index);
+}
+
+void XdmfDomainRemoveGridCollectionByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeGridCollection(Name);
+}
+
+XDMFGRAPH * XdmfDomainGetGraph(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFGRAPH *)((void *)(domainPointer->getGraph(index).get()));
+}
+
+XDMFGRAPH * XdmfDomainGetGraphByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFGRAPH *)((void *)(domainPointer->getGraph(Name).get()));
+}
+
+unsigned int XdmfDomainGetNumberGraphs(XDMFDOMAIN * domain)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return domainPointer->getNumberGraphs();
+}
+
+void XdmfDomainInsertGraph(XDMFDOMAIN * domain, XDMFGRAPH * Graph, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  if (passControl) {
+    domainPointer->insert(shared_ptr<XdmfGraph>((XdmfGraph *)Graph));
+  }
+  else {
+    domainPointer->insert(shared_ptr<XdmfGraph>((XdmfGraph *)Graph, XdmfNullDeleter()));
+  }
+}
+
+void XdmfDomainRemoveGraph(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeGraph(index);
+}
+
+void XdmfDomainRemoveGraphByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeGraph(Name);
+}
+
+XDMFCURVILINEARGRID * XdmfDomainGetCurvilinearGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(domainPointer->getCurvilinearGrid(index).get())));
+}
+
+XDMFCURVILINEARGRID * XdmfDomainGetCurvilinearGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFCURVILINEARGRID *)((void *)((XdmfItem *)(domainPointer->getCurvilinearGrid(Name).get())));
+}
+
+unsigned int XdmfDomainGetNumberCurvilinearGrids(XDMFDOMAIN * domain)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return domainPointer->getNumberCurvilinearGrids();
+}
+
+void XdmfDomainInsertCurvilinearGrid(XDMFDOMAIN * domain, XDMFCURVILINEARGRID * CurvilinearGrid, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  if (passControl) {
+    domainPointer->insert(shared_ptr<XdmfCurvilinearGrid>((XdmfCurvilinearGrid *)CurvilinearGrid));
+  }
+  else {
+    domainPointer->insert(shared_ptr<XdmfCurvilinearGrid>((XdmfCurvilinearGrid *)CurvilinearGrid, XdmfNullDeleter()));
+  }
+}
+
+void XdmfDomainRemoveCurvilinearGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeCurvilinearGrid(index);
+}
+
+void XdmfDomainRemoveCurvilinearGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeCurvilinearGrid(Name);
+}
+
+XDMFRECTILINEARGRID * XdmfDomainGetRectilinearGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(domainPointer->getRectilinearGrid(index).get())));
+}
+
+XDMFRECTILINEARGRID * XdmfDomainGetRectilinearGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(domainPointer->getRectilinearGrid(Name).get())));
+}
+
+unsigned int XdmfDomainGetNumberRectilinearGrids(XDMFDOMAIN * domain)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return domainPointer->getNumberRectilinearGrids();
+}
+
+void XdmfDomainInsertRectilinearGrid(XDMFDOMAIN * domain, XDMFRECTILINEARGRID * RectilinearGrid, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  if (passControl) {
+    domainPointer->insert(shared_ptr<XdmfRectilinearGrid>((XdmfRectilinearGrid *)RectilinearGrid));
+  }
+  else {
+    domainPointer->insert(shared_ptr<XdmfRectilinearGrid>((XdmfRectilinearGrid *)RectilinearGrid, XdmfNullDeleter()));
+  }
+}
+
+void XdmfDomainRemoveRectilinearGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeRectilinearGrid(index);
+}
+
+void XdmfDomainRemoveRectilinearGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeRectilinearGrid(Name);
+}
+
+XDMFREGULARGRID * XdmfDomainGetRegularGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFREGULARGRID *)((void *)((XdmfItem *)(domainPointer->getRegularGrid(index).get())));
+}
+
+XDMFREGULARGRID * XdmfDomainGetRegularGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFREGULARGRID *)((void *)((XdmfItem *)(domainPointer->getRegularGrid(Name).get())));
+}
+
+unsigned int XdmfDomainGetNumberRegularGrids(XDMFDOMAIN * domain)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return domainPointer->getNumberRegularGrids();
+}
+
+void XdmfDomainInsertRegularGrid(XDMFDOMAIN * domain, XDMFREGULARGRID * RegularGrid, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  if (passControl) {
+    domainPointer->insert(shared_ptr<XdmfRegularGrid>((XdmfRegularGrid *)RegularGrid));
+  }
+  else {
+    domainPointer->insert(shared_ptr<XdmfRegularGrid>((XdmfRegularGrid *)RegularGrid, XdmfNullDeleter()));
+  }
+}
+
+void XdmfDomainRemoveRegularGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeRegularGrid(index);
+}
+
+void XdmfDomainRemoveRegularGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeRegularGrid(Name);
+}
+
+XDMFUNSTRUCTUREDGRID * XdmfDomainGetUnstructuredGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(domainPointer->getUnstructuredGrid(index).get())));
+}
+
+XDMFUNSTRUCTUREDGRID * XdmfDomainGetUnstructuredGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(domainPointer->getUnstructuredGrid(Name).get())));
+}
+
+unsigned int XdmfDomainGetNumberUnstructuredGrids(XDMFDOMAIN * domain)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  return domainPointer->getNumberUnstructuredGrids();
+}
+
+void XdmfDomainInsertUnstructuredGrid(XDMFDOMAIN * domain, XDMFUNSTRUCTUREDGRID * UnstructuredGrid, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  if (passControl) {
+    domainPointer->insert(shared_ptr<XdmfUnstructuredGrid>((XdmfUnstructuredGrid *)UnstructuredGrid));
+  }
+  else {
+    domainPointer->insert(shared_ptr<XdmfUnstructuredGrid>((XdmfUnstructuredGrid *)UnstructuredGrid, XdmfNullDeleter()));
+  }
+}
+
+void XdmfDomainRemoveUnstructuredGrid(XDMFDOMAIN * domain, unsigned int index)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeUnstructuredGrid(index);
+}
+
+void XdmfDomainRemoveUnstructuredGridByName(XDMFDOMAIN * domain, char * Name)
+{
+  XdmfItem * classedPointer = (XdmfItem *)domain;
+  XdmfDomain * domainPointer = dynamic_cast<XdmfDomain *>(classedPointer);
+  domainPointer->removeUnstructuredGrid(Name);
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfDomain, XDMFDOMAIN)
diff --git a/XdmfDomain.hpp b/XdmfDomain.hpp
new file mode 100644
index 0000000..cdcaecf
--- /dev/null
+++ b/XdmfDomain.hpp
@@ -0,0 +1,428 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDomain.hpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFDOMAIN_HPP_
+#define XDMFDOMAIN_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfGridCollection;
+
+/**
+ * @brief The root XdmfItem that holds XdmfGrids.
+ *
+ * XdmfDomain is the top XdmfItem in an Xdmf structure.  It can store
+ * a number of grids and provides methods to insert, retrieve, and
+ * remove these grids.
+ */
+class XDMF_EXPORT XdmfDomain : public virtual XdmfItem {
+
+public:
+
+  /**
+   * Create a new XdmfDomain.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDomain.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDomain.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfDomain.
+   */
+  static shared_ptr<XdmfDomain> New();
+
+  virtual ~XdmfDomain();
+
+  LOKI_DEFINE_VISITABLE(XdmfDomain, XdmfItem)
+  XDMF_CHILDREN(XdmfDomain, XdmfGridCollection, GridCollection, Name)
+  XDMF_CHILDREN(XdmfDomain, XdmfGraph, Graph, Name)
+  XDMF_CHILDREN(XdmfDomain, XdmfCurvilinearGrid, CurvilinearGrid, Name)
+  XDMF_CHILDREN(XdmfDomain, XdmfRectilinearGrid, RectilinearGrid, Name)
+  XDMF_CHILDREN(XdmfDomain, XdmfRegularGrid, RegularGrid, Name)
+  XDMF_CHILDREN(XdmfDomain, XdmfUnstructuredGrid, UnstructuredGrid, Name)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  using XdmfItem::insert;
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfDomain(XdmfDomain &);
+
+protected:
+
+  XdmfDomain();
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfDomain(const XdmfDomain &);  // Not implemented.
+  void operator=(const XdmfDomain &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFDOMAIN; // Simply as a typedef to ensure correct typing
+typedef struct XDMFDOMAIN XDMFDOMAIN;
+
+#ifndef XDMFGRIDCOLLECTIONCDEFINE
+#define XDMFGRIDCOLLECTIONCDEFINE
+struct XDMFGRIDCOLLECTION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRIDCOLLECTION XDMFGRIDCOLLECTION;
+#endif
+
+XDMF_EXPORT XDMFDOMAIN * XdmfDomainNew();
+
+XDMF_EXPORT XDMFGRIDCOLLECTION * XdmfDomainGetGridCollection(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT XDMFGRIDCOLLECTION * XdmfDomainGetGridCollectionByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT unsigned int XdmfDomainGetNumberGridCollections(XDMFDOMAIN * domain);
+
+XDMF_EXPORT void XdmfDomainInsertGridCollection(XDMFDOMAIN * domain, XDMFGRIDCOLLECTION * GridCollection, int passControl);
+
+XDMF_EXPORT void XdmfDomainRemoveGridCollection(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT void XdmfDomainRemoveGridCollectionByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT XDMFGRAPH * XdmfDomainGetGraph(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT XDMFGRAPH * XdmfDomainGetGraphByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT unsigned int XdmfDomainGetNumberGraphs(XDMFDOMAIN * domain);
+
+XDMF_EXPORT void XdmfDomainInsertGraph(XDMFDOMAIN * domain, XDMFGRAPH * graph, int passControl);
+
+XDMF_EXPORT void XdmfDomainRemoveGraph(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT void XdmfDomainRemoveGraphByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT XDMFCURVILINEARGRID * XdmfDomainGetCurvilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT XDMFCURVILINEARGRID * XdmfDomainGetCurvilinearGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT unsigned int XdmfDomainGetNumberCurvilinearGrids(XDMFDOMAIN * domain);
+
+XDMF_EXPORT void XdmfDomainInsertCurvilinearGrid(XDMFDOMAIN * domain, XDMFCURVILINEARGRID * CurvilinearGrid, int passControl);
+
+XDMF_EXPORT void XdmfDomainRemoveCurvilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT void XdmfDomainRemoveCurvilinearGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT XDMFRECTILINEARGRID * XdmfDomainGetRectilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT XDMFRECTILINEARGRID * XdmfDomainGetRectilinearGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT unsigned int XdmfDomainGetNumberRectilinearGrids(XDMFDOMAIN * domain);
+
+XDMF_EXPORT void XdmfDomainInsertRectilinearGrid(XDMFDOMAIN * domain, XDMFRECTILINEARGRID * RectilinearGrid, int passControl);
+
+XDMF_EXPORT void XdmfDomainRemoveRectilinearGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT void XdmfDomainRemoveRectilinearGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT XDMFREGULARGRID * XdmfDomainGetRegularGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT XDMFREGULARGRID * XdmfDomainGetRegularGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT unsigned int XdmfDomainGetNumberRegularGrids(XDMFDOMAIN * domain);
+
+XDMF_EXPORT void XdmfDomainInsertRegularGrid(XDMFDOMAIN * domain, XDMFREGULARGRID * RegularGrid, int passControl);
+
+XDMF_EXPORT void XdmfDomainRemoveRegularGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT void XdmfDomainRemoveRegularGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT XDMFUNSTRUCTUREDGRID * XdmfDomainGetUnstructuredGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT XDMFUNSTRUCTUREDGRID * XdmfDomainGetUnstructuredGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_EXPORT unsigned int XdmfDomainGetNumberUnstructuredGrids(XDMFDOMAIN * domain);
+
+XDMF_EXPORT void XdmfDomainInsertUnstructuredGrid(XDMFDOMAIN * domain, XDMFUNSTRUCTUREDGRID * UnstructuredGrid, int passControl);
+
+XDMF_EXPORT void XdmfDomainRemoveUnstructuredGrid(XDMFDOMAIN * domain, unsigned int index);
+
+XDMF_EXPORT void XdmfDomainRemoveUnstructuredGridByName(XDMFDOMAIN * domain, char * Name);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfDomain, XDMFDOMAIN, XDMF)
+
+#define XDMF_DOMAIN_C_CHILD_DECLARE(ClassName, CClassName, Level)                                                                     \
+                                                                                                                                      \
+Level##_EXPORT XDMFGRIDCOLLECTION * ClassName##GetGridCollection(CClassName * domain, unsigned int index);                            \
+Level##_EXPORT XDMFGRIDCOLLECTION * ClassName##GetGridCollectionByName(CClassName * domain, char * Name);                             \
+Level##_EXPORT unsigned int ClassName##GetNumberGridCollections(CClassName * domain);                                                 \
+Level##_EXPORT void ClassName##InsertGridCollection(CClassName * domain, XDMFGRIDCOLLECTION * GridCollection, int passControl);       \
+Level##_EXPORT void ClassName##RemoveGridCollection(CClassName * domain, unsigned int index);                                         \
+Level##_EXPORT void ClassName##RemoveGridCollectionByName(CClassName * domain, char * Name);                                          \
+Level##_EXPORT XDMFGRAPH * ClassName##GetGraph(CClassName * domain, unsigned int index);                                              \
+Level##_EXPORT XDMFGRAPH * ClassName##GetGraphByName(CClassName * domain, char * Name);                                               \
+Level##_EXPORT unsigned int ClassName##GetNumberGraphs(CClassName * domain);                                                          \
+Level##_EXPORT void ClassName##InsertGraph(CClassName * domain, XDMFGRAPH * Graph, int passControl);                                  \
+Level##_EXPORT void ClassName##RemoveGraph(CClassName * domain, unsigned int index);                                                  \
+Level##_EXPORT void ClassName##RemoveGraphByName(CClassName * domain, char * Name);                                                   \
+Level##_EXPORT XDMFCURVILINEARGRID * ClassName##GetCurvilinearGrid(CClassName * domain, unsigned int index);                          \
+Level##_EXPORT XDMFCURVILINEARGRID * ClassName##GetCurvilinearGridByName(CClassName * domain, char * Name);                           \
+Level##_EXPORT unsigned int ClassName##GetNumberCurvilinearGrids(CClassName * domain);                                                \
+Level##_EXPORT void ClassName##InsertCurvilinearGrid(CClassName * domain, XDMFCURVILINEARGRID * CurvilinearGrid, int passControl);    \
+Level##_EXPORT void ClassName##RemoveCurvilinearGrid(CClassName * domain, unsigned int index);                                        \
+Level##_EXPORT void ClassName##RemoveCurvilinearGridByName(CClassName * domain, char * Name);                                         \
+Level##_EXPORT XDMFRECTILINEARGRID * ClassName##GetRectilinearGrid(CClassName * domain, unsigned int index);                          \
+Level##_EXPORT XDMFRECTILINEARGRID * ClassName##GetRectilinearGridByName(CClassName * domain, char * Name);                           \
+Level##_EXPORT unsigned int ClassName##GetNumberRectilinearGrids(CClassName * domain);                                                \
+Level##_EXPORT void ClassName##InsertRectilinearGrid(CClassName * domain, XDMFRECTILINEARGRID * RectilinearGrid, int passControl);    \
+Level##_EXPORT void ClassName##RemoveRectilinearGrid(CClassName * domain, unsigned int index);                                        \
+Level##_EXPORT void ClassName##RemoveRectilinearGridByName(CClassName * domain, char * Name);                                         \
+Level##_EXPORT XDMFREGULARGRID * ClassName##GetRegularGrid(CClassName * domain, unsigned int index);                                  \
+Level##_EXPORT XDMFREGULARGRID * ClassName##GetRegularGridByName(CClassName * domain, char * Name);                                   \
+Level##_EXPORT unsigned int ClassName##GetNumberRegularGrids(CClassName * domain);                                                    \
+Level##_EXPORT void ClassName##InsertRegularGrid(CClassName * domain, XDMFREGULARGRID * RegularGrid, int passControl);                \
+Level##_EXPORT void ClassName##RemoveRegularGrid(CClassName * domain, unsigned int index);                                            \
+Level##_EXPORT void ClassName##RemoveRegularGridByName(CClassName * domain, char * Name);                                             \
+Level##_EXPORT XDMFUNSTRUCTUREDGRID * ClassName##GetUnstructuredGrid(CClassName * domain, unsigned int index);                        \
+Level##_EXPORT XDMFUNSTRUCTUREDGRID * ClassName##GetUnstructuredGridByName(CClassName * domain, char * Name);                         \
+Level##_EXPORT unsigned int ClassName##GetNumberUnstructuredGrids(CClassName * domain);                                               \
+Level##_EXPORT void ClassName##InsertUnstructuredGrid(CClassName * domain, XDMFUNSTRUCTUREDGRID * UnstructuredGrid, int passControl); \
+Level##_EXPORT void ClassName##RemoveUnstructuredGrid(CClassName * domain, unsigned int index);                                       \
+Level##_EXPORT void ClassName##RemoveUnstructuredGridByName(CClassName * domain, char * Name);
+
+
+#define XDMF_DOMAIN_C_CHILD_WRAPPER(ClassName, CClassName)                                                                            \
+                                                                                                                                      \
+XDMFGRIDCOLLECTION * ClassName##GetGridCollection(CClassName * domain, unsigned int index)                                            \
+{                                                                                                                                     \
+  return XdmfDomainGetGridCollection((XDMFDOMAIN *)((void *)domain), index);                                                          \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFGRIDCOLLECTION * ClassName##GetGridCollectionByName(CClassName * domain, char * Name)                                             \
+{                                                                                                                                     \
+  return XdmfDomainGetGridCollectionByName((XDMFDOMAIN *)((void *)domain), Name);                                                     \
+}                                                                                                                                     \
+                                                                                                                                      \
+unsigned int ClassName##GetNumberGridCollections(CClassName * domain)                                                                 \
+{                                                                                                                                     \
+  return XdmfDomainGetNumberGridCollections((XDMFDOMAIN *)((void *)domain));                                                          \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##InsertGridCollection(CClassName * domain, XDMFGRIDCOLLECTION * GridCollection, int passControl)                       \
+{                                                                                                                                     \
+  XdmfDomainInsertGridCollection((XDMFDOMAIN *)((void *)domain), GridCollection, passControl);                                        \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveGridCollection(CClassName * domain, unsigned int index)                                                         \
+{                                                                                                                                     \
+  XdmfDomainRemoveGridCollection((XDMFDOMAIN *)((void *)domain), index);                                                              \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveGridCollectionByName(CClassName * domain, char * Name)                                                          \
+{                                                                                                                                     \
+  XdmfDomainRemoveGridCollectionByName((XDMFDOMAIN *)((void *)domain), Name);                                                         \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFGRAPH * ClassName##GetGraph(CClassName * domain, unsigned int index)                                                              \
+{                                                                                                                                     \
+  return XdmfDomainGetGraph((XDMFDOMAIN *)((void *)domain), index);                                                                   \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFGRAPH * ClassName##GetGraphByName(CClassName * domain, char * Name)                                                               \
+{                                                                                                                                     \
+  return XdmfDomainGetGraphByName((XDMFDOMAIN *)((void *)domain), Name);                                                              \
+}                                                                                                                                     \
+                                                                                                                                      \
+unsigned int ClassName##GetNumberGraphs(CClassName * domain)                                                                          \
+{                                                                                                                                     \
+  return XdmfDomainGetNumberGraphs((XDMFDOMAIN *)((void *)domain));                                                                   \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##InsertGraph(CClassName * domain, XDMFGRAPH * Graph, int passControl)                                                  \
+{                                                                                                                                     \
+  XdmfDomainInsertGraph((XDMFDOMAIN *)((void *)domain), Graph, passControl);                                                          \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveGraph(CClassName * domain, unsigned int index)                                                                  \
+{                                                                                                                                     \
+  XdmfDomainRemoveGraph((XDMFDOMAIN *)((void *)domain), index);                                                                       \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveGraphByName(CClassName * domain, char * Name)                                                                   \
+{                                                                                                                                     \
+  XdmfDomainRemoveGraphByName((XDMFDOMAIN *)((void *)domain), Name);                                                                  \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFCURVILINEARGRID * ClassName##GetCurvilinearGrid(CClassName * domain, unsigned int index)                                          \
+{                                                                                                                                     \
+  return XdmfDomainGetCurvilinearGrid((XDMFDOMAIN *)((void *)domain), index);                                                         \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFCURVILINEARGRID * ClassName##GetCurvilinearGridByName(CClassName * domain, char * Name)                                           \
+{                                                                                                                                     \
+  return XdmfDomainGetCurvilinearGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                    \
+}                                                                                                                                     \
+                                                                                                                                      \
+unsigned int ClassName##GetNumberCurvilinearGrids(CClassName * domain)                                                                \
+{                                                                                                                                     \
+  return XdmfDomainGetNumberCurvilinearGrids((XDMFDOMAIN *)((void *)domain));                                                         \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##InsertCurvilinearGrid(CClassName * domain, XDMFCURVILINEARGRID * CurvilinearGrid, int passControl)                    \
+{                                                                                                                                     \
+  XdmfDomainInsertCurvilinearGrid((XDMFDOMAIN *)((void *)domain), CurvilinearGrid, passControl);                                      \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveCurvilinearGrid(CClassName * domain, unsigned int index)                                                        \
+{                                                                                                                                     \
+  XdmfDomainRemoveCurvilinearGrid((XDMFDOMAIN *)((void *)domain), index);                                                             \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveCurvilinearGridByName(CClassName * domain, char * Name)                                                         \
+{                                                                                                                                     \
+  XdmfDomainRemoveCurvilinearGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                        \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFRECTILINEARGRID * ClassName##GetRectilinearGrid(CClassName * domain, unsigned int index)                                          \
+{                                                                                                                                     \
+  return XdmfDomainGetRectilinearGrid((XDMFDOMAIN *)((void *)domain), index);                                                         \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFRECTILINEARGRID * ClassName##GetRectilinearGridByName(CClassName * domain, char * Name)                                           \
+{                                                                                                                                     \
+  return XdmfDomainGetRectilinearGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                    \
+}                                                                                                                                     \
+                                                                                                                                      \
+unsigned int ClassName##GetNumberRectilinearGrids(CClassName * domain)                                                                \
+{                                                                                                                                     \
+  return XdmfDomainGetNumberRectilinearGrids((XDMFDOMAIN *)((void *)domain));                                                         \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##InsertRectilinearGrid(CClassName * domain, XDMFRECTILINEARGRID * RectilinearGrid, int passControl)                    \
+{                                                                                                                                     \
+  XdmfDomainInsertRectilinearGrid((XDMFDOMAIN *)((void *)domain), RectilinearGrid, passControl);                                      \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveRectilinearGrid(CClassName * domain, unsigned int index)                                                        \
+{                                                                                                                                     \
+  XdmfDomainRemoveRectilinearGrid((XDMFDOMAIN *)((void *)domain), index);                                                             \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveRectilinearGridByName(CClassName * domain, char * Name)                                                         \
+{                                                                                                                                     \
+  XdmfDomainRemoveRectilinearGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                        \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFREGULARGRID * ClassName##GetRegularGrid(CClassName * domain, unsigned int index)                                                  \
+{                                                                                                                                     \
+  return XdmfDomainGetRegularGrid((XDMFDOMAIN *)((void *)domain), index);                                                             \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFREGULARGRID * ClassName##GetRegularGridByName(CClassName * domain, char * Name)                                                   \
+{                                                                                                                                     \
+  return XdmfDomainGetRegularGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                        \
+}                                                                                                                                     \
+                                                                                                                                      \
+unsigned int ClassName##GetNumberRegularGrids(CClassName * domain)                                                                    \
+{                                                                                                                                     \
+  return XdmfDomainGetNumberRegularGrids((XDMFDOMAIN *)((void *)domain));                                                             \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##InsertRegularGrid(CClassName * domain, XDMFREGULARGRID * RegularGrid, int passControl)                                \
+{                                                                                                                                     \
+  XdmfDomainInsertRegularGrid((XDMFDOMAIN *)((void *)domain), RegularGrid, passControl);                                              \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveRegularGrid(CClassName * domain, unsigned int index)                                                            \
+{                                                                                                                                     \
+  XdmfDomainRemoveRegularGrid((XDMFDOMAIN *)((void *)domain), index);                                                                 \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveRegularGridByName(CClassName * domain, char * Name)                                                             \
+{                                                                                                                                     \
+  XdmfDomainRemoveRegularGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                            \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFUNSTRUCTUREDGRID * ClassName##GetUnstructuredGrid(CClassName * domain, unsigned int index)                                        \
+{                                                                                                                                     \
+  return XdmfDomainGetUnstructuredGrid((XDMFDOMAIN *)((void *)domain), index);                                                        \
+}                                                                                                                                     \
+                                                                                                                                      \
+XDMFUNSTRUCTUREDGRID * ClassName##GetUnstructuredGridByName(CClassName * domain, char * Name)                                         \
+{                                                                                                                                     \
+  return XdmfDomainGetUnstructuredGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                   \
+}                                                                                                                                     \
+                                                                                                                                      \
+unsigned int ClassName##GetNumberUnstructuredGrids(CClassName * domain)                                                               \
+{                                                                                                                                     \
+  return XdmfDomainGetNumberUnstructuredGrids((XDMFDOMAIN *)((void *)domain));                                                        \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##InsertUnstructuredGrid(CClassName * domain, XDMFUNSTRUCTUREDGRID * UnstructuredGrid, int passControl)                 \
+{                                                                                                                                     \
+  XdmfDomainInsertUnstructuredGrid((XDMFDOMAIN *)((void *)domain), UnstructuredGrid, passControl);                                    \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveUnstructuredGrid(CClassName * domain, unsigned int index)                                                       \
+{                                                                                                                                     \
+  XdmfDomainRemoveUnstructuredGrid((XDMFDOMAIN *)((void *)domain), index);                                                            \
+}                                                                                                                                     \
+                                                                                                                                      \
+void ClassName##RemoveUnstructuredGridByName(CClassName * domain, char * Name)                                                        \
+{                                                                                                                                     \
+  XdmfDomainRemoveUnstructuredGridByName((XDMFDOMAIN *)((void *)domain), Name);                                                       \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFDOMAIN_HPP_ */
diff --git a/XdmfGeometry.cpp b/XdmfGeometry.cpp
new file mode 100644
index 0000000..44fcfd4
--- /dev/null
+++ b/XdmfGeometry.cpp
@@ -0,0 +1,353 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGeometry.cpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfFunction.hpp"
+#include <boost/tokenizer.hpp>
+
+shared_ptr<XdmfGeometry> XdmfGeometry::New()
+{
+  shared_ptr<XdmfGeometry> p(new XdmfGeometry());
+  return p;
+}
+
+XdmfGeometry::XdmfGeometry() :
+  XdmfArray(),
+  mNumberPoints(0),
+  mType(XdmfGeometryType::NoGeometryType())
+{
+}
+
+XdmfGeometry::XdmfGeometry(XdmfGeometry & refGeometry) :
+  XdmfArray(refGeometry),
+  mType(refGeometry.mType),
+  mOrigin(refGeometry.mOrigin)
+{
+}
+
+XdmfGeometry::~XdmfGeometry()
+{
+}
+
+const std::string XdmfGeometry::ItemTag = "Geometry";
+
+std::map<std::string, std::string>
+XdmfGeometry::getItemProperties() const
+{
+  std::map<std::string, std::string> geometryProperties;
+  mType->getProperties(geometryProperties);
+  std::stringstream originstream;
+  for (unsigned int i = 0; i < mOrigin.size(); ++i) {
+    originstream << mOrigin[i];
+    if (i + 1 < mOrigin.size()) {
+      originstream << " ";
+    }
+  }
+  geometryProperties["Origin"] = originstream.str();
+  return geometryProperties;
+}
+
+std::string
+XdmfGeometry::getItemTag() const
+{
+  return ItemTag;
+}
+
+unsigned int
+XdmfGeometry::getNumberPoints() const
+{
+  if(mType->getDimensions() == 0) {
+    return 0;
+  }
+  else {
+    return this->getSize() / mType->getDimensions();
+  }
+}
+
+std::vector<double>
+XdmfGeometry::getOrigin() const
+{
+  std::vector<double> returnVector(mOrigin);
+  return returnVector;
+}
+
+shared_ptr<const XdmfGeometryType>
+XdmfGeometry::getType() const
+{
+  return mType;
+}
+
+void
+XdmfGeometry::populateItem(const std::map<std::string, std::string> & itemProperties,
+                           const std::vector<shared_ptr<XdmfItem> > & childItems,
+                           const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("Type");
+  if(type == itemProperties.end()) {
+    type = itemProperties.find("GeometryType");
+  }
+
+  if (type != itemProperties.end()) {
+    if(type->second.compare("X_Y_Z") == 0) {
+      mType = XdmfGeometryType::XYZ();
+
+      // Building Function equivalent
+      std::vector<std::string> dimensionIDVector;
+      dimensionIDVector.push_back("X");
+      dimensionIDVector.push_back("Y");
+      dimensionIDVector.push_back("Z");
+
+      std::map<std::string, shared_ptr<XdmfArray> > dimensionMap;
+
+      unsigned int dimensionIDIndex = 0;
+
+      // Find X, Y, and Z Arrays
+      for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+            childItems.begin();
+          iter != childItems.end() && dimensionIDIndex < dimensionIDVector.size();
+          ++iter) {
+        if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+          dimensionMap[dimensionIDVector[dimensionIDIndex]] = array;
+          dimensionIDIndex++;
+        }
+      }
+
+      shared_ptr<XdmfFunction> geoFunction = XdmfFunction::New("X#Y#Z", dimensionMap);
+
+      this->setReference(geoFunction);
+      this->setReadMode(XdmfArray::Reference);
+    }
+    else if(type->second.compare("X_Y") == 0) {
+      mType = XdmfGeometryType::XY();
+
+      // Building Function equivalent
+      std::vector<std::string> dimensionIDVector;
+      dimensionIDVector.push_back("X");
+      dimensionIDVector.push_back("Y");
+
+      std::map<std::string, shared_ptr<XdmfArray> > dimensionMap;
+
+      unsigned int dimensionIDIndex = 0;
+
+      // Find X, Y, and Z Arrays
+      for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+            childItems.begin();
+          iter != childItems.end() && dimensionIDIndex < dimensionIDVector.size();
+          ++iter) {
+        if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+          dimensionMap[dimensionIDVector[dimensionIDIndex]] = array;
+          dimensionIDIndex++;
+        }
+      }
+
+      shared_ptr<XdmfFunction> geoFunction = XdmfFunction::New("X#Y", dimensionMap);
+
+      this->setReference(geoFunction);
+      this->setReadMode(XdmfArray::Reference);
+    }
+    else {
+      mType = XdmfGeometryType::New(itemProperties);
+      for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+            childItems.begin();
+          iter != childItems.end();
+          ++iter) {
+        if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+          this->swap(array);
+          if (array->getReference()) {
+            this->setReference(array->getReference());
+            this->setReadMode(XdmfArray::Reference);
+          }
+          break;
+        }
+      }
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Neither 'Type' nor 'GeometryType' in itemProperties "
+                       "in XdmfGeometry::populateItem");
+  }
+
+  std::map<std::string, std::string>::const_iterator origin =
+    itemProperties.find("Origin");
+  if (origin != itemProperties.end()) {
+    boost::tokenizer<> tokens(origin->second);
+    for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+        iter != tokens.end();
+        ++iter) {
+      mOrigin.push_back(atof((*iter).c_str()));
+    }
+  }
+}
+
+void
+XdmfGeometry::setOrigin(double newX, double newY, double newZ)
+{
+  mOrigin.clear();
+  mOrigin.push_back(newX);
+  mOrigin.push_back(newY);
+  mOrigin.push_back(newZ);
+  this->setIsChanged(true);
+}
+
+void
+XdmfGeometry::setOrigin(std::vector<double> newOrigin)
+{
+  mOrigin.clear();
+  for (unsigned int i = 0; i < newOrigin.size(); ++i) {
+    mOrigin.push_back(newOrigin[i]);
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfGeometry::setType(const shared_ptr<const XdmfGeometryType> type)
+{
+  mType = type;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFGEOMETRY * XdmfGeometryNew()
+{
+  try
+  {
+    shared_ptr<XdmfGeometry> generatedGeometry = XdmfGeometry::New();
+    return (XDMFGEOMETRY *)((void *)(new XdmfGeometry(*generatedGeometry.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfGeometry> generatedGeometry = XdmfGeometry::New();
+    return (XDMFGEOMETRY *)((void *)(new XdmfGeometry(*generatedGeometry.get())));
+  }
+}
+
+unsigned int XdmfGeometryGetNumberPoints(XDMFGEOMETRY * geometry)
+{
+  return ((XdmfGeometry *) geometry)->getNumberPoints();
+}
+
+double *
+XdmfGeometryGetOrigin(XDMFGEOMETRY * geometry)
+{
+  try
+  {
+    std::vector<double> tempVector = ((XdmfGeometry *)(geometry))->getOrigin();
+    unsigned int returnSize = tempVector.size();
+    double * returnArray = new double[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<double> tempVector = ((XdmfGeometry *)(geometry))->getOrigin();
+    unsigned int returnSize = tempVector.size();
+    double * returnArray = new double[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+int
+XdmfGeometryGetOriginSize(XDMFGEOMETRY * geometry)
+{
+  return ((XdmfGeometry *) geometry)->getOrigin().size();
+}
+
+int XdmfGeometryGetType(XDMFGEOMETRY * geometry)
+{
+  if (((XdmfGeometry *) geometry)->getType() == XdmfGeometryType::NoGeometryType()) {
+    return XDMF_GEOMETRY_TYPE_NO_GEOMETRY_TYPE;
+  }
+  else if (((XdmfGeometry *) geometry)->getType() == XdmfGeometryType::XYZ()) {
+    return XDMF_GEOMETRY_TYPE_XYZ;
+  }
+  else if (((XdmfGeometry *) geometry)->getType() == XdmfGeometryType::XY()) {
+    return XDMF_GEOMETRY_TYPE_XY;
+  }
+  else if (((XdmfGeometry *) geometry)->getType() == XdmfGeometryType::Polar()) {
+    return XDMF_GEOMETRY_TYPE_POLAR;
+  }
+  else if (((XdmfGeometry *) geometry)->getType() == XdmfGeometryType::Spherical()) {
+    return XDMF_GEOMETRY_TYPE_SPHERICAL;
+  }
+  else {
+    return -1;
+  }
+}
+
+void
+XdmfGeometrySetOrigin(XDMFGEOMETRY * geometry, double newX, double newY, double newZ)
+{
+  ((XdmfGeometry *) geometry)->setOrigin(newX, newY, newZ);
+}
+
+void
+XdmfGeometrySetOriginArray(XDMFGEOMETRY * geometry, double * originVals, unsigned int numDims)
+{
+  std::vector<double> originVector;
+  for (unsigned int i = 0; i < numDims; ++i)
+  {
+    originVector.push_back(originVals[i]);
+  }
+  ((XdmfGeometry *) geometry)->setOrigin(originVector);
+}
+
+void XdmfGeometrySetType(XDMFGEOMETRY * geometry, int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (type) {
+    case XDMF_GEOMETRY_TYPE_NO_GEOMETRY_TYPE:
+      ((XdmfGeometry *) geometry)->setType(XdmfGeometryType::NoGeometryType());
+      break;
+    case XDMF_GEOMETRY_TYPE_XYZ:
+      ((XdmfGeometry *) geometry)->setType(XdmfGeometryType::XYZ());
+      break;
+    case XDMF_GEOMETRY_TYPE_XY:
+      ((XdmfGeometry *) geometry)->setType(XdmfGeometryType::XY());
+      break;
+    case XDMF_GEOMETRY_TYPE_POLAR:
+      ((XdmfGeometry *) geometry)->setType(XdmfGeometryType::Polar());
+      break;
+    case XDMF_GEOMETRY_TYPE_SPHERICAL:
+      ((XdmfGeometry *) geometry)->setType(XdmfGeometryType::Spherical());
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Geometry Type: Code " + type);
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfGeometry, XDMFGEOMETRY)
+XDMF_ARRAY_C_CHILD_WRAPPER(XdmfGeometry, XDMFGEOMETRY)
diff --git a/XdmfGeometry.hpp b/XdmfGeometry.hpp
new file mode 100644
index 0000000..8cd97cd
--- /dev/null
+++ b/XdmfGeometry.hpp
@@ -0,0 +1,260 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGeometry.hpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGEOMETRY_HPP_
+#define XDMFGEOMETRY_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometryType.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Handles the coordinate positions of points in an XdmfGrid.
+ *
+ * XdmfGeometry is a required part of an XdmfGrid. It stores the
+ * coordinate locations of all points contained in an
+ * XdmfGrid. XdmfGeometry contains an XdmfGeometryType property which
+ * should be set that specifies the types of coordinate values stored.
+ */
+class XDMF_EXPORT XdmfGeometry : public XdmfArray {
+
+public:
+
+  /**
+   * Create a new XdmfGeometry.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometry.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometry.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfGeometry.
+   */
+  static shared_ptr<XdmfGeometry> New();
+
+  virtual ~XdmfGeometry();
+
+  LOKI_DEFINE_VISITABLE(XdmfGeometry, XdmfArray)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the number of points stored in this geometry.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometry.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getNumberPoints
+   * @until //#getNumberPoints
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometry.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getNumberPoints
+   * @until #//getNumberPoints
+   */
+  virtual unsigned int getNumberPoints() const;
+
+  /**
+   * Gets the origin of the geometry. This value defaults to (0, 0, 0)
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometry.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getOrigin
+   * @until //#getOrigin
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometry.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getOrigin
+   * @until #//getOrigin
+   *
+   * @return    A vector containing the current location
+   *            of the origin of this geometry
+   */
+  std::vector<double> getOrigin() const;
+
+  /**
+   * Get the XdmfGeometryType associated with this geometry.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometry.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getType
+   * @until //#getType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometry.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getType
+   * @until #//getType
+   *
+   * @return    XdmfGeometryType of this geometry.
+   */
+  shared_ptr<const XdmfGeometryType> getType() const;
+
+  /**
+   * Sets the origin of the geometry.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometry.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setOrigin
+   * @until //#setOrigin
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometry.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setOrigin
+   * @until #//setOrigin
+   *
+   * @param     newX    The new X value of the origin.
+   * @param     newY    The new Y value of the origin.
+   * @param     newZ    The new Z value of the origin.
+   */
+  void setOrigin(double newX, double newY, double newZ = 0.0);
+
+  void setOrigin(std::vector<double> newOrigin);
+
+  /**
+   * Set the XdmfGeometryType associated with this geometry.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometry.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setType
+   * @until //#setType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometry.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setType
+   * @until #//setType
+   *
+   * @param     type    The XdmfGeometryType to set.
+   */
+  void setType(const shared_ptr<const XdmfGeometryType> type);
+
+  XdmfGeometry(XdmfGeometry &);
+
+protected:
+
+  XdmfGeometry();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfGeometry(const XdmfGeometry &);  // Not implemented.
+  void operator=(const XdmfGeometry &);  // Not implemented.
+
+  int mNumberPoints;
+  shared_ptr<const XdmfGeometryType> mType;
+
+  std::vector<double> mOrigin;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFGEOMETRY; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGEOMETRY XDMFGEOMETRY; 
+
+XDMF_EXPORT XDMFGEOMETRY * XdmfGeometryNew();
+
+XDMF_EXPORT unsigned int XdmfGeometryGetNumberPoints(XDMFGEOMETRY * geometry);
+
+XDMF_EXPORT double * XdmfGeometryGetOrigin(XDMFGEOMETRY * geometry);
+
+XDMF_EXPORT int XdmfGeometryGetOriginSize(XDMFGEOMETRY * geometry);
+
+XDMF_EXPORT int XdmfGeometryGetType(XDMFGEOMETRY * geometry);
+
+XDMF_EXPORT void XdmfGeometrySetOrigin(XDMFGEOMETRY * geometry, double newX, double newY, double newZ);
+
+XDMF_EXPORT void XdmfGeometrySetOriginArray(XDMFGEOMETRY * geometry, double * originVals, unsigned int numDims);
+
+XDMF_EXPORT void XdmfGeometrySetType(XDMFGEOMETRY * geometry, int type, int * status);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfGeometry, XDMFGEOMETRY, XDMF)
+XDMF_ARRAY_C_CHILD_DECLARE(XdmfGeometry, XDMFGEOMETRY, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFGEOMETRY_HPP_ */
diff --git a/XdmfGeometryType.cpp b/XdmfGeometryType.cpp
new file mode 100644
index 0000000..f6a8c54
--- /dev/null
+++ b/XdmfGeometryType.cpp
@@ -0,0 +1,239 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGeometryType.cpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfGeometryType.hpp"
+#include "XdmfError.hpp"
+#include "string.h"
+
+std::map<std::string, shared_ptr<const XdmfGeometryType>(*)()> XdmfGeometryType::mGeometryDefinitions;
+
+// Supported XdmfGeometryTypes
+shared_ptr<const XdmfGeometryType>
+XdmfGeometryType::NoGeometryType()
+{
+  static shared_ptr<const XdmfGeometryType> p(new XdmfGeometryType("None", 0));
+  return p;
+}
+
+shared_ptr<const XdmfGeometryType>
+XdmfGeometryType::XYZ()
+{
+  static shared_ptr<const XdmfGeometryType> p(new XdmfGeometryType("XYZ", 3));
+  return p;
+}
+
+shared_ptr<const XdmfGeometryType>
+XdmfGeometryType::XY()
+{
+  static shared_ptr<const XdmfGeometryType> p(new XdmfGeometryType("XY", 2));
+  return p;
+}
+
+shared_ptr<const XdmfGeometryType>
+XdmfGeometryType::Polar()
+{
+  static shared_ptr<const XdmfGeometryType> p(new XdmfGeometryType("Polar", 2));
+  return p;
+}
+
+shared_ptr<const XdmfGeometryType>
+XdmfGeometryType::Spherical()
+{
+  static shared_ptr<const XdmfGeometryType> p(new XdmfGeometryType("Spherical", 3));
+  return p;
+}
+
+void
+XdmfGeometryType::InitTypes()
+{
+  mGeometryDefinitions["NONE"] = NoGeometryType;
+  mGeometryDefinitions["XYZ"] = XYZ;
+  mGeometryDefinitions["XY"] = XY;
+  mGeometryDefinitions["POLAR"] = Polar;
+  mGeometryDefinitions["SPHERICAL"] = Spherical;
+}
+
+XdmfGeometryType::XdmfGeometryType(const std::string& name,
+                                   const int& dimensions) :
+  mDimensions(dimensions),
+  mName(name)
+{
+}
+
+XdmfGeometryType::~XdmfGeometryType()
+{
+}
+
+shared_ptr<const XdmfGeometryType>
+XdmfGeometryType::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("Type");
+  if(type == itemProperties.end()) {
+    type = itemProperties.find("GeometryType");
+  }
+  if(type == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL, 
+                       "Neither 'Type' nor 'GeometryType' in itemProperties "
+                       "in XdmfGeometryType::New");
+  }
+
+  const std::string & typeVal = ConvertToUpper(type->second);
+
+  std::map<std::string, shared_ptr<const XdmfGeometryType>(*)()>::const_iterator returnType 
+    = mGeometryDefinitions.find(typeVal);
+
+  if (returnType == mGeometryDefinitions.end()) {
+    XdmfError::message(XdmfError::FATAL, "Type "
+                     + typeVal + " not Supported "
+                     "in XdmfGeometryType::New");
+  }
+  else {
+    return (*(returnType->second))();
+  }
+
+  return shared_ptr<const XdmfGeometryType>();
+}
+
+unsigned int
+XdmfGeometryType::getDimensions() const
+{
+  return mDimensions;
+}
+
+std::string
+XdmfGeometryType::getName() const
+{
+  return mName;
+}
+
+void
+XdmfGeometryType::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("Type", mName));
+}
+
+// C Wrappers
+
+int XdmfGeometryTypeNoGeometryType()
+{
+  return XDMF_GEOMETRY_TYPE_NO_GEOMETRY_TYPE;
+}
+
+int XdmfGeometryTypeXYZ()
+{
+  return XDMF_GEOMETRY_TYPE_XYZ;
+}
+
+int XdmfGeometryTypeXY()
+{
+  return XDMF_GEOMETRY_TYPE_XY;
+}
+
+int XdmfGeometryTypePolar()
+{
+  return XDMF_GEOMETRY_TYPE_POLAR;
+}
+
+int XdmfGeometryTypeSpherical()
+{
+  return XDMF_GEOMETRY_TYPE_SPHERICAL;
+}
+
+unsigned int XdmfGeometryTypeGetDimensions(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (type) {
+    case XDMF_GEOMETRY_TYPE_NO_GEOMETRY_TYPE:
+      return XdmfGeometryType::NoGeometryType()->getDimensions();
+      break;
+    case XDMF_GEOMETRY_TYPE_XYZ:
+      return XdmfGeometryType::XYZ()->getDimensions();
+      break;
+    case XDMF_GEOMETRY_TYPE_XY:
+      return XdmfGeometryType::XY()->getDimensions();
+      break;
+    case XDMF_GEOMETRY_TYPE_POLAR:
+      return XdmfGeometryType::Polar()->getDimensions();
+      break;
+    case XDMF_GEOMETRY_TYPE_SPHERICAL:
+      return XdmfGeometryType::Spherical()->getDimensions();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Geometry Type: Code " + type);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+char * XdmfGeometryTypeGetName(int type)
+{
+  switch (type) {
+    case XDMF_GEOMETRY_TYPE_NO_GEOMETRY_TYPE:
+    {
+      char * returnPointer = strdup(XdmfGeometryType::NoGeometryType()->getName().c_str());
+      return returnPointer;
+      break;
+    }
+    case XDMF_GEOMETRY_TYPE_XYZ:
+    {
+      char * returnPointer = strdup(XdmfGeometryType::XYZ()->getName().c_str());
+      return returnPointer;
+      break;
+    }
+    case XDMF_GEOMETRY_TYPE_XY:
+    {
+      char * returnPointer = strdup(XdmfGeometryType::XY()->getName().c_str());
+      return returnPointer;
+      break;
+    }
+    case XDMF_GEOMETRY_TYPE_POLAR:
+    {
+      char * returnPointer = strdup(XdmfGeometryType::Polar()->getName().c_str());
+      return returnPointer;
+      break;
+    }
+    case XDMF_GEOMETRY_TYPE_SPHERICAL:
+    {
+      char * returnPointer = strdup(XdmfGeometryType::Spherical()->getName().c_str());
+      return returnPointer;
+      break;
+    }
+    default:
+    {
+      char * returnPointer = NULL;
+      return returnPointer;
+      break;
+    }
+  }
+}
diff --git a/XdmfGeometryType.hpp b/XdmfGeometryType.hpp
new file mode 100644
index 0000000..fa6e429
--- /dev/null
+++ b/XdmfGeometryType.hpp
@@ -0,0 +1,190 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGeometryType.hpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGEOMETRYTYPE_HPP_
+#define XDMFGEOMETRYTYPE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include "XdmfItemProperty.hpp"
+#include <map>
+
+/**
+ * @brief Property describing the types of coordinate values stored in
+ * an XdmfGeometry.
+ *
+ * XdmfGeometryType is a property used by XdmfGeometry to specify the
+ * type of coordinate values stored in the XdmfGeometry. A specific
+ * XdmfGeometryType can be created by calling one of the static
+ * methods in the class, i.e.  XdmfAttributeType::XYZ().
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfGeometryType.cpp
+ * @skipline //#initialization
+ * @until //#initialization
+ * @skipline //#getType
+ * @until //#getType
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleGeometryType.py
+ * @skipline #//getType
+ * @until #//getType
+ *
+ * Xdmf supports the following geometry types:
+ *   NoGeometryType
+ *   XYZ
+ *   XY
+ *   Polar
+ *   Spherical
+ *
+ * The Polar and Spherical types consist of a series of coordinates.
+ * These coordinates are in order of: radius, polar, azimuthal. 
+ * In accordance with the ISO standard.
+ *
+ */
+class XDMF_EXPORT XdmfGeometryType : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfGeometryType();
+
+  friend class XdmfGeometry;
+
+  // Supported Xdmf Geometry Types
+  static shared_ptr<const XdmfGeometryType> NoGeometryType();
+  static shared_ptr<const XdmfGeometryType> XYZ();
+  static shared_ptr<const XdmfGeometryType> XY();
+  static shared_ptr<const XdmfGeometryType> Polar();
+  static shared_ptr<const XdmfGeometryType> Spherical();
+
+  /**
+   * Get the dimensions of this geometry type - i.e. XYZ = 3.
+   *
+   * Example of use:
+   * 
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometryType.cpp
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometryType.py
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    An int containing number of dimensions.
+   */
+  virtual unsigned int getDimensions() const;
+
+  /**
+   * Get the name of this geometry type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGeometryType.cpp
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGeometryType.py
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    The name of this geometry type.
+   */
+  std::string getName() const;
+
+  virtual void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+protected:
+
+  /**
+   * Protected constructor for XdmfGeometryType.  The constructor is
+   * protected because all geometry types supported by Xdmf should be
+   * accessed through more specific static methods that construct
+   * XdmfGeometryTypes - i.e.  XdmfGeometryType::XYZ().
+   *
+   * @param name a std::string containing the name of the geometry type..
+   * @param dimensions an int containing the dimensions of the geometry type.
+   */
+  XdmfGeometryType(const std::string & name, const int & dimensions);
+
+  static std::map<std::string, shared_ptr<const XdmfGeometryType>(*)()> mGeometryDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfGeometryType(const XdmfGeometryType &); // Not implemented.
+  void operator=(const XdmfGeometryType &); // Not implemented.
+
+  static shared_ptr<const XdmfGeometryType>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  unsigned int mDimensions;
+  std::string mName;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#define XDMF_GEOMETRY_TYPE_NO_GEOMETRY_TYPE 300
+#define XDMF_GEOMETRY_TYPE_XYZ              301
+#define XDMF_GEOMETRY_TYPE_XY               302
+#define XDMF_GEOMETRY_TYPE_POLAR            303
+#define XDMF_GEOMETRY_TYPE_SPHERICAL        304
+
+XDMF_EXPORT int XdmfGeometryTypeNoGeometryType();
+XDMF_EXPORT int XdmfGeometryTypeXYZ();
+XDMF_EXPORT int XdmfGeometryTypeXY();
+XDMF_EXPORT int XdmfGeometryTypePolar();
+XDMF_EXPORT int XdmfGeometryTypeSpherical();
+
+XDMF_EXPORT unsigned int XdmfGeometryTypeGetDimensions(int type, int * status);
+
+XDMF_EXPORT char * XdmfGeometryTypeGetName(int type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFGEOMETRYTYPE_HPP_ */
diff --git a/XdmfGraph.cpp b/XdmfGraph.cpp
new file mode 100644
index 0000000..fc3ae23
--- /dev/null
+++ b/XdmfGraph.cpp
@@ -0,0 +1,175 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGraph.cpp                                                       */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfAttribute.hpp"
+#include "XdmfGraph.hpp"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfGraph, XdmfAttribute, Attribute, Name)
+
+shared_ptr<XdmfGraph>
+XdmfGraph::New(const unsigned int numberNodes)
+{
+  shared_ptr<XdmfGraph> p(new XdmfGraph(numberNodes));
+  return p;
+}
+
+XdmfGraph::XdmfGraph(const unsigned int numberNodes) :
+  XdmfSparseMatrix(numberNodes,
+                   numberNodes),
+  mTime(shared_ptr<XdmfTime>())
+{
+}
+
+XdmfGraph::XdmfGraph(XdmfGraph & refGraph) :
+  XdmfSparseMatrix(refGraph),
+  mAttributes(refGraph.mAttributes),
+  mTime(refGraph.mTime)
+{
+}
+
+XdmfGraph::~XdmfGraph()
+{
+}
+
+const std::string XdmfGraph::ItemTag = "Graph";
+
+std::string
+XdmfGraph::getItemTag() const
+{
+  return ItemTag;
+}
+
+shared_ptr<XdmfTime>
+XdmfGraph::getTime()
+{
+  return boost::const_pointer_cast<XdmfTime>
+    (static_cast<const XdmfGraph &>(*this).getTime());
+}
+
+shared_ptr<const XdmfTime>
+XdmfGraph::getTime() const
+{
+  return mTime;
+}
+
+unsigned int
+XdmfGraph::getNumberNodes() const
+{
+  // The number of nodes is equal to the number of rows or columns. Either will work.
+  return this->getNumberRows();
+}
+
+void
+XdmfGraph::populateItem(const std::map<std::string, std::string> & itemProperties,
+                        const std::vector<shared_ptr<XdmfItem> > & childItems,
+                        const XdmfCoreReader * const reader)
+{
+  XdmfSparseMatrix::populateItem(itemProperties,
+                                 childItems,
+                                 reader);
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfAttribute> attribute =
+       shared_dynamic_cast<XdmfAttribute>(*iter)) {
+      this->insert(attribute);
+    }
+  }
+}
+
+void
+XdmfGraph::setTime(const shared_ptr<XdmfTime> time)
+{
+  mTime = time;
+  this->setIsChanged(true);
+}
+
+void
+XdmfGraph::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfSparseMatrix::traverse(visitor);
+  for (unsigned int i = 0; i < mAttributes.size(); ++i)
+  {
+    mAttributes[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+XDMFGRAPH * XdmfGraphNew(unsigned int numberNodes)
+{
+  try
+  {
+    shared_ptr<XdmfGraph> generatedGraph = XdmfGraph::New(numberNodes);
+    return (XDMFGRAPH *)((void *)(new XdmfGraph(*generatedGraph.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfGraph> generatedGraph = XdmfGraph::New(numberNodes);
+    return (XDMFGRAPH *)((void *)(new XdmfGraph(*generatedGraph.get())));
+  }
+}
+
+XDMFATTRIBUTE * XdmfGraphGetAttribute(XDMFGRAPH * graph, unsigned int index)
+{
+  return (XDMFATTRIBUTE *)((void *)(((XdmfGraph *)(graph))->getAttribute(index).get()));
+}
+
+XDMFATTRIBUTE * XdmfGraphGetAttributeByName(XDMFGRAPH * graph, char * Name)
+{
+  return (XDMFATTRIBUTE *)((void *)(((XdmfGraph *)(graph))->getAttribute(std::string(Name)).get()));
+}
+
+unsigned int XdmfGraphGetNumberAttributes(XDMFGRAPH * graph)
+{
+  return ((XdmfGraph *)graph)->getNumberAttributes();
+}
+
+void XdmfGraphInsertAttribute(XDMFGRAPH * graph, XDMFATTRIBUTE * Attribute, int passControl)
+{
+  if (passControl) {
+    ((XdmfGraph *)(graph))->insert(shared_ptr<XdmfAttribute>((XdmfAttribute *)Attribute));
+  }
+  else {
+    ((XdmfGraph *)(graph))->insert(shared_ptr<XdmfAttribute>((XdmfAttribute *)Attribute, XdmfNullDeleter()));
+  }
+}
+
+void XdmfGraphRemoveAttribute(XDMFGRAPH * graph, unsigned int index)
+{
+  ((XdmfGraph *)graph)->removeAttribute(index);
+}
+
+void XdmfGraphRemoveAttributeByName(XDMFGRAPH * graph, char * Name)
+{
+  ((XdmfGraph *)graph)->removeAttribute(std::string(Name));
+}
+
+unsigned int XdmfGraphGetNumberNodes(XDMFGRAPH * graph)
+{
+  return ((XdmfGraph *)graph)->getNumberNodes();
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfGraph, XDMFGRAPH)
+XDMF_SPARSEMATRIX_C_CHILD_WRAPPER(XdmfGraph, XDMFGRAPH)
diff --git a/XdmfGraph.hpp b/XdmfGraph.hpp
new file mode 100644
index 0000000..f06dac1
--- /dev/null
+++ b/XdmfGraph.hpp
@@ -0,0 +1,141 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGraph.hpp                                                       */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGRAPH_HPP_
+#define XDMFGRAPH_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfSparseMatrix.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Graph stored in sparse matrix form.
+ *
+ * Stores graph information in sparse matrix form. Attributes defining
+ * node and edge information can be inserted.
+ */
+class XDMF_EXPORT XdmfGraph : public XdmfSparseMatrix {
+
+public:
+
+  /**
+   * Create a new XdmfGraph.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGraph.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGraph.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param numberNodes number of nodes in graph.
+   *
+   * @return    Constructed XdmfGraph.
+   */
+  static shared_ptr<XdmfGraph> New(const unsigned int numberNodes);
+
+  virtual ~XdmfGraph();
+
+  LOKI_DEFINE_VISITABLE(XdmfGraph, XdmfSparseMatrix)
+  XDMF_CHILDREN(XdmfGraph, XdmfAttribute, Attribute, Name)
+  static const std::string ItemTag;
+
+  std::string getItemTag() const;
+
+  shared_ptr<XdmfTime> getTime();
+
+  shared_ptr<const XdmfTime> getTime() const;
+
+  unsigned int getNumberNodes() const;
+
+  using XdmfSparseMatrix::insert;
+
+  void setTime(const shared_ptr<XdmfTime> time);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfGraph(XdmfGraph &);
+
+protected:
+
+  XdmfGraph(const unsigned int numberNodes);
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfGraph(const XdmfGraph &);  // Not implemented.
+  void operator=(const XdmfGraph &);  // Not implemented.
+
+  shared_ptr<XdmfTime> mTime;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFGRAPH; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRAPH XDMFGRAPH;
+
+XDMF_EXPORT XDMFGRAPH * XdmfGraphNew(unsigned int numberNodes);
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfGraphGetAttribute(XDMFGRAPH * graph, unsigned int index);
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfGraphGetAttributeByName(XDMFGRAPH * graph, char * Name);
+
+XDMF_EXPORT unsigned int XdmfGraphGetNumberAttributes(XDMFGRAPH * graph);
+
+XDMF_EXPORT void XdmfGraphInsertAttribute(XDMFGRAPH * graph, XDMFATTRIBUTE * Attribute, int passControl);
+
+XDMF_EXPORT void XdmfGraphRemoveAttribute(XDMFGRAPH * graph, unsigned int index);
+
+XDMF_EXPORT void XdmfGraphRemoveAttributeByName(XDMFGRAPH * graph, char * Name);
+
+XDMF_EXPORT unsigned int XdmfGraphGetNumberNodes(XDMFGRAPH * graph);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfGraph, XDMFGRAPH, XDMF)
+XDMF_SPARSEMATRIX_C_CHILD_DECLARE(XdmfGraph, XDMFGRAPH, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFGRAPH_HPP_ */
diff --git a/XdmfGrid.cpp b/XdmfGrid.cpp
new file mode 100644
index 0000000..1b992d8
--- /dev/null
+++ b/XdmfGrid.cpp
@@ -0,0 +1,518 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGrid.cpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include <string.h>
+#include "XdmfAttribute.hpp"
+#include "XdmfError.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfTopology.hpp"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfGrid, XdmfAttribute, Attribute, Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfGrid, XdmfMap, Map, Name)
+XDMF_CHILDREN_IMPLEMENTATION(XdmfGrid, XdmfSet, Set, Name)
+
+XdmfGrid::XdmfGrid(const shared_ptr<XdmfGeometry> geometry,
+                   const shared_ptr<XdmfTopology> topology,
+                   const std::string & name) :
+  mGeometry(geometry),
+  mTopology(topology),
+  mName(name),
+  mTime(shared_ptr<XdmfTime>())
+{
+}
+
+XdmfGrid::XdmfGrid(XdmfGrid &refGrid):
+  XdmfItem(refGrid),
+  mAttributes(refGrid.mAttributes),
+  mSets(refGrid.mSets),
+  mMaps(refGrid.mMaps),
+  mGeometry(refGrid.mGeometry),
+  mTopology(refGrid.mTopology),
+  mName(refGrid.mName),
+  mTime(refGrid.mTime)
+{
+  XdmfGridImpl * holder = refGrid.mImpl;
+  XdmfGridImpl * duplicateImpl = holder->duplicate();
+  mImpl = duplicateImpl;
+}
+
+XdmfGrid::~XdmfGrid()
+{
+}
+
+const std::string XdmfGrid::ItemTag = "Grid";
+
+shared_ptr<XdmfGridController>
+XdmfGrid::getGridController()
+{
+  return mGridController;
+}
+
+void
+XdmfGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
+{
+  this->setName(sourceGrid->getName());
+  this->setTime(sourceGrid->getTime());
+  while(this->getNumberAttributes() > 0)
+  {
+    this->removeAttribute(0);
+  }
+  for (unsigned int i = 0; i < sourceGrid->getNumberAttributes(); ++i)
+  {
+    this->insert(sourceGrid->getAttribute(i));
+  }
+  while(this->getNumberInformations() > 0)
+  {
+    this->removeInformation(0);
+  }
+  for (unsigned int i = 0; i < sourceGrid->getNumberInformations(); ++i)
+  {
+    this->insert(sourceGrid->getInformation(i));
+  }
+  while(this->getNumberSets() > 0)
+  {
+    this->removeSet(0);
+  }
+  for (unsigned int i = 0; i < sourceGrid->getNumberSets(); ++i)
+  {
+    this->insert(sourceGrid->getSet(i));
+  }
+  while(this->getNumberMaps() > 0)
+  {
+    this->removeMap(0);
+  }
+  for (unsigned int i = 0; i < sourceGrid->getNumberMaps(); ++i)
+  {
+    this->insert(sourceGrid->getMap(i));
+  }
+}
+
+shared_ptr<const XdmfGeometry>
+XdmfGrid::getGeometry() const
+{
+  return mGeometry;
+}
+
+std::map<std::string, std::string>
+XdmfGrid::getItemProperties() const
+{
+  std::map<std::string, std::string> gridProperties;
+  gridProperties.insert(std::make_pair("Name", mName));
+  return gridProperties;
+}
+
+std::string
+XdmfGrid::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfGrid::getName() const
+{
+    return mName;
+}
+
+shared_ptr<XdmfTime>
+XdmfGrid::getTime()
+{
+  return boost::const_pointer_cast<XdmfTime>
+    (static_cast<const XdmfGrid &>(*this).getTime());
+}
+
+shared_ptr<const XdmfTime>
+XdmfGrid::getTime() const
+{
+  return mTime;
+}
+
+shared_ptr<const XdmfTopology>
+XdmfGrid::getTopology() const
+{
+  return mTopology;
+}
+
+void
+XdmfGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
+                       const std::vector<shared_ptr<XdmfItem> > & childItems,
+                       const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  std::map<std::string, std::string>::const_iterator name =
+    itemProperties.find("Name");
+  if(name != itemProperties.end()) {
+    mName = name->second;
+  }
+  else {
+    mName = "";
+  }
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfAttribute> attribute =
+       shared_dynamic_cast<XdmfAttribute>(*iter)) {
+      this->insert(attribute);
+    }
+    else if(shared_ptr<XdmfGeometry> geometry =
+            shared_dynamic_cast<XdmfGeometry>(*iter)) {
+      mGeometry = geometry;
+    }
+    else if(shared_ptr<XdmfMap> map =
+            shared_dynamic_cast<XdmfMap>(*iter)) {
+      this->insert(map);
+    }
+    else if(shared_ptr<XdmfSet> set =
+            shared_dynamic_cast<XdmfSet>(*iter)) {
+      this->insert(set);
+    }
+    else if(shared_ptr<XdmfTime> time =
+            shared_dynamic_cast<XdmfTime>(*iter)) {
+      mTime = time;
+    }
+    else if(shared_ptr<XdmfTopology> topology =
+            shared_dynamic_cast<XdmfTopology>(*iter)) {
+      mTopology = topology;
+    }
+    else if(shared_ptr<XdmfGridController> gridController =
+            shared_dynamic_cast<XdmfGridController>(*iter)) {
+      this->setGridController(gridController);
+    }
+  }
+}
+
+void
+XdmfGrid::read()
+{
+
+}
+
+void
+XdmfGrid::release()
+{
+  this->setName("");
+  this->setTime(shared_ptr<XdmfTime>());
+  while(this->getNumberAttributes() > 0)
+  {
+    this->removeAttribute(0);
+  }
+  while(this->getNumberInformations() > 0)
+  {
+    this->removeInformation(0);
+  }
+  while(this->getNumberSets() > 0)
+  {
+    this->removeSet(0);
+  }
+  while(this->getNumberMaps() > 0)
+  {
+    this->removeMap(0);
+  }
+}
+
+void
+XdmfGrid::setGridController(shared_ptr<XdmfGridController> newController)
+{
+  mGridController = newController;
+}
+
+
+void
+XdmfGrid::setName(const std::string & name)
+{
+  mName = name;
+  this->setIsChanged(true);
+}
+
+void
+XdmfGrid::setTime(const shared_ptr<XdmfTime> time)
+{
+  mTime = time;
+  this->setIsChanged(true);
+}
+
+void
+XdmfGrid::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+  if (mGridController) {
+    mGridController->accept(visitor);
+  }
+  if(mTime) {
+    mTime->accept(visitor);
+  }
+  if(mGeometry) {
+    mGeometry->accept(visitor);
+  }
+  if(mTopology) {
+    mTopology->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mAttributes.size(); ++i)
+  {
+    mAttributes[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mMaps.size(); ++i)
+  {
+    mMaps[i]->accept(visitor);
+  }
+  for (unsigned int i = 0; i < mSets.size(); ++i)
+  {
+    mSets[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+XDMFATTRIBUTE * XdmfGridGetAttribute(XDMFGRID * grid, unsigned int index)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return (XDMFATTRIBUTE *)((void *)(gridPointer->getAttribute(index).get()));
+}
+
+XDMFATTRIBUTE * XdmfGridGetAttributeByName(XDMFGRID * grid, char * Name)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return (XDMFATTRIBUTE *)((void *)(gridPointer->getAttribute(Name).get()));
+}
+
+unsigned int XdmfGridGetNumberAttributes(XDMFGRID * grid)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return gridPointer->getNumberAttributes();
+}
+
+void XdmfGridInsertAttribute(XDMFGRID * grid, XDMFATTRIBUTE * Attribute, int passControl)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  if (passControl) {
+    gridPointer->insert(shared_ptr<XdmfAttribute>((XdmfAttribute *)Attribute));
+  }
+  else {
+    gridPointer->insert(shared_ptr<XdmfAttribute>((XdmfAttribute *)Attribute, XdmfNullDeleter()));
+  }
+}
+
+void XdmfGridRemoveAttribute(XDMFGRID * grid, unsigned int index)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->removeAttribute(index);
+}
+
+void XdmfGridRemoveAttributeByName(XDMFGRID * grid, char * Name)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->removeAttribute(Name);
+}
+
+XDMFSET * XdmfGridGetSet(XDMFGRID * grid, unsigned int index)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return (XDMFSET *)((void *)(gridPointer->getSet(index).get()));
+}
+
+XDMFSET * XdmfGridGetSetByName(XDMFGRID * grid, char * Name)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return (XDMFSET *)((void *)(gridPointer->getSet(Name).get()));
+}
+
+unsigned int XdmfGridGetNumberSets(XDMFGRID * grid)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return gridPointer->getNumberSets();
+}
+
+void XdmfGridInsertSet(XDMFGRID * grid, XDMFSET * Set, int passControl)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  if (passControl) {
+    gridPointer->insert(shared_ptr<XdmfSet>((XdmfSet *)Set));
+  }
+  else {
+    gridPointer->insert(shared_ptr<XdmfSet>((XdmfSet *)Set, XdmfNullDeleter()));
+  }
+}
+
+void XdmfGridRemoveSet(XDMFGRID * grid, unsigned int index)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->removeSet(index);
+}
+
+void XdmfGridRemoveSetByName(XDMFGRID * grid, char * Name)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->removeSet(Name);
+}
+
+XDMFMAP * XdmfGridGetMap(XDMFGRID * grid, unsigned int index)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return (XDMFMAP *)((void *)(gridPointer->getMap(index).get()));
+}
+
+XDMFMAP * XdmfGridGetMapByName(XDMFGRID * grid, char * Name)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return (XDMFMAP *)((void *)(gridPointer->getMap(Name).get()));
+}
+
+unsigned int XdmfGridGetNumberMaps(XDMFGRID * grid)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return gridPointer->getNumberMaps();
+}
+
+void XdmfGridInsertMap(XDMFGRID * grid, XDMFMAP * Map, int passControl)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  if (passControl) {
+    gridPointer->insert(shared_ptr<XdmfMap>((XdmfMap *)Map));
+  }
+  else {
+    gridPointer->insert(shared_ptr<XdmfMap>((XdmfMap *)Map, XdmfNullDeleter()));
+  }
+}
+
+void XdmfGridRemoveMap(XDMFGRID * grid, unsigned int index)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->removeMap(index);
+}
+
+void XdmfGridRemoveMapByName(XDMFGRID * grid, char * Name)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->removeMap(Name);
+}
+
+XDMFGRIDCONTROLLER * XdmfGridGetGridController(XDMFGRID * grid)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+  shared_ptr<XdmfGridController> generatedController = gridPointer->getGridController();
+  return (XDMFGRIDCONTROLLER *)((void *)(generatedController.get()));
+
+}
+
+char * XdmfGridGetName(XDMFGRID * grid)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  return strdup(gridPointer->getName().c_str());
+}
+
+XDMFTIME * XdmfGridGetTime(XDMFGRID * grid)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+  shared_ptr<XdmfTime> generatedTime = gridPointer->getTime();
+  return (XDMFTIME *)((void *)(generatedTime.get()));
+}
+
+void
+XdmfGridRead(XDMFGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+    gridPointer->read();
+  }
+  catch (...)
+  {
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+    gridPointer->read();
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfGridRelease(XDMFGRID * grid)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+  gridPointer->release();
+}
+
+void XdmfGridSetGridController(XDMFGRID * grid, XDMFGRIDCONTROLLER * controller, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+  XdmfItem * controllerPointer = (XdmfItem *) controller;
+  XdmfGridController * classedController = dynamic_cast<XdmfGridController *>(controllerPointer);
+  if (passControl) {
+    gridPointer->setGridController(shared_ptr<XdmfGridController>(classedController));
+  }
+  else {
+    gridPointer->setGridController(shared_ptr<XdmfGridController>(classedController, XdmfNullDeleter()));
+  }
+}
+
+void XdmfGridSetName(XDMFGRID * grid, char * name, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * tempPointer = (XdmfItem *)(grid);
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(tempPointer);
+  gridPointer->setName(name);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfGridSetTime(XDMFGRID * grid, XDMFTIME * time, int passControl)
+{
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfGrid * gridPointer = dynamic_cast<XdmfGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setTime(shared_ptr<XdmfTime>((XdmfTime *)time));
+  }
+  else {
+    gridPointer->setTime(shared_ptr<XdmfTime>((XdmfTime *)time, XdmfNullDeleter()));
+  }
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfGrid, XDMFGRID)
diff --git a/XdmfGrid.hpp b/XdmfGrid.hpp
new file mode 100644
index 0000000..04c25fc
--- /dev/null
+++ b/XdmfGrid.hpp
@@ -0,0 +1,649 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGrid.hpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGRID_HPP_
+#define XDMFGRID_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGridController.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfSet.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfSubGrid;
+class XdmfTime;
+
+/**
+ * @brief A mesh containing elements, points, and fields attached to
+ * the mesh.
+ *
+ * XdmfGrid represents a mesh. It is required to contain two other
+ * Xdmf data structures, an XdmfGeometry that stores point locations
+ * and an XdmfTopology that store connectivity
+ * information. XdmfAttributes can be inserted into the XdmfGrid to
+ * specify fields centered on various parts of the mesh.  XdmfSets can
+ * be inserted into XdmfGrids to specify collections of mesh elements.
+ *
+ * XdmfGrid is an abstract base class. There are several
+ * implementations for representing both structured and unstructured
+ * grids.
+ */
+class XDMF_EXPORT XdmfGrid : public virtual XdmfItem {
+
+public:
+
+  virtual ~XdmfGrid();
+
+  LOKI_DEFINE_VISITABLE(XdmfGrid, XdmfItem)
+  XDMF_CHILDREN(XdmfGrid, XdmfAttribute, Attribute, Name)
+  XDMF_CHILDREN(XdmfGrid, XdmfSet, Set, Name)
+  XDMF_CHILDREN(XdmfGrid, XdmfMap, Map, Name)
+  static const std::string ItemTag;
+
+  /**
+   * Get the geometry associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getGeometry
+   * @until //#getGeometry
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getGeometry
+   * @until #//getGeometry
+   *
+   * @return    The geometry associated with this grid.
+   */
+  virtual shared_ptr<const XdmfGeometry> getGeometry() const;
+
+  /**
+   * Gets the current external reference for this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGridController
+   * @until //#setGridController
+   * @skipline //#getGridController
+   * @until //#getGridController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGridController
+   * @until #//setGridController
+   * @skipline #//getGridController
+   * @until #//getGridController
+   *
+   * @return    The current reference.
+   */
+  shared_ptr<XdmfGridController> getGridController();
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  /**
+   * Get the name of the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    The name of the grid.
+   */
+  std::string getName() const;
+
+  /**
+   * Get the time associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setTime
+   * @until //#setTime
+   * @skipline //#getTime
+   * @until //#getTime
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setTime
+   * @until #//setTime
+   * @skipline #//getTime
+   * @until #//getTime
+   *
+   * @return    Pointer to the XdmfTime attached to this grid. If no
+   *            XdmfTime is attached, return a NULL pointer.
+   */
+  virtual shared_ptr<XdmfTime> getTime();
+
+  /**
+   * Get the time associated with this grid (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setTime
+   * @until //#setTime
+   * @skipline //#getTimeconst
+   * @until //#getTimeconst
+   *
+   * Python: Python doesn't have a constant version
+   * 
+   * @return    Pointer to the XdmfTime attached to this grid. If no
+   *            XdmfTime is attached, return a NULL pointer.
+   */
+  virtual shared_ptr<const XdmfTime> getTime() const;
+
+  /**
+   * Get the topology associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getTopology
+   * @until //#getTopology
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getTopology
+   * @until #//getTopology
+   *
+   * @return    The topology associated with this grid.
+   */
+  virtual shared_ptr<const XdmfTopology> getTopology() const;
+
+  using XdmfItem::insert;
+
+  /**
+   * Reads the tree structure fromt he grid controller set to this grid
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//read
+   * @until #//read
+   */
+  virtual void read();
+
+  /**
+   * Releases the grid structure that this grid contains.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#release
+   * @until //#release
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//release
+   * @until #//release
+   */
+  virtual void release();
+
+  /**
+   * Sets the reference to an external xdmf tree from which to populate the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGridController
+   * @until //#setGridController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGridController
+   * @until #//setGridController
+   *
+   * @param     newController   A reference to the external tree.
+   */
+  void setGridController(shared_ptr<XdmfGridController> newController);
+
+  /**
+   * Set the name of the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   *
+   * @param     name    Name of the grid to set.
+   */
+  void setName(const std::string & name);
+
+  /**
+   * Set the time associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setTime
+   * @until //#setTime
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setTime
+   * @until #//setTime
+   *
+   * @param     time    An XdmfTime to associate with this grid.
+   */
+  virtual void setTime(const shared_ptr<XdmfTime> time);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfGrid(XdmfGrid &);
+
+protected:
+
+  XdmfGrid(const shared_ptr<XdmfGeometry> geometry,
+           const shared_ptr<XdmfTopology> topology,
+           const std::string & name = "Grid");
+
+  virtual void
+  copyGrid(shared_ptr<XdmfGrid> sourceGrid);
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+  shared_ptr<XdmfGeometry> mGeometry;
+  shared_ptr<XdmfTopology> mTopology;
+
+  class XdmfGridImpl
+  {
+    public:
+    XdmfGridImpl()
+    {
+    }
+
+    ~XdmfGridImpl()
+    {
+    }
+
+    virtual XdmfGridImpl * duplicate() = 0;
+
+    std::string getGridType() const
+    {
+      return mGridType;
+    }
+
+    std::string mGridType;
+  };
+
+  XdmfGridImpl * mImpl;
+
+  shared_ptr<XdmfGridController> mGridController;
+
+private:
+
+  XdmfGrid(const XdmfGrid &);  // Not implemented.
+  void operator=(const XdmfGrid &);  // Not implemented.
+
+  std::string mName;
+  shared_ptr<XdmfTime> mTime;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#ifndef XDMFGRIDCDEFINE
+#define XDMFGRIDCDEFINE
+struct XDMFGRID; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRID XDMFGRID;
+#endif
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfGridGetAttribute(XDMFGRID * grid, unsigned int index);
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfGridGetAttributeByName(XDMFGRID * grid, char * Name);
+
+XDMF_EXPORT unsigned int XdmfGridGetNumberAttributes(XDMFGRID * grid);
+
+XDMF_EXPORT void XdmfGridInsertAttribute(XDMFGRID * grid, XDMFATTRIBUTE * Attribute, int passControl);
+
+XDMF_EXPORT void XdmfGridRemoveAttribute(XDMFGRID * grid, unsigned int index);
+
+XDMF_EXPORT void XdmfGridRemoveAttributeByName(XDMFGRID * grid, char * Name);
+
+XDMF_EXPORT XDMFSET * XdmfGridGetSet(XDMFGRID * grid, unsigned int index);
+
+XDMF_EXPORT XDMFSET * XdmfGridGetSetByName(XDMFGRID * grid, char * Name);
+
+XDMF_EXPORT unsigned int XdmfGridGetNumberSets(XDMFGRID * grid);
+
+XDMF_EXPORT void XdmfGridInsertSet(XDMFGRID * grid, XDMFSET * Set, int passControl);
+
+XDMF_EXPORT void XdmfGridRemoveSet(XDMFGRID * grid, unsigned int index);
+
+XDMF_EXPORT void XdmfGridRemoveSetByName(XDMFGRID * grid, char * Name);
+
+XDMF_EXPORT XDMFMAP * XdmfGridGetMap(XDMFGRID * grid, unsigned int index);
+
+XDMF_EXPORT XDMFMAP * XdmfGridGetMapByName(XDMFGRID * grid, char * Name);
+
+XDMF_EXPORT unsigned int XdmfGridGetNumberMaps(XDMFGRID * grid); 
+
+XDMF_EXPORT void XdmfGridInsertMap(XDMFGRID * grid, XDMFMAP * Map, int passControl);
+
+XDMF_EXPORT void XdmfGridRemoveMap(XDMFGRID * grid, unsigned int index);
+
+XDMF_EXPORT void XdmfGridRemoveMapByName(XDMFGRID * grid, char * Name);
+
+XDMF_EXPORT XDMFGRIDCONTROLLER * XdmfGridGetGridController(XDMFGRID * grid);
+
+XDMF_EXPORT char * XdmfGridGetName(XDMFGRID * grid);
+
+XDMF_EXPORT XDMFTIME * XdmfGridGetTime(XDMFGRID * grid);
+
+XDMF_EXPORT void XdmfGridRead(XDMFGRID * grid, int * status);
+
+XDMF_EXPORT void XdmfGridRelease(XDMFGRID * grid);
+
+XDMF_EXPORT void XdmfGridSetGridController(XDMFGRID * grid, XDMFGRIDCONTROLLER * controller, int passControl);
+
+XDMF_EXPORT void XdmfGridSetName(XDMFGRID * grid, char * name, int * status);
+
+XDMF_EXPORT void XdmfGridSetTime(XDMFGRID * grid, XDMFTIME * time, int passControl);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfGrid, XDMFGRID, XDMF)
+
+#define XDMF_GRID_C_CHILD_DECLARE(ClassName, CClassName, Level)                                                        \
+                                                                                                                       \
+Level##_EXPORT XDMFATTRIBUTE * ClassName##GetAttribute(CClassName * grid, unsigned int index);                         \
+Level##_EXPORT XDMFATTRIBUTE * ClassName##GetAttributeByName(CClassName * grid, char * Name);                          \
+Level##_EXPORT unsigned int ClassName##GetNumberAttributes(CClassName * grid);                                         \
+Level##_EXPORT void ClassName##InsertAttribute(CClassName * grid, XDMFATTRIBUTE * Attribute, int passControl);         \
+Level##_EXPORT void ClassName##RemoveAttribute(CClassName * grid, unsigned int index);                                 \
+Level##_EXPORT void ClassName##RemoveAttributeByName(CClassName * grid, char * Name);                                  \
+Level##_EXPORT XDMFSET * ClassName##GetSet(CClassName * grid, unsigned int index);                                     \
+Level##_EXPORT XDMFSET * ClassName##GetSetByName(CClassName * grid, char * Name);                                      \
+Level##_EXPORT unsigned int ClassName##GetNumberSets(CClassName * grid);                                               \
+Level##_EXPORT void ClassName##InsertSet(CClassName * grid, XDMFSET * Set, int passControl);                           \
+Level##_EXPORT void ClassName##RemoveSet(CClassName * grid, unsigned int index);                                       \
+Level##_EXPORT void ClassName##RemoveSetByName(CClassName * grid, char * Name);                                        \
+Level##_EXPORT XDMFMAP * ClassName##GetMap(CClassName * grid, unsigned int index);                                     \
+Level##_EXPORT XDMFMAP * ClassName##GetMapByName(CClassName * grid, char * Name);                                      \
+Level##_EXPORT unsigned int ClassName##GetNumberMaps(CClassName * grid);                                               \
+Level##_EXPORT void ClassName##InsertMap(CClassName * grid, XDMFMAP * Map, int passControl);                           \
+Level##_EXPORT void ClassName##RemoveMap(CClassName * grid, unsigned int index);                                       \
+Level##_EXPORT void ClassName##RemoveMapByName(CClassName * grid, char * Name);                                        \
+Level##_EXPORT XDMFGRIDCONTROLLER * ClassName##GetGridController(CClassName * grid);                                   \
+Level##_EXPORT char * ClassName##GetName(CClassName * grid);                                                           \
+Level##_EXPORT XDMFTIME * ClassName##GetTime(CClassName * grid);                                                       \
+Level##_EXPORT void ClassName##Read( CClassName * grid, int * status);                                                 \
+Level##_EXPORT void ClassName##Release( CClassName * grid);                                                            \
+Level##_EXPORT void ClassName##SetGridController(CClassName * grid, XDMFGRIDCONTROLLER * controller, int passControl); \
+Level##_EXPORT void ClassName##SetName(CClassName * grid, char * name, int * status);                                  \
+Level##_EXPORT void ClassName##SetTime(CClassName * grid, XDMFTIME * time, int passControl);
+
+
+
+#define XDMF_GRID_C_CHILD_WRAPPER(ClassName, CClassName)                                                       \
+XDMFATTRIBUTE * ClassName##GetAttribute(CClassName * grid, unsigned int index)                                 \
+{                                                                                                              \
+  return XdmfGridGetAttribute((XDMFGRID *)((void *)grid), index);                                              \
+}                                                                                                              \
+                                                                                                               \
+XDMFATTRIBUTE * ClassName##GetAttributeByName(CClassName * grid, char * Name)                                  \
+{                                                                                                              \
+  return XdmfGridGetAttributeByName((XDMFGRID *)((void *)grid), Name);                                         \
+}                                                                                                              \
+                                                                                                               \
+unsigned int ClassName##GetNumberAttributes(CClassName * grid)                                                 \
+{                                                                                                              \
+  return XdmfGridGetNumberAttributes((XDMFGRID *)((void *)grid));                                              \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##InsertAttribute(CClassName * grid, XDMFATTRIBUTE * Attribute, int passControl)                 \
+{                                                                                                              \
+  XdmfGridInsertAttribute((XDMFGRID *)((void *)grid), Attribute, passControl);                                 \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##RemoveAttribute(CClassName * grid, unsigned int index)                                         \
+{                                                                                                              \
+  XdmfGridRemoveAttribute((XDMFGRID *)((void *)grid), index);                                                  \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##RemoveAttributeByName(CClassName * grid, char * Name)                                          \
+{                                                                                                              \
+  XdmfGridRemoveAttributeByName((XDMFGRID *)((void *)grid), Name);                                             \
+}                                                                                                              \
+                                                                                                               \
+XDMFSET * ClassName##GetSet(CClassName * grid, unsigned int index)                                             \
+{                                                                                                              \
+  return XdmfGridGetSet((XDMFGRID *)((void *)grid), index);                                                    \
+}                                                                                                              \
+                                                                                                               \
+XDMFSET * ClassName##GetSetByName(CClassName * grid, char * Name)                                              \
+{                                                                                                              \
+  return XdmfGridGetSetByName((XDMFGRID *)((void *)grid), Name);                                               \
+}                                                                                                              \
+                                                                                                               \
+unsigned int ClassName##GetNumberSets(CClassName * grid)                                                       \
+{                                                                                                              \
+  return XdmfGridGetNumberSets((XDMFGRID *)((void *)grid));                                                    \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##InsertSet(CClassName * grid, XDMFSET * Set, int passControl)                                   \
+{                                                                                                              \
+  XdmfGridInsertSet((XDMFGRID *)((void *)grid), Set, passControl);                                             \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##RemoveSet(CClassName * grid, unsigned int index)                                               \
+{                                                                                                              \
+  XdmfGridRemoveSet((XDMFGRID *)((void *)grid), index);                                                        \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##RemoveSetByName(CClassName * grid, char * Name)                                                \
+{                                                                                                              \
+  XdmfGridRemoveSetByName((XDMFGRID *)((void *)grid), Name);                                                   \
+}                                                                                                              \
+                                                                                                               \
+XDMFMAP * ClassName##GetMap(CClassName * grid, unsigned int index)                                             \
+{                                                                                                              \
+  return XdmfGridGetMap((XDMFGRID *)((void *)grid), index);                                                    \
+}                                                                                                              \
+                                                                                                               \
+XDMFMAP * ClassName##GetMapByName(CClassName * grid, char * Name)                                              \
+{                                                                                                              \
+  return XdmfGridGetMapByName((XDMFGRID *)((void *)grid), Name);                                               \
+}                                                                                                              \
+                                                                                                               \
+unsigned int ClassName##GetNumberMaps(CClassName * grid)                                                       \
+{                                                                                                              \
+  return XdmfGridGetNumberMaps((XDMFGRID *)((void *)grid));                                                    \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##InsertMap(CClassName * grid, XDMFMAP * Map, int passControl)                                   \
+{                                                                                                              \
+  XdmfGridInsertMap((XDMFGRID *)((void *)grid), Map, passControl);                                             \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##RemoveMap(CClassName * grid, unsigned int index)                                               \
+{                                                                                                              \
+  XdmfGridRemoveMap((XDMFGRID *)((void *)grid), index);                                                        \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##RemoveMapByName(CClassName * grid, char * Name)                                                \
+{                                                                                                              \
+  XdmfGridRemoveMapByName((XDMFGRID *)((void *)grid), Name);                                                   \
+}                                                                                                              \
+                                                                                                               \
+XDMFGRIDCONTROLLER * ClassName##GetGridController(CClassName * grid)                                           \
+{                                                                                                              \
+  return XdmfGridGetGridController((XDMFGRID *)((void *)grid));                                                \
+}                                                                                                              \
+                                                                                                               \
+char * ClassName##GetName(CClassName * grid)                                                                   \
+{                                                                                                              \
+  return XdmfGridGetName((XDMFGRID *)((void *)grid));                                                          \
+}                                                                                                              \
+                                                                                                               \
+XDMFTIME * ClassName##GetTime(CClassName * grid)                                                               \
+{                                                                                                              \
+  return XdmfGridGetTime((XDMFGRID *)((void *)grid));                                                          \
+}                                                                                                              \
+                                                                                                               \
+void                                                                                                           \
+ClassName##Read( CClassName * grid, int * status)                                                              \
+{                                                                                                              \
+  XdmfGridRead((XDMFGRID *)((void *)grid), status);                                                            \
+}                                                                                                              \
+                                                                                                               \
+void                                                                                                           \
+ClassName##Release( CClassName * grid)                                                                         \
+{                                                                                                              \
+  XdmfGridRelease((XDMFGRID *)((void *)grid));                                                                 \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##SetGridController(CClassName * grid, XDMFGRIDCONTROLLER * controller, int passControl)         \
+{                                                                                                              \
+  XdmfGridSetGridController((XDMFGRID *)((void *)grid), controller, passControl);                              \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##SetName(CClassName * grid, char * name, int * status)                                          \
+{                                                                                                              \
+  XdmfGridSetName((XDMFGRID *)((void *)grid), name, status);                                                   \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##SetTime(CClassName * grid, XDMFTIME * time, int passControl)                                   \
+{                                                                                                              \
+  XdmfGridSetTime((XDMFGRID *)((void *)grid), time, passControl);                                              \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFGRID_HPP_ */
diff --git a/XdmfGridCollection.cpp b/XdmfGridCollection.cpp
new file mode 100644
index 0000000..e4eef6b
--- /dev/null
+++ b/XdmfGridCollection.cpp
@@ -0,0 +1,405 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGridCollection.cpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfError.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+
+class XdmfGridCollection::XdmfGridCollectionImpl : public XdmfGridImpl
+{
+  public:
+  XdmfGridCollectionImpl()
+  {
+    mGridType = "Collection";
+  }
+
+  ~XdmfGridCollectionImpl()
+  {
+  }
+
+  XdmfGridImpl * duplicate()
+  {
+    return new XdmfGridCollectionImpl();
+  }
+
+  std::string getGridType() const
+  {
+    return mGridType;
+  }
+};
+
+shared_ptr<XdmfGridCollection>
+XdmfGridCollection::New()
+{
+  shared_ptr<XdmfGridCollection> p(new XdmfGridCollection());
+  return p;
+}
+
+XdmfGridCollection::XdmfGridCollection() :
+  XdmfDomain(),
+  XdmfGrid(shared_ptr<XdmfGeometry>(), shared_ptr<XdmfTopology>(), "Collection"),
+  mType(XdmfGridCollectionType::NoCollectionType())
+{
+    mImpl = new XdmfGridCollectionImpl();
+}
+
+XdmfGridCollection::XdmfGridCollection(XdmfGridCollection & refCollection) :
+  XdmfDomain(refCollection),
+  XdmfGrid(refCollection),
+  mType(refCollection.mType)
+{
+}
+
+XdmfGridCollection::~XdmfGridCollection()
+{
+  if (mImpl) {
+    delete mImpl;
+  }
+  mImpl = NULL;
+}
+
+const std::string XdmfGridCollection::ItemTag = "Grid";
+
+void
+XdmfGridCollection::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
+{
+  XdmfGrid::copyGrid(sourceGrid);
+  if (shared_ptr<XdmfGridCollection> classedGrid = shared_dynamic_cast<XdmfGridCollection>(sourceGrid))
+  {
+    // Copy stucture from read grid to this grid
+    while (this->getNumberGridCollections() > 0)
+    {
+      this->removeGridCollection(0);
+    }
+    for (unsigned int i = 0; i < classedGrid->getNumberGridCollections(); ++i)
+    {
+      this->insert(classedGrid->getGridCollection(i));
+    }
+    while (this->getNumberCurvilinearGrids() > 0)
+    {
+      this->removeCurvilinearGrid(0);
+    }
+    for (unsigned int i = 0; i < classedGrid->getNumberCurvilinearGrids(); ++i)
+    {
+      this->insert(classedGrid->getCurvilinearGrid(i));
+    }
+    while (this->getNumberGraphs() > 0)
+    {
+      this->removeGraph(0);
+    }
+    for (unsigned int i = 0; i < classedGrid->getNumberGraphs(); ++i)
+    {
+      this->insert(classedGrid->getGraph(i));
+    }
+    while (this->getNumberRectilinearGrids() > 0)
+    {
+      this->removeRectilinearGrid(0);
+    }
+    for (unsigned int i = 0; i < classedGrid->getNumberRectilinearGrids(); ++i)
+    {
+      this->insert(classedGrid->getRectilinearGrid(i));
+    }
+    while (this->getNumberRegularGrids() > 0)
+    {
+      this->removeRegularGrid(0);
+    }
+    for (unsigned int i = 0; i < classedGrid->getNumberRegularGrids(); ++i)
+    {
+      this->insert(classedGrid->getRegularGrid(i));
+    }
+    while (this->getNumberUnstructuredGrids() > 0)
+    {
+      this->removeUnstructuredGrid(0);
+    }
+    for (unsigned int i = 0; i < classedGrid->getNumberUnstructuredGrids(); ++i)
+    {
+      this->insert(classedGrid->getUnstructuredGrid(i));
+    }
+  }
+}
+
+std::map<std::string, std::string>
+XdmfGridCollection::getItemProperties() const
+{
+  std::map<std::string, std::string> collectionProperties =
+    XdmfGrid::getItemProperties();
+  collectionProperties.insert(std::make_pair("GridType", "Collection"));
+  mType->getProperties(collectionProperties);
+  return collectionProperties;
+}
+
+std::string
+XdmfGridCollection::getItemTag() const
+{
+  return ItemTag;
+}
+
+shared_ptr<const XdmfGridCollectionType>
+XdmfGridCollection::getType() const
+{
+  return mType;
+}
+
+void
+XdmfGridCollection::insert(const shared_ptr<XdmfInformation> information)
+{
+  XdmfItem::insert(information);
+}
+
+void
+XdmfGridCollection::populateItem(const std::map<std::string, std::string> & itemProperties,
+                                 const std::vector<shared_ptr<XdmfItem> > & childItems,
+                                 const XdmfCoreReader * const reader)
+{
+  mType = XdmfGridCollectionType::New(itemProperties);
+  XdmfDomain::populateItem(itemProperties, childItems, reader);
+  mInformations.clear();
+  XdmfGrid::populateItem(itemProperties, childItems, reader);
+}
+
+void
+XdmfGridCollection::read()
+{
+  if (mGridController)
+  {
+    if (shared_ptr<XdmfGridCollection> grid = shared_dynamic_cast<XdmfGridCollection>(mGridController->read()))
+    {
+      // Copy stucture from read grid to this grid
+      while(this->getNumberGridCollections() > 0)
+      {
+        this->removeGridCollection(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberGridCollections(); ++i)
+      {
+        this->insert(grid->getGridCollection(i));
+      }
+      while(this->getNumberUnstructuredGrids() > 0)
+      {
+        this->removeUnstructuredGrid(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberUnstructuredGrids(); ++i)
+      {
+        this->insert(grid->getUnstructuredGrid(i));
+      }
+      while(this->getNumberCurvilinearGrids() > 0)
+      {
+        this->removeCurvilinearGrid(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberCurvilinearGrids(); ++i)
+      {
+        this->insert(grid->getCurvilinearGrid(i));
+      }
+      while(this->getNumberRectilinearGrids() > 0)
+      {
+        this->removeRectilinearGrid(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberRectilinearGrids(); ++i)
+      {
+        this->insert(grid->getRectilinearGrid(i));
+      }
+      while(this->getNumberRegularGrids() > 0)
+      {
+        this->removeRegularGrid(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberRegularGrids(); ++i)
+      {
+        this->insert(grid->getRegularGrid(i));
+      }
+      while(this->getNumberAttributes() > 0)
+      {
+        this->removeAttribute(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberAttributes(); ++i)
+      {
+        this->insert(grid->getAttribute(i));
+      }
+      while(this->getNumberInformations() > 0)
+      {
+        this->removeInformation(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberInformations(); ++i)
+      {
+        this->insert(grid->getInformation(i));
+      }
+      while(this->getNumberSets() > 0)
+      {
+        this->removeSet(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberSets(); ++i)
+      {
+        this->insert(grid->getSet(i));
+      }
+      while(this->getNumberMaps() > 0)
+      {
+        this->removeMap(0);
+      }
+      for (unsigned int i = 0; i < grid->getNumberMaps(); ++i)
+      {
+        this->insert(grid->getMap(i));
+      }
+    }
+    else if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(mGridController->read()))
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
+    }
+    else
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
+    }
+  }
+}
+
+void
+XdmfGridCollection::release()
+{
+  while(this->getNumberGridCollections() > 0)
+  {
+    this->removeGridCollection(0);
+  }
+  while(this->getNumberUnstructuredGrids() > 0)
+  {
+    this->removeUnstructuredGrid(0);
+  }
+  while(this->getNumberCurvilinearGrids() > 0)
+  {
+    this->removeCurvilinearGrid(0);
+  }
+  while(this->getNumberRectilinearGrids() > 0)
+  {
+    this->removeRectilinearGrid(0);
+  }
+  while(this->getNumberRegularGrids() > 0)
+  {
+    this->removeRegularGrid(0);
+  }
+  while(this->getNumberAttributes() > 0)
+  {
+    this->removeAttribute(0);
+  }
+  while(this->getNumberInformations() > 0)
+  {
+    this->removeInformation(0);
+  }
+  while(this->getNumberSets() > 0)
+  {
+    this->removeSet(0);
+  }
+  while(this->getNumberMaps() > 0)
+  {
+    this->removeMap(0);
+  }
+}
+
+void
+XdmfGridCollection::setType(const shared_ptr<const XdmfGridCollectionType> type)
+{
+  mType = type;
+  this->setIsChanged(true);
+}
+
+void
+XdmfGridCollection::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfGrid::traverse(visitor);
+
+  // Only write XdmfInformations once (deal with diamond inheritance)
+  std::vector<shared_ptr<XdmfInformation> > informations;
+  informations.swap(mInformations);
+  XdmfDomain::traverse(visitor);
+  informations.swap(mInformations);
+}
+
+// C Wrappers
+
+XDMFGRIDCOLLECTION * XdmfGridCollectionNew()
+{
+  try
+  {
+    XDMFGRIDCOLLECTION * returnCollection = NULL;
+    shared_ptr<XdmfGridCollection> generatedCollection = XdmfGridCollection::New();
+    returnCollection = (XDMFGRIDCOLLECTION *)((void *)((XdmfItem *)(new XdmfGridCollection(*generatedCollection.get()))));
+    generatedCollection.reset();
+    return returnCollection;
+  }
+  catch (...)
+  {
+    XDMFGRIDCOLLECTION * returnCollection = NULL;
+    shared_ptr<XdmfGridCollection> generatedCollection = XdmfGridCollection::New();
+    returnCollection = (XDMFGRIDCOLLECTION *)((void *)((XdmfItem *)(new XdmfGridCollection(*generatedCollection.get()))));
+    generatedCollection.reset();
+    return returnCollection;
+  }
+}
+
+int XdmfGridCollectionGetType(XDMFGRIDCOLLECTION * collection, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * tempPointer = (XdmfItem *)collection;
+  XdmfGridCollection * tempCollection = dynamic_cast<XdmfGridCollection *>(tempPointer);
+  shared_ptr<const XdmfGridCollectionType> checkType = tempCollection->getType();
+  if (checkType == XdmfGridCollectionType::NoCollectionType()) {
+    return XDMF_GRID_COLLECTION_TYPE_NO_COLLECTION_TYPE;
+  }
+  else if (checkType == XdmfGridCollectionType::Spatial()) {
+    return XDMF_GRID_COLLECTION_TYPE_SPATIAL;
+  }
+  else if (checkType == XdmfGridCollectionType::Temporal()) {
+    return XDMF_GRID_COLLECTION_TYPE_TEMPORAL;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Invalid ArrayType.");
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+void XdmfGridCollectionSetType(XDMFGRIDCOLLECTION * collection, int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * tempPointer = (XdmfItem *)collection;
+  XdmfGridCollection * tempCollection = dynamic_cast<XdmfGridCollection *>(tempPointer);
+  switch (type) {
+    case XDMF_GRID_COLLECTION_TYPE_NO_COLLECTION_TYPE:
+      tempCollection->setType(XdmfGridCollectionType::NoCollectionType());
+      break;
+    case XDMF_GRID_COLLECTION_TYPE_SPATIAL:
+      tempCollection->setType(XdmfGridCollectionType::Spatial());
+      break;
+    case XDMF_GRID_COLLECTION_TYPE_TEMPORAL:
+      tempCollection->setType(XdmfGridCollectionType::Temporal());
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_DOMAIN_C_CHILD_WRAPPER(XdmfGridCollection, XDMFGRIDCOLLECTION)
+XDMF_GRID_C_CHILD_WRAPPER(XdmfGridCollection, XDMFGRIDCOLLECTION)
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfGridCollection, XDMFGRIDCOLLECTION)
diff --git a/XdmfGridCollection.hpp b/XdmfGridCollection.hpp
new file mode 100644
index 0000000..63dcaee
--- /dev/null
+++ b/XdmfGridCollection.hpp
@@ -0,0 +1,220 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGridCollection.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGRIDCOLLECTION_HPP_
+#define XDMFGRIDCOLLECTION_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfGrid.hpp"
+#include "XdmfGridCollectionType.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief A spatial or temporal collection of XdmfGrids.
+ *
+ * A temporal collection is timestep data.  Each child grid represents
+ * the state at a single timestep.  A spatial collection consists of
+ * XdmfGrids that are arranged together in space. E.g. a partitioned
+ * mesh.
+ *
+ * It is valid to nest collections. A spatial collection inside a
+ * temporal collection is commonly used.
+ */
+class XDMF_EXPORT XdmfGridCollection : public virtual XdmfDomain,
+                                       public XdmfGrid {
+
+public:
+
+  /**
+   * Create a new XdmfGridCollection.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGridCollection.cpp
+   * @skipline //#initalization
+   * @until //#initalization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGridCollection.py
+   * @skipline #//initalization
+   * @until #//initalization
+   *
+   * @return    Constructed XdmfGridCollection.
+   */
+  static shared_ptr<XdmfGridCollection> New();
+
+  virtual ~XdmfGridCollection();
+
+  LOKI_DEFINE_VISITABLE(XdmfGridCollection, XdmfGrid)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the XdmfGridCollectionType associated with this grid collection.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGridCollection.cpp
+   * @skipline //#initalization
+   * @until //#initalization
+   * @skipline //#getType
+   * @until //#getType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGridCollection.py
+   * @skipline #//initalization
+   * @until #//initalization
+   * @skipline #//getType
+   * @until #//getType
+   *
+   * @return    XdmfGridCollectionType of this collection.
+   */
+  shared_ptr<const XdmfGridCollectionType> getType() const;
+
+  using XdmfDomain::insert;
+  using XdmfGrid::insert;
+
+  /**
+   * Insert an information into the grid collection.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGridCollection.cpp
+   * @skipline //#initalization
+   * @until //#initalization
+   * @skipline //#insert
+   * @until //#insert
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGridCollection.py
+   * @skipline #//initalization
+   * @until #//initalization
+   * @skipline #//insert
+   * @until #//insert
+   *
+   * @param     information     An XdmfInformation to attach to this item.
+   */
+  void insert(const shared_ptr<XdmfInformation> information);
+
+  void read();
+
+  void release();
+
+  /**
+   * Set the XdmfGridCollectionType associated with this grid
+   * collection.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGridCollection.cpp
+   * @skipline //#initalization
+   * @until //#initalization
+   * @skipline //#setType
+   * @until //#setType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGridCollection.py
+   * @skipline #//initalization
+   * @until #//initalization
+   * @skipline #//setType
+   * @until #//setType
+   *
+   * @param     type    The XdmfGridCollectionType to set.
+   */
+  void setType(const shared_ptr<const XdmfGridCollectionType> type);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfGridCollection(XdmfGridCollection &);
+
+protected:
+
+  XdmfGridCollection();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+  void copyGrid(shared_ptr<XdmfGrid> sourceGrid);
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfGridCollectionImpl;
+
+  XdmfGridCollection(const XdmfGridCollection &);  // Not implemented.
+  void operator=(const XdmfGridCollection &);  // Not implemented.
+
+  shared_ptr<const XdmfGridCollectionType> mType;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#ifndef XDMFGRIDCOLLECTIONCDEFINE
+#define XDMFGRIDCOLLECTIONCDEFINE
+struct XDMFGRIDCOLLECTION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRIDCOLLECTION XDMFGRIDCOLLECTION;
+#endif
+
+XDMF_EXPORT XDMFGRIDCOLLECTION * XdmfGridCollectionNew();
+
+XDMF_EXPORT int XdmfGridCollectionGetType(XDMFGRIDCOLLECTION * collection, int * status);
+
+XDMF_EXPORT void XdmfGridCollectionSetType(XDMFGRIDCOLLECTION * collection, int type, int * status);
+
+XDMF_DOMAIN_C_CHILD_DECLARE(XdmfGridCollection, XDMFGRIDCOLLECTION, XDMF)
+XDMF_GRID_C_CHILD_DECLARE(XdmfGridCollection, XDMFGRIDCOLLECTION, XDMF)
+XDMF_ITEM_C_CHILD_DECLARE(XdmfGridCollection, XDMFGRIDCOLLECTION, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFGRID_HPP_ */
diff --git a/XdmfGridCollectionType.cpp b/XdmfGridCollectionType.cpp
new file mode 100644
index 0000000..793f217
--- /dev/null
+++ b/XdmfGridCollectionType.cpp
@@ -0,0 +1,129 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGridCollectionType.cpp                                          */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfError.hpp"
+#include "XdmfGridCollectionType.hpp"
+
+std::map<std::string, shared_ptr<const XdmfGridCollectionType>(*)()>
+  XdmfGridCollectionType::mGridCollectionDefinitions;
+
+// Supported XdmfGridCollectionTypes
+shared_ptr<const XdmfGridCollectionType>
+XdmfGridCollectionType::NoCollectionType()
+{
+  static shared_ptr<const XdmfGridCollectionType>
+    p(new XdmfGridCollectionType("None"));
+  return p;
+}
+
+shared_ptr<const XdmfGridCollectionType>
+XdmfGridCollectionType::Spatial()
+{
+  static shared_ptr<const XdmfGridCollectionType>
+    p(new XdmfGridCollectionType("Spatial"));
+  return p;
+}
+
+shared_ptr<const XdmfGridCollectionType>
+XdmfGridCollectionType::Temporal()
+{
+  static shared_ptr<const XdmfGridCollectionType>
+    p(new XdmfGridCollectionType("Temporal"));
+  return p;
+}
+
+void
+XdmfGridCollectionType::InitTypes()
+{
+  mGridCollectionDefinitions["NONE"] = NoCollectionType;
+  mGridCollectionDefinitions["SPATIAL"] = Spatial;
+  mGridCollectionDefinitions["TEMPORAL"] = Temporal;
+}
+
+XdmfGridCollectionType::XdmfGridCollectionType(const std::string & name) :
+  mName(name)
+{
+}
+
+XdmfGridCollectionType::~XdmfGridCollectionType()
+{
+}
+
+shared_ptr<const XdmfGridCollectionType>
+XdmfGridCollectionType::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("CollectionType");
+  if(type == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL, 
+                       "'CollectionType' not in itemProperties in "
+                       "XdmfGridCollectionType::New");
+  }
+
+  const std::string & typeVal = ConvertToUpper(type->second);
+
+  std::map<std::string, shared_ptr<const XdmfGridCollectionType>(*)()>::const_iterator returnType
+    = mGridCollectionDefinitions.find(typeVal);
+
+  if (returnType == mGridCollectionDefinitions.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "'CollectionType' not of 'None', 'Spatial', or "
+                       "'Temporal' in XdmfGridCollectionType::New");
+  }
+  else {
+    return (*(returnType->second))();
+  }
+
+  XdmfError::message(XdmfError::FATAL, 
+                     "'CollectionType' not of 'None', 'Spatial', or "
+                     "'Temporal' in XdmfGridCollectionType::New");
+
+  // unreachable
+  return shared_ptr<const XdmfGridCollectionType>();
+}
+
+void
+XdmfGridCollectionType::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("CollectionType", mName));
+}
+
+// C Wrappers
+
+int XdmfGridCollectionTypeNoCollectionType()
+{
+  return XDMF_GRID_COLLECTION_TYPE_NO_COLLECTION_TYPE;
+}
+
+int XdmfGridCollectionTypeSpatial()
+{
+  return XDMF_GRID_COLLECTION_TYPE_SPATIAL;
+}
+
+int XdmfGridCollectionTypeTemporal()
+{
+  return XDMF_GRID_COLLECTION_TYPE_TEMPORAL;
+}
diff --git a/XdmfGridCollectionType.hpp b/XdmfGridCollectionType.hpp
new file mode 100644
index 0000000..fabfed1
--- /dev/null
+++ b/XdmfGridCollectionType.hpp
@@ -0,0 +1,133 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGridCollectionType.hpp                                          */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGRIDCOLLECTIONTYPE_HPP_
+#define XDMFGRIDCOLLECTIONTYPE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include "XdmfItemProperty.hpp"
+
+/**
+ * @brief Property describing the type of an XdmfGridCollection.
+ *
+ * XdmfGridCollectionType is a property used by XdmfGridCollection to
+ * specify what type of collection the XdmfGridCollection contains. A
+ * specific XdmfGridCollectionType can be created by calling one of
+ * the static methods in the class,
+ * i.e. XdmfGridCollectionType::Temporal().
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfGridCollection.cpp
+ * @skipline //#initalization
+ * @until //#initalization
+ * @skipline //#getType
+ * @until //#getType
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleGridCollection.py
+ * @skipline #//initalization
+ * @until #//initalization
+ * @skipline #//getType
+ * @until #//getType
+ *
+ * Xdmf supports the following collection types:
+ *   NoCollectionType
+ *   Spatial
+ *   Temporal
+ */
+class XDMF_EXPORT XdmfGridCollectionType : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfGridCollectionType();
+
+  friend class XdmfGridCollection;
+  friend class XdmfGridTemplate;
+
+  // Supported XdmfGridCollectionTypes
+  static shared_ptr<const XdmfGridCollectionType> NoCollectionType();
+  static shared_ptr<const XdmfGridCollectionType> Spatial();
+  static shared_ptr<const XdmfGridCollectionType> Temporal();
+
+  void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+protected:
+
+  /**
+   * Protected constructor for XdmfGridCollectionType. The constructor
+   * is protected because all collection types supported by Xdmf
+   * should be accessed through more specific static methods that
+   * construct XdmfGridCollectionType -
+   * i.e. XdmfGridCollectionType::Temporal().
+   *
+   * @param name the name of the XdmfGridCollectionType to construct.
+   */
+  XdmfGridCollectionType(const std::string & name);
+
+  static std::map<std::string, shared_ptr<const XdmfGridCollectionType>(*)()> mGridCollectionDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfGridCollectionType(const XdmfGridCollectionType &); // Not implemented.
+  void operator=(const XdmfGridCollectionType &); // Not implemented.
+
+  static shared_ptr<const XdmfGridCollectionType>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  std::string mName;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#define XDMF_GRID_COLLECTION_TYPE_SPATIAL            400
+#define XDMF_GRID_COLLECTION_TYPE_TEMPORAL           401
+#define XDMF_GRID_COLLECTION_TYPE_NO_COLLECTION_TYPE 402
+
+XDMF_EXPORT int XdmfGridCollectionTypeNoCollectionType();
+XDMF_EXPORT int XdmfGridCollectionTypeSpatial();
+XDMF_EXPORT int XdmfGridCollectionTypeTemporal();
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* XDMFGRIDCOLLECTIONTYPE_HPP_ */
diff --git a/XdmfGridController.cpp b/XdmfGridController.cpp
new file mode 100644
index 0000000..3d9a396
--- /dev/null
+++ b/XdmfGridController.cpp
@@ -0,0 +1,195 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGridController.cpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at arl.army.mil                                          */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2015 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfError.hpp"
+#include "XdmfGrid.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridController.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "string.h"
+#include <stdio.h>
+
+shared_ptr<XdmfGridController>
+XdmfGridController::New(const std::string & filePath,
+                        const std::string & xmlPath)
+{
+  shared_ptr<XdmfGridController> p(new XdmfGridController(filePath,
+                                                          xmlPath));
+  return p;
+}
+
+XdmfGridController::XdmfGridController(const std::string & filePath,
+                                       const std::string & xmlPath) :
+  mFilePath(filePath),
+  mXMLPath(xmlPath)
+{
+}
+
+XdmfGridController::XdmfGridController(const XdmfGridController& refController):
+  mFilePath(refController.getFilePath()),
+  mXMLPath(refController.getXMLPath())
+{
+}
+
+XdmfGridController::~XdmfGridController()
+{
+}
+
+const std::string XdmfGridController::ItemTag = "XGrid";
+
+std::string
+XdmfGridController::getFilePath() const
+{
+  return mFilePath;
+}
+
+std::string
+XdmfGridController::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::map<std::string, std::string>
+XdmfGridController::getItemProperties() const
+{
+  std::map<std::string, std::string> gridProperties;
+  gridProperties.insert(std::make_pair("File", mFilePath));
+  gridProperties.insert(std::make_pair("XPath", mXMLPath));
+  return gridProperties;
+}
+
+std::string
+XdmfGridController::getXMLPath() const
+{
+  return mXMLPath;
+}
+
+shared_ptr<XdmfGrid>
+XdmfGridController::read()
+{
+  shared_ptr<XdmfReader> gridReader = XdmfReader::New();
+  return shared_dynamic_cast<XdmfGrid>(gridReader->read(mFilePath, mXMLPath)[0]);
+}
+
+// C Wrappers
+
+XDMFGRIDCONTROLLER *
+XdmfGridControllerNew(char * filePath, char * xmlPath)
+{
+  try
+  {
+    XDMFGRIDCONTROLLER * returnController = NULL;
+    shared_ptr<XdmfGridController> generatedController = XdmfGridController::New(std::string(filePath), std::string(xmlPath));
+    returnController = (XDMFGRIDCONTROLLER *)((void *)((XdmfItem *)(new XdmfGridController(*generatedController.get()))));
+    generatedController.reset();
+    return returnController;
+  }
+  catch (...)
+  {
+    XDMFGRIDCONTROLLER * returnController = NULL;
+    shared_ptr<XdmfGridController> generatedController = XdmfGridController::New(std::string(filePath), std::string(xmlPath));
+    returnController = (XDMFGRIDCONTROLLER *)((void *)((XdmfItem *)(new XdmfGridController(*generatedController.get()))));
+    generatedController.reset();
+    return returnController;
+  }
+}
+
+char *
+XdmfGridControllerGetFilePath(XDMFGRIDCONTROLLER * controller)
+{
+  try
+  {
+    XdmfGridController referenceController = *(XdmfGridController *)(controller);
+    char * returnPointer = strdup(referenceController.getFilePath().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    XdmfGridController referenceController = *(XdmfGridController *)(controller);
+    char * returnPointer = strdup(referenceController.getFilePath().c_str());
+    return returnPointer;
+  }
+}
+
+char *
+XdmfGridControllerGetXMLPath(XDMFGRIDCONTROLLER * controller)
+{
+  try
+  {
+    XdmfGridController referenceController = *(XdmfGridController *)(controller);
+    char * returnPointer = strdup(referenceController.getXMLPath().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    XdmfGridController referenceController = *(XdmfGridController *)(controller);
+    char * returnPointer = strdup(referenceController.getXMLPath().c_str());
+    return returnPointer;
+  }
+}
+
+XDMFGRID *
+XdmfGridControllerRead(XDMFGRIDCONTROLLER * controller)
+{
+  try
+  {
+    XdmfGridController referenceController = *(XdmfGridController *)(controller);
+    shared_ptr<XdmfGrid> returnGrid = referenceController.read();
+    XDMFGRID * returnPointer;
+    if (shared_ptr<XdmfCurvilinearGrid> curvilinearGrid =
+        shared_dynamic_cast<XdmfCurvilinearGrid>(returnGrid))
+    {
+      returnPointer = (XDMFGRID *)((void *)((XdmfItem *)(new XdmfCurvilinearGrid(*curvilinearGrid.get()))));
+    }
+    else if (shared_ptr<XdmfRectilinearGrid> rectilinearGrid =
+             shared_dynamic_cast<XdmfRectilinearGrid>(returnGrid))
+    {
+      returnPointer = (XDMFGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*rectilinearGrid.get()))));
+    }
+    else if (shared_ptr<XdmfRegularGrid> regularGrid =
+        shared_dynamic_cast<XdmfRegularGrid>(returnGrid))
+    {
+      returnPointer = (XDMFGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*regularGrid.get()))));
+    }
+    else if (shared_ptr<XdmfGridCollection> collectionGrid =
+        shared_dynamic_cast<XdmfGridCollection>(returnGrid))
+    {
+      returnPointer = (XDMFGRID *)((void *)((XdmfItem *)(new XdmfGridCollection(*collectionGrid.get()))));
+    }
+    else if (shared_ptr<XdmfUnstructuredGrid> unstructuredGrid =
+        shared_dynamic_cast<XdmfUnstructuredGrid>(returnGrid))
+    {
+      returnPointer = (XDMFGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*unstructuredGrid.get()))));
+    }
+    return returnPointer;
+  }
+  catch (...)
+  {
+  }
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfGridController, XDMFGRIDCONTROLLER)
diff --git a/XdmfGridController.hpp b/XdmfGridController.hpp
new file mode 100644
index 0000000..5a84dff
--- /dev/null
+++ b/XdmfGridController.hpp
@@ -0,0 +1,226 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGridController.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at arl.army.mil                                          */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2015 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGRIDCONTROLLER_HPP_
+#define XDMFGRIDCONTROLLER_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfGrid;
+
+// Includes
+#include <string>
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Couples an XdmfGrid with a grid on a different XML file.
+ *
+ * Serves as an method to reduce memory usage by leaving part of
+ * the xdmf tree in file.
+ */
+class XDMF_EXPORT XdmfGridController : public virtual XdmfItem {
+
+public:
+
+  /**
+   * Creates a link to an xdmf tree in another file.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGridController
+   * @until //#setGridController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGridController
+   * @until #//setGridController
+   *
+   * @param     filePath        
+   * @param     xmlPath         
+   *
+   * @return    A reference to the external xdmf tree
+   */
+  static shared_ptr<XdmfGridController>
+  New(const std::string & filePath,
+      const std::string & xmlPath);
+
+  friend class XdmfWriter;
+  friend class XdmfGrid;
+
+  virtual ~XdmfGridController();
+
+  static const std::string ItemTag;
+
+  /**
+   * Gets the file path of the grid that this reference reads from.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGridController
+   * @until //#setGridController
+   * @skipline //#getFilePath
+   * @until //#getFilePath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGridController
+   * @until #//setGridController
+   * @skipline #//getFilePath
+   * @until #//getFilePath
+   *
+   * @return    The file path.
+   */
+  std::string getFilePath() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  /**
+   * Gets the XML path that refers to the base node in the reference file.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGridController
+   * @until //#setGridController
+   * @skipline //#getXMLPath
+   * @until //#getXMLPath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGridController
+   * @until #//setGridController
+   * @skipline #//getXMLPath
+   * @until #//getXMLPath
+   *
+   * @return    The XML path.
+   */
+  std::string getXMLPath() const;
+
+  /**
+   * Reads the grid that his controller references.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGridController
+   * @until //#setGridController
+   * @skipline //#controllerRead
+   * @until //#controllerRead
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGridController
+   * @until #//setGridController
+   * @skipline #//controllerRead
+   * @until #//controllerRead
+   *
+   * @return    The grid read from the controller's stored location
+   */
+  virtual shared_ptr<XdmfGrid> read();
+
+  XdmfGridController(const XdmfGridController&);
+
+protected:
+
+  XdmfGridController(const std::string & filePath,
+                     const std::string & xmlPath);
+
+  const std::string mFilePath;
+  const std::string mXMLPath;
+
+private:
+
+//  XdmfGridController(const XdmfGridController&);  // Not implemented.
+  void operator=(const XdmfGridController &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#ifndef XDMFGRIDCDEFINE
+#define XDMFGRIDCDEFINE
+struct XDMFGRID; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRID XDMFGRID;
+#endif
+
+struct XDMFGRIDCONTROLLER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRIDCONTROLLER XDMFGRIDCONTROLLER;
+
+XDMF_EXPORT XDMFGRIDCONTROLLER * XdmfGridControllerNew(char * filePath,
+                                                       char * xmlPath);
+
+XDMF_EXPORT char * XdmfGridControllerGetFilePath(XDMFGRIDCONTROLLER * controller);
+
+XDMF_EXPORT char * XdmfGridControllerGetXMLPath(XDMFGRIDCONTROLLER * controller);
+
+XDMF_EXPORT XDMFGRID * XdmfGridControllerRead(XDMFGRIDCONTROLLER * controller);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfGridController, XDMFGRIDCONTROLLER, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFGRIDCONTROLLER_HPP_ */
diff --git a/XdmfGridTemplate.cpp b/XdmfGridTemplate.cpp
new file mode 100644
index 0000000..5e67990
--- /dev/null
+++ b/XdmfGridTemplate.cpp
@@ -0,0 +1,975 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTemplate.cpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <sstream>
+#include <utility>
+#include "XdmfArray.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfItemFactory.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfGridTemplate.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfTemplate.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfError.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfVisitor.hpp"
+#include "XdmfWriter.hpp"
+
+#include "XdmfSystemUtils.hpp"
+
+#include <boost/tokenizer.hpp>
+
+#include <stdio.h>
+
+shared_ptr<XdmfGridTemplate>
+XdmfGridTemplate::New()
+{
+  shared_ptr<XdmfGridTemplate> p(new XdmfGridTemplate());
+  return p;
+}
+
+
+XdmfGridTemplate::XdmfGridTemplate() :
+  XdmfTemplate(),
+  XdmfGridCollection(),
+  mTimeCollection(XdmfArray::New())
+{
+  mTimeCollection->setName("Time Collection");
+}
+
+XdmfGridTemplate::XdmfGridTemplate(XdmfGridTemplate & refTemplate) :
+  XdmfTemplate(refTemplate),
+  XdmfGridCollection(refTemplate),
+  mTimeCollection(refTemplate.mTimeCollection)
+{
+}
+
+XdmfGridTemplate::~XdmfGridTemplate()
+{
+}
+
+const std::string XdmfGridTemplate::ItemTag = "Template";
+
+unsigned int
+XdmfGridTemplate::addStep()
+{
+  XdmfTemplate::addStep();
+  if (shared_dynamic_cast<XdmfGrid>(mBase)->getTime()) {
+    if (!mTimeCollection->isInitialized()) {
+      mTimeCollection->read();
+    }
+    mTimeCollection->pushBack(shared_dynamic_cast<XdmfGrid>(mBase)->getTime()->getValue());
+  }
+  return mCurrentStep;
+}
+
+std::map<std::string, std::string>
+XdmfGridTemplate::getItemProperties() const
+{
+  std::map<std::string, std::string> templateProperties = XdmfGridCollection::getItemProperties();
+
+  templateProperties["BaseType"] = "Grid";
+  return templateProperties;
+}
+
+std::string
+XdmfGridTemplate::getItemTag() const
+{
+  return ItemTag;
+}
+
+shared_ptr<XdmfArray>
+XdmfGridTemplate::getTimes()
+{
+  return mTimeCollection;
+}
+
+shared_ptr<XdmfGridCollection>
+XdmfGridTemplate::getGridCollection(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      this->clearStep();
+      this->setStep(index);
+      if (shared_ptr<XdmfGridCollection> grid =
+            shared_dynamic_cast<XdmfGridCollection>(mBase)) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfGridCollection>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfGridCollection>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
+    return shared_ptr<XdmfGridCollection>();
+  }
+}
+
+shared_ptr<const XdmfGridCollection>
+XdmfGridTemplate::getGridCollection(const unsigned int index) const
+{
+  if (shared_ptr<XdmfGridCollection> grid =
+      shared_dynamic_cast<XdmfGridCollection>(mBase)) {
+    if (index != mCurrentStep)
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
+      return shared_ptr<XdmfGridCollection>();
+    }
+    else
+    {
+      return grid;
+    }
+  }
+  else {
+    return shared_ptr<XdmfGridCollection>();
+  }
+}
+
+shared_ptr<XdmfGridCollection>
+XdmfGridTemplate::getGridCollection(const std::string & Name)
+{
+  if (mBase) {
+   if (shared_ptr<XdmfGridCollection> grid =
+          shared_dynamic_cast<XdmfGridCollection>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfGridCollection>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfGridCollection>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
+    return shared_ptr<XdmfGridCollection>();
+  }
+}
+
+shared_ptr<const XdmfGridCollection>
+XdmfGridTemplate::getGridCollection(const std::string & Name) const
+{
+  if (mBase) {
+   if (shared_ptr<XdmfGridCollection> grid =
+          shared_dynamic_cast<XdmfGridCollection>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfGridCollection>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfGridCollection>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
+    return shared_ptr<XdmfGridCollection>();
+  }
+}
+
+unsigned int
+XdmfGridTemplate::getNumberGridCollections() const
+{
+  if (shared_ptr<XdmfGridCollection> grid =
+        shared_dynamic_cast<XdmfGridCollection>(mBase)) {
+    return this->getNumberSteps();
+  }
+  else {
+    return 0;
+  }
+}
+
+void
+XdmfGridTemplate::insert(const shared_ptr<XdmfGridCollection> GridCollection)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfGridCollection to an XdmfGridTemplate. "
+                                       "Use addStep instead of insert to add to an XdmfGridTemplate");
+}
+
+void
+XdmfGridTemplate::removeGridCollection(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      if (shared_ptr<XdmfGridCollection> grid =
+            shared_dynamic_cast<XdmfGridCollection>(mBase)) {
+        this->removeStep(index);
+      }
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get GridCollection from template without a base");
+  }
+}
+
+void
+XdmfGridTemplate::removeGridCollection(const std::string & Name)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
+}
+
+shared_ptr<XdmfCurvilinearGrid>
+XdmfGridTemplate::getCurvilinearGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      this->clearStep();
+      this->setStep(index);
+      if (shared_ptr<XdmfCurvilinearGrid> grid =
+            shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfCurvilinearGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfCurvilinearGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
+    return shared_ptr<XdmfCurvilinearGrid>();
+  }
+}
+
+shared_ptr<const XdmfCurvilinearGrid>
+XdmfGridTemplate::getCurvilinearGrid(const unsigned int index) const
+{
+  if (shared_ptr<XdmfCurvilinearGrid> grid =
+      shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
+    if (index != mCurrentStep)
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
+      return shared_ptr<XdmfCurvilinearGrid>();
+    }
+    else
+    {
+      return grid;
+    }
+  }
+  else {
+    return shared_ptr<XdmfCurvilinearGrid>();
+  }
+}
+
+shared_ptr<XdmfCurvilinearGrid>
+XdmfGridTemplate::getCurvilinearGrid(const std::string & Name)
+{
+  if (mBase) {
+   if (shared_ptr<XdmfCurvilinearGrid> grid =
+          shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfCurvilinearGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfCurvilinearGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
+    return shared_ptr<XdmfCurvilinearGrid>();
+  }
+}
+
+shared_ptr<const XdmfCurvilinearGrid>
+XdmfGridTemplate::getCurvilinearGrid(const std::string & Name) const
+{
+  if (mBase) {
+   if (shared_ptr<XdmfCurvilinearGrid> grid =
+          shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfCurvilinearGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfCurvilinearGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
+    return shared_ptr<XdmfCurvilinearGrid>();
+  }
+}
+
+unsigned int
+XdmfGridTemplate::getNumberCurvilinearGrids() const
+{
+  if (shared_ptr<XdmfCurvilinearGrid> grid =
+        shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
+    return this->getNumberSteps();
+  }
+  else {
+    return 0;
+  }
+}
+
+void
+XdmfGridTemplate::insert(const shared_ptr<XdmfCurvilinearGrid> CurvilinearGrid)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfCurvilinearGrid to an XdmfGridTemplate. "
+                                       "Use addStep instead of insert to add to an XdmfGridTemplate");
+}
+
+void
+XdmfGridTemplate::removeCurvilinearGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      if (shared_ptr<XdmfCurvilinearGrid> grid =
+            shared_dynamic_cast<XdmfCurvilinearGrid>(mBase)) {
+        this->removeStep(index);
+      }
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get CurvilinearGrid from template without a base");
+  }
+}
+
+void
+XdmfGridTemplate::removeCurvilinearGrid(const std::string & Name)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
+}
+
+shared_ptr<XdmfRectilinearGrid>
+XdmfGridTemplate::getRectilinearGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      this->clearStep();
+      this->setStep(index);
+      if (shared_ptr<XdmfRectilinearGrid> grid =
+            shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfRectilinearGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfRectilinearGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
+    return shared_ptr<XdmfRectilinearGrid>();
+  }
+}
+
+shared_ptr<const XdmfRectilinearGrid>
+XdmfGridTemplate::getRectilinearGrid(const unsigned int index) const
+{
+  if (shared_ptr<XdmfRectilinearGrid> grid =
+      shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
+    if (index != mCurrentStep)
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
+      return shared_ptr<XdmfRectilinearGrid>();
+    }
+    else
+    {
+      return grid;
+    }
+  }
+  else {
+    return shared_ptr<XdmfRectilinearGrid>();
+  }
+}
+
+shared_ptr<XdmfRectilinearGrid>
+XdmfGridTemplate::getRectilinearGrid(const std::string & Name)
+{
+  if (mBase) {
+   if (shared_ptr<XdmfRectilinearGrid> grid =
+          shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfRectilinearGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfRectilinearGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
+    return shared_ptr<XdmfRectilinearGrid>();
+  }
+}
+
+shared_ptr<const XdmfRectilinearGrid>
+XdmfGridTemplate::getRectilinearGrid(const std::string & Name) const
+{
+  if (mBase) {
+   if (shared_ptr<XdmfRectilinearGrid> grid =
+          shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfRectilinearGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfRectilinearGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
+    return shared_ptr<XdmfRectilinearGrid>();
+  }
+}
+
+unsigned int
+XdmfGridTemplate::getNumberRectilinearGrids() const
+{
+  if (shared_ptr<XdmfRectilinearGrid> grid =
+        shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
+    return this->getNumberSteps();
+  }
+  else {
+    return 0;
+  }
+}
+
+void
+XdmfGridTemplate::insert(const shared_ptr<XdmfRectilinearGrid> RectilinearGrid)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add a XdmfRectilinearGrid to an XdmfGridTemplate."
+                                       "Use addStep instead of insert to add to an XdmfGridTemplate");
+}
+
+void
+XdmfGridTemplate::removeRectilinearGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      if (shared_ptr<XdmfRectilinearGrid> grid =
+            shared_dynamic_cast<XdmfRectilinearGrid>(mBase)) {
+        this->removeStep(index);
+      }
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RectilinearGrid from template without a base");
+  }
+}
+
+void
+XdmfGridTemplate::removeRectilinearGrid(const std::string & Name)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
+}
+
+shared_ptr<XdmfRegularGrid>
+XdmfGridTemplate::getRegularGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      this->clearStep();
+      this->setStep(index);
+      if (shared_ptr<XdmfRegularGrid> grid =
+            shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfRegularGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfRegularGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
+    return shared_ptr<XdmfRegularGrid>();
+  }
+}
+
+shared_ptr<const XdmfRegularGrid>
+XdmfGridTemplate::getRegularGrid(const unsigned int index) const
+{
+  if (shared_ptr<XdmfRegularGrid> grid =
+      shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
+    if (index != mCurrentStep)
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
+      return shared_ptr<XdmfRegularGrid>();
+    }
+    else
+    {
+      return grid;
+    }
+  }
+  else {
+    return shared_ptr<XdmfRegularGrid>();
+  }
+}
+
+shared_ptr<XdmfRegularGrid>
+XdmfGridTemplate::getRegularGrid(const std::string & Name)
+{
+  if (mBase) {
+   if (shared_ptr<XdmfRegularGrid> grid =
+          shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfRegularGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfRegularGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
+    return shared_ptr<XdmfRegularGrid>();
+  }
+}
+
+shared_ptr<const XdmfRegularGrid>
+XdmfGridTemplate::getRegularGrid(const std::string & Name) const
+{
+  if (mBase) {
+   if (shared_ptr<XdmfRegularGrid> grid =
+          shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfRegularGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfRegularGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
+    return shared_ptr<XdmfRegularGrid>();
+  }
+}
+
+unsigned int
+XdmfGridTemplate::getNumberRegularGrids() const
+{
+  if (shared_ptr<XdmfRegularGrid> grid =
+        shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
+    return this->getNumberSteps();
+  }
+  else {
+    return 0;
+  }
+}
+
+void
+XdmfGridTemplate::insert(const shared_ptr<XdmfRegularGrid> RegularGrid)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfRegularGrid to an XdmfGridTemplate."
+                                       "Use addStep instead of insert to add to an XdmfGridTemplate");
+}
+
+void
+XdmfGridTemplate::removeRegularGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      if (shared_ptr<XdmfRegularGrid> grid =
+            shared_dynamic_cast<XdmfRegularGrid>(mBase)) {
+        this->removeStep(index);
+      }
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get RegularGrid from template without a base");
+  }
+}
+
+void
+XdmfGridTemplate::removeRegularGrid(const std::string & Name)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
+}
+
+shared_ptr<XdmfUnstructuredGrid>
+XdmfGridTemplate::getUnstructuredGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      this->clearStep();
+      this->setStep(index);
+      if (shared_ptr<XdmfUnstructuredGrid> grid =
+            shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfUnstructuredGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfUnstructuredGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
+    return shared_ptr<XdmfUnstructuredGrid>();
+  }
+}
+
+shared_ptr<const XdmfUnstructuredGrid>
+XdmfGridTemplate::getUnstructuredGrid(const unsigned int index) const
+{
+  if (shared_ptr<XdmfUnstructuredGrid> grid =
+      shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
+    if (index != mCurrentStep)
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: GridTemplates can not return a constant reference to its base on an index other than the currently loaded one.");
+      return shared_ptr<XdmfUnstructuredGrid>();
+    }
+    else
+    {
+      return grid;
+    }
+  }
+  else {
+    return shared_ptr<XdmfUnstructuredGrid>();
+  }
+}
+
+shared_ptr<XdmfUnstructuredGrid>
+XdmfGridTemplate::getUnstructuredGrid(const std::string & Name)
+{
+  if (mBase) {
+   if (shared_ptr<XdmfUnstructuredGrid> grid =
+          shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfUnstructuredGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfUnstructuredGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
+    return shared_ptr<XdmfUnstructuredGrid>();
+  }
+}
+
+shared_ptr<const XdmfUnstructuredGrid>
+XdmfGridTemplate::getUnstructuredGrid(const std::string & Name) const
+{
+  if (mBase) {
+   if (shared_ptr<XdmfUnstructuredGrid> grid =
+          shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
+      if (grid->getName().compare(Name) == 0) {
+        return grid;
+      }
+      else {
+        return shared_ptr<XdmfUnstructuredGrid>();
+      }
+    }
+    else {
+      return shared_ptr<XdmfUnstructuredGrid>();
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
+    return shared_ptr<XdmfUnstructuredGrid>();
+  }
+}
+
+unsigned int
+XdmfGridTemplate::getNumberUnstructuredGrids() const
+{
+  if (shared_ptr<XdmfUnstructuredGrid> grid =
+        shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
+    return this->getNumberSteps();
+  }
+  else {
+    return 0;
+  }
+}
+
+
+void
+XdmfGridTemplate::insert(const shared_ptr<XdmfUnstructuredGrid> UnstructuredGrid)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Attempting to use insert to add an XdmfUnstructuredGrid to an XdmfGridTemplate."
+                                       "Use addStep instead of insert to add to an XdmfGridTemplate");
+}
+
+void
+XdmfGridTemplate::removeUnstructuredGrid(const unsigned int index)
+{
+  if (mBase) {
+    if (index < getNumberSteps()) {
+      if (shared_ptr<XdmfUnstructuredGrid> grid =
+            shared_dynamic_cast<XdmfUnstructuredGrid>(mBase)) {
+        this->removeStep(index);
+      }
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Attempting to get UnstructuredGrid from template without a base");
+  }
+}
+
+
+void
+XdmfGridTemplate::removeUnstructuredGrid(const std::string & Name)
+{
+  XdmfError::message(XdmfError::FATAL, "Error: Removing Grids by name from XdmfGridTemplate is not supported");
+}
+
+void
+XdmfGridTemplate::populateItem(const std::map<std::string, std::string> & itemProperties,
+                               const std::vector<shared_ptr<XdmfItem> > & childItems,
+                               const XdmfCoreReader * const reader)
+{
+  // We are overrriding the populate item of the template and grid collection here
+  // The template functions internally different from either. 
+
+  this->setType(XdmfGridCollectionType::New(itemProperties));
+
+  // The first child item is the base
+  mBase = childItems[0];
+  mCurrentStep = 0;
+
+  if (childItems.size() > 1) {
+    for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+          childItems.begin() + 1;
+        iter != childItems.end();
+        ++iter) {
+      if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+        if (array->getName().compare("Data Description") == 0) {
+          // Split description into substrings based on the " character
+
+          if (array->getNumberHeavyDataControllers() > 0 & !mHeavyWriter) {
+            mHeavyWriter = reader->generateHeavyDataWriter(array->getHeavyDataController(0)->getName(), array->getHeavyDataController(0)->getFilePath());
+          }
+
+          array->read();
+
+          // If a character array, create std::string version? TODO
+          std::string descriptionString;
+          if (array->getArrayType() == XdmfArrayType::Int8())
+          {
+            descriptionString = std::string((char *)array->getValuesInternal());
+          }
+          else if (array->getArrayType() == XdmfArrayType::String())
+          {
+            descriptionString = array->getValue<std::string>(0);
+          }
+
+          size_t index = descriptionString.find_first_of("\"");
+          size_t previousIndex = 0;
+
+          if (index != std::string::npos) {
+            // Removing the prepended "
+            previousIndex = index + 1;
+            index = descriptionString.find_first_of("\"", previousIndex);
+          }
+
+          while (index != std::string::npos) {
+            std::string type = descriptionString.substr(previousIndex, index - previousIndex);
+            mDataTypes.push_back(type);
+            previousIndex = index + 1;
+            index = descriptionString.find_first_of("\"", previousIndex);
+            if (index - previousIndex > 0) {
+              std::string description;
+              description = descriptionString.substr(previousIndex, index - previousIndex);
+              mDataDescriptions.push_back(description);
+              // create controllers here based on the type/description?
+              // Is array type already filled?
+              // Potentially call "fillControllers" after populating?
+              if (index != std::string::npos) {
+                previousIndex = index + 1;
+                index = descriptionString.find_first_of("\"", previousIndex);
+              }
+            }
+            else {
+              XdmfError::message(XdmfError::FATAL, "Error: Type without a description in XdmfTemplate::populateItem");
+            }
+          }
+        }
+        else if (array->getName().compare("Time Collection") == 0) {
+          mTimeCollection = array;
+        }
+        else {
+          mTrackedArrays.push_back(array.get());
+          mTrackedArrayDims.push_back(array->getDimensions());
+          mTrackedArrayTypes.push_back(array->getArrayType());
+        }
+      }
+    }
+  }
+  mDataControllers.resize(mDataTypes.size());
+  if (!mItemFactory) {
+    mItemFactory = XdmfItemFactory::New();
+  }
+  std::map<std::string, std::string> populateProperties;
+  if (mHeavyWriter) {
+    // The heavy writer provides the XMLDir, which is used to get full paths for the controllers
+    // It is assumed that the files that the controllers reference are in the same directory
+    // as the file that the writer references
+    std::string filepath = XdmfSystemUtils::getRealPath(mHeavyWriter->getFilePath());
+    size_t index = filepath.find_last_of("/\\");
+    filepath = filepath.substr(0, index + 1);
+    populateProperties["XMLDir"] = filepath;
+  }
+  for (unsigned int i = 0;  i < mDataDescriptions.size(); ++i) {
+    populateProperties["Content"] = mDataDescriptions[i];
+    std::vector<shared_ptr<XdmfHeavyDataController> > readControllers =
+      reader->generateHeavyDataControllers(populateProperties, mTrackedArrayDims[i % mTrackedArrays.size()], mTrackedArrayTypes[i % mTrackedArrays.size()], mDataTypes[i]);
+    if (readControllers.size() > 0) {
+      // Heavy data controllers reference the data
+      for (unsigned int j = 0; j < readControllers.size(); ++j) {
+        mDataControllers[i].push_back(readControllers[j]);
+      }
+    }
+  }
+  // Compare the first set of controllers to the size of the first array
+  unsigned int controllerTotal = 0;
+  for (unsigned int i = 0; i < mDataControllers[0].size(); ++i)
+  {
+    controllerTotal += mDataControllers[0][i]->getSize();
+  }
+  // If the array is smaller, set the writer to append.
+  if (controllerTotal > mTrackedArrays[0]->getSize())
+  {
+    mHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+    mNumSteps = controllerTotal / mTrackedArrays[0]->getSize();
+  }
+  else {
+    mNumSteps = mDataControllers.size() / mTrackedArrays.size();
+  }
+}
+
+void
+XdmfGridTemplate::removeStep(unsigned int stepId)
+{
+  if (stepId < this->getNumberSteps()) {
+    XdmfTemplate::removeStep(stepId);
+    mTimeCollection->erase(stepId);
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfGridTemplate::setBase(shared_ptr<XdmfItem> newBase)
+{
+  if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(newBase)) {
+    XdmfTemplate::setBase(newBase);
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: XdmfGridTemplate::setBase,"
+                                         " attempting to set a Base that is not grid type.");
+  }
+}
+
+void
+XdmfGridTemplate::setStep(unsigned int stepId)
+{
+  XdmfTemplate::setStep(stepId);
+  if (mTimeCollection->getSize() >= stepId) {
+    if (!mTimeCollection->isInitialized()) {
+      mTimeCollection->read();
+    }
+    if (shared_dynamic_cast<XdmfGrid>(mBase)->getTime()) {
+      shared_dynamic_cast<XdmfGrid>(mBase)->getTime()->setValue(mTimeCollection->getValue<double>(stepId));
+    }
+    else {
+      shared_dynamic_cast<XdmfGrid>(mBase)->setTime(XdmfTime::New(mTimeCollection->getValue<double>(stepId)));
+    }
+  }
+}
+
+void
+XdmfGridTemplate::setStep(shared_ptr<XdmfTime> time)
+{
+  if (mTimeCollection->getSize() > 0)
+  {
+    if (!mTimeCollection->isInitialized()) {
+      mTimeCollection->read();
+    }
+    unsigned int index = 0;
+    while (index < mTimeCollection->getSize() &&
+           time->getValue() != mTimeCollection->getValue<double>(index))
+    {
+      ++index;
+    }
+    if (index < mTimeCollection->getSize())
+    {
+      this->setStep(index);
+    }
+  }
+}
+
+void
+XdmfGridTemplate::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  // We are only using the template traverse
+  // since the grid data is only held in the Base
+  if (mTimeCollection->getSize() > 0)
+  {
+    this->setType(XdmfGridCollectionType::Temporal());
+  }
+  else
+  {
+    this->setType(XdmfGridCollectionType::Spatial());
+  }
+  XdmfTemplate::traverse(visitor);
+  mTimeCollection->accept(visitor);
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfGridTemplate, XDMFGRIDTEMPLATE)
diff --git a/XdmfGridTemplate.hpp b/XdmfGridTemplate.hpp
new file mode 100644
index 0000000..b9b203a
--- /dev/null
+++ b/XdmfGridTemplate.hpp
@@ -0,0 +1,224 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTemplate.hpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGRIDTEMPLATE_HPP_
+#define XDMFGRIDTEMPLATE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfItemFactory.hpp"
+#include "XdmfTemplate.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+
+/**
+ * @brief Defines a template that can be filled with multiple sets of data.
+ *
+ * An XdmfTemplate defines a structure. The arrays within that structure
+ * are stored if they are not initialized when the structure is first set.
+ * Steps can then be added and references to heavy data are produced and
+ * stored for later retrieval.
+ *
+ * This effectively lets an object have several variations with different
+ * contained data.
+ */
+class XDMF_EXPORT XdmfGridTemplate : public XdmfTemplate,
+                                     public XdmfGridCollection {
+
+public:
+
+  /**
+   * Creates a new instance of the XdmfTemplate object
+   *
+   * @return    A constructed XdmfTemplate object.
+   */
+  static shared_ptr<XdmfGridTemplate> New();
+
+  virtual ~XdmfGridTemplate();
+
+  LOKI_DEFINE_VISITABLE(XdmfGridTemplate, XdmfGrid);
+  static const std::string ItemTag;
+
+  /**
+   * Writes all tracked arrays to heavy data via the provided
+   * heavy data writer then stores the heavy data descriptions.
+   *
+   * @return    The ID of the step that was added
+   */
+  virtual unsigned int addStep();
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  using XdmfGrid::insert;
+
+  // Overriding the parent versions so that all of these reference the Base item
+  // instead of the template
+
+  virtual shared_ptr<XdmfArray> getTimes();
+
+  virtual shared_ptr<XdmfGridCollection> getGridCollection(const unsigned int index);
+
+  virtual shared_ptr<const XdmfGridCollection> getGridCollection(const unsigned int index) const;
+
+  virtual shared_ptr<XdmfGridCollection> getGridCollection(const std::string & Name);
+
+  virtual shared_ptr<const XdmfGridCollection> getGridCollection(const std::string & Name) const;
+
+  virtual unsigned int getNumberGridCollections() const;
+
+  virtual void insert(const shared_ptr<XdmfGridCollection> GridCollection);
+
+  virtual void removeGridCollection(const unsigned int index);
+
+  virtual void removeGridCollection(const std::string & Name);
+
+  virtual shared_ptr<XdmfCurvilinearGrid> getCurvilinearGrid(const unsigned int index);
+
+  virtual shared_ptr<const XdmfCurvilinearGrid> getCurvilinearGrid(const unsigned int index) const;
+
+  virtual shared_ptr<XdmfCurvilinearGrid> getCurvilinearGrid(const std::string & Name);
+
+  virtual shared_ptr<const XdmfCurvilinearGrid> getCurvilinearGrid(const std::string & Name) const;
+
+  virtual unsigned int getNumberCurvilinearGrids() const;
+
+  virtual void insert(const shared_ptr<XdmfCurvilinearGrid> CurvilinearGrid);
+
+  virtual void removeCurvilinearGrid(const unsigned int index);
+
+  virtual void removeCurvilinearGrid(const std::string & Name);
+
+  virtual shared_ptr<XdmfRectilinearGrid> getRectilinearGrid(const unsigned int index);
+
+  virtual shared_ptr<const XdmfRectilinearGrid> getRectilinearGrid(const unsigned int index) const;
+
+  virtual shared_ptr<XdmfRectilinearGrid> getRectilinearGrid(const std::string & Name);
+
+  virtual shared_ptr<const XdmfRectilinearGrid> getRectilinearGrid(const std::string & Name) const;
+
+  virtual unsigned int getNumberRectilinearGrids() const;
+
+  virtual void insert(const shared_ptr<XdmfRectilinearGrid> RectilinearGrid);
+
+  virtual void removeRectilinearGrid(const unsigned int index);
+
+  virtual void removeRectilinearGrid(const std::string & Name);
+
+  virtual shared_ptr<XdmfRegularGrid> getRegularGrid(const unsigned int index);
+
+  virtual shared_ptr<const XdmfRegularGrid> getRegularGrid(const unsigned int index) const;
+
+  virtual shared_ptr<XdmfRegularGrid> getRegularGrid(const std::string & Name);
+
+  virtual shared_ptr<const XdmfRegularGrid> getRegularGrid(const std::string & Name) const;
+
+  virtual unsigned int getNumberRegularGrids() const;
+
+  virtual void insert(const shared_ptr<XdmfRegularGrid> RegularGrid);
+
+  virtual void removeRegularGrid(const unsigned int index);
+
+  virtual void removeRegularGrid(const std::string & Name);
+
+  virtual shared_ptr<XdmfUnstructuredGrid> getUnstructuredGrid(const unsigned int index);
+
+  virtual shared_ptr<const XdmfUnstructuredGrid> getUnstructuredGrid(const unsigned int index) const;
+
+  virtual shared_ptr<XdmfUnstructuredGrid> getUnstructuredGrid(const std::string & Name);
+
+  virtual shared_ptr<const XdmfUnstructuredGrid> getUnstructuredGrid(const std::string & Name) const;
+
+  virtual unsigned int getNumberUnstructuredGrids() const;
+
+  virtual void insert(const shared_ptr<XdmfUnstructuredGrid> UnstructuredGrid);
+
+  virtual void removeUnstructuredGrid(const unsigned int index);
+
+  virtual void removeUnstructuredGrid(const std::string & Name);
+
+  /**
+   *
+   */
+  virtual void removeStep(unsigned int stepId);
+
+  virtual void setBase(shared_ptr<XdmfItem> newBase);
+
+  /**
+   * Reads in the heavy data associated with the provided step id.
+   *
+   * @param     stepId  The id of the step whose heavy data
+   *                    is to be read in from file
+   */
+  void setStep(unsigned int stepId);
+
+  void setStep(shared_ptr<XdmfTime> time);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfGridTemplate(XdmfGridTemplate &);
+
+protected:
+
+  XdmfGridTemplate();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+  shared_ptr<XdmfArray> mTimeCollection;
+
+private:
+
+  XdmfGridTemplate(const XdmfGridTemplate &);  // Not implemented.
+  void operator=(const XdmfGridTemplate &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFGRIDTEMPLATE; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGRIDTEMPLATE XDMFGRIDTEMPLATE;
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfGridTemplate, XDMFGRIDTEMPLATE, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* XDMFGRIDTEMPLATE_HPP_ */
diff --git a/XdmfItemFactory.cpp b/XdmfItemFactory.cpp
new file mode 100644
index 0000000..7642209
--- /dev/null
+++ b/XdmfItemFactory.cpp
@@ -0,0 +1,390 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfItemFactory.cpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cctype>
+#include <boost/tokenizer.hpp>
+#include "XdmfAttribute.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfError.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridTemplate.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfItemFactory.hpp"
+#include "XdmfAggregate.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfTemplate.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+shared_ptr<XdmfItemFactory>
+XdmfItemFactory::New()
+{
+  shared_ptr<XdmfItemFactory> p(new XdmfItemFactory());
+  return p;
+}
+
+XdmfItemFactory::XdmfItemFactory()
+{
+}
+
+XdmfItemFactory::~XdmfItemFactory()
+{
+}
+
+shared_ptr<XdmfItem>
+XdmfItemFactory::createItem(const std::string & itemTag,
+                            const std::map<std::string, std::string> & itemProperties,
+                            const std::vector<shared_ptr<XdmfItem> > & childItems) const
+{
+#ifdef XDMF_BUILD_DSM
+  shared_ptr<XdmfItem> newItem =
+    XdmfDSMItemFactory::createItem(itemTag, itemProperties, childItems);
+#else
+  shared_ptr<XdmfItem> newItem =
+    XdmfCoreItemFactory::createItem(itemTag, itemProperties, childItems);
+#endif
+  
+  if(newItem) {
+    return newItem;
+  }
+
+  if(itemTag.compare(XdmfAttribute::ItemTag) == 0) {
+    return XdmfAttribute::New();
+  }
+  else if(itemTag.compare(XdmfAggregate::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("ConstructedType");
+    std::string arraySubType;
+    if(type == itemProperties.end()) {
+      // If no type is specified an array is generated
+      arraySubType = XdmfArray::ItemTag;
+    }
+    else {
+      arraySubType = type->second;
+    }
+    std::vector<shared_ptr<XdmfItem> > newArrayChildren;
+    shared_ptr<XdmfItem> createdItem = createItem(arraySubType,
+                                       itemProperties,
+                                       newArrayChildren);
+
+    shared_ptr<XdmfArray> returnArray = shared_dynamic_cast<XdmfArray>(createdItem);
+
+    shared_ptr<XdmfAggregate> returnAggregate = XdmfAggregate::New();
+
+    bool placeholderFound = false;
+    for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+          childItems.begin();
+        iter != childItems.end();
+        ++iter) {
+      if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+        if (!placeholderFound) {
+          placeholderFound = true;
+        }
+        else {
+          returnAggregate->insert(array);
+        }
+      }
+    }
+
+    returnArray->setReference(returnAggregate);
+    returnArray->setReadMode(XdmfArray::Reference);
+
+    return returnArray;
+  }
+  else if(itemTag.compare(XdmfDomain::ItemTag) == 0) {
+    return XdmfDomain::New();
+  }
+  else if(itemTag.compare(XdmfGeometry::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("Type");
+    if(type == itemProperties.end()) {
+      type = itemProperties.find("GeometryType");
+    }
+    
+    if(type != itemProperties.end()) {
+      const std::string & typeVal = type->second;
+      if(typeVal.compare("ORIGIN_DXDY") == 0 ||
+         typeVal.compare("ORIGIN_DXDYDZ") == 0 ||
+         typeVal.compare("ORIGIN_DISPLACEMENT") == 0) {
+        shared_ptr<XdmfArray> origin = shared_ptr<XdmfArray>();
+        shared_ptr<XdmfArray> brickSize = shared_ptr<XdmfArray>();
+        for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+              childItems.begin();
+            iter != childItems.end();
+            ++iter) {
+          if(shared_ptr<XdmfArray> array = 
+             shared_dynamic_cast<XdmfArray>(*iter)) {
+            if(!origin) {
+              origin = array;
+            }
+            else if(!brickSize) {
+              brickSize = array;
+              break;
+            }
+          }
+        }
+        if(origin && brickSize) {
+          return XdmfRegularGrid::New(brickSize,
+                                      shared_ptr<XdmfArray>(),
+                                      origin);
+        }
+        return shared_ptr<XdmfItem>();
+      }
+      else if(typeVal.compare("VXVY") == 0 ||
+              typeVal.compare("VXVYVZ") == 0 ||
+              typeVal.compare("VECTORED") == 0) {
+        std::vector<shared_ptr<XdmfArray> > coordinateValues;
+        for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+              childItems.begin();
+            iter != childItems.end();
+            ++iter) {
+          if(shared_ptr<XdmfArray> array = 
+             shared_dynamic_cast<XdmfArray>(*iter)) {
+            coordinateValues.push_back(array);
+          }
+        }
+        return shared_dynamic_cast<XdmfItem>(XdmfRectilinearGrid::New(coordinateValues));
+      }
+    }
+    return XdmfGeometry::New();
+  }
+  else if(itemTag.compare(XdmfGraph::ItemTag) == 0) {
+    return XdmfGraph::New(0);
+  }
+  else if(itemTag.compare(XdmfGrid::ItemTag) == 0) {
+    // For backwards compatibility with the old format, this tag can
+    // correspond to multiple XdmfItems.
+    std::map<std::string, std::string>::const_iterator gridType =
+      itemProperties.find("GridType");
+    if(gridType != itemProperties.end() &&
+       gridType->second.compare("Collection") == 0) {
+      return XdmfGridCollection::New();
+    }
+    else {
+      // Find out what kind of grid we have
+      for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+            childItems.begin();
+          iter != childItems.end();
+          ++iter) {
+        if(shared_ptr<XdmfCurvilinearGrid> curvilinear =
+           shared_dynamic_cast<XdmfCurvilinearGrid>(*iter)) {
+          return XdmfCurvilinearGrid::New(0, 0);
+        }
+        else if(shared_ptr<XdmfRegularGrid> regularGrid =
+                shared_dynamic_cast<XdmfRegularGrid>(*iter)) {
+          return XdmfRegularGrid::New(0, 0, 0, 0, 0, 0);
+        }
+        else if(shared_ptr<XdmfRectilinearGrid> rectilinearGrid =
+                shared_dynamic_cast<XdmfRectilinearGrid>(*iter)) {
+          std::vector<shared_ptr<XdmfArray> > coordinateValues;
+          return XdmfRectilinearGrid::New(coordinateValues);
+        }
+      }
+      return XdmfUnstructuredGrid::New();
+    }
+  }
+  else if(itemTag.compare(XdmfGridController::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator filename =
+      itemProperties.find("File");
+    std::map<std::string, std::string>::const_iterator xpath =
+      itemProperties.find("XPath");
+    return XdmfGridController::New(filename->second, xpath->second);
+  }
+  else if(itemTag.compare(XdmfInformation::ItemTag) == 0) {
+    return XdmfInformation::New();
+  }
+  else if(itemTag.compare(XdmfMap::ItemTag) == 0) {
+    return XdmfMap::New();
+  }
+  else if(itemTag.compare(XdmfSet::ItemTag) == 0) {
+    return XdmfSet::New();
+  }
+  else if(itemTag.compare(XdmfSparseMatrix::ItemTag) == 0) {
+    return XdmfSparseMatrix::New(0, 0);
+  }
+  else if (itemTag.compare(XdmfTemplate::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("BaseType");
+    if(type == itemProperties.end()) {
+      return XdmfTemplate::New();
+    }
+    else {
+      if (type->second.compare("Grid") == 0) {
+        return XdmfGridTemplate::New();
+      }
+      else {
+        return XdmfTemplate::New();
+      }
+    }
+    return XdmfTemplate::New();
+  }
+  else if(itemTag.compare(XdmfTime::ItemTag) == 0) {
+    return XdmfTime::New();
+  }
+  else if(itemTag.compare(XdmfTopology::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("Type");
+    if(type == itemProperties.end()) {
+      type = itemProperties.find("TopologyType");
+    }
+
+    if(type != itemProperties.end()) {
+      std::string typeVal = type->second;
+      std::transform(typeVal.begin(),
+                     typeVal.end(),
+                     typeVal.begin(),
+                     (int(*)(int))toupper);
+      if(typeVal.compare("2DCORECTMESH") == 0 ||
+         typeVal.compare("3DCORECTMESH") == 0 ||
+         typeVal.compare("CORECTMESH") == 0 ||
+         typeVal.compare("2DSMESH") == 0 ||
+         typeVal.compare("3DSMESH") == 0 ||
+         typeVal.compare("SMESH") == 0) {
+        shared_ptr<XdmfArray> dimensionsArray = XdmfArray::New();
+        std::string dimensionsString = "";
+        std::map<std::string, std::string>::const_iterator dimensions =
+          itemProperties.find("Dimensions");
+        if(dimensions != itemProperties.end()) {
+          dimensionsString = dimensions->second;
+        }
+        boost::tokenizer<> tokens(dimensionsString);
+        for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+            iter != tokens.end();
+            ++iter) {
+          dimensionsArray->pushBack<unsigned int>(atoi((*iter).c_str()));
+        }
+        if(typeVal.compare("2DCORECTMESH") == 0 ||
+           typeVal.compare("3DCORECTMESH") == 0 ||
+           typeVal.compare("CORECTMESH") == 0) {
+          return XdmfRegularGrid::New(shared_ptr<XdmfArray>(),
+                                      dimensionsArray,
+                                      shared_ptr<XdmfArray>());
+        }
+        else {
+          return XdmfCurvilinearGrid::New(dimensionsArray);
+        }
+      }
+      else if(typeVal.compare("2DRECTMESH") == 0 ||
+              typeVal.compare("3DRECTMESH") == 0 ||
+              typeVal.compare("RECTMESH") == 0) {
+        std::vector<shared_ptr<XdmfArray> > coordinateValues;
+        return XdmfRectilinearGrid::New(coordinateValues);
+      }
+
+    }
+    return XdmfTopology::New();
+  }
+  return shared_ptr<XdmfItem>();
+}
+
+bool
+XdmfItemFactory::isArrayTag(char * tag) const
+{
+#ifdef XDMF_BUILD_DSM
+  if (XdmfDSMItemFactory::isArrayTag(tag))
+  {
+    return true;
+  }
+#else
+  if (XdmfCoreItemFactory::isArrayTag(tag))
+  {
+    return true;
+  }
+#endif
+  else if (XdmfAggregate::ItemTag.compare(tag) == 0) {
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+XdmfItem *
+XdmfItemFactory::DuplicatePointer(shared_ptr<XdmfItem> original) const
+{
+#ifdef XDMF_BUILD_DSM
+  XdmfItem * returnPointer = XdmfDSMItemFactory::DuplicatePointer(original);
+#else
+  XdmfItem * returnPointer = XdmfCoreItemFactory::DuplicatePointer(original);
+#endif
+
+  if (returnPointer) {
+    return returnPointer;
+  }
+  else {
+   if (original->getItemTag().compare(XdmfTime::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfTime(*((XdmfTime *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfAttribute::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfAttribute(*((XdmfAttribute *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfDomain::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfDomain(*(shared_dynamic_cast<XdmfDomain>(original).get())));
+   }
+   else if (original->getItemTag().compare(XdmfTopology::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfTopology(*((XdmfTopology *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfGeometry::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfGeometry(*((XdmfGeometry *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfGraph::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfGraph(*((XdmfGraph *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfSet::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfSet(*((XdmfSet *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfMap::ItemTag) == 0) {
+     return (XdmfItem *)(new XdmfMap(*((XdmfMap *)original.get())));
+   }
+   else if (original->getItemTag().compare(XdmfGrid::ItemTag) == 0) {
+       if (shared_ptr<XdmfGridCollection> collection =
+           shared_dynamic_cast<XdmfGridCollection>(original)) {
+         return (XdmfItem *)(new XdmfGridCollection(*(shared_dynamic_cast<XdmfGridCollection>(original).get())));
+       }
+       else if (shared_ptr<XdmfCurvilinearGrid> curvilinear =
+           shared_dynamic_cast<XdmfCurvilinearGrid>(original)) {
+         return (XdmfItem *)(new XdmfCurvilinearGrid(*(shared_dynamic_cast<XdmfCurvilinearGrid>(original).get())));
+       }
+       else if(shared_ptr<XdmfRegularGrid> regularGrid =
+               shared_dynamic_cast<XdmfRegularGrid>(original)) {
+           return (XdmfItem *)(new XdmfRegularGrid(*(shared_dynamic_cast<XdmfRegularGrid>(original).get())));
+       }
+       else if(shared_ptr<XdmfRectilinearGrid> rectilinearGrid =
+               shared_dynamic_cast<XdmfRectilinearGrid>(original)) {
+         return (XdmfItem *)(new XdmfRectilinearGrid(*(shared_dynamic_cast<XdmfRectilinearGrid>(original).get())));
+       }
+       return (XdmfItem *)(new XdmfUnstructuredGrid(*(shared_dynamic_cast<XdmfUnstructuredGrid>(original).get())));
+   }
+  }
+  return NULL;
+}
diff --git a/XdmfItemFactory.hpp b/XdmfItemFactory.hpp
new file mode 100644
index 0000000..8c85546
--- /dev/null
+++ b/XdmfItemFactory.hpp
@@ -0,0 +1,102 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfItemFactory.hpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFITEMFACTORY_HPP_
+#define XDMFITEMFACTORY_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfCoreItemFactory.hpp"
+#ifdef XDMF_BUILD_DSM
+  #include "XdmfDSMItemFactory.hpp"
+#endif
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfItem;
+
+// Includes
+#include "Xdmf.hpp"
+#include "XdmfCoreItemFactory.hpp"
+
+/**
+ * @brief Factory for constructing XdmfItems from their ItemTag and
+ * ItemProperties.
+ */
+#ifdef XDMF_BUILD_DSM
+class XDMF_EXPORT XdmfItemFactory : public XdmfDSMItemFactory {
+#else
+class XDMF_EXPORT XdmfItemFactory : public XdmfCoreItemFactory {
+#endif
+
+public:
+
+  /**
+   * Create a new XdmfItemFactory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfItemFactory.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleItemFactory.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfItemFactory.
+   */
+  static shared_ptr<XdmfItemFactory> New();
+
+  virtual ~XdmfItemFactory();
+
+  virtual shared_ptr<XdmfItem>
+  createItem(const std::string & itemTag,
+             const std::map<std::string, std::string> & itemProperties,
+             const std::vector<shared_ptr<XdmfItem> > & childItems) const;
+
+  virtual bool isArrayTag(char * tag) const;
+
+  virtual XdmfItem *
+  DuplicatePointer(shared_ptr<XdmfItem> original) const;
+
+protected:
+
+  XdmfItemFactory();
+
+private:
+
+  XdmfItemFactory(const XdmfItemFactory &);  // Not implemented.
+  void operator=(const XdmfItemFactory &);  // Not implemented.
+
+};
+
+
+#endif
+
+#endif /* XDMFITEMFACTORY_HPP_ */
diff --git a/XdmfMap.cpp b/XdmfMap.cpp
new file mode 100644
index 0000000..46bbecf
--- /dev/null
+++ b/XdmfMap.cpp
@@ -0,0 +1,707 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfMap.cpp                                                         */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include <string.h>
+#include "XdmfAttribute.hpp"
+#include "XdmfError.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfWriter.hpp"
+
+shared_ptr<XdmfMap>
+XdmfMap::New()
+{
+  shared_ptr<XdmfMap> p(new XdmfMap());
+  return p;
+}
+
+std::vector<shared_ptr<XdmfMap> >
+XdmfMap::New(const std::vector<shared_ptr<XdmfAttribute> > & globalNodeIds)
+{
+  // globalNodeId | taskId | localNodeId at taskId
+  std::map<node_id, std::map<task_id, node_id> > globalNodeIdMap;
+
+  // fill globalNodeIdMap using globalNodeIds
+  std::vector<bool> releaseGlobalNodeIds(globalNodeIds.size(), false);
+  for(unsigned int i=0; i<globalNodeIds.size(); ++i) {
+    const shared_ptr<XdmfAttribute> currGlobalNodeIds = globalNodeIds[i];
+    if(!currGlobalNodeIds->isInitialized()) {
+      currGlobalNodeIds->read();
+      releaseGlobalNodeIds[i] = true;
+    }
+    for(unsigned int j=0; j<currGlobalNodeIds->getSize(); ++j) {
+      const node_id currGlobalNodeId = currGlobalNodeIds->getValue<node_id>(j);
+      globalNodeIdMap[currGlobalNodeId][i] = j;
+    }
+  }
+
+  std::vector<shared_ptr<XdmfMap> > returnValue;
+  returnValue.resize(globalNodeIds.size());
+
+  // fill maps for each partition
+  for(unsigned int i=0; i<globalNodeIds.size(); ++i)  {
+    shared_ptr<XdmfMap> map = XdmfMap::New();
+    returnValue[i] = map;
+    const shared_ptr<XdmfAttribute> currGlobalNodeIds = globalNodeIds[i];
+
+    for(unsigned int j=0; j<currGlobalNodeIds->getSize(); ++j) {
+      const node_id currGlobalNodeId = currGlobalNodeIds->getValue<node_id>(j);
+      const std::map<task_id, node_id> & currMap = 
+        globalNodeIdMap[currGlobalNodeId];
+      if(currMap.size() > 1) {
+        for(std::map<task_id, node_id>::const_iterator iter = currMap.begin();
+            iter != currMap.end();
+            ++iter) {
+          if(iter->first != (int)i) {
+            map->insert(iter->first, j, iter->second);
+          }
+        }
+      }
+    }
+    if(releaseGlobalNodeIds[i]) {
+      currGlobalNodeIds->release();
+    }
+  }
+
+  return returnValue;
+}
+
+XdmfMap::XdmfMap() :
+  mName("")
+{
+}
+
+XdmfMap::XdmfMap(XdmfMap & refMap):
+  mLocalNodeIdsControllers(refMap.mLocalNodeIdsControllers),
+  mMap(refMap.mMap),
+  mName(refMap.mName),
+  mRemoteLocalNodeIdsControllers(refMap.mRemoteLocalNodeIdsControllers),
+  mRemoteTaskIdsControllers(refMap.mRemoteTaskIdsControllers)
+{
+}
+
+XdmfMap::~XdmfMap()
+{
+}
+
+const std::string XdmfMap::ItemTag = "Map";
+
+std::map<std::string, std::string>
+XdmfMap::getItemProperties() const
+{
+  std::map<std::string, std::string> mapProperties;
+  mapProperties.insert(std::make_pair("Name", mName));
+  return mapProperties;
+}
+
+std::string
+XdmfMap::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::map<XdmfMap::task_id, XdmfMap::node_id_map>
+XdmfMap::getMap() const
+{
+  return mMap;
+}
+
+std::string
+XdmfMap::getName() const
+{
+  return mName;
+}
+
+XdmfMap::node_id_map
+XdmfMap::getRemoteNodeIds(const task_id remoteTaskId)
+{
+  std::map<task_id, node_id_map>::const_iterator iter =
+    mMap.find(remoteTaskId);
+  if(iter != mMap.end()) {
+    return iter->second;
+  }
+  // No entry, return empty map.
+  return node_id_map();
+}
+
+void
+XdmfMap::insert(const task_id remoteTaskId,
+                const node_id localNodeId,
+                const node_id remoteLocalNodeId)
+{
+  mMap[remoteTaskId][localNodeId].insert(remoteLocalNodeId);
+  this->setIsChanged(true);
+}
+
+bool XdmfMap::isInitialized() const
+{
+  return mMap.size() > 0;
+}
+
+void
+XdmfMap::populateItem(const std::map<std::string, std::string> & itemProperties,
+                      const std::vector<shared_ptr<XdmfItem> > & childItems,
+                      const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  std::map<std::string, std::string>::const_iterator name =
+    itemProperties.find("Name");
+  if(name != itemProperties.end()) {
+    mName = name->second;
+  }
+  else {
+    mName = "";
+  }
+  std::vector<shared_ptr<XdmfArray> > arrayVector;
+  arrayVector.reserve(3);
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+      arrayVector.push_back(array);
+    }
+  }
+
+  if(arrayVector.size() != 0) {
+    if(arrayVector.size() != 3) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Expected 3 arrays attached to "
+                         "XdmfMap::populateItem");
+    }
+    if(!(arrayVector[0]->getSize() == arrayVector[1]->getSize() &&
+         arrayVector[0]->getSize() == arrayVector[2]->getSize())) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Arrays must be of equal size in "
+                         "XdmfMap:: populateItem");
+    }
+
+    // check if any arrays have values in memory - if so, they need to be
+    // read into map
+    bool needToRead = false;
+    for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
+          arrayVector.begin();
+        iter != arrayVector.end();
+        ++iter) {
+      if((*iter)->isInitialized()) {
+        needToRead = true;
+        break;
+      }
+    }
+
+    if(needToRead) {
+      for(std::vector<shared_ptr<XdmfArray> >::const_iterator iter =
+            arrayVector.begin();
+          iter != arrayVector.end();
+          ++iter) {
+        if(!(*iter)->isInitialized()) {
+          (*iter)->read();
+        }
+      }
+      for(unsigned int i=0; i<arrayVector[0]->getSize(); ++i) {
+        this->insert(arrayVector[0]->getValue<task_id>(i),
+                     arrayVector[1]->getValue<node_id>(i),
+                     arrayVector[2]->getValue<node_id>(i));
+      }
+    }
+    else {
+
+      mRemoteTaskIdsControllers.clear();
+      for (unsigned int i = 0; i <  arrayVector[0]->getNumberHeavyDataControllers(); ++i)
+      {
+        mRemoteTaskIdsControllers.push_back(arrayVector[0]->getHeavyDataController(i));
+      }
+      mLocalNodeIdsControllers.clear();
+      for (unsigned int i = 0; i <  arrayVector[1]->getNumberHeavyDataControllers(); ++i)
+      {
+        mLocalNodeIdsControllers.push_back(arrayVector[1]->getHeavyDataController(i));
+      }
+      mRemoteLocalNodeIdsControllers.clear();
+      for (unsigned int i = 0; i <  arrayVector[2]->getNumberHeavyDataControllers(); ++i)
+      {
+        mRemoteLocalNodeIdsControllers.push_back(arrayVector[2]->getHeavyDataController(i));
+      }
+    }
+  }
+}
+
+void
+XdmfMap::read()
+{
+  if(mLocalNodeIdsControllers.size() > 0 &&
+     mRemoteTaskIdsControllers.size() > 0 &&
+     mRemoteLocalNodeIdsControllers.size() > 0) {
+
+    unsigned int localNodeCount = 0;
+    for (unsigned int i = 0; i< mLocalNodeIdsControllers.size(); ++i)
+    {
+      localNodeCount += mLocalNodeIdsControllers[i]->getSize();
+    }
+    unsigned int remoteTaskCount = 0;
+    for (unsigned int i = 0; i< mRemoteTaskIdsControllers.size(); ++i)
+    {
+      remoteTaskCount += mRemoteTaskIdsControllers[i]->getSize();
+    }
+    unsigned int remoteNodeCount = 0;
+    for (unsigned int i = 0; i< mRemoteLocalNodeIdsControllers.size(); ++i)
+    {
+      remoteNodeCount += mRemoteLocalNodeIdsControllers[i]->getSize();
+    }
+
+    if(!(localNodeCount ==
+         remoteTaskCount &&
+         localNodeCount ==
+         remoteNodeCount)){
+      XdmfError::message(XdmfError::FATAL,
+                         "Arrays must be of equal size in XdmfMap::read");
+    }
+
+    shared_ptr<XdmfArray> remoteTaskIds = XdmfArray::New();
+    shared_ptr<XdmfArray> localNodeIds = XdmfArray::New();
+    shared_ptr<XdmfArray> remoteLocalNodeIds = XdmfArray::New();
+
+    mRemoteTaskIdsControllers[0]->read(remoteTaskIds.get());
+    for (unsigned int i = 1; i < mRemoteTaskIdsControllers.size(); ++i)
+    {
+      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+      mRemoteTaskIdsControllers[i]->read(tempArray.get());
+      remoteTaskIds->insert(remoteTaskIds->getSize(), tempArray, 0, tempArray->getSize());
+    }
+    mLocalNodeIdsControllers[0]->read(localNodeIds.get());
+    for (unsigned int i = 1; i < mLocalNodeIdsControllers.size(); ++i)
+    {
+      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+      mLocalNodeIdsControllers[i]->read(tempArray.get());
+      localNodeIds->insert(localNodeIds->getSize(), tempArray, 0, tempArray->getSize());
+    }
+    mRemoteLocalNodeIdsControllers[0]->read(remoteLocalNodeIds.get());
+    for (unsigned int i = 1; i < mRemoteLocalNodeIdsControllers.size(); ++i)
+    {
+      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+      mRemoteLocalNodeIdsControllers[i]->read(tempArray.get());
+      remoteLocalNodeIds->insert(remoteLocalNodeIds->getSize(), tempArray, 0, tempArray->getSize());
+    }
+
+    for(unsigned int i=0; i<remoteTaskIds->getSize(); ++i) {
+      const unsigned int remoteTaskId = remoteTaskIds->getValue<task_id>(i);
+      const unsigned int localNodeId = localNodeIds->getValue<node_id>(i);
+      const unsigned int remoteLocalNodeId =
+        remoteLocalNodeIds->getValue<node_id>(i);
+      mMap[remoteTaskId][localNodeId].insert(remoteLocalNodeId);
+    }
+  }
+}
+
+
+void
+XdmfMap::release()
+{
+  mMap.clear();
+}
+
+void
+XdmfMap::setHeavyDataControllers(std::vector<shared_ptr<XdmfHeavyDataController> > remoteTaskIdsControllers,
+                                 std::vector<shared_ptr<XdmfHeavyDataController> > localNodeIdsControllers,
+                                 std::vector<shared_ptr<XdmfHeavyDataController> > remoteLocalNodeIdsControllers)
+{
+  unsigned int localNodeCount = 0;
+  for (unsigned int i = 0; i< localNodeIdsControllers.size(); ++i)
+  {
+    localNodeCount += localNodeIdsControllers[i]->getSize();
+  }
+  unsigned int remoteTaskCount = 0;
+  for (unsigned int i = 0; i< remoteTaskIdsControllers.size(); ++i)
+  {
+    remoteTaskCount += remoteTaskIdsControllers[i]->getSize();
+  }
+  unsigned int remoteNodeCount = 0;
+  for (unsigned int i = 0; i< remoteLocalNodeIdsControllers.size(); ++i)
+  {
+    remoteNodeCount += remoteLocalNodeIdsControllers[i]->getSize();
+  }
+  if(!(localNodeCount ==
+       remoteTaskCount &&
+       localNodeCount ==
+       remoteNodeCount)) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Arrays must be of equal size in "
+                       "XdmfMap::setHeavyDataControllers");
+  }
+  mRemoteTaskIdsControllers = remoteTaskIdsControllers;
+  mLocalNodeIdsControllers = localNodeIdsControllers;
+  mRemoteLocalNodeIdsControllers = remoteLocalNodeIdsControllers;
+  this->setIsChanged(true);
+}
+
+void 
+XdmfMap::setMap(std::map<task_id, node_id_map> map)
+{
+  mMap = map;
+  this->setIsChanged(true);
+}
+
+void
+XdmfMap::setName(const std::string & name)
+{
+  mName = name;
+  this->setIsChanged(true);
+}
+
+void
+XdmfMap::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+
+  shared_ptr<XdmfArray> remoteTaskIds = XdmfArray::New();
+  shared_ptr<XdmfArray> localNodeIds = XdmfArray::New();
+  shared_ptr<XdmfArray> remoteLocalNodeIds = XdmfArray::New();
+
+  for(std::map<task_id, node_id_map>::const_iterator
+        iter = mMap.begin();
+      iter != mMap.end();
+      ++iter) {
+    for(node_id_map::const_iterator
+          iter2 = iter->second.begin();
+        iter2 != iter->second.end();
+        ++iter2) {
+      for(node_id_map::mapped_type::const_iterator iter3 =
+            iter2->second.begin();
+          iter3 != iter2->second.end();
+          ++iter3) {
+        remoteTaskIds->pushBack(iter->first);
+        localNodeIds->pushBack(iter2->first);
+        remoteLocalNodeIds->pushBack(*iter3);
+      }
+    }
+  }
+
+  for (unsigned int i = 0; i < mRemoteTaskIdsControllers.size(); ++i)
+  {
+    remoteTaskIds->insert(mRemoteTaskIdsControllers[i]);
+  }
+  for (unsigned int i = 0; i < mLocalNodeIdsControllers.size(); ++i)
+  {
+    localNodeIds->insert(mLocalNodeIdsControllers[i]);
+  }
+  for (unsigned int i = 0; i < mRemoteLocalNodeIdsControllers.size(); ++i)
+  {
+    remoteLocalNodeIds->insert(mRemoteLocalNodeIdsControllers[i]);
+  }
+
+  bool originalXPath;
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    originalXPath = writer->getWriteXPaths();
+    writer->setWriteXPaths(false);
+  }
+
+  remoteTaskIds->accept(visitor);
+  localNodeIds->accept(visitor);
+  remoteLocalNodeIds->accept(visitor);
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    writer->setWriteXPaths(originalXPath);
+  }
+
+  mLocalNodeIdsControllers.clear();
+  mRemoteTaskIdsControllers.clear();
+  mRemoteLocalNodeIdsControllers.clear();
+
+  for (unsigned int i = 0; i < remoteTaskIds->getNumberHeavyDataControllers(); ++i)
+  {
+    mRemoteTaskIdsControllers.push_back(remoteTaskIds->getHeavyDataController(i));
+  }
+  for (unsigned int i = 0; i < localNodeIds->getNumberHeavyDataControllers(); ++i)
+  {
+    mLocalNodeIdsControllers.push_back(localNodeIds->getHeavyDataController(i));
+  }
+  for (unsigned int i = 0; i < remoteLocalNodeIds->getNumberHeavyDataControllers(); ++i)
+  {
+    mRemoteLocalNodeIdsControllers.push_back(remoteLocalNodeIds->getHeavyDataController(i));
+  }
+
+  remoteTaskIds.reset();
+  localNodeIds.reset();
+  remoteLocalNodeIds.reset();
+}
+
+// C Wrappers
+
+XDMFMAP * XdmfMapNew()
+{
+  try
+  {
+    shared_ptr<XdmfMap> generatedMap = XdmfMap::New();
+    return (XDMFMAP *)((void *)(new XdmfMap(*generatedMap.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfMap> generatedMap = XdmfMap::New();
+    return (XDMFMAP *)((void *)(new XdmfMap(*generatedMap.get())));
+  }
+}
+
+XDMFMAP ** XdmfMapNewFromIdVector(int ** globalNodeIds, int * numIdsOnNode, int numIds)
+{
+  try
+  {
+    std::vector<shared_ptr<XdmfAttribute> > insertedAttributeVector;
+    for (int i = 0; i < numIds; ++i) {
+      shared_ptr<XdmfAttribute> insertedAttribute = XdmfAttribute::New();
+      insertedAttribute->insert(0, globalNodeIds[i], numIdsOnNode[i], 1, 1);
+      insertedAttributeVector.push_back(insertedAttribute);
+    }
+    std::vector<shared_ptr<XdmfMap> > generatedMaps = XdmfMap::New(insertedAttributeVector);
+    unsigned int returnSize = generatedMaps.size();
+    XDMFMAP ** returnArray = new XDMFMAP *[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = (XDMFMAP *)((void *)(new XdmfMap(*generatedMaps[i].get())));
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<shared_ptr<XdmfAttribute> > insertedAttributeVector;
+    for (int i = 0; i < numIds; ++i) {
+      shared_ptr<XdmfAttribute> insertedAttribute = XdmfAttribute::New();
+      insertedAttribute->insert(0, globalNodeIds[i], numIdsOnNode[i], 1, 1);
+      insertedAttributeVector.push_back(insertedAttribute);
+    }
+    std::vector<shared_ptr<XdmfMap> > generatedMaps = XdmfMap::New(insertedAttributeVector);
+    unsigned int returnSize = generatedMaps.size();
+    XDMFMAP ** returnArray = new XDMFMAP *[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = (XDMFMAP *)((void *)(new XdmfMap(*generatedMaps[i].get())));
+    }
+    return returnArray;
+  }
+}
+
+char * XdmfMapGetName(XDMFMAP * map)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfMap *)(map))->getName().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfMap *)(map))->getName().c_str());
+    return returnPointer;
+  }
+}
+
+void XdmfMapInsert(XDMFMAP * map, int remoteTaskId, int localNodeId, int remoteLocalNodeId)
+{
+  ((XdmfMap *)(map))->insert(remoteTaskId, localNodeId, remoteLocalNodeId);
+}
+
+int XdmfMapIsInitialized(XDMFMAP * map)
+{
+  return ((XdmfMap *)(map))->isInitialized();
+}
+
+void XdmfMapRead(XDMFMAP * map, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfMap *)(map))->read();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfMapRelease(XDMFMAP * map)
+{
+  ((XdmfMap *)(map))->release();
+}
+
+int * XdmfMapRetrieveLocalNodeIds(XDMFMAP * map, int remoteTaskId)
+{
+  try
+  {
+    int * returnPointer = new int[XdmfMapRetrieveNumberLocalNodeIds(map, remoteTaskId)]();
+    std::map<int, std::map<int, std::set<int> > > testMap = ((XdmfMap *)(map))->getMap();
+    std::map<int, std::map<int, std::set<int> > >::const_iterator iter = testMap.find(remoteTaskId);
+    unsigned int i = 0;
+    for(std::map<int, std::set<int> >::const_iterator
+          iter2 = iter->second.begin();
+        iter2 != iter->second.end();
+        ++iter2) {
+      returnPointer[i] = iter2->first;
+      ++i;
+    }
+    return returnPointer;
+  }
+  catch (...)
+  {
+    int * returnPointer = new int[XdmfMapRetrieveNumberLocalNodeIds(map, remoteTaskId)]();
+    std::map<int, std::map<int, std::set<int> > > testMap = ((XdmfMap *)(map))->getMap();
+    std::map<int, std::map<int, std::set<int> > >::const_iterator iter = testMap.find(remoteTaskId);
+    unsigned int i = 0;
+    for(std::map<int, std::set<int> >::const_iterator
+          iter2 = iter->second.begin();
+        iter2 != iter->second.end();
+        ++iter2) {
+      returnPointer[i] = iter2->first;
+      ++i;
+    }
+    return returnPointer;
+  }
+}
+
+int XdmfMapRetrieveNumberLocalNodeIds(XDMFMAP * map, int remoteTaskId)
+{
+  return ((XdmfMap *)(map))->getMap()[remoteTaskId].size();
+}
+
+int XdmfMapRetrieveNumberRemoteTaskIds(XDMFMAP * map)
+{
+  return ((XdmfMap *)(map))->getMap().size();
+}
+
+int XdmfMapRetrieveNumberRemoteNodeIds(XDMFMAP * map, int remoteTaskId, int localNodeId)
+{
+  return ((XdmfMap *)(map))->getMap()[remoteTaskId][localNodeId].size();
+}
+
+int * XdmfMapRetrieveRemoteTaskIds(XDMFMAP * map)
+{
+  try
+  {
+    int * returnPointer = new int[((XdmfMap *)(map))->getMap().size()]();
+    std::map<int, std::map<int, std::set<int> > > testMap = ((XdmfMap *)(map))->getMap();
+    unsigned int i = 0;
+    for(std::map<int, std::map<int, std::set<int> > >::const_iterator
+          iter = testMap.begin();
+        iter != testMap.end();
+        ++iter) {
+      returnPointer[i] = iter->first;
+      ++i;
+    }
+    return returnPointer;
+  }
+  catch (...)
+  {
+    int * returnPointer = new int[((XdmfMap *)(map))->getMap().size()]();
+    std::map<int, std::map<int, std::set<int> > > testMap = ((XdmfMap *)(map))->getMap();
+    unsigned int i = 0;
+    for(std::map<int, std::map<int, std::set<int> > >::const_iterator
+          iter = testMap.begin();
+        iter != testMap.end();
+        ++iter) {
+      returnPointer[i] = iter->first;
+      ++i;
+    }
+    return returnPointer;
+  }
+}
+
+int * XdmfMapRetrieveRemoteNodeIds(XDMFMAP * map, int remoteTaskId, int localNodeId)
+{
+  try
+  {
+    int * returnPointer = new int[XdmfMapRetrieveNumberRemoteNodeIds(map, remoteTaskId, localNodeId)]();
+    std::map<int, std::map<int, std::set<int> > > testMap = ((XdmfMap *)(map))->getMap();
+    std::map<int, std::map<int, std::set<int> > >::const_iterator iter = testMap.find(remoteTaskId);
+    std::map<int, std::set<int> >::const_iterator iter2 = iter->second.find(localNodeId);
+    unsigned int i = 0;
+    for(std::map<int, std::set<int> >::mapped_type::const_iterator iter3 =
+          iter2->second.begin();
+        iter3 != iter2->second.end();
+        ++iter3) {
+      returnPointer[i] = *iter3;
+      i++;
+    }
+    return returnPointer;
+  }
+  catch (...)
+  {
+    int * returnPointer = new int[XdmfMapRetrieveNumberRemoteNodeIds(map, remoteTaskId, localNodeId)]();
+    std::map<int, std::map<int, std::set<int> > > testMap = ((XdmfMap *)(map))->getMap();
+    std::map<int, std::map<int, std::set<int> > >::const_iterator iter = testMap.find(remoteTaskId);
+    std::map<int, std::set<int> >::const_iterator iter2 = iter->second.find(localNodeId);
+    unsigned int i = 0;
+    for(std::map<int, std::set<int> >::mapped_type::const_iterator iter3 =
+          iter2->second.begin();
+        iter3 != iter2->second.end();
+        ++iter3) {
+      returnPointer[i] = *iter3;
+      i++;
+    }
+    return returnPointer;
+  }
+}
+
+void XdmfMapSetHeavyDataControllers(XDMFMAP * map,
+                                    XDMFHEAVYDATACONTROLLER ** remoteTaskControllers,
+                                    int numRemoteTaskControllers,
+                                    XDMFHEAVYDATACONTROLLER ** localNodeControllers,
+                                    int numLocalNodeControllers,
+                                    XDMFHEAVYDATACONTROLLER ** remoteLocalNodeControllers,
+                                    int numRemoteLocalNodeControllers,
+                                    int passControl,
+                                    int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<shared_ptr<XdmfHeavyDataController> > insertRemoteTaskControllers;
+  for (int i = 0; i < numRemoteTaskControllers; ++i) {
+    if (passControl) {
+      insertRemoteTaskControllers.push_back(shared_ptr<XdmfHeavyDataController>(((XdmfHeavyDataController *)remoteTaskControllers[i])));
+    }
+    else {
+      insertRemoteTaskControllers.push_back(shared_ptr<XdmfHeavyDataController>(((XdmfHeavyDataController *)remoteTaskControllers[i]), XdmfNullDeleter()));
+    }
+  }
+
+  std::vector<shared_ptr<XdmfHeavyDataController> > insertLocalNodeControllers;
+  for (int i = 0; i < numLocalNodeControllers; ++i) {
+    if (passControl) {
+      insertLocalNodeControllers.push_back(shared_ptr<XdmfHeavyDataController>(((XdmfHeavyDataController *)localNodeControllers[i])));
+    }
+    else {
+      insertLocalNodeControllers.push_back(shared_ptr<XdmfHeavyDataController>(((XdmfHeavyDataController *)localNodeControllers[i]), XdmfNullDeleter()));
+    }
+  }
+
+  std::vector<shared_ptr<XdmfHeavyDataController> > insertRemoteLocalNodeControllers;
+  for (int i = 0; i < numRemoteLocalNodeControllers; ++i) {
+    if (passControl) {
+      insertRemoteLocalNodeControllers.push_back(shared_ptr<XdmfHeavyDataController>(((XdmfHeavyDataController *)remoteLocalNodeControllers[i])));
+    }
+    else {
+      insertRemoteLocalNodeControllers.push_back(shared_ptr<XdmfHeavyDataController>(((XdmfHeavyDataController *)remoteLocalNodeControllers[i]), XdmfNullDeleter()));
+    }
+  }
+  ((XdmfMap *)(map))->setHeavyDataControllers(insertRemoteTaskControllers, insertLocalNodeControllers, insertRemoteLocalNodeControllers);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfMapSetName(XDMFMAP * map, char * newName)
+{
+  ((XdmfMap *)(map))->setName(std::string(newName));
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfMap, XDMFMAP)
diff --git a/XdmfMap.hpp b/XdmfMap.hpp
new file mode 100644
index 0000000..aca1ae5
--- /dev/null
+++ b/XdmfMap.hpp
@@ -0,0 +1,481 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfMap.hpp                                                         */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFMAP_HPP_
+#define XDMFMAP_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+class XdmfAttribute;
+class XdmfHeavyDataController;
+
+// Includes
+
+#include <set>
+
+/**
+ * @brief Boundary communicator map for partitioned spatial
+ * collections.
+ *
+ * Provides mechanism for mapping nodes across partition
+ * boundaries. Each partitioned grid contains its own map, mapping its
+ * own nodes to all other nodes in the global system.
+ *
+ * There are two methods for constructing XdmfMaps:
+ *
+ * Calling New() with no parameters will construct an empty map. The
+ * map can be filled manually with subsequent insert commands.
+ *
+ * Calling New(const std::vector<shared_ptr<XdmfAttribute> > &
+ * globalNodeIds) will construct XdmfMaps for each grid in an entire
+ * global system. Each entry in the vector contains the globalNodeIds
+ * for that partition. The constructor accepts global node ids for
+ * each partition to construct the proper XdmfMaps.
+ */
+class XDMF_EXPORT XdmfMap : public XdmfItem {
+
+public:
+
+  typedef int node_id;
+  typedef int task_id;
+  typedef std::map<node_id, std::set<node_id> > node_id_map;
+
+  /**
+   * Create a new XdmfMap.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfMap.
+   */
+  static shared_ptr<XdmfMap> New();
+
+  /**
+   * Create XdmfMaps for each grid in a domain decomposed mesh. Each
+   * entry in the globalNodeIds vector contains the global node ids
+   * for that partition.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initializationnode
+   * @until //#initializationnode
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initializationnode
+   * @until #//initializationnode
+   *
+   * @param     globalNodeIds   A vector of attributes containing globalNodeId
+   *                            values for each partition to be mapped.
+   *
+   * @return                    Constructed XdmfMaps for each partition. The
+   *                            size of the vector will be the same as the
+   *                            globalNodeIds vector.
+   */
+  static std::vector<shared_ptr<XdmfMap> >
+  New(const std::vector<shared_ptr<XdmfAttribute> > & globalNodeIds);
+
+  virtual ~XdmfMap();
+
+  LOKI_DEFINE_VISITABLE(XdmfMap, XdmfItem)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  /**
+   * Get stored boundary communicator map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getMap
+   * @until //#getMap
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getMap
+   * @until #//getMap
+   *
+   * @return    Stored boundary communicator map.
+   */
+  std::map<task_id, node_id_map> getMap() const;
+
+  /**
+   * Get name of boundary communicator map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    Name of boundary communicator map.
+   */
+  std::string getName() const;
+
+  /**
+   * Given a remote task id return a map of local node ids to remote
+   * node ids
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getRemoteNodeIds
+   * @until //#getRemoteNodeIds
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getRemoteNodeIds
+   * @until #//getRemoteNodeIds
+   *
+   * @param     remoteTaskId    Task id to retrieve mapping for.
+   *
+   * @return                    A map of local node ids to a vector of
+   *                            remote node ids on remoteTaskId.
+   */
+  node_id_map getRemoteNodeIds(const task_id remoteTaskId);
+
+  std::string getItemTag() const;
+
+  using XdmfItem::insert;
+
+  /**
+   * Insert a new entry in map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#inserttuple
+   * @until //#inserttuple
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//inserttuple
+   * @until #//inserttuple
+   *
+   * @param     remoteTaskId            task id where the remoteLoalNodeId is
+   *                                    located.
+   * @param     localNodeId             The node id of the node being mapped.
+   * @param     remoteLocalNodeId       A node id on the remoteTaskId that the
+   *                                    localNodeId is mapped to.
+   */
+  void insert(const task_id  remoteTaskId,
+              const node_id  localNodeId,
+              const node_id  remoteLocalNodeId);
+
+  /**
+   * Returns whether the map is initialized (contains values in
+   * memory).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#isInitialized
+   * @until //#isInitialized
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline #//isInitialized
+   * @until #//isInitialized
+   *
+   * @return    bool true if map contains values in memory.
+   */
+  bool isInitialized() const;
+
+  /**
+   * Read data from disk into memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#isInitialized
+   * @until //#isInitialized
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline #//isInitialized
+   * @until #//isInitialized
+   */
+  void read();
+
+  /**
+   * Release all data held in memory. The heavy data remain attached.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#release
+   * @until //#release
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline #//release
+   * @until #//release
+   */
+  void release();
+
+  /**
+   * Set the heavy data controllers for this map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setHeavyDataController
+   * @until //#setHeavyDataController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline #//setHeavyDataController
+   * @until #//setHeavyDataController
+   *
+   * @param     remoteTaskIdsControllers        A vector of XdmfHeavyDataControllers 
+   *                                            to the remote task ids dataset.
+   * @param     localNodeIdsControllers         A vector of XdmfHeavyDataControllers
+   *                                            to the local node ids dataset.
+   * @param     remoteLocalNodeIdsControllers   A vector of XdmfHeavyDataControllers
+   *                                            to the remote local node ids dataset.
+   */
+  void
+  setHeavyDataControllers(std::vector<shared_ptr<XdmfHeavyDataController> > remoteTaskIdsControllers,
+                          std::vector<shared_ptr<XdmfHeavyDataController> > localNodeIdsControllers,
+                          std::vector<shared_ptr<XdmfHeavyDataController> > remoteLocalNodeIdsControllers);
+
+  /**
+   * Set the boundary communicator map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setMap
+   * @until //#setMap
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setMap
+   * @until #//setMap
+   *
+   * @param     map     The boundary communicator map to store.
+   */
+  void setMap(std::map<task_id, node_id_map> map);
+
+  /**
+   * Set the name of the boundary communicator map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfMap.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleMap.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   *
+   * @param     name    The name of the boundary communicator map to set.
+   */
+  void setName(const std::string & name);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfMap(XdmfMap & map);
+
+protected:
+
+  XdmfMap();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfMap(const XdmfMap & map);  // Not implemented.
+  void operator=(const XdmfMap & map);  // Not implemented.
+
+  std::vector<shared_ptr<XdmfHeavyDataController> > mLocalNodeIdsControllers;
+  // remoteTaskId | localNodeId | remoteLocalNodeId
+  std::map<task_id, node_id_map > mMap;
+  std::string mName;
+  std::vector<shared_ptr<XdmfHeavyDataController> > mRemoteLocalNodeIdsControllers;
+  std::vector<shared_ptr<XdmfHeavyDataController> > mRemoteTaskIdsControllers;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFMAP; // Simply as a typedef to ensure correct typing
+typedef struct XDMFMAP XDMFMAP;
+
+XDMF_EXPORT XDMFMAP * XdmfMapNew();
+
+XDMF_EXPORT XDMFMAP ** XdmfMapNewFromIdVector(int ** globalNodeIds, int * numIdsOnNode, int numIds);
+
+XDMF_EXPORT char * XdmfMapGetName(XDMFMAP * map);
+
+XDMF_EXPORT void XdmfMapInsert(XDMFMAP * map, int remoteTaskId, int localNodeId, int remoteLocalNodeId);
+
+XDMF_EXPORT int XdmfMapIsInitialized(XDMFMAP * map);
+
+XDMF_EXPORT void XdmfMapRead(XDMFMAP * map, int * status);
+
+XDMF_EXPORT void XdmfMapRelease(XDMFMAP * map);
+
+XDMF_EXPORT int * XdmfMapRetrieveLocalNodeIds(XDMFMAP * map, int remoteTaskId);
+
+XDMF_EXPORT int XdmfMapRetrieveNumberLocalNodeIds(XDMFMAP * map, int remoteTaskId);
+
+XDMF_EXPORT int XdmfMapRetrieveNumberRemoteTaskIds(XDMFMAP * map);
+
+XDMF_EXPORT int XdmfMapRetrieveNumberRemoteNodeIds(XDMFMAP * map, int remoteTaskId, int localNodeId);
+
+XDMF_EXPORT int * XdmfMapRetrieveRemoteTaskIds(XDMFMAP * map);
+
+XDMF_EXPORT int * XdmfMapRetrieveRemoteNodeIds(XDMFMAP * map, int remoteTaskId, int localNodeId);
+
+XDMF_EXPORT void XdmfMapSetHeavyDataControllers(XDMFMAP * map,
+                                                XDMFHEAVYDATACONTROLLER ** remoteTaskControllers,
+                                                int numRemoteTaskControllers,
+                                                XDMFHEAVYDATACONTROLLER ** localNodeControllers,
+                                                int numberLocalNodeControllers,
+                                                XDMFHEAVYDATACONTROLLER ** remoteLocalNodeControllers,
+                                                int numRemoteLocalNodeControllers,
+                                                int passControl,
+                                                int * status);
+
+XDMF_EXPORT void XdmfMapSetName(XDMFMAP * map, char * newName);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfMap, XDMFMAP, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFMAP_HPP_ */
diff --git a/XdmfReader.cpp b/XdmfReader.cpp
new file mode 100644
index 0000000..8af91fd
--- /dev/null
+++ b/XdmfReader.cpp
@@ -0,0 +1,83 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfReader.cpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfItemFactory.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfError.hpp"
+
+shared_ptr<XdmfReader>
+XdmfReader::New()
+{
+  shared_ptr<XdmfReader> p(new XdmfReader());
+  return p;
+}
+
+XdmfReader::XdmfReader() :
+  XdmfCoreReader(XdmfItemFactory::New())
+{
+}
+
+XdmfReader::XdmfReader(const XdmfReader &) :
+  XdmfCoreReader(XdmfItemFactory::New())
+{
+}
+
+XdmfReader::~XdmfReader()
+{
+}
+
+XdmfItem *
+XdmfReader::DuplicatePointer(shared_ptr<XdmfItem> original) const
+{
+  return XdmfCoreReader::DuplicatePointer(original);
+}
+
+// Implemented to make SWIG wrapping work correctly
+// (typemaps to return specific subclass instances of XdmfItems)
+shared_ptr<XdmfItem>
+XdmfReader::read(const std::string & filePath) const
+{
+  return XdmfCoreReader::read(filePath);
+}
+
+std::vector<shared_ptr<XdmfItem> >
+XdmfReader::read(const std::string & filePath,
+                 const std::string & xPath) const
+{
+  return XdmfCoreReader::read(filePath, xPath);
+}
+
+// C Wrappers
+
+XDMFREADER * XdmfReaderNew()
+{
+  shared_ptr<XdmfReader> returnReader = XdmfReader::New();
+  return (XDMFREADER *)((void *)(new XdmfReader(*returnReader.get())));
+}
+
+void XdmfReaderFree(XDMFREADER * item)
+{
+  delete ((XdmfReader *)item);
+}
+
+XDMF_CORE_READER_C_CHILD_WRAPPER(XdmfReader, XDMFREADER)
diff --git a/XdmfReader.hpp b/XdmfReader.hpp
new file mode 100644
index 0000000..bc3301e
--- /dev/null
+++ b/XdmfReader.hpp
@@ -0,0 +1,115 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfReader.hpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFREADER_HPP_
+#define XDMFREADER_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfCoreReader.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Reads an Xdmf file stored on disk into memory.
+ *
+ * Reads an Xdmf file stored on disk into an Xdmf structure in
+ * memory. All light data is parsed in order to create appropriate
+ * Xdmf objects. Heavy data controllers are created and attached to
+ * XdmfArrays but no heavy data is read into memory.
+ */
+class XDMF_EXPORT XdmfReader : public XdmfCoreReader {
+
+public:
+
+  /**
+   * Create a new XdmfReader.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfReader.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleReader.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfReader.
+   */
+  static shared_ptr<XdmfReader> New();
+
+  virtual ~XdmfReader();
+
+  /**
+   * Uses the internal item factory to create a copy of the internal pointer
+   * of the provided shared pointer. Primarily used for C wrapping.
+   *
+   * @param     original        The source shared pointer that the pointer will be pulled from.
+   * @return                    A duplicate of the object contained in the pointer.
+   */
+  virtual XdmfItem * DuplicatePointer(shared_ptr<XdmfItem> original) const;
+
+  shared_ptr<XdmfItem> read(const std::string & filePath) const;
+
+  std::vector<shared_ptr<XdmfItem> >
+  read(const std::string & filePath,
+       const std::string & xPath) const;
+
+  XdmfReader(const XdmfReader &);
+
+protected:
+
+  XdmfReader();
+
+private:
+
+  void operator=(const XdmfReader &);  // Not implemented.
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFREADER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFREADER XDMFREADER;
+
+XDMF_EXPORT XDMFREADER * XdmfReaderNew();
+
+XDMF_EXPORT void XdmfReaderFree(XDMFREADER * item);
+
+XDMF_CORE_READER_C_CHILD_DECLARE(XdmfReader, XDMFREADER, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFREADER_HPP_ */
diff --git a/XdmfRectilinearGrid.cpp b/XdmfRectilinearGrid.cpp
new file mode 100644
index 0000000..8ec1a00
--- /dev/null
+++ b/XdmfRectilinearGrid.cpp
@@ -0,0 +1,677 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfRectilinearGrid.cpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cmath>
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfError.hpp"
+
+/**
+ * PIMPL
+ */
+class XdmfRectilinearGrid::XdmfRectilinearGridImpl : public XdmfGridImpl {
+
+public:
+
+  class XdmfGeometryRectilinear : public XdmfGeometry
+  {
+
+  public:
+
+    static shared_ptr<XdmfGeometryRectilinear>
+    New(XdmfRectilinearGrid * const rectilinearGrid)
+    {
+      shared_ptr<XdmfGeometryRectilinear>
+        p(new XdmfGeometryRectilinear(rectilinearGrid));
+      return p;
+    }
+
+    unsigned int
+    getNumberPoints() const
+    {
+      const shared_ptr<const XdmfArray> dimensions =
+        mRectilinearGrid->getDimensions();
+      if(dimensions->getSize() == 0) {
+        return 0;
+      }
+      unsigned int toReturn = 1;
+      for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+        toReturn *= dimensions->getValue<unsigned int>(i);
+      }
+      return toReturn;
+    }
+
+    bool isInitialized() const
+    {
+      return true;
+    }
+
+    void
+    traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+    {
+      const std::vector<shared_ptr<XdmfArray> > & coordinates =
+        mRectilinearGrid->getCoordinates();
+      for (unsigned int i = 0; i < coordinates.size(); ++i)
+      {
+        coordinates[i]->accept(visitor);
+      }
+    }
+
+  private:
+
+    XdmfGeometryRectilinear(XdmfRectilinearGrid * const rectilinearGrid) :
+      mRectilinearGrid(rectilinearGrid)
+    {
+      this->setType(XdmfGeometryTypeRectilinear::New(mRectilinearGrid));
+    }
+
+    const XdmfRectilinearGrid * const mRectilinearGrid;
+  };
+
+  class XdmfGeometryTypeRectilinear : public XdmfGeometryType
+  {
+
+  public:
+
+    static shared_ptr<const XdmfGeometryTypeRectilinear>
+    New(const XdmfRectilinearGrid * const rectilinearGrid)
+    {
+      shared_ptr<const XdmfGeometryTypeRectilinear>
+        p(new XdmfGeometryTypeRectilinear(rectilinearGrid));
+      return p;
+    }
+
+    unsigned int
+    getDimensions() const
+    {
+      return mRectilinearGrid->getDimensions()->getSize();
+    }
+
+    void
+    getProperties(std::map<std::string, std::string> & collectedProperties) const
+    {
+      const unsigned int dimensions = this->getDimensions();
+      if(dimensions == 3) {
+        collectedProperties["Type"] = "VXVYVZ";
+      }
+      else if(dimensions == 2) {
+        collectedProperties["Type"] = "VXVY";
+      }
+      else {
+        collectedProperties["Type"] = "VECTORED";
+      }
+    }
+
+  private:
+
+    XdmfGeometryTypeRectilinear(const XdmfRectilinearGrid * const rectilinearGrid) :
+      XdmfGeometryType("", 0),
+      mRectilinearGrid(rectilinearGrid)
+    {
+    }
+
+    const XdmfRectilinearGrid * const mRectilinearGrid;
+
+  };
+
+  class XdmfTopologyRectilinear : public XdmfTopology
+  {
+
+  public:
+
+    static shared_ptr<XdmfTopologyRectilinear>
+    New(const XdmfRectilinearGrid * const rectilinearGrid)
+    {
+      shared_ptr<XdmfTopologyRectilinear>
+        p(new XdmfTopologyRectilinear(rectilinearGrid));
+      return p;
+    }
+
+    bool isInitialized() const
+    {
+      return true;
+    }
+
+    unsigned int
+    getNumberElements() const
+    {
+      const shared_ptr<const XdmfArray> dimensions = 
+        mRectilinearGrid->getDimensions();
+      if(dimensions->getSize() == 0) {
+        return 0;
+      }
+      unsigned int toReturn = 1;
+      for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+        toReturn *= (dimensions->getValue<unsigned int>(i) - 1);
+      }
+      return toReturn;
+    }
+
+  private:
+
+    XdmfTopologyRectilinear(const XdmfRectilinearGrid * const rectilinearGrid) :
+      mRectilinearGrid(rectilinearGrid)
+    {
+      this->setType(XdmfTopologyTypeRectilinear::New(rectilinearGrid));
+    }
+
+    const XdmfRectilinearGrid * const mRectilinearGrid;
+  };
+
+  class XdmfTopologyTypeRectilinear : public XdmfTopologyType
+  {
+
+  public:
+
+    static shared_ptr<const XdmfTopologyTypeRectilinear>
+    New(const XdmfRectilinearGrid * const rectilinearGrid)
+    {
+      shared_ptr<const XdmfTopologyTypeRectilinear>
+        p(new XdmfTopologyTypeRectilinear(rectilinearGrid));
+      return p;
+    }
+
+    unsigned int
+    getEdgesPerElement() const
+    {
+      return calculateHypercubeNumElements(mRectilinearGrid->getDimensions()->getSize(), 1);
+    }
+
+    unsigned int
+    getFacesPerElement() const
+    {
+      return calculateHypercubeNumElements(mRectilinearGrid->getDimensions()->getSize(), 2);
+    }
+
+    unsigned int
+    getNodesPerElement() const
+    {
+      return calculateHypercubeNumElements(mRectilinearGrid->getDimensions()->getSize(), 0);
+    }
+
+    void
+    getProperties(std::map<std::string, std::string> & collectedProperties) const
+    {
+      shared_ptr<const XdmfArray> dimensions = 
+        mRectilinearGrid->getDimensions();
+      if(dimensions->getSize() == 3) {
+        collectedProperties["Type"] = "3DRectMesh";
+      }
+      else if(dimensions->getSize() == 2) {
+        collectedProperties["Type"] = "2DRectMesh";
+      }
+      else {
+        collectedProperties["Type"] = "RectMesh";
+      }
+      collectedProperties["Dimensions"] = dimensions->getValuesString();
+    }
+
+  private:
+
+    XdmfTopologyTypeRectilinear(const XdmfRectilinearGrid * const rectilinearGrid) :
+      XdmfTopologyType(0,
+                       0,
+                       std::vector<shared_ptr<const XdmfTopologyType> >(),
+                       0,
+                       "foo",
+                       XdmfTopologyType::Structured,
+                       0x1101),
+      mRectilinearGrid(rectilinearGrid)
+    {
+    }
+
+    const XdmfRectilinearGrid * const mRectilinearGrid;
+
+  };
+
+  XdmfRectilinearGridImpl(const std::vector<shared_ptr<XdmfArray> > & coordinates) :
+    mCoordinates(coordinates.begin(), coordinates.end())
+  {
+    mGridType = "Rectilinear";
+  }
+
+  XdmfGridImpl * duplicate()
+  {
+    return new XdmfRectilinearGridImpl(mCoordinates);
+  }
+
+  std::vector<shared_ptr<XdmfArray> > mCoordinates;
+};
+
+shared_ptr<XdmfRectilinearGrid>
+XdmfRectilinearGrid::New(const shared_ptr<XdmfArray> xCoordinates,
+                         const shared_ptr<XdmfArray> yCoordinates)
+{
+  std::vector<shared_ptr<XdmfArray> > axesCoordinates;
+  axesCoordinates.resize(2);
+  axesCoordinates[0] = xCoordinates;
+  axesCoordinates[1] = yCoordinates;
+  shared_ptr<XdmfRectilinearGrid> p(new XdmfRectilinearGrid(axesCoordinates));
+  return p;
+}
+
+shared_ptr<XdmfRectilinearGrid>
+XdmfRectilinearGrid::New(const shared_ptr<XdmfArray> xCoordinates,
+                         const shared_ptr<XdmfArray> yCoordinates,
+                         const shared_ptr<XdmfArray> zCoordinates)
+{
+  std::vector<shared_ptr<XdmfArray> > axesCoordinates;
+  axesCoordinates.resize(3);
+  axesCoordinates[0] = xCoordinates;
+  axesCoordinates[1] = yCoordinates;
+  axesCoordinates[2] = zCoordinates;
+  shared_ptr<XdmfRectilinearGrid> p(new XdmfRectilinearGrid(axesCoordinates));
+  return p;
+}
+
+shared_ptr<XdmfRectilinearGrid>
+XdmfRectilinearGrid::New(const std::vector<shared_ptr<XdmfArray> > & axesCoordinates)
+{
+  shared_ptr<XdmfRectilinearGrid> p(new XdmfRectilinearGrid(axesCoordinates));
+  return p;
+}
+
+XdmfRectilinearGrid::XdmfRectilinearGrid(const std::vector<shared_ptr<XdmfArray> > & axesCoordinates) :
+  XdmfGrid(XdmfRectilinearGridImpl::XdmfGeometryRectilinear::New(this),
+           XdmfRectilinearGridImpl::XdmfTopologyRectilinear::New(this))
+{
+  mImpl = new XdmfRectilinearGridImpl(axesCoordinates);
+}
+
+XdmfRectilinearGrid::XdmfRectilinearGrid(XdmfRectilinearGrid & refGrid):
+  XdmfGrid(refGrid)
+{
+  mTopology = XdmfRectilinearGridImpl::XdmfTopologyRectilinear::New(this);
+  mGeometry = XdmfRectilinearGridImpl::XdmfGeometryRectilinear::New(this);
+}
+
+XdmfRectilinearGrid::~XdmfRectilinearGrid()
+{
+  if (mImpl) {
+    delete mImpl;
+  }
+  mImpl = NULL;
+}
+
+const std::string XdmfRectilinearGrid::ItemTag = "Grid";
+
+void
+XdmfRectilinearGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
+{
+  XdmfGrid::copyGrid(sourceGrid);
+  if (shared_ptr<XdmfRectilinearGrid> classedGrid = shared_dynamic_cast<XdmfRectilinearGrid>(sourceGrid))
+  {
+    // Copy stucture from read grid to this grid
+    this->setCoordinates(classedGrid->getCoordinates());
+  }
+}
+
+shared_ptr<XdmfArray>
+XdmfRectilinearGrid::getCoordinates(const unsigned int axisIndex)
+{
+  return boost::const_pointer_cast<XdmfArray>
+    (static_cast<const XdmfRectilinearGrid &>
+     (*this).getCoordinates(axisIndex));
+}
+
+shared_ptr<const XdmfArray>
+XdmfRectilinearGrid::getCoordinates(const unsigned int axisIndex) const
+{
+  if(axisIndex < ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.size()) {
+    return ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates[axisIndex];
+  }
+  return shared_ptr<XdmfArray>();
+}
+
+std::vector<shared_ptr<XdmfArray> >
+XdmfRectilinearGrid::getCoordinates()
+{
+  return static_cast<const XdmfRectilinearGrid &>(*this).getCoordinates();
+}
+
+const std::vector<shared_ptr<XdmfArray> >
+XdmfRectilinearGrid::getCoordinates() const
+{
+  return ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates;
+}
+
+shared_ptr<XdmfArray>
+XdmfRectilinearGrid::getDimensions()
+{
+  return boost::const_pointer_cast<XdmfArray>
+    (static_cast<const XdmfRectilinearGrid &>(*this).getDimensions());
+}
+
+shared_ptr<const XdmfArray>
+XdmfRectilinearGrid::getDimensions() const
+{
+  shared_ptr<XdmfArray> dimensions = XdmfArray::New();
+  std::vector<shared_ptr<XdmfArray> > heldCoordinates =
+    ((XdmfRectilinearGridImpl*)mImpl)->mCoordinates;
+  dimensions->reserve(heldCoordinates.size());
+  for (unsigned int i = 0; i < heldCoordinates.size(); ++i)
+  {
+    dimensions->pushBack(heldCoordinates[i]->getSize());
+  }
+  return dimensions;
+}
+
+void
+XdmfRectilinearGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
+                                  const std::vector<shared_ptr<XdmfItem> > & childItems,
+                                  const XdmfCoreReader * const reader)
+{
+  XdmfGrid::populateItem(itemProperties, childItems, reader);
+
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfRectilinearGrid> rectilinearGrid =
+       shared_dynamic_cast<XdmfRectilinearGrid>(*iter)) {
+      if(rectilinearGrid->getGeometry()->getType()->getDimensions() > 0) {
+        this->setCoordinates(rectilinearGrid->getCoordinates());
+        break;
+      }
+    }
+  }
+}
+
+void
+XdmfRectilinearGrid::read()
+{
+  if (mGridController)
+  {
+    if (shared_ptr<XdmfRectilinearGrid> grid = shared_dynamic_cast<XdmfRectilinearGrid>(mGridController->read()))
+    { 
+      // Copy stucture from read grid to this grid
+      copyGrid(grid);
+    }
+    else if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(mGridController->read()))
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
+    }
+    else
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
+    }
+  }
+}
+
+void
+XdmfRectilinearGrid::release()
+{
+  XdmfGrid::release();
+  ((XdmfRectilinearGridImpl*)mImpl)->mCoordinates.clear();
+}
+
+void
+XdmfRectilinearGrid::setCoordinates(const unsigned int axisIndex,
+                                    const shared_ptr<XdmfArray> axisCoordinates)
+{
+  if(((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.size() <= axisIndex) {
+    ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.reserve(axisIndex + 1);
+    unsigned int numArraysToInsert =
+      axisIndex - ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.size() + 1;
+    for(unsigned int i=0; i<numArraysToInsert; ++i) {
+      ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates.push_back(XdmfArray::New());
+    }
+  }
+  ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates[axisIndex] = axisCoordinates;
+  this->setIsChanged(true);
+}
+
+void
+XdmfRectilinearGrid::setCoordinates(const std::vector<shared_ptr<XdmfArray> > axesCoordinates)
+{
+  ((XdmfRectilinearGridImpl *)mImpl)->mCoordinates = axesCoordinates;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFRECTILINEARGRID * XdmfRectilinearGridNew(XDMFARRAY ** axesCoordinates, unsigned int numCoordinates, int passControl)
+{
+  try
+  {
+    std::vector<shared_ptr<XdmfArray> > holderVector;
+    for (unsigned int i = 0; i < numCoordinates; ++i) {
+      if (passControl) {
+        holderVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)axesCoordinates[i]));
+      }
+      else {
+        holderVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)axesCoordinates[i], XdmfNullDeleter()));
+      }
+    }
+    shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(holderVector);
+    return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    std::vector<shared_ptr<XdmfArray> > holderVector;
+    for (unsigned int i = 0; i < numCoordinates; ++i) {
+      if (passControl) {
+        holderVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)axesCoordinates[i]));
+      }
+      else {
+        holderVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)axesCoordinates[i], XdmfNullDeleter()));
+      }
+    }
+    shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(holderVector);
+    return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+  }
+}
+
+XDMFRECTILINEARGRID * XdmfRectilinearGridNew2D(XDMFARRAY * xCoordinates, XDMFARRAY * yCoordinates, int passControl)
+{
+  try
+  {
+    if (passControl) {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+    else {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates, XdmfNullDeleter()),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates, XdmfNullDeleter()));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+  }
+  catch (...)
+  {
+    if (passControl) {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+    else {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates, XdmfNullDeleter()),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates, XdmfNullDeleter()));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+  }
+}
+
+XDMFRECTILINEARGRID * XdmfRectilinearGridNew3D(XDMFARRAY * xCoordinates, XDMFARRAY * yCoordinates, XDMFARRAY * zCoordinates, int passControl)
+{
+  try
+  {
+    if (passControl) {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)zCoordinates));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+    else {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates, XdmfNullDeleter()),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates, XdmfNullDeleter()),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)zCoordinates, XdmfNullDeleter()));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+  }
+  catch (...)
+  {
+    if (passControl) {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)zCoordinates));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+    else {
+      shared_ptr<XdmfRectilinearGrid> generatedGrid = XdmfRectilinearGrid::New(shared_ptr<XdmfArray>((XdmfArray *)xCoordinates, XdmfNullDeleter()),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)yCoordinates, XdmfNullDeleter()),
+                                                                               shared_ptr<XdmfArray>((XdmfArray *)zCoordinates, XdmfNullDeleter()));
+      return (XDMFRECTILINEARGRID *)((void *)((XdmfItem *)(new XdmfRectilinearGrid(*generatedGrid.get()))));
+    }
+  }
+}
+
+XDMFARRAY * XdmfRectilinearGridGetCoordinatesByIndex(XDMFRECTILINEARGRID * grid, unsigned int axisIndex, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedPointer);
+  return (XDMFARRAY *)((void *)(gridPointer->getCoordinates(axisIndex).get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY ** XdmfRectilinearGridGetCoordinates(XDMFRECTILINEARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    XDMFARRAY ** returnPointer;
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedPointer);
+    std::vector<shared_ptr<XdmfArray> > heldCoordinates = gridPointer->getCoordinates();
+    returnPointer = new XDMFARRAY *[heldCoordinates.size()]();
+    for (unsigned int i = 0; i < heldCoordinates.size(); ++i) {
+      XDMFARRAY * insertArray = (XDMFARRAY *)((void *)(new XdmfArray(*(heldCoordinates[i].get()))));
+      returnPointer[i] = insertArray;
+    }
+    return returnPointer;
+  }
+  catch (...)
+  {
+    XDMFARRAY ** returnPointer;
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedPointer);
+    std::vector<shared_ptr<XdmfArray> > heldCoordinates = gridPointer->getCoordinates();
+    returnPointer = new XDMFARRAY *[heldCoordinates.size()]();
+    for (unsigned int i = 0; i < heldCoordinates.size(); ++i) {
+      XDMFARRAY * insertArray = (XDMFARRAY *)((void *)(new XdmfArray(*(heldCoordinates[i].get()))));
+      returnPointer[i] = insertArray;
+    }
+    return returnPointer;
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+int XdmfRectilinearGridGetNumberCoordinates(XDMFRECTILINEARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedPointer);
+  std::vector<shared_ptr<XdmfArray> > heldCoordinates = gridPointer->getCoordinates();
+  return heldCoordinates.size();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+XDMFARRAY * XdmfRectilinearGridGetDimensions(XDMFRECTILINEARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    XdmfArray * copyArray;
+    shared_ptr<XdmfArray> returnDimensions;
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfGrid * classedGrid = dynamic_cast<XdmfGrid *>(classedPointer);
+    XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedGrid);
+    XDMFARRAY * returnArray;
+    returnDimensions = gridPointer->getDimensions();
+    copyArray = new XdmfArray(*(returnDimensions.get()));
+    void * copyVoid = (void *)copyArray;
+    returnArray = (XDMFARRAY *) copyVoid;
+    returnDimensions.reset();
+    return returnArray;
+  }
+  catch (...)
+  {
+    XdmfArray * copyArray;
+    shared_ptr<XdmfArray> returnDimensions;
+    XdmfItem * classedPointer = (XdmfItem *)grid;
+    XdmfGrid * classedGrid = dynamic_cast<XdmfGrid *>(classedPointer);
+    XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedGrid);
+    XDMFARRAY * returnArray;
+    returnDimensions = gridPointer->getDimensions();
+    copyArray = new XdmfArray(*(returnDimensions.get()));
+    void * copyVoid = (void *)copyArray;
+    returnArray = (XDMFARRAY *) copyVoid;
+    returnDimensions.reset();
+    return returnArray;
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void XdmfRectilinearGridSetCoordinates(XDMFRECTILINEARGRID * grid, XDMFARRAY ** axesCoordinates, unsigned int numCoordinates, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedPointer);
+  std::vector<shared_ptr<XdmfArray> > holderVector;
+  for (unsigned int i = 0; i < numCoordinates; ++i) {
+    if (passControl) {
+      holderVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)axesCoordinates[i]));
+    }
+    else {
+      holderVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)axesCoordinates[i], XdmfNullDeleter()));
+    }
+  }
+  gridPointer->setCoordinates(holderVector);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfRectilinearGridSetCoordinatesByIndex(XDMFRECTILINEARGRID * grid, unsigned int index, XDMFARRAY * coordinates, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRectilinearGrid * gridPointer = dynamic_cast<XdmfRectilinearGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setCoordinates(index, shared_ptr<XdmfArray>((XdmfArray *)coordinates));
+  }
+  else {
+    gridPointer->setCoordinates(index, shared_ptr<XdmfArray>((XdmfArray *)coordinates, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfRectilinearGrid, XDMFRECTILINEARGRID)
+XDMF_GRID_C_CHILD_WRAPPER(XdmfRectilinearGrid, XDMFRECTILINEARGRID)
diff --git a/XdmfRectilinearGrid.hpp b/XdmfRectilinearGrid.hpp
new file mode 100644
index 0000000..73f5bc1
--- /dev/null
+++ b/XdmfRectilinearGrid.hpp
@@ -0,0 +1,439 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfRectilinearGrid.hpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFRECTILINEARGRID_HPP_
+#define XDMFRECTILINEARGRID_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfGrid.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+/**
+ * @brief A rectilinear grid consists of cells and points arranged on
+ * a regular lattice in space.
+ *
+ * XdmfRectilinearGrid represents a mesh of cells and points arranged
+ * on a regular lattice in space. Points are arranged along coordinate
+ * axes, but the spacing between points may vary.
+ *
+ * In order to define a rectilinear grid, the coordinates along each
+ * axis direction must be specified.
+ *
+ */
+class XDMF_EXPORT XdmfRectilinearGrid : public XdmfGrid {
+
+public:
+
+  /**
+   * Create a new rectilinear grid (Two dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initialization2
+   * @until //#initialization2
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initialization2
+   * @until #//initialization2
+   *
+   * @param     xCoordinates    The coordinates of points along the x axis
+   * @param     yCoordinates    The coordinates of points along the y axis.
+   *
+   * @return                    Constructed rectilinear grid.
+   */
+  static shared_ptr<XdmfRectilinearGrid>
+  New(const shared_ptr<XdmfArray> xCoordinates,
+      const shared_ptr<XdmfArray> yCoordinates);
+
+  /**
+   * Create a new rectilinear grid (Three dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initialization3
+   * @until //#initialization3
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initialization3
+   * @until #//initialization3
+   *
+   * @param     xCoordinates    The coordinates of points along the x axis
+   * @param     yCoordinates    The coordinates of points along the y axis.
+   * @param     zCoordinates    The coordinates of points along the z axis.
+   *
+   * @return                    Constructed rectilinear grid.
+   */
+  static shared_ptr<XdmfRectilinearGrid>
+  New(const shared_ptr<XdmfArray> xCoordinates,
+      const shared_ptr<XdmfArray> yCoordinates,
+      const shared_ptr<XdmfArray> zCoordinates);
+
+  /**
+   * Create a new rectilinear grid (N dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   *
+   * @param     axesCoordinates         The coordinates of points along each axis.
+   *
+   * @return                            Constructed rectilinear grid.
+   */
+  static shared_ptr<XdmfRectilinearGrid>
+  New(const std::vector<shared_ptr<XdmfArray> > & axesCoordinates);
+
+  virtual ~XdmfRectilinearGrid();
+
+  LOKI_DEFINE_VISITABLE(XdmfRectilinearGrid, XdmfGrid)
+  static const std::string ItemTag;
+
+  /**
+   * Get the coordinates of the grid along a single axis.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getCoodinatessingle
+   * @until //#getCoodinatessingle
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initialization2
+   * @until #//initialization2
+   * @skipline #//getCoodinatessingle
+   * @until #//getCoodinatessingle
+   *
+   * @param     axisIndex       The index of the axis to retrieve, (i.e. 0 for
+   *                            x-axis). If no array exists at the index,
+   *                            return NULL.
+   *
+   * @return                    Array of coordinates along requested axis
+   */
+  shared_ptr<XdmfArray> getCoordinates(const unsigned int axisIndex);
+
+  /**
+   * Get the coordinates of the grid along a single axis (const
+   * version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getCoodinatessingleconst
+   * @until //#getCoodinatessingleconst
+   *
+   * Python: does not support a constant version of this function
+   *
+   * @param     axisIndex       The index of the axis to retrieve (i.e. 0 for
+   *                            x-axis). If no array exists at the index,
+   *                            return NULL.
+   *
+   * @return                    Array of coordinates along requeste axis
+   */
+  shared_ptr<const XdmfArray>
+  getCoordinates(const unsigned int axisIndex) const;
+
+  /**
+   * Get the coordinates of the grid along all axes.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#getCoodinatesvector
+   * @until //#getCoodinatesvector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   * @skipline #//getCoodinatesvector
+   * @until #//getCoodinatesvector
+   *
+   * @return    Vector containing an array of coordinates along each
+   *            direction.
+   */
+  std::vector<shared_ptr<XdmfArray> > getCoordinates();
+
+  /**
+   * Get the coordinates of the grid along all axes (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#getCoodinatesvectorconst
+   * @until //#getCoodinatesvectorconst
+   *
+   * Python: does not support a constant version of this function
+   *
+   * @return    Vector containing an array of coordinates along each
+   *            direction.
+   */
+  const std::vector<shared_ptr<XdmfArray> > getCoordinates() const;
+
+  /**
+   * Get the dimensions of the grid, the number of points in each
+   * direction.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    XdmfArray containing dimensions of this grid.
+   */
+  shared_ptr<XdmfArray> getDimensions();
+
+  /**
+   * Get the dimensions of the grid, the number of points in each
+   * direction (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#getDimensionsconst
+   * @until //#getDimensionsconst
+   *
+   * Python: Doesn't support a constant version of this function
+   *
+   * @return    XdmfArray containing the dimensions of this grid.
+   */
+  shared_ptr<const XdmfArray> getDimensions() const;
+
+  virtual void read();
+
+  virtual void release();
+
+  /**
+   * Set the coordinates of the grid along a single axis.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initialization3
+   * @until //#initialization3
+   * @skipline //#setCoordinatessingle
+   * @until //#setCoordinatessingle
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initialization3
+   * @until #//initialization3
+   * @skipline #//setCoordinatessingle
+   * @until #//setCoordinatessingle
+   *
+   * @param     axisIndex               The index of the axis to set
+   *                                    (i.e. 0 for x-axis).
+   * @param     axisCoordinates         The coordinates of points along
+   *                                    a single axis to set.
+   */
+  void setCoordinates(const unsigned int axisIndex,
+                      const shared_ptr<XdmfArray> axisCoordinates);
+
+  /**
+   * Set the coordinates of the grid along all axes.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRectilinearGrid.cpp
+   * @skipline //#initvalues
+   * @until //#initvalues
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#setCoordinatesvector
+   * @until //#setCoordinatesvector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRectilinearGrid.py
+   * @skipline #//initvalues
+   * @until #//initvalues
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   * @skipline #//setCoordinatesvector
+   * @until #//setCoordinatesvector
+   *
+   * @param     axesCoordinates         The coordinates of points
+   *                                    along each axis.
+   */
+  void
+  setCoordinates(const std::vector<shared_ptr<XdmfArray> > axesCoordinates);
+
+  XdmfRectilinearGrid(XdmfRectilinearGrid &);
+
+protected:
+
+  XdmfRectilinearGrid(const std::vector<shared_ptr<XdmfArray> > & axesCoordinates);
+
+  void copyGrid(shared_ptr<XdmfGrid> sourceGrid);
+
+  void populateItem(const std::map<std::string, std::string> & itemProperties,
+                    const std::vector<shared_ptr<XdmfItem> > & childItems,
+                    const XdmfCoreReader * const reader);
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfRectilinearGridImpl;
+
+  XdmfRectilinearGrid(const XdmfRectilinearGrid &);  // Not implemented.
+  void operator=(const XdmfRectilinearGrid &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFRECTILINEARGRID; // Simply as a typedef to ensure correct typing
+typedef struct XDMFRECTILINEARGRID XDMFRECTILINEARGRID;
+
+XDMF_EXPORT XDMFRECTILINEARGRID * XdmfRectilinearGridNew(XDMFARRAY ** axesCoordinates, unsigned int numCoordinates, int passControl);
+
+XDMF_EXPORT XDMFRECTILINEARGRID * XdmfRectilinearGridNew2D(XDMFARRAY * xCoordinates, XDMFARRAY * yCoordinates, int passControl);
+
+XDMF_EXPORT XDMFRECTILINEARGRID * XdmfRectilinearGridNew3D(XDMFARRAY * xCoordinates, XDMFARRAY * yCoordinates, XDMFARRAY * zCoordinates, int passControl);
+
+XDMF_EXPORT XDMFARRAY * XdmfRectilinearGridGetCoordinatesByIndex(XDMFRECTILINEARGRID * grid, unsigned int axisIndex, int * status);
+
+XDMF_EXPORT XDMFARRAY ** XdmfRectilinearGridGetCoordinates(XDMFRECTILINEARGRID * grid, int * status);
+
+XDMF_EXPORT int XdmfRectilinearGridGetNumberCoordinates(XDMFRECTILINEARGRID * grid, int * status);
+
+XDMF_EXPORT XDMFARRAY * XdmfRectilinearGridGetDimensions(XDMFRECTILINEARGRID * grid, int * status);
+
+XDMF_EXPORT void XdmfRectilinearGridSetCoordinates(XDMFRECTILINEARGRID * grid, XDMFARRAY ** axesCoordinates, unsigned int numCoordinates, int passControl, int * status);
+
+XDMF_EXPORT void XdmfRectilinearGridSetCoordinatesByIndex(XDMFRECTILINEARGRID * grid, unsigned int index, XDMFARRAY * coordinates, int passControl, int * status);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfRectilinearGrid, XDMFRECTILINEARGRID, XDMF)
+XDMF_GRID_C_CHILD_DECLARE(XdmfRectilinearGrid, XDMFRECTILINEARGRID, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFRECTILINEARGRID_HPP_ */
diff --git a/XdmfRegularGrid.cpp b/XdmfRegularGrid.cpp
new file mode 100644
index 0000000..1aa91c0
--- /dev/null
+++ b/XdmfRegularGrid.cpp
@@ -0,0 +1,673 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfRegularGrid.cpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cmath>
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfError.hpp"
+
+/**
+ * PIMPL
+ */
+class XdmfRegularGrid::XdmfRegularGridImpl : public XdmfGridImpl {
+
+public:
+
+  class XdmfGeometryRegular : public XdmfGeometry
+  {
+
+  public:
+
+    static shared_ptr<XdmfGeometryRegular>
+    New(XdmfRegularGrid * const regularGrid)
+    {
+      shared_ptr<XdmfGeometryRegular> p(new XdmfGeometryRegular(regularGrid));
+      return p;
+    }
+
+    unsigned int
+    getNumberPoints() const
+    {
+      const shared_ptr<const XdmfArray> dimensions = 
+        mRegularGrid->getDimensions();
+      if(dimensions->getSize() == 0) {
+        return 0;
+      }
+      unsigned int toReturn = 1;
+      for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+        toReturn *= dimensions->getValue<unsigned int>(i);
+      }
+      return toReturn;
+    }
+
+    bool isInitialized() const
+    {
+      return true;
+    }
+
+    void
+    traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+    {
+      shared_ptr<XdmfArray> origin = mRegularGrid->getOrigin();
+      shared_ptr<XdmfArray> brickSize = mRegularGrid->getBrickSize();
+      origin->accept(visitor);
+      brickSize->accept(visitor);
+    }
+
+  private:
+
+    XdmfGeometryRegular(XdmfRegularGrid * const regularGrid) :
+      mRegularGrid(regularGrid)
+    {
+      this->setType(XdmfGeometryTypeRegular::New(mRegularGrid));
+    }
+
+    XdmfRegularGrid * const mRegularGrid;
+  };
+
+  class XdmfGeometryTypeRegular : public XdmfGeometryType
+  {
+
+  public:
+
+    static shared_ptr<const XdmfGeometryTypeRegular>
+    New(const XdmfRegularGrid * const regularGrid)
+    {
+      shared_ptr<const XdmfGeometryTypeRegular> 
+        p(new XdmfGeometryTypeRegular(regularGrid));
+      return p;
+    }
+
+    unsigned int
+    getDimensions() const
+    {
+      return mRegularGrid->getDimensions()->getSize();
+    }
+
+    void
+    getProperties(std::map<std::string, std::string> & collectedProperties) const
+    {
+      const unsigned int dimensions = this->getDimensions();
+      if(dimensions == 3) {
+        collectedProperties["Type"] = "ORIGIN_DXDYDZ";
+      }
+      else if(dimensions == 2) {
+        collectedProperties["Type"] = "ORIGIN_DXDY";
+      }
+      else {
+        collectedProperties["Type"] = "ORIGIN_DISPLACEMENT";
+//        XdmfError::message(XdmfError::FATAL, "Dimensions not 2 or 3 in XdmfGeometryTypeRegular::getProperties");
+      }
+    }
+
+  private:
+
+    XdmfGeometryTypeRegular(const XdmfRegularGrid * const regularGrid) :
+      XdmfGeometryType("", 0),
+      mRegularGrid(regularGrid)
+    {
+    }
+
+    const XdmfRegularGrid * const mRegularGrid;
+
+  };
+
+  class XdmfTopologyRegular : public XdmfTopology
+  {
+
+  public:
+
+    static shared_ptr<XdmfTopologyRegular>
+    New(const XdmfRegularGrid * const regularGrid)
+    {
+      shared_ptr<XdmfTopologyRegular> p(new XdmfTopologyRegular(regularGrid));
+      return p;
+    }
+
+    bool isInitialized() const
+    {
+      return true;
+    }
+
+    unsigned int
+    getNumberElements() const
+    {
+      const shared_ptr<const XdmfArray> dimensions = 
+        mRegularGrid->getDimensions();
+      if(dimensions->getSize() == 0) {
+        return 0;
+      }
+      unsigned int toReturn = 1;
+      for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+        toReturn *= (dimensions->getValue<unsigned int>(i) - 1);
+      }
+      return toReturn;
+    }
+
+  private:
+
+    XdmfTopologyRegular(const XdmfRegularGrid * const regularGrid) :
+      mRegularGrid(regularGrid)
+    {
+      this->setType(XdmfTopologyTypeRegular::New(regularGrid));
+    }
+
+    const XdmfRegularGrid * const mRegularGrid;
+  };
+
+  class XdmfTopologyTypeRegular : public XdmfTopologyType
+  {
+
+  public:
+
+    static shared_ptr<const XdmfTopologyTypeRegular>
+    New(const XdmfRegularGrid * const regularGrid)
+    {
+      shared_ptr<const XdmfTopologyTypeRegular>
+        p(new XdmfTopologyTypeRegular(regularGrid));
+      return p;
+    }
+
+    unsigned int
+    getEdgesPerElement() const
+    {
+      return calculateHypercubeNumElements(mRegularGrid->getDimensions()->getSize(), 1);
+    }
+
+    unsigned int
+    getFacesPerElement() const
+    {
+      return calculateHypercubeNumElements(mRegularGrid->getDimensions()->getSize(), 2);
+    }
+
+    unsigned int
+    getNodesPerElement() const
+    {
+      return calculateHypercubeNumElements(mRegularGrid->getDimensions()->getSize(), 0);
+    }
+
+    void
+    getProperties(std::map<std::string, std::string> & collectedProperties) const
+    {
+      shared_ptr<const XdmfArray> dimensions = mRegularGrid->getDimensions();
+      if(dimensions->getSize() == 3){
+        collectedProperties["Type"] = "3DCoRectMesh";
+      }
+      else if(dimensions->getSize() == 2) {
+        collectedProperties["Type"] = "2DCoRectMesh";
+      }
+      else {
+        // If not 2 or 3 just mark it as a mesh of unknown dims
+        collectedProperties["Type"] = "CoRectMesh";
+//        XdmfError::message(XdmfError::FATAL, 
+//                           "Dimensions not 2 or 3 in "
+//                           "XdmfTopologyTypeRegular::getProperties");
+      }
+      collectedProperties["Dimensions"] = dimensions->getValuesString();
+    }
+
+  private:
+
+    XdmfTopologyTypeRegular(const XdmfRegularGrid * const regularGrid) :
+      XdmfTopologyType(0, 0, std::vector<shared_ptr<const XdmfTopologyType> >(), 0, "foo", XdmfTopologyType::Structured, 0x1102),
+      mRegularGrid(regularGrid)
+    {
+    }
+
+    const XdmfRegularGrid * const mRegularGrid;
+
+  };
+
+  XdmfRegularGridImpl(const shared_ptr<XdmfArray> brickSize,
+                      const shared_ptr<XdmfArray> numPoints,
+                      const shared_ptr<XdmfArray> origin) :
+    mBrickSize(brickSize),
+    mDimensions(numPoints),
+    mOrigin(origin)
+  {
+    mGridType = "Regular";
+  }
+
+  XdmfGridImpl * duplicate()
+  {
+    return new XdmfRegularGridImpl(mBrickSize, mDimensions, mOrigin);
+  }
+
+  shared_ptr<XdmfArray> mBrickSize;
+  shared_ptr<XdmfArray> mDimensions;
+  shared_ptr<XdmfArray> mOrigin;
+};
+
+shared_ptr<XdmfRegularGrid>
+XdmfRegularGrid::New(const double xBrickSize,
+                     const double yBrickSize,
+                     const unsigned int xNumPoints,
+                     const unsigned int yNumPoints,
+                     const double xOrigin,
+                     const double yOrigin)
+{
+  shared_ptr<XdmfArray> brickSize = XdmfArray::New();
+  brickSize->initialize<double>(2);
+  brickSize->insert(0, xBrickSize);
+  brickSize->insert(1, yBrickSize);
+  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
+  numPoints->initialize<unsigned int>(2);
+  numPoints->insert(0, xNumPoints);
+  numPoints->insert(1, yNumPoints);
+  shared_ptr<XdmfArray> origin = XdmfArray::New();
+  origin->initialize<double>(2);
+  origin->insert(0, xOrigin);
+  origin->insert(1, yOrigin);
+  shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize,
+                                                    numPoints,
+                                                    origin));
+  return p;
+}
+
+shared_ptr<XdmfRegularGrid>
+XdmfRegularGrid::New(const double xBrickSize,
+                     const double yBrickSize,
+                     const double zBrickSize,
+                     const unsigned int xNumPoints,
+                     const unsigned int yNumPoints,
+                     const unsigned int zNumPoints,
+                     const double xOrigin,
+                     const double yOrigin,
+                     const double zOrigin)
+{
+  shared_ptr<XdmfArray> brickSize = XdmfArray::New();
+  brickSize->initialize<double>(3);
+  brickSize->insert(0, xBrickSize);
+  brickSize->insert(1, yBrickSize);
+  brickSize->insert(2, zBrickSize);
+  shared_ptr<XdmfArray> numPoints = XdmfArray::New();
+  numPoints->initialize<unsigned int>(3);
+  numPoints->insert(0, xNumPoints);
+  numPoints->insert(1, yNumPoints);
+  numPoints->insert(2, zNumPoints);
+  shared_ptr<XdmfArray> origin = XdmfArray::New();
+  origin->initialize<double>(3);
+  origin->insert(0, xOrigin);
+  origin->insert(1, yOrigin);
+  origin->insert(2, zOrigin);
+  shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize,
+                                                    numPoints,
+                                                    origin));
+  return p;
+}
+
+shared_ptr<XdmfRegularGrid>
+XdmfRegularGrid::New(const shared_ptr<XdmfArray> brickSize,
+                     const shared_ptr<XdmfArray> numPoints,
+                     const shared_ptr<XdmfArray> origin)
+{
+  shared_ptr<XdmfRegularGrid> p(new XdmfRegularGrid(brickSize,
+                                                    numPoints,
+                                                    origin));
+  return p;
+}
+
+XdmfRegularGrid::XdmfRegularGrid(const shared_ptr<XdmfArray> brickSize,
+                                 const shared_ptr<XdmfArray> numPoints,
+                                 const shared_ptr<XdmfArray> origin) :
+  XdmfGrid(XdmfRegularGridImpl::XdmfGeometryRegular::New(this),
+           XdmfRegularGridImpl::XdmfTopologyRegular::New(this))
+{
+  mImpl = new XdmfRegularGridImpl(brickSize, numPoints, origin);
+}
+
+XdmfRegularGrid::XdmfRegularGrid(XdmfRegularGrid & refGrid) :
+  XdmfGrid(refGrid)
+{
+  mGeometry = XdmfRegularGridImpl::XdmfGeometryRegular::New(this);
+  mTopology = XdmfRegularGridImpl::XdmfTopologyRegular::New(this);  
+}
+
+XdmfRegularGrid::~XdmfRegularGrid()
+{
+  if (mImpl) {
+    delete mImpl;
+  }
+  mImpl = NULL;
+}
+
+const std::string XdmfRegularGrid::ItemTag = "Grid";
+
+void
+XdmfRegularGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
+{
+  XdmfGrid::copyGrid(sourceGrid); 
+  if (shared_ptr<XdmfRegularGrid> classedGrid = shared_dynamic_cast<XdmfRegularGrid>(sourceGrid))
+  { 
+    // Copy stucture from read grid to this grid
+    this->setOrigin(classedGrid->getOrigin());
+    this->setDimensions(classedGrid->getDimensions());
+    this->setBrickSize(classedGrid->getBrickSize());
+  }
+}
+
+shared_ptr<XdmfArray>
+XdmfRegularGrid::getBrickSize()
+{
+  return boost::const_pointer_cast<XdmfArray>
+    (static_cast<const XdmfRegularGrid &>(*this).getBrickSize());
+}
+
+shared_ptr<const XdmfArray>
+XdmfRegularGrid::getBrickSize() const
+{
+  return ((XdmfRegularGridImpl *)mImpl)->mBrickSize;
+}
+
+shared_ptr<XdmfArray>
+XdmfRegularGrid::getDimensions()
+{
+  return boost::const_pointer_cast<XdmfArray>
+    (static_cast<const XdmfRegularGrid &>(*this).getDimensions());
+}
+
+shared_ptr<const XdmfArray>
+XdmfRegularGrid::getDimensions() const
+{
+  return ((XdmfRegularGridImpl *)mImpl)->mDimensions;
+}
+
+shared_ptr<XdmfArray>
+XdmfRegularGrid::getOrigin()
+{
+  return boost::const_pointer_cast<XdmfArray>
+    (static_cast<const XdmfRegularGrid &>(*this).getOrigin());
+}
+
+shared_ptr<const XdmfArray>
+XdmfRegularGrid::getOrigin() const
+{
+  return ((XdmfRegularGridImpl *)mImpl)->mOrigin;
+}
+
+void
+XdmfRegularGrid::populateItem(const std::map<std::string, std::string> & itemProperties,
+                              const std::vector<shared_ptr<XdmfItem> > & childItems,
+                              const XdmfCoreReader * const reader)
+{
+  XdmfGrid::populateItem(itemProperties, childItems, reader);
+
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfRegularGrid> regularGrid =
+       shared_dynamic_cast<XdmfRegularGrid>(*iter)) {
+      if(regularGrid->getBrickSize()) {
+        ((XdmfRegularGridImpl *)mImpl)->mBrickSize = regularGrid->getBrickSize();
+      }
+
+      if(regularGrid->getDimensions()) {
+        ((XdmfRegularGridImpl *)mImpl)->mDimensions = regularGrid->getDimensions();
+      }
+
+      if(regularGrid->getOrigin()) {
+        ((XdmfRegularGridImpl *)mImpl)->mOrigin = regularGrid->getOrigin();
+      }
+    }
+  }
+}
+
+void
+XdmfRegularGrid::read()
+{
+  if (mGridController)
+  {
+    if (shared_ptr<XdmfRegularGrid> grid = shared_dynamic_cast<XdmfRegularGrid>(mGridController->read()))
+    { 
+      // Copy stucture from read grid to this grid
+      copyGrid(grid);
+    }
+    else if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(mGridController->read()))
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
+    }
+    else
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
+    }
+  }
+}
+
+void
+XdmfRegularGrid::release()
+{
+  XdmfGrid::release();
+  this->setOrigin(shared_ptr<XdmfArray>());
+  this->setDimensions(shared_ptr<XdmfArray>());
+  this->setBrickSize(shared_ptr<XdmfArray>());
+}
+
+void
+XdmfRegularGrid::setBrickSize(const shared_ptr<XdmfArray> brickSize)
+{
+  ((XdmfRegularGridImpl *)mImpl)->mBrickSize = brickSize;
+  this->setIsChanged(true);
+}
+
+void
+XdmfRegularGrid::setDimensions(const shared_ptr<XdmfArray> dimensions)
+{
+  ((XdmfRegularGridImpl *)mImpl)->mDimensions = dimensions;
+  this->setIsChanged(true);
+}
+
+void
+XdmfRegularGrid::setOrigin(const shared_ptr<XdmfArray> origin)
+{
+  ((XdmfRegularGridImpl *)mImpl)->mOrigin = origin;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFREGULARGRID * XdmfRegularGridNew2D(double xBrickSize,
+                                       double yBrickSize,
+                                       unsigned int xNumPoints,
+                                       unsigned int yNumPoints,
+                                       double xOrigin,
+                                       double yOrigin)
+{
+  try
+  {
+    shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(xBrickSize,
+                                                                     yBrickSize,
+                                                                     xNumPoints,
+                                                                     yNumPoints,
+                                                                     xOrigin,
+                                                                     yOrigin);
+    return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(xBrickSize,
+                                                                     yBrickSize,
+                                                                     xNumPoints,
+                                                                     yNumPoints,
+                                                                     xOrigin,
+                                                                     yOrigin);
+    return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+  }
+}
+
+XDMFREGULARGRID * XdmfRegularGridNew3D(double xBrickSize,
+                                       double yBrickSize,
+                                       double zBrickSize,
+                                       unsigned int xNumPoints,
+                                       unsigned int yNumPoints,
+                                       unsigned int zNumPoints,
+                                       double xOrigin,
+                                       double yOrigin,
+                                       double zOrigin)
+{
+  try
+  {
+    shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(xBrickSize,
+                                                                     yBrickSize,
+                                                                     zBrickSize,
+                                                                     xNumPoints,
+                                                                     yNumPoints,
+                                                                     zNumPoints,
+                                                                     xOrigin,
+                                                                     yOrigin,
+                                                                     zOrigin);
+    return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(xBrickSize,
+                                                                     yBrickSize,
+                                                                     zBrickSize,
+                                                                     xNumPoints,
+                                                                     yNumPoints,
+                                                                     zNumPoints,
+                                                                     xOrigin,
+                                                                     yOrigin,
+                                                                     zOrigin);
+    return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+  }
+}
+
+XDMFREGULARGRID * XdmfRegularGridNew(XDMFARRAY * brickSize,
+                                     XDMFARRAY * numPoints,
+                                     XDMFARRAY * origin,
+                                     int passControl)
+{
+  try
+  {
+    if (passControl) {
+      shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(shared_ptr<XdmfArray>((XdmfArray *)brickSize),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)numPoints),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)origin));
+      return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+    }
+    else {
+      shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(shared_ptr<XdmfArray>((XdmfArray *)brickSize, XdmfNullDeleter()),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)numPoints, XdmfNullDeleter()),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)origin, XdmfNullDeleter()));
+      return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+    }
+  }
+  catch (...)
+  {
+    if (passControl) {
+      shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(shared_ptr<XdmfArray>((XdmfArray *)brickSize),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)numPoints),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)origin));
+      return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+    }
+    else {
+      shared_ptr<XdmfRegularGrid> generatedGrid = XdmfRegularGrid::New(shared_ptr<XdmfArray>((XdmfArray *)brickSize, XdmfNullDeleter()),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)numPoints, XdmfNullDeleter()),
+                                                                       shared_ptr<XdmfArray>((XdmfArray *)origin, XdmfNullDeleter()));
+      return (XDMFREGULARGRID *)((void *)((XdmfItem *)(new XdmfRegularGrid(*generatedGrid.get()))));
+    }
+  }
+}
+
+XDMFARRAY * XdmfRegularGridGetBrickSize(XDMFREGULARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRegularGrid * gridPointer = dynamic_cast<XdmfRegularGrid *>(classedPointer);
+  shared_ptr<XdmfArray> generatedBrick = gridPointer->getBrickSize();
+  return (XDMFARRAY *)((void *)(generatedBrick.get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfRegularGridGetDimensions(XDMFREGULARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRegularGrid * gridPointer = dynamic_cast<XdmfRegularGrid *>(classedPointer);
+  shared_ptr<XdmfArray> generatedDimensions = gridPointer->getDimensions();
+  return (XDMFARRAY *)((void *)(generatedDimensions.get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfRegularGridGetOrigin(XDMFREGULARGRID * grid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRegularGrid * gridPointer = dynamic_cast<XdmfRegularGrid *>(classedPointer);
+  shared_ptr<XdmfArray> generatedOrigin = gridPointer->getOrigin();
+  return (XDMFARRAY *)((void *)(generatedOrigin.get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void XdmfRegularGridSetBrickSize(XDMFREGULARGRID * grid, XDMFARRAY * brickSize, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRegularGrid * gridPointer = dynamic_cast<XdmfRegularGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setBrickSize(shared_ptr<XdmfArray>((XdmfArray *)brickSize));
+  }
+  else {
+    gridPointer->setBrickSize(shared_ptr<XdmfArray>((XdmfArray *)brickSize, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfRegularGridSetDimensions(XDMFREGULARGRID * grid, XDMFARRAY * dimensions, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRegularGrid * gridPointer = dynamic_cast<XdmfRegularGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setDimensions(shared_ptr<XdmfArray>((XdmfArray *)dimensions));
+  }
+  else {
+    gridPointer->setDimensions(shared_ptr<XdmfArray>((XdmfArray *)dimensions, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfRegularGridSetOrigin(XDMFREGULARGRID * grid, XDMFARRAY * origin, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfItem * classedPointer = (XdmfItem *)grid;
+  XdmfRegularGrid * gridPointer = dynamic_cast<XdmfRegularGrid *>(classedPointer);
+  if (passControl) {
+    gridPointer->setOrigin(shared_ptr<XdmfArray>((XdmfArray *)origin));
+  }
+  else {
+    gridPointer->setOrigin(shared_ptr<XdmfArray>((XdmfArray *)origin, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfRegularGrid, XDMFREGULARGRID)
+XDMF_GRID_C_CHILD_WRAPPER(XdmfRegularGrid, XDMFREGULARGRID)
diff --git a/XdmfRegularGrid.hpp b/XdmfRegularGrid.hpp
new file mode 100644
index 0000000..6b8c3a6
--- /dev/null
+++ b/XdmfRegularGrid.hpp
@@ -0,0 +1,482 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfRegularGrid.hpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFREGULARGRID_HPP_
+#define XDMFREGULARGRID_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfGrid.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+/**
+ * @brief A regular grid consists of congruent points arranged
+ * regularly in space.
+ *
+ * XdmfRegularGrid represents a regular mesh of congruent points
+ * arranged in space. In order to define a regular grid, three sets of
+ * terms need to be supplied:
+ *
+ * Brick Size (Dx, Dy, (Dz)) - Size of an individual brick.
+ * Dimensions (X, Y, (Z)) - Number of points in X, Y, and Z directions
+ * Origin Location (X, Y, (Z)) - Location of the origin of the mesh in space.
+ */
+class XDMF_EXPORT XdmfRegularGrid : public XdmfGrid {
+
+public:
+
+  /**
+   * Create a new structured grid (Two dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initvalue
+   * @until #//initvalue
+   * @skipline #//initialization2
+   * @until #//initialization2
+   *
+   * @param     xBrickSize      The size of the brick in the x direction.
+   * @param     yBrickSize      The size of the brick in the y direction.
+   * @param     xNumPoints      The number of points in the x direction.
+   * @param     yNumPoints      The number of points in the y direction.
+   * @param     xOrigin         The x coordinate of the origin.
+   * @param     yOrigin         The y coordinate of the origin.
+   *
+   * @return                    Constructed structured grid.
+   */
+  static shared_ptr<XdmfRegularGrid> New(const double xBrickSize,
+                                         const double yBrickSize,
+                                         const unsigned int xNumPoints,
+                                         const unsigned int yNumPoints,
+                                         const double xOrigin,
+                                         const double yOrigin);
+
+  /**
+   * Create a new structured grid (Three dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization3
+   * @until //#initialization3
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initvalue
+   * @until #//initvalue
+   * @skipline #//initialization3
+   * @until #//initialization3
+   *
+   * @param     xBrickSize      The size of the brick in the x direction.
+   * @param     yBrickSize      The size of the brick in the y direction.
+   * @param     zBrickSize      The size of the brick in the z direction.
+   * @param     xNumPoints      The number of points in the x direction.
+   * @param     yNumPoints      The number of points in the y direction.
+   * @param     zNumPoints      The number of points in the z direction.
+   * @param     xOrigin         The x coordinate of the origin.
+   * @param     yOrigin         The y coordinate of the origin.
+   * @param     zOrigin         The z coordinate of the origin.
+   *
+   * @return                    Constructed structured grid.
+   */
+  static shared_ptr<XdmfRegularGrid> New(const double xBrickSize,
+                                         const double yBrickSize,
+                                         const double zBrickSize,
+                                         const unsigned int xNumPoints,
+                                         const unsigned int yNumPoints,
+                                         const unsigned int zNumPoints,
+                                         const double xOrigin,
+                                         const double yOrigin,
+                                         const double zOrigin);
+
+  /**
+   * Create a new structured grid (N dimensional).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   *
+   * @param     brickSize       The size of the brick in each direction.
+   * @param     numPoints       The number of points in each direction.
+   * @param     origin          The coordinates of the origin.
+   *
+   * @return                    Constructed structured grid.
+   */
+  static shared_ptr<XdmfRegularGrid>
+  New(const shared_ptr<XdmfArray> brickSize,
+      const shared_ptr<XdmfArray> numPoints,
+      const shared_ptr<XdmfArray> origin);
+
+  virtual ~XdmfRegularGrid();
+
+  LOKI_DEFINE_VISITABLE(XdmfRegularGrid, XdmfGrid)
+  static const std::string ItemTag;
+
+  /**
+   * Get the size of the bricks composing the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getBrickSize
+   * @until //#getBrickSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initvalue
+   * @until #//initvalue
+   * @skipline #//initialization2
+   * @until #//initialization2
+   * @skipline #//getBrickSize
+   * @until #//getBrickSize
+   *
+   * @return    XdmfArray containing brick sizes for this grid.
+   */
+  shared_ptr<XdmfArray> getBrickSize();
+
+  /**
+   * Get the size of the bricks composing the grid (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getBrickSizeconst
+   * @until //#getBrickSizeconst
+   *
+   * Python: Does not support a constant version of this function
+   *
+   * @return    XdmfArray containing brick sizes for this grid.
+   */
+  shared_ptr<const XdmfArray> getBrickSize() const;
+
+  /**
+   * Get the dimensions of the grid, the number of points in each
+   * direction.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initvalue
+   * @until #//initvalue
+   * @skipline #//initialization2
+   * @until #//initialization2
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    XdmfArray containing dimensions of this grid.
+   */
+  shared_ptr<XdmfArray> getDimensions();
+
+  /**
+   * Get the dimensions of the grid, the number of points in each
+   * direction (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getDimensionsconst
+   * @until //#getDimensionsconst
+   *
+   * Python: Does not support a constant version of this function
+   *
+   * @return    XdmfArray containing the dimensions of this grid.
+   */
+  shared_ptr<const XdmfArray> getDimensions() const;
+
+  /**
+   * Get the location of the origin of the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getOrigin
+   * @until //#getOrigin
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initvalue
+   * @until #//initvalue
+   * @skipline #//initialization2
+   * @until #//initialization2
+   * @skipline #//getOrigin
+   * @until #//getOrigin
+   *
+   * @return    XdmfArray containing the location of the origin of the
+   *            grid.
+   */
+  shared_ptr<XdmfArray> getOrigin();
+
+  /**
+   * Get the location of the origin of the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initvalue
+   * @until //#initvalue
+   * @skipline //#initialization2
+   * @until //#initialization2
+   * @skipline //#getOriginconst
+   * @until //#getOriginconst
+   *
+   * Python: Does not support a constant version of this function
+   *
+   * @return    XdmfArray containing the location of the origin of the
+   *            grid (const version).
+   */
+  shared_ptr<const XdmfArray> getOrigin() const;
+
+  virtual void read();
+
+  virtual void release();
+
+  /**
+   * Set the size of the points composing the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#setBrickSize
+   * @until //#setBrickSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   * @skipline #//setBrickSize
+   * @until #//setBrickSize
+   *
+   * @param     brickSize       The sizes of the points composing the mesh. This
+   *                            should have the same number of terms as the
+   *                            dimensionality of the mesh.
+   */
+  void setBrickSize(const shared_ptr<XdmfArray> brickSize);
+
+  /**
+   * Set the dimensions of the grid, the number of points in each
+   * direction.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#setDimensions
+   * @until //#setDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   * @skipline #//setDimensions
+   * @until #//setDimensions
+   *
+   * @param     dimensions      The dimension of the grid.
+   */
+  void setDimensions(const shared_ptr<XdmfArray> dimensions);
+
+  /**
+   * Set the origin of the grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfRegularGrid.cpp
+   * @skipline //#initializationvector
+   * @until //#initializationvector
+   * @skipline //#setOrigin
+   * @until //#setOrigin
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleRegularGrid.py
+   * @skipline #//initializationvector
+   * @until #//initializationvector
+   * @skipline #//setOrigin
+   * @until #//setOrigin
+   *
+   * @param     origin  Location of the origin of the grid.  This should
+   *                    have the same number of terms as the dimensionality
+   *                    of the mesh.
+   */
+  void setOrigin(const shared_ptr<XdmfArray> origin);
+
+  XdmfRegularGrid(XdmfRegularGrid &);
+
+protected:
+
+  XdmfRegularGrid(const shared_ptr<XdmfArray> brickSize,
+                  const shared_ptr<XdmfArray> numPoints,
+                  const shared_ptr<XdmfArray> origin);
+
+  virtual void
+  copyGrid(shared_ptr<XdmfGrid> sourceGrid);
+
+  void populateItem(const std::map<std::string, std::string> & itemProperties,
+                    const std::vector<shared_ptr<XdmfItem> > & childItems,
+                    const XdmfCoreReader * const reader);
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfRegularGridImpl;
+
+  XdmfRegularGrid(const XdmfRegularGrid &);  // Not implemented.
+  void operator=(const XdmfRegularGrid &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFREGULARGRID; // Simply as a typedef to ensure correct typing
+typedef struct XDMFREGULARGRID XDMFREGULARGRID;
+
+XDMF_EXPORT XDMFREGULARGRID * XdmfRegularGridNew2D(double xBrickSize,
+                                                   double yBrickSize,
+                                                   unsigned int xNumPoints,
+                                                   unsigned int yNumPoints,
+                                                   double xOrigin,
+                                                   double yOrigin);
+
+XDMF_EXPORT XDMFREGULARGRID * XdmfRegularGridNew3D(double xBrickSize,
+                                                   double yBrickSize,
+                                                   double zBrickSize,
+                                                   unsigned int xNumPoints,
+                                                   unsigned int yNumPoints,
+                                                   unsigned int zNumPoints,
+                                                   double xOrigin,
+                                                   double yOrigin,
+                                                   double zOrigin);
+
+XDMF_EXPORT XDMFREGULARGRID * XdmfRegularGridNew(XDMFARRAY * brickSize,
+                                                 XDMFARRAY * numPoints,
+                                                 XDMFARRAY * origin,
+                                                 int passControl);
+
+XDMF_EXPORT XDMFARRAY * XdmfRegularGridGetBrickSize(XDMFREGULARGRID * grid, int * status);
+
+XDMF_EXPORT XDMFARRAY * XdmfRegularGridGetDimensions(XDMFREGULARGRID * grid, int * status);
+
+XDMF_EXPORT XDMFARRAY * XdmfRegularGridGetOrigin(XDMFREGULARGRID * grid, int * status);
+
+XDMF_EXPORT void XdmfRegularGridSetBrickSize(XDMFREGULARGRID * grid, XDMFARRAY * brickSize, int passControl, int * status);
+
+XDMF_EXPORT void XdmfRegularGridSetDimensions(XDMFREGULARGRID * grid, XDMFARRAY * dimensions, int passControl, int * status);
+
+XDMF_EXPORT void XdmfRegularGridSetOrigin(XDMFREGULARGRID * grid, XDMFARRAY * origin, int passControl, int * status);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfRegularGrid, XDMFREGULARGRID, XDMF)
+XDMF_GRID_C_CHILD_DECLARE(XdmfRegularGrid, XDMFREGULARGRID, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFREGULARGRID_HPP_ */
diff --git a/XdmfSet.cpp b/XdmfSet.cpp
new file mode 100644
index 0000000..93c9bfd
--- /dev/null
+++ b/XdmfSet.cpp
@@ -0,0 +1,251 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSet.cpp                                                         */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfAttribute.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfError.hpp"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfSet, XdmfAttribute, Attribute, Name)
+
+  shared_ptr<XdmfSet>
+XdmfSet::New()
+{
+  shared_ptr<XdmfSet> p(new XdmfSet());
+  return p;
+}
+
+XdmfSet::XdmfSet() :
+  mName(""),
+  mType(XdmfSetType::NoSetType())
+{
+}
+
+XdmfSet::XdmfSet(XdmfSet & refSet) :
+  XdmfArray(refSet),
+  mName(refSet.mName),
+  mType(refSet.mType)
+{
+}
+
+XdmfSet::~XdmfSet()
+{
+}
+
+const std::string XdmfSet::ItemTag = "Set";
+
+std::map<std::string, std::string>
+XdmfSet::getItemProperties() const
+{
+  std::map<std::string, std::string> setProperties;
+  setProperties.insert(std::make_pair("Name", mName));
+  mType->getProperties(setProperties);
+  return setProperties;
+}
+
+std::string
+XdmfSet::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfSet::getName() const
+{
+  return mName;
+}
+
+shared_ptr<const XdmfSetType>
+XdmfSet::getType() const
+{
+  return mType;
+}
+
+void
+XdmfSet::populateItem(const std::map<std::string, std::string> & itemProperties,
+                      const std::vector<shared_ptr<XdmfItem> > & childItems,
+                      const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  std::map<std::string, std::string>::const_iterator name =
+    itemProperties.find("Name");
+  if(name != itemProperties.end()) {
+    mName = name->second;
+  }
+  mType = XdmfSetType::New(itemProperties);
+  bool filled = false;
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfAttribute> attribute =
+       shared_dynamic_cast<XdmfAttribute>(*iter)) {
+      this->insert(attribute);
+    }
+    else if(shared_ptr<XdmfArray> array = 
+            shared_dynamic_cast<XdmfArray>(*iter)) {
+      if (!filled) {
+        this->swap(array);
+        filled = true;
+      }
+      if (array->getReference()) {
+        this->setReference(array->getReference());
+        this->setReadMode(XdmfArray::Reference);
+      }
+      // TODO: If multiple dataitems.
+    }
+  }
+}
+
+void
+XdmfSet::setName(const std::string & name)
+{
+  mName = name;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSet::setType(const shared_ptr<const XdmfSetType> type)
+{
+  mType = type;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSet::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+  for (unsigned int i = 0; i < mAttributes.size(); ++i)
+  {
+    mAttributes[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+XDMFSET * XdmfSetNew()
+{
+  try
+  {
+    shared_ptr<XdmfSet> generatedSet = XdmfSet::New();
+    return (XDMFSET*)((void *)(new XdmfSet(*generatedSet.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfSet> generatedSet = XdmfSet::New();
+    return (XDMFSET*)((void *)(new XdmfSet(*generatedSet.get())));
+  }
+}
+
+XDMFATTRIBUTE * XdmfSetGetAttribute(XDMFSET * set, unsigned int index)
+{
+  return (XDMFATTRIBUTE *)((void *)(((XdmfSet *)(set))->getAttribute(index).get()));
+}
+
+XDMFATTRIBUTE * XdmfSetGetAttributeByName(XDMFSET * set, char * Name)
+{
+  return (XDMFATTRIBUTE *)((void *)(((XdmfSet *)(set))->getAttribute(Name).get()));
+}
+
+unsigned int XdmfSetGetNumberAttributes(XDMFSET * set)
+{
+  return ((XdmfSet *)(set))->getNumberAttributes();
+}
+
+int XdmfSetGetType(XDMFSET * set)
+{
+  shared_ptr<const XdmfSetType> checkType = ((XdmfSet *)set)->getType();
+
+  if (checkType == XdmfSetType::NoSetType()) {
+    return XDMF_SET_TYPE_NO_SET_TYPE;
+  }
+  else if (checkType == XdmfSetType::Node()) {
+    return XDMF_SET_TYPE_NODE;
+  }
+  else if (checkType == XdmfSetType::Cell()) {
+    return XDMF_SET_TYPE_CELL;
+  }
+  else if (checkType == XdmfSetType::Face()) {
+    return XDMF_SET_TYPE_FACE;
+  }
+  else if (checkType == XdmfSetType::Edge()) {
+    return XDMF_SET_TYPE_EDGE;
+  }
+  else {
+    return -1;
+  }
+}
+
+void XdmfSetInsertAttribute(XDMFSET * set, XDMFATTRIBUTE * Attribute, int passControl)
+{
+  if (passControl) {
+    ((XdmfSet *)(set))->insert(shared_ptr<XdmfAttribute>((XdmfAttribute *)Attribute));
+  }
+  else {
+    ((XdmfSet *)(set))->insert(shared_ptr<XdmfAttribute>((XdmfAttribute *)Attribute, XdmfNullDeleter()));
+  }
+}
+
+void XdmfSetRemoveAttribute(XDMFSET * set, unsigned int index)
+{
+  ((XdmfSet *)(set))->removeAttribute(index);
+}
+
+void XdmfSetRemoveAttributeByName(XDMFSET * set, char * Name)
+{
+  ((XdmfSet *)(set))->removeAttribute(Name);
+}
+
+void XdmfSetSetType(XDMFSET * set, int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<const XdmfSetType> newType = shared_ptr<const XdmfSetType>();
+  switch (type) {
+    case XDMF_SET_TYPE_NO_SET_TYPE:
+      newType = XdmfSetType::NoSetType();
+      break;
+    case XDMF_SET_TYPE_NODE:
+      newType = XdmfSetType::Node();
+      break;
+    case XDMF_SET_TYPE_CELL:
+      newType = XdmfSetType::Cell();
+      break;
+    case XDMF_SET_TYPE_FACE:
+      newType = XdmfSetType::Face();
+      break;
+    case XDMF_SET_TYPE_EDGE:
+      newType = XdmfSetType::Edge();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Set Type: Code " + type);
+      break;
+  }
+  ((XdmfSet *)set)->setType(newType);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfSet, XDMFSET)
+XDMF_ARRAY_C_CHILD_WRAPPER(XdmfSet, XDMFSET)
diff --git a/XdmfSet.hpp b/XdmfSet.hpp
new file mode 100644
index 0000000..5b239aa
--- /dev/null
+++ b/XdmfSet.hpp
@@ -0,0 +1,257 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSet.hpp                                                         */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFSET_HPP_
+#define XDMFSET_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfSetType.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfAttribute;
+class XdmfHDF5Controller;
+
+/**
+ * @brief Holds a collection of individual nodes, cells, faces, or
+ * edges that are part of an XdmfGrid.
+ *
+ * An XdmfSet holds a collection of nodes, cells, faces, or edges that
+ * are part of an XdmfGrid. For instance, a simulation may want to
+ * hold a set of nodes on a boundary. The individual elements making
+ * up the set are determined by their id. An XdmfSet can have
+ * XdmfAttributes attached that contain extra values attached to the
+ * elements in the set.
+ */
+class XDMF_EXPORT XdmfSet : public XdmfArray {
+
+public:
+
+  /**
+   * Create a new XdmfSet.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSet.cpp
+   * @skipline //#initialize
+   * @until //#initialize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSet.py
+   * @skipline #//initialize
+   * @until #//initialize
+   *
+   * @return    Constructed XdmfSet.
+   */
+  static shared_ptr<XdmfSet> New();
+
+  virtual ~XdmfSet();
+
+  LOKI_DEFINE_VISITABLE(XdmfSet, XdmfArray)
+  XDMF_CHILDREN(XdmfSet, XdmfAttribute, Attribute, Name)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the name of the set.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSet.cpp
+   * @skipline //#initialize
+   * @until //#initialize
+   * @skipline //#setName
+   * @until //#setName
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSet.py
+   * @skipline #//initialize
+   * @until #//initialize
+   * @skipline #//setName
+   * @until #//setName
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    A string containing the name of the set.
+   */
+  std::string getName() const;
+
+  /**
+   * Get the XdmfSetType associated with this set.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSet.cpp
+   * @skipline //#initialize
+   * @until //#initialize
+   * @skipline //#setType
+   * @until //#setType
+   * @skipline //#getType
+   * @until //#getType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSet.py
+   * @skipline #//initialize
+   * @until #//initialize
+   * @skipline #//setType
+   * @until #//setType
+   * @skipline #//getType
+   * @until #//getType
+   *
+   * @return    XdmfSetType of this set.
+   */
+  shared_ptr<const XdmfSetType> getType() const;
+
+  using XdmfArray::insert;
+  
+#if defined(SWIG)
+  using XdmfItem::insert;
+#endif
+
+  /**
+   * Set the name of the set.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSet.cpp
+   * @skipline //#initialize
+   * @until //#initialize
+   * @skipline //#setName
+   * @until //#setName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSet.py
+   * @skipline #//initialize
+   * @until #//initialize
+   * @skipline #//setName
+   * @until #//setName
+   *
+   * @param     name    A string containing the name to set.
+   */
+  void setName(const std::string & name);
+
+  /**
+   * Set the XdmfSetType associated with this set.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSet.cpp
+   * @skipline //#initialize
+   * @until //#initialize
+   * @skipline //#setType
+   * @until //#setType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSet.py
+   * @skipline //#initialize
+   * @until //#initialize
+   * @skipline //#setType
+   * @until //#setType
+   *
+   * @param     type    The XdmfSetType to set.
+   */
+  void setType(const shared_ptr<const XdmfSetType> type);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfSet(XdmfSet &);
+
+protected:
+
+  XdmfSet();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfSet(const XdmfSet &);
+  void operator=(const XdmfSet &);  // Not implemented.
+
+  std::string mName;
+  shared_ptr<const XdmfSetType> mType;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFSET; // Simply as a typedef to ensure correct typing
+typedef struct XDMFSET XDMFSET;
+
+XDMF_EXPORT XDMFSET * XdmfSetNew();
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfSetGetAttribute(XDMFSET * set, unsigned int index);
+
+XDMF_EXPORT XDMFATTRIBUTE * XdmfSetGetAttributeByName(XDMFSET * set, char * Name);
+
+XDMF_EXPORT unsigned int XdmfSetGetNumberAttributes(XDMFSET * set);
+
+XDMF_EXPORT int XdmfSetGetType(XDMFSET * set);
+
+XDMF_EXPORT void XdmfSetInsertAttribute(XDMFSET * set, XDMFATTRIBUTE * Attribute, int passControl);
+
+XDMF_EXPORT void XdmfSetRemoveAttribute(XDMFSET * set, unsigned int index);
+
+XDMF_EXPORT void XdmfSetRemoveAttributeByName(XDMFSET * set, char * Name);
+
+XDMF_EXPORT void XdmfSetSetType(XDMFSET * set, int type, int * status);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfSet, XDMFSET, XDMF)
+XDMF_ARRAY_C_CHILD_DECLARE(XdmfSet, XDMFSET, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFSET_HPP_ */
diff --git a/XdmfSetType.cpp b/XdmfSetType.cpp
new file mode 100644
index 0000000..5e80896
--- /dev/null
+++ b/XdmfSetType.cpp
@@ -0,0 +1,153 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSetType.cpp                                                     */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "XdmfSetType.hpp"
+#include "XdmfError.hpp"
+
+std::map<std::string, shared_ptr<const XdmfSetType>(*)()> XdmfSetType::mSetDefinitions;
+
+// Supported XdmfSetTypes
+shared_ptr<const XdmfSetType>
+XdmfSetType::NoSetType()
+{
+  static shared_ptr<const XdmfSetType> p(new XdmfSetType("None"));
+  return p;
+}
+
+shared_ptr<const XdmfSetType>
+XdmfSetType::Node()
+{
+  static shared_ptr<const XdmfSetType> p(new XdmfSetType("Node"));
+  return p;
+}
+
+shared_ptr<const XdmfSetType>
+XdmfSetType::Cell()
+{
+  static shared_ptr<const XdmfSetType> p(new XdmfSetType("Cell"));
+  return p;
+}
+
+shared_ptr<const XdmfSetType>
+XdmfSetType::Face()
+{
+  static shared_ptr<const XdmfSetType> p(new XdmfSetType("Face"));
+  return p;
+}
+
+shared_ptr<const XdmfSetType>
+XdmfSetType::Edge()
+{
+  static shared_ptr<const XdmfSetType> p(new XdmfSetType("Edge"));
+  return p;
+}
+
+void
+XdmfSetType::InitTypes()
+{
+  mSetDefinitions["NONE"] = NoSetType;
+  mSetDefinitions["NODE"] = Node;
+  mSetDefinitions["CELL"] = Cell;
+  mSetDefinitions["FACE"] = Face;
+  mSetDefinitions["EDGE"] = Edge;
+}
+
+XdmfSetType::XdmfSetType(const std::string & name) :
+  mName(name)
+{
+}
+
+XdmfSetType::~XdmfSetType()
+{
+}
+
+shared_ptr<const XdmfSetType>
+XdmfSetType::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("Type");
+  if(type == itemProperties.end()) {
+    type = itemProperties.find("SetType");
+  }
+  if(type == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL, 
+                       "Neither 'Type' nor 'SetType' found in itemProperties "
+                       "in XdmfSetType::New");
+  }
+  const std::string & typeVal = ConvertToUpper(type->second);
+
+  std::map<std::string, shared_ptr<const XdmfSetType>(*)()>::const_iterator returnType
+    = mSetDefinitions.find(typeVal);
+
+  if (returnType == mSetDefinitions.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Type not of 'None', 'Node', 'Cell', 'Face', or "
+                       "'Edge' in XdmfSetType::New");
+  }
+  else {
+    return (*(returnType->second))();
+  }
+
+  XdmfError::message(XdmfError::FATAL, 
+                     "Type not of 'None', 'Node', 'Cell', 'Face', or "
+                     "'Edge' in XdmfSetType::New");
+
+  // unreachable
+  return shared_ptr<const XdmfSetType>();
+}
+
+void
+XdmfSetType::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("Type", mName));
+}
+
+// C Wrappers
+
+int XdmfSetTypeNoSetType()
+{
+  return XDMF_SET_TYPE_NO_SET_TYPE;
+}
+
+int XdmfSetTypeNode()
+{
+  return XDMF_SET_TYPE_NODE;
+}
+
+int XdmfSetTypeCell()
+{
+  return XDMF_SET_TYPE_CELL;
+}
+
+int XdmfSetTypeFace()
+{
+  return XDMF_SET_TYPE_FACE;
+}
+
+int XdmfSetTypeEdge()
+{
+  return XDMF_SET_TYPE_EDGE;
+}
diff --git a/XdmfSetType.hpp b/XdmfSetType.hpp
new file mode 100644
index 0000000..4ffa3af
--- /dev/null
+++ b/XdmfSetType.hpp
@@ -0,0 +1,117 @@
+#ifndef XDMFSETTYPE_HPP_
+#define XDMFSETTYPE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include "XdmfItemProperty.hpp"
+
+/**
+ * @brief Property describing the type of ids an XdmfSet contains.
+ *
+ * An XdmfSet holds ids for a collection of nodes, cells, faces, or
+ * edges that are part of an XdmfGrid. This property indicates which
+ * type the set contains.
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfSet.cpp
+ * @skipline //#initialize
+ * @until //#initialize
+ * @skipline //#setType
+ * @until //#setType
+ * @skipline //#getType
+ * @until //#getType
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleSet.py
+ * @skipline #//initialize
+ * @until #//initialize
+ * @skipline #//setType
+ * @until #//setType
+ * @skipline #//getType
+ * @until #//getType
+ *
+ * Xdmf supports the following set types:
+ *   NoSetType
+ *   Node
+ *   Cell
+ *   Face
+ *   Edge
+ */
+class XDMF_EXPORT XdmfSetType : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfSetType();
+
+  friend class XdmfSet;
+
+  // Supported Xdmf Set Types
+  static shared_ptr<const XdmfSetType> NoSetType();
+  static shared_ptr<const XdmfSetType> Node();
+  static shared_ptr<const XdmfSetType> Cell();
+  static shared_ptr<const XdmfSetType> Face();
+  static shared_ptr<const XdmfSetType> Edge();
+
+  void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+protected:
+
+  /**
+   * Protected constructor for XdmfSetType. The constructor is
+   * protected because all set types supported by Xdmf should be
+   * accessed through more specific static methods that construct
+   * XdmfSetTypes - i.e. XdmfSetType::Node().
+   *
+   * @param     name    A std::string containing the name of the XdmfSetType.
+   */
+  XdmfSetType(const std::string & name);
+
+  static std::map<std::string, shared_ptr<const XdmfSetType>(*)()> mSetDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfSetType(const XdmfSetType &); // Not implemented.
+  void operator=(const XdmfSetType &); // Not implemented.
+
+  static shared_ptr<const XdmfSetType>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  std::string mName;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#define XDMF_SET_TYPE_NO_SET_TYPE 600
+#define XDMF_SET_TYPE_NODE        601
+#define XDMF_SET_TYPE_CELL        602
+#define XDMF_SET_TYPE_FACE        603
+#define XDMF_SET_TYPE_EDGE        604
+
+XDMF_EXPORT int XdmfSetTypeNoSetType();
+XDMF_EXPORT int XdmfSetTypeNode();
+XDMF_EXPORT int XdmfSetTypeCell();
+XDMF_EXPORT int XdmfSetTypeFace();
+XDMF_EXPORT int XdmfSetTypeEdge();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFSETTYPE_HPP_ */
diff --git a/XdmfTemplate.cpp b/XdmfTemplate.cpp
new file mode 100644
index 0000000..b9c19af
--- /dev/null
+++ b/XdmfTemplate.cpp
@@ -0,0 +1,1244 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTemplate.cpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <sstream>
+#include <utility>
+#include <climits>
+#include <set>
+#include "XdmfArray.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfItemFactory.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTemplate.hpp"
+#include "XdmfError.hpp"
+#include "XdmfVisitor.hpp"
+#include "XdmfWriter.hpp"
+
+#include "XdmfSystemUtils.hpp"
+
+#include <boost/tokenizer.hpp>
+
+#include <stdio.h>
+
+std::vector<shared_ptr<XdmfHeavyDataController> >
+getStepControllers(unsigned int stepId,
+                   std::vector<unsigned int> stepDims,
+                   std::vector<shared_ptr<XdmfHeavyDataController> > datasetControllers)
+{
+  std::vector<shared_ptr<XdmfHeavyDataController> > returnVector;
+  if (datasetControllers.size() > 0)
+  {
+    unsigned int sizePerStep = 1;
+    for (unsigned int i = 0; i < stepDims.size(); ++i)
+    {
+      sizePerStep *= stepDims[i];
+    }
+//    unsigned int offset = (sizePerStep * stepId);
+//    unsigned int offsetStepsRemaining = 0;
+    unsigned int offset = 0;
+    unsigned int offsetStepsRemaining = stepId;
+    // grabbing the subset is a little different for each type
+    // Right now we assume controllers are of the same type
+    unsigned int controllerIndex = 0;
+    unsigned int sizeRemaining = sizePerStep;
+    unsigned int arrayoffset = 0;
+    while (sizeRemaining > 0)
+    {
+//printf("sizeRemaining = %u\n", sizeRemaining);
+      // We don't reset the controller index between runs of the while loop
+      // On iterations after the first it should only execute the loop once
+      // because offset is set to 0
+      while (controllerIndex < datasetControllers.size())
+      {
+//printf("offset = %u\n", offset);
+//printf("%u >= %u\n", offset, datasetControllers[controllerIndex]->getSize());
+        //Iterate until we find the controller that the step starts in
+        if (offset >= datasetControllers[controllerIndex]->getSize())
+        {
+          offset -= datasetControllers[controllerIndex]->getSize();
+          ++controllerIndex;
+        }
+        else
+        {
+          if (offsetStepsRemaining == 0)
+          {
+            // offset is within the current controller
+            break;
+          }
+          else
+          {
+            // There are steps left to offset
+//printf("accounting for step %d\n", offsetStepsRemaining);
+            offset += sizePerStep;
+            --offsetStepsRemaining;
+          }
+        }
+      }
+//printf("final offset = %u\n", offset);
+      std::vector<unsigned int> newDimVector;
+      std::vector<unsigned int> newStarts;
+//printf("after creating dim vector but before filling it\n");
+//printf("%d < %d\n", controllerIndex, datasetControllers.size());
+//printf("size left %d\n", sizeRemaining);
+      if (offset + sizeRemaining <= datasetControllers[controllerIndex]->getSize())
+      {
+//printf("step is entirely in the controller\n");
+        // step is entirely within this controller
+        newStarts.push_back(offset + datasetControllers[controllerIndex]->getStart()[0]); // TODO multidim version
+        newDimVector.push_back(sizeRemaining);
+        sizeRemaining = 0;
+      }
+      else
+      {
+//printf("step is partially in the controller\n");
+        if (controllerIndex + 1 >= datasetControllers.size()) {
+          // Error, step doesn't fit in the data set provided
+          XdmfError::message(XdmfError::FATAL, "Error: Step does not fit in data step provided");
+        }
+        // step is partially in this controller
+        newDimVector.push_back(sizeRemaining -
+                               (sizeRemaining - (datasetControllers[controllerIndex]->getSize() - offset)));
+        newStarts.push_back(offset+datasetControllers[controllerIndex]->getStart()[0]); // TODO multidim version
+        sizeRemaining -= newDimVector[0];
+      }
+//printf("size for other controllers %d\n", sizeRemaining);
+//printf("before creating the new controller\n");
+      // Using the remaining space in the controller
+      // Slightly differen creation method for each controller
+      if (datasetControllers[0]->getName().compare("Binary") == 0) {
+        shared_ptr<XdmfBinaryController> createdController =
+          XdmfBinaryController::New(datasetControllers[0]->getFilePath(),
+                                    datasetControllers[0]->getType(),
+                                    shared_dynamic_cast<XdmfBinaryController>(
+                                      datasetControllers[0])->getEndian(),
+                                    newStarts[0],
+                                    newDimVector);
+        returnVector.push_back(createdController);
+      }
+      else if (datasetControllers[0]->getName().compare("HDF") == 0) {
+        // TODO
+        // The writer should only write to contiguous sets when in this mode.
+        // A user would need to do something custom to foul this up.
+        std::vector<unsigned int> newStrides;
+        newStrides.push_back(1);
+        shared_ptr<XdmfHDF5Controller> createdController =
+          XdmfHDF5Controller::New(datasetControllers[controllerIndex]->getFilePath(),
+                                  shared_dynamic_cast<XdmfHDF5Controller>(
+                                    datasetControllers[controllerIndex])->getDataSetPath(),
+                                  datasetControllers[0]->getType(),
+                                  newStarts,
+                                  newStrides,
+                                  newDimVector,
+                                  shared_dynamic_cast<XdmfHDF5Controller>(
+                                    datasetControllers[controllerIndex])->getDataspaceDimensions());
+        returnVector.push_back(createdController);
+      }
+//printf("after creating the new controller\n");
+      returnVector[returnVector.size()-1]->setArrayOffset(arrayoffset);
+      arrayoffset += returnVector[returnVector.size()-1]->getSize();
+      offset = 0;
+      ++controllerIndex;
+      // Starts at the beggining of the next controller
+    }
+  }
+/*
+printf("size of return vector = %d\n", returnVector.size());
+for (unsigned int i = 0; i < returnVector.size(); ++i)
+{
+  shared_ptr<XdmfHDF5Controller> currentController = shared_dynamic_cast<XdmfHDF5Controller>(returnVector[i]);
+assert(currentController);
+  printf("file = %s\n", currentController->getFilePath().c_str());
+  printf("dataset = %s\n", currentController->getDataSetPath().c_str());
+  printf("start = %u\n", currentController->getStart()[0]);
+  printf("dimension = %u\n", currentController->getDimensions()[0]);
+  printf("dataspace = %u\n", currentController->getDataspaceDimensions()[0]);
+}
+*/
+  return returnVector;
+}
+
+std::vector<shared_ptr<XdmfHeavyDataController> >
+getControllersExcludingStep(unsigned int stepId,
+                            std::vector<unsigned int> stepDims,
+                            std::vector<shared_ptr<XdmfHeavyDataController> > datasetControllers)
+{
+  std::vector<shared_ptr<XdmfHeavyDataController> > returnVector;
+  if (datasetControllers.size() > 0)
+  {
+    unsigned int sizePerStep = 1;
+    for (unsigned int i = 0; i < stepDims.size(); ++i)
+    {
+      sizePerStep *= stepDims[i];
+    }
+    unsigned int offset = sizePerStep * stepId;
+    unsigned int sizeRemaining = sizePerStep;
+//printf("base offset = %u\nstarting size remaining = %u\ncutting from %u controllers\n", offset, sizeRemaining, datasetControllers.size());
+    // grabbing the subset is a little different for each type
+    // Right now we assume controllers are of the same type
+    for (unsigned int controllerIndex = 0; controllerIndex < datasetControllers.size(); ++controllerIndex)
+    {
+//printf("offset = %u out of controller size %u\n", offset, datasetControllers[controllerIndex]->getSize());
+      if (offset >= datasetControllers[controllerIndex]->getSize())
+      {
+        // The removed step isn't in the controller provided
+        // Simply add it back into the return set
+        returnVector.push_back(datasetControllers[controllerIndex]);
+        // then subtract the size from the offset
+        offset -= datasetControllers[controllerIndex]->getSize();
+      }
+      else
+      {
+        // The removed step is inside the controller provided
+        if (offset > 0)
+        {
+//printf("removed step is inside this controller\n");
+          // If offset is greater than zero the controller has a section chopped off the front
+          std::vector<unsigned int> newDim;
+          newDim.push_back(offset);
+          // Dataspace is the same
+          // stride is the same
+          // start is the same
+          // TODO dims is reduced to just cover the offset size
+          if (datasetControllers[controllerIndex]->getName().compare("Binary") == 0) {
+            shared_ptr<XdmfBinaryController> createdController =
+              XdmfBinaryController::New(datasetControllers[controllerIndex]->getFilePath(),
+                                        datasetControllers[controllerIndex]->getType(),
+                                        shared_dynamic_cast<XdmfBinaryController>(
+                                          datasetControllers[controllerIndex])->getEndian(),
+                                        shared_dynamic_cast<XdmfBinaryController>(
+                                          datasetControllers[controllerIndex])->getSeek(),
+                                        datasetControllers[controllerIndex]->getStart(),
+                                        datasetControllers[controllerIndex]->getStride(),
+                                        newDim,
+                                        datasetControllers[controllerIndex]->getDataspaceDimensions());
+            returnVector.push_back(createdController);
+          }
+          else if (datasetControllers[controllerIndex]->getName().compare("HDF") == 0) {
+            // TODO
+            // The writer should only write to contiguous sets when in this mode.
+            // A user would need to do something custom to foul this up.
+            shared_ptr<XdmfHDF5Controller> createdController =
+              XdmfHDF5Controller::New(datasetControllers[controllerIndex]->getFilePath(),
+                                      shared_dynamic_cast<XdmfHDF5Controller>(
+                                        datasetControllers[controllerIndex])->getDataSetPath(),
+                                      datasetControllers[controllerIndex]->getType(),
+                                      datasetControllers[controllerIndex]->getStart(),
+                                      datasetControllers[controllerIndex]->getStride(),
+                                      newDim,
+                                      shared_dynamic_cast<XdmfHDF5Controller>(
+                                        datasetControllers[controllerIndex])->getDataspaceDimensions());
+            returnVector.push_back(createdController);
+          }
+          // These are the stats for the first half of the dataset
+          if (sizeRemaining <= datasetControllers[controllerIndex]->getSize() - offset)
+          {
+            // The controller is large enough to need to be split into two controllers
+            std::vector<unsigned int> newStart; //TODO we're assuming one dim for now
+            newStart.push_back(datasetControllers[controllerIndex]->getStart()[0] +sizeRemaining + offset);
+            std::vector<unsigned int> newDim;
+            newDim.push_back(datasetControllers[controllerIndex]->getSize() - (sizeRemaining + offset));
+            // These are the stats of the second controller
+            sizeRemaining = 0;
+            if (datasetControllers[controllerIndex]->getName().compare("Binary") == 0) {
+              shared_ptr<XdmfBinaryController> createdController =
+                XdmfBinaryController::New(datasetControllers[controllerIndex]->getFilePath(),
+                                          datasetControllers[controllerIndex]->getType(),
+                                          shared_dynamic_cast<XdmfBinaryController>(
+                                            datasetControllers[controllerIndex])->getEndian(),
+                                          shared_dynamic_cast<XdmfBinaryController>(
+                                            datasetControllers[controllerIndex])->getSeek(),
+                                          newStart,
+                                          datasetControllers[controllerIndex]->getStride(),
+                                          newDim,
+                                          datasetControllers[controllerIndex]->getDataspaceDimensions());
+              returnVector.push_back(createdController);
+            }
+            else if (datasetControllers[controllerIndex]->getName().compare("HDF") == 0) {
+              // TODO
+              // The writer should only write to contiguous sets when in this mode.
+              // A user would need to do something custom to foul this up.
+              shared_ptr<XdmfHDF5Controller> createdController =
+                XdmfHDF5Controller::New(datasetControllers[controllerIndex]->getFilePath(),
+                                        shared_dynamic_cast<XdmfHDF5Controller>(
+                                          datasetControllers[controllerIndex])->getDataSetPath(),
+                                        datasetControllers[controllerIndex]->getType(),
+                                        newStart,
+                                        datasetControllers[controllerIndex]->getStride(),
+                                        newDim,
+                                        shared_dynamic_cast<XdmfHDF5Controller>(
+                                          datasetControllers[controllerIndex])->getDataspaceDimensions());
+              returnVector.push_back(createdController);
+            }
+          }
+          else {
+            // The controller only contains part of the dataset
+            sizeRemaining -= (datasetControllers[controllerIndex]->getSize() - offset);
+          }
+          offset = 0;
+        }
+        else
+        {
+          // in the case of 0 offset, we either need to trim from the front or just use the whole controller
+          if (sizeRemaining > 0)
+          {
+            if (sizeRemaining < datasetControllers[controllerIndex]->getSize())
+            {
+              std::vector<unsigned int> newStart;
+              newStart.push_back(sizeRemaining);
+              std::vector<unsigned int> newDim;
+              newDim.push_back(datasetControllers[controllerIndex]->getSize() - sizeRemaining);
+              sizeRemaining = 0;
+              if (datasetControllers[controllerIndex]->getName().compare("Binary") == 0) {
+                shared_ptr<XdmfBinaryController> createdController =
+                  XdmfBinaryController::New(datasetControllers[controllerIndex]->getFilePath(),
+                                            datasetControllers[controllerIndex]->getType(),
+                                            shared_dynamic_cast<XdmfBinaryController>(
+                                            datasetControllers[controllerIndex])->getEndian(),
+                                            shared_dynamic_cast<XdmfBinaryController>(
+                                              datasetControllers[controllerIndex])->getSeek(),
+                                            newStart,
+                                            datasetControllers[controllerIndex]->getStride(),
+                                            newDim,
+                                            datasetControllers[controllerIndex]->getDataspaceDimensions());
+                returnVector.push_back(createdController);
+              }
+              else if (datasetControllers[controllerIndex]->getName().compare("HDF") == 0) {
+                // TODO
+                // The writer should only write to contiguous sets when in this mode.
+                // A user would need to do something custom to foul this up.
+                shared_ptr<XdmfHDF5Controller> createdController =
+                  XdmfHDF5Controller::New(datasetControllers[controllerIndex]->getFilePath(),
+                                          shared_dynamic_cast<XdmfHDF5Controller>(
+                                            datasetControllers[controllerIndex])->getDataSetPath(),
+                                          datasetControllers[controllerIndex]->getType(),
+                                          newStart,
+                                          datasetControllers[controllerIndex]->getStride(),
+                                          newDim,
+                                          shared_dynamic_cast<XdmfHDF5Controller>(
+                                            datasetControllers[controllerIndex])->getDataspaceDimensions());
+                returnVector.push_back(createdController);
+              }
+            }
+            else {
+              sizeRemaining -= datasetControllers[controllerIndex]->getSize();
+            }
+          }
+          else
+          {
+            // Just use the current controller
+            returnVector.push_back(datasetControllers[controllerIndex]);
+          }
+        }
+      }
+    }
+  }
+  return returnVector;
+}
+
+class XdmfArrayGatherer : public XdmfVisitor, public Loki::Visitor<XdmfArray>
+{
+  public:
+
+    static shared_ptr<XdmfArrayGatherer>
+    New(std::vector<XdmfArray *> * storageVector)
+    {
+       shared_ptr<XdmfArrayGatherer> p(new XdmfArrayGatherer(storageVector));
+       return p;
+    }
+
+    ~XdmfArrayGatherer()
+    {
+    }
+
+    virtual void
+    visit(XdmfArray & array,
+          const shared_ptr<XdmfBaseVisitor> visitor)
+    {
+      ++mDepth;
+      if (!array.isInitialized())
+      {
+//      mStorage->push_back(&array);
+        mArrayCollection.insert(&array);
+      }
+      array.traverse(visitor);
+      --mDepth;
+      if (mDepth == 0)
+      {
+        moveToStorage();
+      }
+    }
+
+    virtual void
+    visit(XdmfItem & item,
+          const shared_ptr<XdmfBaseVisitor> visitor)
+    {
+      ++mDepth;
+      item.traverse(visitor);
+      --mDepth;
+      if (mDepth == 0)
+      {
+        moveToStorage();
+      }
+    }
+
+    void
+    moveToStorage()
+    {
+      for (std::set<XdmfArray *>::iterator iter = mArrayCollection.begin();
+           iter != mArrayCollection.end();
+           ++iter)
+      {
+        mStorage->push_back(*iter);
+      }
+    }
+
+  private: 
+
+    XdmfArrayGatherer(std::vector<XdmfArray *> * storageVector) :
+      mDepth(0),
+      mStorage(storageVector)
+    {
+    }
+
+  unsigned int mDepth;
+  std::set<XdmfArray *> mArrayCollection;
+  std::vector<XdmfArray *> * mStorage;
+};
+
+shared_ptr<XdmfTemplate>
+XdmfTemplate::New()
+{
+  shared_ptr<XdmfTemplate> p(new XdmfTemplate());
+  return p;
+}
+
+
+XdmfTemplate::XdmfTemplate() :
+  mHeavyWriter(shared_ptr<XdmfHeavyDataWriter>()),
+  mBase(shared_ptr<XdmfItem>()),
+  mCurrentStep(-1),
+  mNumSteps(0),
+  mItemFactory(shared_ptr<XdmfItemFactory>())
+{
+}
+
+XdmfTemplate::XdmfTemplate(XdmfTemplate & refTemplate) :
+  XdmfItem(refTemplate),
+  mBase(refTemplate.mBase),
+  mCurrentStep(refTemplate.mCurrentStep),
+  mNumSteps(refTemplate.mNumSteps),
+  mItemFactory(refTemplate.mItemFactory)
+{
+}
+
+XdmfTemplate::~XdmfTemplate()
+{
+}
+
+const std::string XdmfTemplate::ItemTag = "Template";
+
+unsigned int
+XdmfTemplate::addStep()
+{
+  mCurrentStep = this->getNumberSteps();
+  std::stringstream datastream;
+  if (mTrackedArrays.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: XdmfTemplate attempting to add a step when no arrays are tracked");
+  }
+  for (unsigned int arrayIndex = 0; arrayIndex < mTrackedArrays.size(); ++arrayIndex) {
+    if (mTrackedArrayTypes.size() < mTrackedArrays.size()){
+      mTrackedArrayTypes.resize(mTrackedArrays.size());
+    }
+    if (mTrackedArrayDims.size() < mTrackedArrays.size()){
+      mTrackedArrayDims.resize(mTrackedArrays.size());
+    }
+    if (!mTrackedArrayTypes[arrayIndex]) {
+      mTrackedArrayTypes[arrayIndex] = mTrackedArrays[arrayIndex]->getArrayType();
+    }
+    if (mTrackedArrayDims[arrayIndex].size() == 0) {
+      mTrackedArrayDims[arrayIndex] = mTrackedArrays[arrayIndex]->getDimensions();
+    }
+    // Write the tracked arrays to heavy data if they aren't already
+    if (mHeavyWriter) {
+      bool revertToAppend = false;
+      if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Append) {
+        // Set to original heavy data controllers for append
+        if (mDataControllers.size() > arrayIndex)
+        {
+          if (mDataControllers[arrayIndex].size() > 0)
+          {
+            while (mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers() > 0) {
+              mTrackedArrays[arrayIndex]->removeHeavyDataController(0);
+            }
+            for (unsigned int i = 0; i < mDataControllers[arrayIndex].size(); ++i)
+            {
+              mTrackedArrays[arrayIndex]->insert(mDataControllers[arrayIndex][i]);
+            }
+          }
+        }
+        else
+        {
+          // Creating new Dataset
+          // Set to default mode so that it doesn't overlap
+          mHeavyWriter->setMode(XdmfHeavyDataWriter::Default);
+          revertToAppend = true;
+        }
+      }
+      else if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Hyperslab) {
+        // Use the controller that references the subset that will be overwritten
+        if (!(arrayIndex < mDataControllers.size()))
+        {
+          // When in overwrite mode the dataset must be preallocated
+          XdmfError::message(XdmfError::FATAL, "Error: Heavy Data dataset must be preallocated "
+                                               "to use Hyperslab mode Templates");
+        }
+        std::vector<shared_ptr<XdmfHeavyDataController> > overwriteControllers =
+          getStepControllers(mCurrentStep, mTrackedArrayDims[arrayIndex], mDataControllers[arrayIndex]);
+        mTrackedArrays[arrayIndex]->setHeavyDataController(overwriteControllers);
+      }
+      mTrackedArrays[arrayIndex]->accept(mHeavyWriter);
+      if (revertToAppend)
+      {
+        mHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+      }
+    }
+    datastream.str(std::string());
+    for (unsigned int controllerIndex = 0; controllerIndex < mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers(); ++controllerIndex) {
+      // TODO throw error if controller types don't match
+      // For each heavy data controller
+      std::string writerPath = XdmfSystemUtils::getRealPath(mHeavyWriter->getFilePath());
+      std::string heavyDataPath =
+        mTrackedArrays[arrayIndex]->getHeavyDataController(controllerIndex)->getFilePath();
+      size_t index = heavyDataPath.find_last_of("/\\");
+      if(index != std::string::npos) {
+        // If path is not a folder
+        // put the directory path into this variable
+        const std::string heavyDataDir = heavyDataPath.substr(0, index + 1);
+        // If the directory is in the XML File Path
+        if(writerPath.find(heavyDataDir) == 0) {
+          heavyDataPath =
+            heavyDataPath.substr(heavyDataDir.size(),
+                                 heavyDataPath.size() - heavyDataDir.size());
+          // Pull the file off of the end and place it in the DataPath
+        }
+        // Otherwise the full path is required
+      }
+      datastream << heavyDataPath;
+      datastream << mTrackedArrays[arrayIndex]->getHeavyDataController(controllerIndex)->getDescriptor();
+        datastream << "|";
+        for (unsigned int i = 0; i < mTrackedArrays[arrayIndex]->getHeavyDataController(controllerIndex)->getDimensions().size(); ++i) {
+          datastream << mTrackedArrays[arrayIndex]->getHeavyDataController(controllerIndex)->getDimensions()[i];
+          if (i < mTrackedArrays[arrayIndex]->getHeavyDataController(controllerIndex)->getDimensions().size() - 1) {
+            datastream << " ";
+          }
+        }
+        if (controllerIndex + 1 < mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers()) {
+          datastream << "|";
+        }
+    }
+    if (mHeavyWriter) {
+      if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Append) {
+        if (mDataControllers.size() > arrayIndex)
+        {
+          // If controllers already exist
+          // Store the overarching controllers again
+          mDataControllers[arrayIndex].clear();
+          for (unsigned int i = 0; i < mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers(); ++i)
+          {
+            mDataControllers[arrayIndex].push_back(mTrackedArrays[arrayIndex]->getHeavyDataController(i));
+          }
+          // Clear controllers from the array
+          while (mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers() > 0) {
+            mTrackedArrays[arrayIndex]->removeHeavyDataController(0);
+          }
+          // If append set controller to the correct subsection of the whole
+          std::vector<shared_ptr<XdmfHeavyDataController> > readControllers = getStepControllers(mCurrentStep, mTrackedArrayDims[arrayIndex], mDataControllers[arrayIndex]);
+          mTrackedArrays[arrayIndex]->setHeavyDataController(readControllers);
+          // Replace with updated description
+          mDataDescriptions[arrayIndex] = datastream.str();
+        }
+        else
+        {
+          // If a new dataset, as normal
+          mDataControllers.push_back(std::vector<shared_ptr<XdmfHeavyDataController> >());
+          for (unsigned int i = 0; i < mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers(); ++i) {
+            mDataControllers[mDataControllers.size()-1].push_back((mTrackedArrays[arrayIndex]->getHeavyDataController(i)));
+          }
+          if (mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers() > 0) {
+            mDataTypes.push_back(mTrackedArrays[arrayIndex]->getHeavyDataController(0)->getName());
+            mDataDescriptions.push_back(datastream.str());
+          }
+        }
+      }
+      else if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Hyperslab) {
+        // Hyperslab is already storing the base controller
+        // So nothing is done here, the controller should already be pointing to the correct location
+        // TODO, to what the file index was before the add, as opposed to 0
+        mHeavyWriter->setFileIndex(0);
+      }
+      else {
+        mDataControllers.push_back(std::vector<shared_ptr<XdmfHeavyDataController> >());
+        for (unsigned int i = 0; i < mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers(); ++i) {
+          mDataControllers[mDataControllers.size()-1].push_back((mTrackedArrays[arrayIndex]->getHeavyDataController(i)));
+        }
+        if (mTrackedArrays[arrayIndex]->getNumberHeavyDataControllers() > 0) {
+          mDataTypes.push_back(mTrackedArrays[arrayIndex]->getHeavyDataController(0)->getName());
+          mDataDescriptions.push_back(datastream.str());
+        }
+      }
+    }
+    else {
+      mDataControllers.push_back(std::vector<shared_ptr<XdmfHeavyDataController> >());
+      mDataTypes.push_back("XML");
+      mDataDescriptions.push_back(mTrackedArrays[arrayIndex]->getValuesString());
+    }
+  }
+  ++mNumSteps;
+  this->setIsChanged(true);
+  return mCurrentStep;
+}
+
+void
+XdmfTemplate::clearStep()
+{
+  for (unsigned int i = 0; i < mTrackedArrays.size(); ++i) {
+    mTrackedArrays[i]->release();
+    while (mTrackedArrays[i]->getNumberHeavyDataControllers() > 0) {
+      mTrackedArrays[i]->removeHeavyDataController(0);
+    }
+  }
+  mCurrentStep = -1;
+}
+
+shared_ptr<XdmfItem>
+XdmfTemplate::getBase()
+{
+  return mBase;
+}
+
+shared_ptr<XdmfHeavyDataWriter>
+XdmfTemplate::getHeavyDataWriter()
+{
+  return mHeavyWriter;
+}
+
+std::map<std::string, std::string>
+XdmfTemplate::getItemProperties() const
+{
+  std::map<std::string, std::string> templateProperties;
+/*
+  std::stringstream value;
+  value << mValue;
+  timeProperties.insert(std::make_pair("Value", value.str()));
+*/
+  return templateProperties;
+}
+
+std::string
+XdmfTemplate::getItemTag() const
+{
+  return ItemTag;
+}
+
+unsigned int
+XdmfTemplate::getNumberSteps() const
+{
+  return mNumSteps;
+}
+
+unsigned int
+XdmfTemplate::getNumberTrackedArrays() const
+{
+  return mTrackedArrays.size();
+}
+
+XdmfArray *
+XdmfTemplate::getTrackedArray(unsigned int index)
+{
+  return mTrackedArrays[index];
+}
+
+
+void
+XdmfTemplate::populateItem(const std::map<std::string, std::string> & itemProperties,
+                           const std::vector<shared_ptr<XdmfItem> > & childItems,
+                           const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+
+  // The first child item is the base
+  mBase = childItems[0];
+  mCurrentStep = 0;
+
+  std::string referenceHDF5File = "";
+
+  if (childItems.size() > 1) {
+    for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+          childItems.begin() + 1;
+        iter != childItems.end();
+        ++iter) {
+      if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+        // Pull hdf5 reference data from the first provided array
+        if (array->getNumberHeavyDataControllers() > 0 & !mHeavyWriter) {
+          mHeavyWriter = reader->generateHeavyDataWriter(array->getHeavyDataController(0)->getName(), array->getHeavyDataController(0)->getFilePath());
+        }
+        if (array->getName().compare("Data Description") == 0) {
+          // Split description into substrings based on the " character
+          array->read();
+
+          std::string descriptionString;
+          if (array->getArrayType() == XdmfArrayType::Int8())
+          {
+            descriptionString = std::string((char *)array->getValuesInternal());
+          }
+          else if (array->getArrayType() == XdmfArrayType::String())
+          {
+            std::stringstream descriptionstream;
+            for (unsigned int i = 0; i < array->getSize(); ++i)
+            {
+              descriptionstream << array->getValue<std::string>(i);
+              if (i < array->getSize() - 1)
+              {
+                descriptionstream << '|';
+              }
+            }
+            descriptionString = descriptionstream.str();
+          }
+
+          size_t index = descriptionString.find_first_of("\"");
+          size_t previousIndex = 0;
+
+          if (index != std::string::npos) {
+            // Removing the prepended "
+            previousIndex = index + 1;
+            index = descriptionString.find_first_of("\"", previousIndex);
+          }
+
+          while (index != std::string::npos) {
+            std::string type = descriptionString.substr(previousIndex, index - previousIndex);
+            mDataTypes.push_back(type);
+            previousIndex = index + 1;
+            index = descriptionString.find_first_of("\"", previousIndex);
+            if (index - previousIndex > 0) {
+              std::string description;
+              description = descriptionString.substr(previousIndex, index - previousIndex);
+              mDataDescriptions.push_back(description);
+              // create controllers here based on the type/description?
+              // Is array type already filled?
+              // Potentially call "fillControllers" after populating?
+              if (index != std::string::npos) {
+                previousIndex = index + 1;
+                index = descriptionString.find_first_of("\"", previousIndex);
+              }
+            }
+            else {
+              XdmfError::message(XdmfError::FATAL, "Error: Type without a description in XdmfTemplate::populateItem");
+            }
+          }
+        }
+        else {
+          mTrackedArrays.push_back(array.get());
+          mTrackedArrayDims.push_back(array->getDimensions());
+          mTrackedArrayTypes.push_back(array->getArrayType());
+        }
+      }
+    }
+  }
+  for (unsigned int i = 0; i < mDataTypes.size(); ++i)
+  {
+    mDataControllers.push_back(std::vector<shared_ptr<XdmfHeavyDataController> >());
+  }
+  mDataControllers.resize(mDataTypes.size());
+  if (!mItemFactory) {
+    mItemFactory = XdmfItemFactory::New();
+  }
+  std::map<std::string, std::string> populateProperties;
+  if (mHeavyWriter) {
+    // The heavy writer provides the XMLDir, which is used to get full paths for the controllers
+    // It is assumed that the files that the controllers reference are in the same directory
+    // as the file that the writer references
+    std::string filepath = XdmfSystemUtils::getRealPath(mHeavyWriter->getFilePath());
+    size_t index = filepath.find_last_of("/\\");
+    filepath = filepath.substr(0, index + 1);
+    populateProperties["XMLDir"] = filepath;
+  }
+  else
+  {
+    // Error because a writer is required? TODO
+  }
+  for (unsigned int i = 0;  i < mDataDescriptions.size(); ++i) {
+    populateProperties["Content"] = mDataDescriptions[i];
+    std::vector<shared_ptr<XdmfHeavyDataController> > readControllers =
+      reader->generateHeavyDataControllers(populateProperties, mTrackedArrayDims[i % mTrackedArrays.size()], mTrackedArrayTypes[i % mTrackedArrays.size()], mDataTypes[i]);
+    if (readControllers.size() > 0) {
+      // Heavy data controllers reference the data
+      for (unsigned int j = 0; j < readControllers.size(); ++j) {
+        mDataControllers[i].push_back(readControllers[j]);
+      }
+    }
+  }
+  // Compare the first set of controllers to the size of the first array
+  unsigned int controllerTotal = 0;
+
+  for (unsigned int i = 0; i < mDataControllers[0].size(); ++i)
+  {
+    unsigned int previousTotal = controllerTotal;
+    controllerTotal += mDataControllers[0][i]->getSize();
+    if (previousTotal != controllerTotal - mDataControllers[0][i]->getSize())
+    {
+      controllerTotal = UINT_MAX;
+      break;
+    }
+  }
+  // If the array is smaller, set the writer to append.
+  if (controllerTotal > mTrackedArrays[0]->getSize())
+  {
+    mHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+    mNumSteps = 0;
+    unsigned int currentTotal = 0;
+    for (unsigned int controllerIndex = 0; controllerIndex < mDataControllers[0].size(); ++controllerIndex)
+    {
+      currentTotal += mDataControllers[0][controllerIndex]->getSize();
+      while (currentTotal >= mTrackedArrays[0]->getSize())
+      {
+        currentTotal -= mTrackedArrays[0]->getSize();
+        ++mNumSteps;
+      }
+    }
+//    mNumSteps = controllerTotal / mTrackedArrays[0]->getSize();
+  }
+  else {
+    mNumSteps = mDataControllers.size() / mTrackedArrays.size();
+  }
+  this->setStep(0);
+}
+
+void
+XdmfTemplate::preallocateSteps(unsigned int numSteps)
+{
+  // Preallocate steps based on the current size of the arrays
+  // Use a temporary array to write data to hdf5
+  shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+  // Set to Default mode so that the new allocations are in new locations
+  mHeavyWriter->setMode(XdmfHeavyDataWriter::Default);
+  int preallocatedSize = 0;
+  int numberSetsPreallocated = 0;
+  std::stringstream datastream;
+  for (unsigned int i = 0; i < mTrackedArrays.size(); ++i) {
+    preallocatedSize = mTrackedArrays[i]->getSize() * numSteps;
+///*
+    numberSetsPreallocated = 1;
+
+    int adjustment = 1;
+    while (preallocatedSize / (numSteps/adjustment) != mTrackedArrays[i]->getSize() || 0 > (int)preallocatedSize) {
+//      XdmfError::message(XdmfError::WARNING, "Overflow error");
+      ++adjustment;
+      while (numSteps % adjustment != 0) {
+//printf("%d / %d remainder %d\n", numSteps, adjustment, (numSteps % adjustment));
+        ++adjustment;
+      }
+      numberSetsPreallocated = numberSetsPreallocated * adjustment;
+      preallocatedSize = mTrackedArrays[i]->getSize() * (numSteps / adjustment);
+//printf("%d / %d = %d ?= %d\n", preallocatedSize , (numSteps/adjustment), preallocatedSize / (numSteps/adjustment), mTrackedArrays[i]->getSize());
+    }
+
+    // If adjusted, split one more time, to ensure that the dataset fits.
+    if (adjustment > 1) {
+      ++adjustment;
+      while (numSteps % adjustment != 0) {
+        ++adjustment;
+      }
+      numberSetsPreallocated = numberSetsPreallocated * adjustment;
+      preallocatedSize = mTrackedArrays[i]->getSize() * (numSteps / adjustment);
+    }
+
+    bool allocateSucceeded = false;
+    while (!allocateSucceeded)
+    {
+      try {
+        mHeavyWriter->openFile();
+//printf("now size %d allocated %d times\n", preallocatedSize, numberSetsPreallocated);
+        for (unsigned int allocateIteration = 0;
+             allocateIteration < numberSetsPreallocated;
+             ++allocateIteration)
+        {
+//printf("allocating subsection %u\n", allocateIteration);
+//*/
+//printf("initializing base array\n");
+          tempArray->initialize(mTrackedArrays[i]->getArrayType(), preallocatedSize);
+//printf("writing subsection");
+          tempArray->accept(mHeavyWriter);
+//printf("subsection written\n");
+//          mHeavyWriter->clearCache();
+///*
+          if (mDataControllers.size() <= i) {
+            mDataControllers.push_back(std::vector<shared_ptr<XdmfHeavyDataController> >());
+          }
+          // Clean Array for the next iteration
+          while (tempArray->getNumberHeavyDataControllers() > 0) {
+            mDataControllers[i].push_back(tempArray->getHeavyDataController(0));
+            if (mDataTypes.size() <= i) {
+              mDataTypes.push_back(tempArray->getHeavyDataController(0)->getName());
+            }
+            tempArray->removeHeavyDataController(0);
+          }
+          tempArray->release();
+//*/
+///*
+//printf("moving to next allocation\n");
+        }
+        mHeavyWriter->closeFile();
+        allocateSucceeded = true;
+//*/
+//TODO catch the controllers created by this.
+///*
+      }
+      catch (...)
+      {
+        while (tempArray->getNumberHeavyDataControllers() > 0) {
+          tempArray->removeHeavyDataController(0);
+        }
+        tempArray->release();
+//        XdmfError::message(XdmfError::WARNING, "Array Allocation failed");
+        int factor = 2;
+        while (preallocatedSize % factor != 0) {
+//printf("%d / %d remainder %d\n", preallocatedSize, factor, (preallocatedSize % factor));
+          factor = factor + 1;
+        }
+//printf("adjusted factor %d\n", factor);
+        numberSetsPreallocated = numberSetsPreallocated * factor;
+        preallocatedSize = (preallocatedSize) / factor;
+//printf("now size %d allocated %d times\n", preallocatedSize, numberSetsPreallocated);
+      }
+    }
+//printf("Done writing to hdf5\n");
+//*/
+/*
+    // Transfer controllers to the appropriate slot before clearing them
+    if (mDataControllers.size() <= i) {
+      mDataControllers.push_back(std::vector<shared_ptr<XdmfHeavyDataController> >());
+    }
+    // Clean Array for the next iteration
+    while (tempArray->getNumberHeavyDataControllers() > 0) {
+      mDataControllers[i].push_back(tempArray->getHeavyDataController(0));
+      if (mDataTypes.size() <= i) {
+        mDataTypes.push_back(tempArray->getHeavyDataController(0)->getName());
+      }
+      tempArray->removeHeavyDataController(0);
+    }
+    tempArray->release();
+*/
+    datastream.str(std::string());
+    for (unsigned int controllerIndex = 0; controllerIndex < mDataControllers[i].size(); ++controllerIndex) {
+      // TODO throw error if controller types don't match
+      // For each heavy data controller
+      std::string writerPath = XdmfSystemUtils::getRealPath(mHeavyWriter->getFilePath());
+      std::string heavyDataPath =
+        mDataControllers[i][controllerIndex]->getFilePath();
+      size_t index = heavyDataPath.find_last_of("/\\");
+      if(index != std::string::npos) {
+        // If path is not a folder
+        // put the directory path into this variable
+        const std::string heavyDataDir = heavyDataPath.substr(0, index + 1);
+        // If the directory is in the XML File Path
+        if(writerPath.find(heavyDataDir) == 0) {
+          heavyDataPath =
+            heavyDataPath.substr(heavyDataDir.size(),
+                                 heavyDataPath.size() - heavyDataDir.size());
+          // Pull the file off of the end and place it in the DataPath
+        }
+        // Otherwise the full path is required
+      }
+      datastream << heavyDataPath;
+      datastream << mDataControllers[i][controllerIndex]->getDescriptor();
+      datastream << "|";
+      for (unsigned int j = 0; j < mDataControllers[i][controllerIndex]->getDimensions().size(); ++j) {
+        datastream << mDataControllers[i][controllerIndex]->getDimensions()[j];
+        if (j < mDataControllers[i][controllerIndex]->getDimensions().size() - 1) {
+          datastream << " ";
+        }
+      }
+      if (controllerIndex + 1 < mDataControllers[i].size()) {
+        datastream << "|";
+      }
+    }
+    mDataDescriptions.push_back(datastream.str());
+  }
+  // To end set the heavy writer to overwrite mode
+  mHeavyWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+}
+
+
+void
+XdmfTemplate::removeStep(unsigned int stepId)
+{
+  if (stepId < this->getNumberSteps()) {
+    for (unsigned int i = 0; i < mTrackedArrays.size(); ++i) {
+      if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Append ||
+          mHeavyWriter->getMode() == XdmfHeavyDataWriter::Hyperslab) {
+        std::vector<shared_ptr<XdmfHeavyDataController> > replacementControllers = getControllersExcludingStep(stepId, mTrackedArrayDims[i], mDataControllers[i]);
+        for (unsigned int j = 0; j < replacementControllers.size(); ++j)
+        {
+          if (mDataControllers[i].size() > j) {
+            mDataControllers[i][j] = replacementControllers[j];
+          }
+          else {
+            mDataControllers[i].push_back(replacementControllers[j]);
+          }
+        }
+      }
+      else {
+        mDataTypes.erase(mDataTypes.begin() + (stepId*mTrackedArrays.size()));
+        mDataDescriptions.erase(mDataDescriptions.begin() + (stepId*mTrackedArrays.size()));
+        mDataControllers.erase(mDataControllers.begin() + (stepId*mTrackedArrays.size()));
+      }
+    }
+    --mNumSteps;
+  }
+  mCurrentStep = -1;
+  this->setIsChanged(true);
+}
+
+void
+XdmfTemplate::setBase(shared_ptr<XdmfItem> newBase)
+{
+  shared_ptr<XdmfArrayGatherer> accumulator = XdmfArrayGatherer::New(&mTrackedArrays);
+  newBase->accept(accumulator);
+  mBase = newBase;
+  this->setIsChanged(true);
+}
+
+void
+XdmfTemplate::setHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter> writer)
+{
+  mHeavyWriter = writer;
+}
+
+void
+XdmfTemplate::setStep(unsigned int stepId)
+{
+  if (stepId != mCurrentStep) {
+    if (!mItemFactory) {
+      mItemFactory = XdmfItemFactory::New();
+    }
+    if (stepId < this->getNumberSteps()) {
+      for (unsigned int i = 0; i < mTrackedArrays.size(); ++i) {
+        unsigned int arrayIndex = 0;
+        if (mHeavyWriter) {
+            if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Append ||
+                mHeavyWriter->getMode() == XdmfHeavyDataWriter::Hyperslab) {
+              arrayIndex = i;
+            }
+            else {
+              arrayIndex = i+(stepId*mTrackedArrays.size());
+            }
+          }
+          else {
+            arrayIndex = i+(stepId*mTrackedArrays.size());
+        }
+        if (mDataControllers[arrayIndex].size() > 0) {
+          if(mHeavyWriter) {
+            if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Append ||
+                mHeavyWriter->getMode() == XdmfHeavyDataWriter::Hyperslab) {
+              std::vector<shared_ptr<XdmfHeavyDataController> > insertVector =
+                getStepControllers(stepId, mTrackedArrayDims[i], mDataControllers[i]);
+               mTrackedArrays[i]->setHeavyDataController(insertVector);
+            }
+            else {
+              mTrackedArrays[i]->setHeavyDataController(mDataControllers[i+(stepId*mTrackedArrays.size())]);
+            }
+          }
+          else {
+            mTrackedArrays[i]->setHeavyDataController(mDataControllers[i+(stepId*mTrackedArrays.size())]);
+          }
+        }
+        else {
+          std::map<std::string, std::string> populateProperties;
+          if (mHeavyWriter) {
+            // The heavy writer provides the XMLDir, which is used to get full paths for the controllers
+            // It is assumed that the files that the controllers reference are in the same directory
+            // as the file that the writer references
+            std::string filepath = XdmfSystemUtils::getRealPath(mHeavyWriter->getFilePath());
+            size_t index = filepath.find_last_of("/\\");
+            filepath = filepath.substr(0, index + 1);
+            populateProperties["XMLDir"] = filepath;
+          }
+          populateProperties["Content"] = mDataDescriptions[arrayIndex];
+          std::vector<shared_ptr<XdmfHeavyDataController> > readControllers;
+          if (mHeavyWriter) {
+            if (mHeavyWriter->getMode() == XdmfHeavyDataWriter::Append ||
+                mHeavyWriter->getMode() == XdmfHeavyDataWriter::Hyperslab) {
+              std::vector<shared_ptr<XdmfHeavyDataController> > totalControllers =
+                mItemFactory->generateHeavyDataControllers(populateProperties, mTrackedArrayDims[i], mTrackedArrayTypes[i], mDataTypes[i+(stepId*mTrackedArrays.size())]);
+              readControllers = getStepControllers(stepId, mTrackedArrayDims[i], totalControllers);
+            }
+            else {
+              readControllers = mItemFactory->generateHeavyDataControllers(populateProperties, mTrackedArrayDims[i], mTrackedArrayTypes[i], mDataTypes[i+(stepId*mTrackedArrays.size())]);
+            }
+          }
+          else {
+            readControllers = mItemFactory->generateHeavyDataControllers(populateProperties, mTrackedArrayDims[i], mTrackedArrayTypes[i], mDataTypes[i+(stepId*mTrackedArrays.size())]);
+          }
+          if (readControllers.size() > 0) {
+            // Heavy data controllers reference the data
+            mTrackedArrays[i]->setHeavyDataController(readControllers);
+            mDataControllers[arrayIndex] = readControllers; 
+          }
+          else {
+            // Data is contained in the content
+            std::string content = mDataDescriptions[i+(stepId*mTrackedArrays.size())];
+
+            mTrackedArrays[i]->initialize(mTrackedArrayTypes[i], mTrackedArrayDims[i]);
+
+            unsigned int index = 0;
+            boost::char_separator<char> sep(" \t\n");
+            boost::tokenizer<boost::char_separator<char> > valtokens(content, sep);
+            if(mTrackedArrayTypes[i] == XdmfArrayType::String()) {
+              for(boost::tokenizer<boost::char_separator<char> >::const_iterator
+                    iter = valtokens.begin();
+                  iter != valtokens.end();
+                  ++iter, ++index) {
+                mTrackedArrays[i]->insert(index, *iter);
+              }
+            }
+            else {
+              for(boost::tokenizer<boost::char_separator<char> >::const_iterator
+                    iter = valtokens.begin();
+                  iter != valtokens.end();
+                  ++iter, ++index) {
+                mTrackedArrays[i]->insert(index, atof((*iter).c_str()));
+              }
+            }
+          }
+        }
+      }
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL, "Error: Template attempting to load invalid step");
+    }
+    mCurrentStep = stepId;
+  }
+}
+
+void
+XdmfTemplate::trackArray(shared_ptr<XdmfArray> newArray)
+{
+  bool found = false;
+
+  for (unsigned int i = 0; i < mTrackedArrays.size() && !found; ++i) {
+    if (mTrackedArrays[i] == newArray.get()) {
+      found = true;
+    }
+  }
+
+  if (!found) {
+    mTrackedArrays.push_back(newArray.get());
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfTemplate::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  // Set to the first step when writing, as the first step is the model for the rest of the template
+  // Will fail if there are no steps
+  if (this->getNumberSteps() == 0) {
+    XdmfError::message(XdmfError::FATAL, "Error: No steps in template in XdmfTemplate::traverse");
+  }
+  this->clearStep();
+
+  unsigned int arraysize = 1;
+  for (unsigned int i = 0; i < mTrackedArrayDims[0].size(); ++i)
+  {
+    arraysize *= mTrackedArrayDims[0][i];
+  }
+
+  unsigned int controllersize = 0;
+  for (unsigned int i = 0; i < mDataControllers[0].size(); ++i)
+  {
+    controllersize += mDataControllers[0][i]->getSize();
+  }
+
+  XdmfHeavyDataWriter::Mode originalMode;
+
+  if (mHeavyWriter)
+  {
+    originalMode = mHeavyWriter->getMode();
+    if (controllersize > arraysize) {
+      mHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+    }
+  }
+
+  this->setStep(0);
+
+  if (mHeavyWriter)
+  {
+    mHeavyWriter->setMode(originalMode);
+  }
+
+  // Sending visitor to the base first so that it appears first when reading.
+  mBase->accept(visitor);
+
+  for (unsigned int i = 0; i < mTrackedArrays.size(); ++i) {
+    mTrackedArrays[i]->release();
+    mTrackedArrays[i]->accept(visitor);
+  }
+
+  // Create an array to hold all of the data information strings
+
+  bool originalXPath;
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    originalXPath = writer->getWriteXPaths();
+    writer->setWriteXPaths(false);
+  }
+
+  shared_ptr<XdmfArray> dataInfoArray = XdmfArray::New();
+
+  dataInfoArray->setName("Data Description");
+
+  unsigned int i = 0;
+
+  std::stringstream arrayInfo;
+  while (i < mDataTypes.size()) {
+    arrayInfo << "\"" << mDataTypes[i] << "\"" << mDataDescriptions[i];
+    ++i;
+  }
+  dataInfoArray->insert(0, arrayInfo.str().c_str(), arrayInfo.str().length());
+  dataInfoArray->insert(dataInfoArray->getSize(), 0);
+
+  dataInfoArray->accept(visitor);
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    writer->setWriteXPaths(originalXPath);
+  }
+
+  XdmfItem::traverse(visitor);
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfTemplate, XDMFTEMPLATE)
diff --git a/XdmfTemplate.hpp b/XdmfTemplate.hpp
new file mode 100644
index 0000000..8ea7d44
--- /dev/null
+++ b/XdmfTemplate.hpp
@@ -0,0 +1,218 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTemplate.hpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFTEMPLATE_HPP_
+#define XDMFTEMPLATE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfItemFactory.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+
+/**
+ * @brief Defines a template that can be filled with multiple sets of data.
+ *
+ * An XdmfTemplate defines a structure. The arrays within that structure
+ * are stored if they are not initialized when the structure is first set.
+ * Steps can then be added and references to heavy data are produced and
+ * stored for later retrieval.
+ *
+ * This effectively lets an object have several variations with different
+ * contained data.
+ */
+class XDMF_EXPORT XdmfTemplate : public virtual XdmfItem {
+
+public:
+
+  /**
+   * Creates a new instance of the XdmfTemplate object
+   *
+   * @return    A constructed XdmfTemplate object.
+   */
+  static shared_ptr<XdmfTemplate> New();
+
+  virtual ~XdmfTemplate();
+
+  LOKI_DEFINE_VISITABLE(XdmfTemplate, XdmfItem);
+  static const std::string ItemTag;
+
+  /**
+   * Writes all tracked arrays to heavy data via the provided
+   * heavy data writer then stores the heavy data descriptions.
+   *
+   * @return    The ID of the step that was added
+   */
+  virtual unsigned int addStep();
+
+  /**
+   * Clears the current data from the tracked arrays.
+   */
+  virtual void clearStep();
+
+  /**
+   * Gets the XdmfItem that serves as the structure for the template.
+   *
+   * @return    The XdmfItem that serves as the structure for the template.
+   */
+  virtual shared_ptr<XdmfItem> getBase();
+
+  /**
+   * Gets the heavy data writer that is used to write step data to heavy data.
+   *
+   * @return    The heavy data writer
+   */
+  shared_ptr<XdmfHeavyDataWriter> getHeavyDataWriter();
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Gets the number of steps currently contained within the template.
+   *
+   * @return    The number of steps contained within the template.
+   */
+  unsigned int getNumberSteps() const;
+
+  /**
+   * Gets the number of arrays tracked across timesteps.
+   *
+   * @return    The numer of tracked arrays.
+   */
+  unsigned int getNumberTrackedArrays() const;
+
+  /**
+   * Gets the tracked array at the specified index. The index of the array
+   * depends on when the internal visitor encountered the array in question.
+   *
+   * @return    The requested array.
+   */
+  XdmfArray * getTrackedArray(unsigned int index);
+
+  using XdmfItem::insert;
+
+  /*
+   *
+   */
+  virtual void preallocateSteps(unsigned int numSteps);
+
+  /**
+   * 
+   */
+  virtual void removeStep(unsigned int stepId);
+
+  /**
+   * Sets the item to define the structure for each step of the template.
+   *
+   * When the base is set all uninitialized arrays are added to
+   * the list of tracked arrays.
+   *
+   * @param     newBase The item to serve as the structure.
+   */
+  virtual void setBase(shared_ptr<XdmfItem> newBase);
+
+  /**
+   * Sets the heavy data writer with which the template will write
+   * to heavy data when adding a step.
+   *
+   * @param     writer  The writer to be used to write to heavy data.
+   */
+  void setHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter> writer);
+
+  /**
+   * Reads in the heavy data associated with the provided step id.
+   *
+   * @param     stepId  The id of the step whose heavy data
+   *                    is to be read in from file
+   */
+  virtual void setStep(unsigned int stepId);
+
+  /**
+   * Adds an array to the list of tracked arrays if that array
+   * is not already there.
+   *
+   * The setBase method automatically sets uninitialized arrays
+   * to be tracked, this can be used to add any missed by setBase.
+   *
+   * @param     newArray        The array to be tracked.
+   */
+  virtual void trackArray(shared_ptr<XdmfArray> newArray);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfTemplate(XdmfTemplate &);
+
+protected:
+
+  XdmfTemplate();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+  shared_ptr<XdmfHeavyDataWriter> mHeavyWriter;
+
+  shared_ptr<XdmfItem> mBase;
+  std::vector<XdmfArray *> mTrackedArrays;
+  std::vector<std::string> mDataTypes;
+  std::vector<std::string> mDataDescriptions;
+  std::vector<std::vector<shared_ptr<XdmfHeavyDataController> > > mDataControllers;
+  std::vector<shared_ptr<const XdmfArrayType> > mTrackedArrayTypes;
+  std::vector<std::vector<unsigned int> > mTrackedArrayDims;
+  int mCurrentStep;
+  unsigned int mNumSteps;
+  shared_ptr<XdmfItemFactory> mItemFactory;
+
+private:
+
+  XdmfTemplate(const XdmfTemplate &);  // Not implemented.
+  void operator=(const XdmfTemplate &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFTEMPLATE; // Simply as a typedef to ensure correct typing
+typedef struct XDMFTEMPLATE XDMFTEMPLATE;
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfTemplate, XDMFTEMPLATE, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* XDMFTEMPLATE_HPP_ */
diff --git a/XdmfTime.cpp b/XdmfTime.cpp
new file mode 100644
index 0000000..028bd29
--- /dev/null
+++ b/XdmfTime.cpp
@@ -0,0 +1,124 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTime.cpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <sstream>
+#include <utility>
+#include "XdmfTime.hpp"
+#include "XdmfError.hpp"
+
+shared_ptr<XdmfTime>
+XdmfTime::New(const double & value)
+{
+  shared_ptr<XdmfTime> p(new XdmfTime(value));
+  return p;
+}
+
+XdmfTime::XdmfTime(const double & value) :
+  mValue(value)
+{
+}
+
+XdmfTime::XdmfTime(XdmfTime & refTime) :
+  XdmfItem(refTime),
+  mValue(refTime.getValue())
+{
+}
+
+XdmfTime::~XdmfTime()
+{
+}
+
+const std::string XdmfTime::ItemTag = "Time";
+
+std::map<std::string, std::string>
+XdmfTime::getItemProperties() const
+{
+  std::map<std::string, std::string> timeProperties;
+  std::stringstream value;
+  value << mValue;
+  timeProperties.insert(std::make_pair("Value", value.str()));
+  return timeProperties;
+}
+
+std::string
+XdmfTime::getItemTag() const
+{
+  return ItemTag;
+}
+
+double
+XdmfTime::getValue() const
+{
+  return mValue;
+}
+
+void
+XdmfTime::populateItem(const std::map<std::string, std::string> & itemProperties,
+                       const std::vector<shared_ptr<XdmfItem> > & childItems,
+                       const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  std::map<std::string, std::string>::const_iterator value =
+    itemProperties.find("Value");
+  if(value != itemProperties.end()) {
+    mValue = atof(value->second.c_str());
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, 
+                       "'Value' not in itemProperties in "
+                       "XdmfTime::populateItem");
+  }
+}
+
+void
+XdmfTime::setValue(const double & value)
+{
+  mValue = value;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFTIME * XdmfTimeNew(double value)
+{
+  try
+  {
+    return (XDMFTIME *)((void *)(new XdmfTime(*(XdmfTime::New(value).get()))));
+  }
+  catch (...)
+  {
+    return (XDMFTIME *)((void *)(new XdmfTime(*(XdmfTime::New(value).get()))));
+  }
+}
+
+double XdmfTimeGetValue(XDMFTIME * timePointer)
+{
+  return ((XdmfTime *)timePointer)->getValue();
+}
+
+void XdmfTimeSetValue(XDMFTIME * timePointer, double time)
+{
+  ((XdmfTime *)timePointer)->setValue(time);
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfTime, XDMFTIME)
diff --git a/XdmfTime.hpp b/XdmfTime.hpp
new file mode 100644
index 0000000..44fe81c
--- /dev/null
+++ b/XdmfTime.hpp
@@ -0,0 +1,165 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTime.hpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFTIME_HPP_
+#define XDMFTIME_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Time specification for an XdmfGrid.
+ *
+ * An XdmfTime sets a time value for an XdmfGrid.
+ */
+class XDMF_EXPORT XdmfTime : public XdmfItem {
+
+public:
+
+  /**
+   * Create a new XdmfTime.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTime.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTime.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     value   The timeValue of the XdmfTime to create.
+   * @return            The new XdmfTime.
+   */
+  static shared_ptr<XdmfTime> New(const double & value = 0);
+
+  virtual ~XdmfTime();
+
+  LOKI_DEFINE_VISITABLE(XdmfTime, XdmfItem)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the time value associated with this XdmfTime.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTime.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getValue
+   * @until //#getValue
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTime.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getValue
+   * @until #//getValue
+   *
+   * @return    A double containing the time value.
+   */
+  double getValue() const;
+
+  /**
+   * Set the time value associated with this XdmfTime.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTime.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setValue
+   * @until //#setValue
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTime.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setValue
+   * @until #//setValue
+   *
+   * @param     time    A double containing the time value.
+   */
+  void setValue(const double & time);
+
+  XdmfTime(XdmfTime &);
+
+protected:
+
+  XdmfTime(const double & value);
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfTime(const XdmfTime &);  // Not implemented.
+  void operator=(const XdmfTime &);  // Not implemented.
+
+  double mValue;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFTIME; // Simply as a typedef to ensure correct typing
+typedef struct XDMFTIME XDMFTIME;
+
+XDMF_EXPORT XDMFTIME * XdmfTimeNew(double value);
+
+XDMF_EXPORT double XdmfTimeGetValue(XDMFTIME * timePointer);
+
+XDMF_EXPORT void XdmfTimeSetValue(XDMFTIME * timePointer, double time);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfTime, XDMFTIME, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFTIME_HPP_ */
diff --git a/XdmfTopology.cpp b/XdmfTopology.cpp
new file mode 100644
index 0000000..2d0c27f
--- /dev/null
+++ b/XdmfTopology.cpp
@@ -0,0 +1,605 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopology.cpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <sstream>
+#include <utility>
+#include "XdmfError.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+
+shared_ptr<XdmfTopology>
+XdmfTopology::New()
+{
+  shared_ptr<XdmfTopology> p(new XdmfTopology());
+  return p;
+}
+
+XdmfTopology::XdmfTopology() :
+  mType(XdmfTopologyType::NoTopologyType()),
+  mBaseOffset(0)
+{
+}
+
+XdmfTopology::XdmfTopology(XdmfTopology & refTopo) :
+  XdmfArray(refTopo),
+  mType(refTopo.mType)
+{
+}
+
+XdmfTopology::~XdmfTopology()
+{
+}
+
+const std::string XdmfTopology::ItemTag = "Topology";
+
+int
+XdmfTopology::getBaseOffset() const
+{
+  return mBaseOffset;
+}
+
+std::string
+XdmfTopology::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::map<std::string, std::string>
+XdmfTopology::getItemProperties() const
+{
+  std::map<std::string, std::string> topologyProperties;
+  mType->getProperties(topologyProperties);
+  if(mType->getCellType() != XdmfTopologyType::Structured) {
+    std::stringstream numElements;
+    numElements << this->getNumberElements();
+    topologyProperties.insert(std::make_pair("Dimensions", numElements.str()));
+  }
+  if (mBaseOffset != 0)
+  {
+    std::stringstream offsetString;
+    offsetString << mBaseOffset;
+    topologyProperties.insert(std::make_pair("BaseOffset", offsetString.str()));
+  }
+  return topologyProperties;
+}
+
+unsigned int
+XdmfTopology::getNumberElements() const
+{
+  // deal with special cases first (mixed / no topology)
+  if(mType->getNodesPerElement() == 0) {
+    if(mType == XdmfTopologyType::Mixed()) {
+      unsigned int index = 0;
+      unsigned int numberElements = 0;
+      // iterate over all values in connectivity, pulling topology type ids
+      // and counting number of elements
+      while(index < this->getSize()) {
+        const unsigned int id = this->getValue<unsigned int>(index);
+        const shared_ptr<const XdmfTopologyType> topologyType =
+          XdmfTopologyType::New(id);
+        if(topologyType == NULL) {
+          XdmfError::message(XdmfError::FATAL,
+                             "Invalid topology type id found in connectivity "
+                             "when parsing mixed topology.");
+        }
+        if(topologyType == XdmfTopologyType::Polyvertex()) {
+          const unsigned int numberPolyvertexElements =
+            this->getValue<unsigned int>(index + 1);
+          numberElements += numberPolyvertexElements;
+          index += numberPolyvertexElements + 2;
+        }
+        else if(topologyType == XdmfTopologyType::Polyline(0) ||
+                topologyType == XdmfTopologyType::Polygon(0)) {
+          const unsigned int numberNodes =
+            this->getValue<unsigned int>(index + 1);
+          numberElements += 1;
+          index += numberNodes + 2;
+        }
+        else if(topologyType == XdmfTopologyType::Polyhedron()) {
+          // get number of face
+          const unsigned int numberFaces =
+            this->getValue<unsigned int>(index + 1);
+          // skip to first face
+          index += 2;
+          // iterate over all faces and add number of nodes per face to index
+          for(unsigned int i=0; i<numberFaces; ++i) {
+            index += this->getValue<unsigned int>(index) + 1;
+          }
+          numberElements += 1;
+        }
+        else {
+          // add 1 to element count and move to next element id
+          numberElements += 1;
+          index += topologyType->getNodesPerElement() + 1;
+        }
+      }
+      return numberElements;
+    }
+    return 0;
+  }
+  return this->getSize() / mType->getNodesPerElement();
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopology::getType() const
+{
+  return mType;
+}
+
+void
+XdmfTopology::populateItem(const std::map<std::string, std::string> & itemProperties,
+                           const std::vector<shared_ptr<XdmfItem> > & childItems,
+                           const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  mType = XdmfTopologyType::New(itemProperties);
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter = childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+      this->swap(array);
+      if (array->getReference()) {
+        this->setReference(array->getReference());
+        this->setReadMode(XdmfArray::Reference);
+      }
+      break;
+    }
+  }
+
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("Offset");
+  if (type != itemProperties.end()) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("BaseOffset");
+  }
+  if (type != itemProperties.end()) {
+    // Convert to double
+    double offset = atof(type->second.c_str());
+    std::stringstream expressionStream;
+    expressionStream << offset << "+X";
+    std::map<std::string, shared_ptr<XdmfArray> > offsetMap;
+    shared_ptr<XdmfArray> offsetBase = XdmfArray::New();
+    this->swap(offsetBase);
+    offsetMap["X"] = offsetBase;
+    shared_ptr<XdmfFunction> offsetFunction = XdmfFunction::New(expressionStream.str(), offsetMap);
+    this->setReference(offsetFunction);
+    this->setReadMode(XdmfArray::Reference);
+  }
+}
+
+void
+XdmfTopology::setBaseOffset(int offset)
+{
+  mBaseOffset = offset;
+}
+
+void
+XdmfTopology::setType(const shared_ptr<const XdmfTopologyType> type)
+{
+  mType = type;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+XDMFTOPOLOGY * XdmfTopologyNew()
+{
+  try
+  {
+    shared_ptr<XdmfTopology> generatedTopology = XdmfTopology::New();
+    return (XDMFTOPOLOGY *)((void *)(new XdmfTopology(*generatedTopology.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfTopology> generatedTopology = XdmfTopology::New();
+    return (XDMFTOPOLOGY *)((void *)(new XdmfTopology(*generatedTopology.get())));
+  }
+}
+
+unsigned int XdmfTopologyGetNumberElements(XDMFTOPOLOGY * topology, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfTopology *)topology)->getNumberElements();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+int XdmfTopologyGetType(XDMFTOPOLOGY * topology)
+{
+  shared_ptr<const XdmfTopologyType> type = ((XdmfTopology *)topology)->getType();
+  int returnType = -1;
+
+  if (type->getID() == XdmfTopologyType::Polyvertex()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_POLYVERTEX;
+  }
+  else if (type->getID() == XdmfTopologyType::Polyline(0)->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_POLYLINE;
+  }
+  else if (type->getID() == XdmfTopologyType::Polygon(0)->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_POLYGON;
+  }
+  else if (type->getID() == XdmfTopologyType::Triangle()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_TRIANGLE;
+  }
+  else if (type->getID() == XdmfTopologyType::Quadrilateral()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_QUADRILATERAL;
+  }
+  else if (type->getID() == XdmfTopologyType::Tetrahedron()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_TETRAHEDRON;
+  }
+  else if (type->getID() == XdmfTopologyType::Pyramid()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_PYRAMID;
+  }
+  else if (type->getID() == XdmfTopologyType::Wedge()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_WEDGE;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON;
+  }
+  else if (type->getID() == XdmfTopologyType::Edge_3()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_EDGE_3;
+  }
+  else if (type->getID() == XdmfTopologyType::Triangle_6()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_TRIANGLE_6;
+  }
+  else if (type->getID() == XdmfTopologyType::Quadrilateral_8()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8;
+  }
+  else if (type->getID() == XdmfTopologyType::Quadrilateral_9()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9;
+  }
+  else if (type->getID() == XdmfTopologyType::Tetrahedron_10()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10;
+  }
+  else if (type->getID() == XdmfTopologyType::Pyramid_13()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_PYRAMID_13;
+  }
+  else if (type->getID() == XdmfTopologyType::Wedge_15()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_WEDGE_15;
+  }
+  else if (type->getID() == XdmfTopologyType::Wedge_18()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_WEDGE_18;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_20()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_24()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_27()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_64()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_125()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_216()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_343()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_512()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_729()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_1000()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_1331()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_64()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_125()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_216()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_343()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_512()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_729()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_1000()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_1331()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331;
+  }
+  else if (type->getID() == XdmfTopologyType::Mixed()->getID()) {
+    returnType = XDMF_TOPOLOGY_TYPE_MIXED;
+  }
+  else {
+    returnType = -1;
+  }
+
+  return returnType;
+}
+
+void XdmfTopologySetType(XDMFTOPOLOGY * topology, int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<const XdmfTopologyType> newType = shared_ptr<const XdmfTopologyType>();
+
+  switch (type) {
+    case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+      newType = XdmfTopologyType::Polyvertex();
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYLINE:
+      newType = XdmfTopologyType::Polyline(0);
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYGON:
+      newType = XdmfTopologyType::Polygon(0);
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+      newType = XdmfTopologyType::Triangle();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+      newType = XdmfTopologyType::Quadrilateral();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+      newType = XdmfTopologyType::Tetrahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID:
+      newType = XdmfTopologyType::Pyramid();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE:
+      newType = XdmfTopologyType::Wedge();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+      newType = XdmfTopologyType::Hexahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_EDGE_3:
+      newType = XdmfTopologyType::Edge_3();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+      newType = XdmfTopologyType::Triangle_6();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+      newType = XdmfTopologyType::Quadrilateral_8();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+      newType = XdmfTopologyType::Quadrilateral_9();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+      newType = XdmfTopologyType::Tetrahedron_10();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+      newType = XdmfTopologyType::Pyramid_13();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+      newType = XdmfTopologyType::Wedge_15();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+      newType = XdmfTopologyType::Wedge_18();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+      newType = XdmfTopologyType::Hexahedron_20();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+      newType = XdmfTopologyType::Hexahedron_24();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+      newType = XdmfTopologyType::Hexahedron_27();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+      newType = XdmfTopologyType::Hexahedron_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+      newType = XdmfTopologyType::Hexahedron_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+      newType = XdmfTopologyType::Hexahedron_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+      newType = XdmfTopologyType::Hexahedron_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+      newType = XdmfTopologyType::Hexahedron_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+      newType = XdmfTopologyType::Hexahedron_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+      newType = XdmfTopologyType::Hexahedron_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+      newType = XdmfTopologyType::Hexahedron_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64:
+      newType = XdmfTopologyType::Hexahedron_Spectral_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125:
+      newType = XdmfTopologyType::Hexahedron_Spectral_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216:
+      newType = XdmfTopologyType::Hexahedron_Spectral_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343:
+      newType = XdmfTopologyType::Hexahedron_Spectral_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512:
+      newType = XdmfTopologyType::Hexahedron_Spectral_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729:
+      newType = XdmfTopologyType::Hexahedron_Spectral_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000:
+      newType = XdmfTopologyType::Hexahedron_Spectral_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331:
+      newType = XdmfTopologyType::Hexahedron_Spectral_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_MIXED:
+      newType = XdmfTopologyType::Mixed();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Topology Type: Code " + type);
+      break;
+  }
+
+  ((XdmfTopology *)topology)->setType(newType);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfTopologySetPolyType(XDMFTOPOLOGY * topology, int type, int nodes, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<const XdmfTopologyType> newType = shared_ptr<const XdmfTopologyType>();
+
+  switch (type) {
+    case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+      newType = XdmfTopologyType::Polyvertex();
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYLINE:
+      newType = XdmfTopologyType::Polyline(nodes);
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYGON:
+      newType = XdmfTopologyType::Polygon(nodes);
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+      newType = XdmfTopologyType::Triangle();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+      newType = XdmfTopologyType::Quadrilateral();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+      newType = XdmfTopologyType::Tetrahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID:
+      newType = XdmfTopologyType::Pyramid();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE:
+      newType = XdmfTopologyType::Wedge();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+      newType = XdmfTopologyType::Hexahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_EDGE_3:
+      newType = XdmfTopologyType::Edge_3();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+      newType = XdmfTopologyType::Triangle_6();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+      newType = XdmfTopologyType::Quadrilateral_8();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+      newType = XdmfTopologyType::Quadrilateral_9();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+      newType = XdmfTopologyType::Tetrahedron_10();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+      newType = XdmfTopologyType::Pyramid_13();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+      newType = XdmfTopologyType::Wedge_15();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+      newType = XdmfTopologyType::Wedge_18();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+      newType = XdmfTopologyType::Hexahedron_20();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+      newType = XdmfTopologyType::Hexahedron_24();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+      newType = XdmfTopologyType::Hexahedron_27();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+      newType = XdmfTopologyType::Hexahedron_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+      newType = XdmfTopologyType::Hexahedron_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+      newType = XdmfTopologyType::Hexahedron_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+      newType = XdmfTopologyType::Hexahedron_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+      newType = XdmfTopologyType::Hexahedron_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+      newType = XdmfTopologyType::Hexahedron_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+      newType = XdmfTopologyType::Hexahedron_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+      newType = XdmfTopologyType::Hexahedron_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64:
+      newType = XdmfTopologyType::Hexahedron_Spectral_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125:
+      newType = XdmfTopologyType::Hexahedron_Spectral_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216:
+      newType = XdmfTopologyType::Hexahedron_Spectral_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343:
+      newType = XdmfTopologyType::Hexahedron_Spectral_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512:
+      newType = XdmfTopologyType::Hexahedron_Spectral_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729:
+      newType = XdmfTopologyType::Hexahedron_Spectral_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000:
+      newType = XdmfTopologyType::Hexahedron_Spectral_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331:
+      newType = XdmfTopologyType::Hexahedron_Spectral_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_MIXED:
+      newType = XdmfTopologyType::Mixed();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Topology Type: Code " + type);
+      break;
+  }
+  ((XdmfTopology *)topology)->setType(newType);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfTopology, XDMFTOPOLOGY)
+XDMF_ARRAY_C_CHILD_WRAPPER(XdmfTopology, XDMFTOPOLOGY)
diff --git a/XdmfTopology.hpp b/XdmfTopology.hpp
new file mode 100644
index 0000000..f76570c
--- /dev/null
+++ b/XdmfTopology.hpp
@@ -0,0 +1,231 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopology.hpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFTOPOLOGY_HPP_
+#define XDMFTOPOLOGY_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfTopologyType.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Holds the connectivity information in an XdmfGrid.
+ *
+ * XdmfTopology is a required part of an XdmfGrid. It stores the
+ * connectivity information for all points contained in an
+ * XdmfGrid. XdmfTopology contains an XdmfTopologyType property which
+ * should be set that specifies the element type stored.
+ *
+ * In the case of mixed topology types, the connectivity stores
+ * topology type ids prior to each element's connectivity
+ * information. For element types of varying sizes (Polyvertex,
+ * Polyline, and Polygon), the topology type id is followed by a
+ * number specifying the number of nodes in the element.  For example,
+ * a tetrahedron element (id 6) followed by a polygon element (id 3)
+ * with 5 points would look similar the following:
+ *
+ * 6 20 25 100 200 3 5 300 301 302 303 304
+ *
+ * The tetrahedron is composed of nodes 20, 25, 100, and 200. The
+ * polygon is composed of nodes 300 to 304.
+ *
+ * Elements of type Polyhedron (i.e. N face cells, where each face is a M edge
+ * polygon) are in the following format:
+ * [nCellFaces, nFace0Pts, id0_0, id0_1, ..., nFace1Pts, id1_0, id1_1, ..., ...]
+ */
+class XDMF_EXPORT XdmfTopology : public XdmfArray {
+
+public:
+
+  /**
+   * Create a new XdmfTopology.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopology.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopology.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfTopology.
+   */
+  static shared_ptr<XdmfTopology> New();
+
+  virtual ~XdmfTopology();
+
+  LOKI_DEFINE_VISITABLE(XdmfTopology, XdmfArray)
+  static const std::string ItemTag;
+
+  /**
+   * 
+   */
+  int getBaseOffset() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the number of elements this Topology contains.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopology.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getNumberElements
+   * @until //#getNumberElements
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopology.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getNumberElements
+   * @until #//getNumberElements
+   *
+   * @return    Int of number elements in the Topology.
+   */
+  virtual unsigned int getNumberElements() const;
+
+  /**
+   * Get the XdmfTopologyType associated with this topology.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopology.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setType
+   * @until //#setType
+   * @skipline //#getType
+   * @until //#getType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopology.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setType
+   * @until #//setType
+   * @skipline #//getType
+   * @until #//getType
+   *
+   * @return    XdmfTopologyType of the topology.
+   */
+  shared_ptr<const XdmfTopologyType> getType() const;
+
+  /**
+   *
+   */
+  void setBaseOffset(int offset);
+
+  /**
+   * Set the XdmfTopologyType associated with this topology.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopology.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setType
+   * @until //#setType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopology.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setType
+   * @until #//setType
+   *
+   * @param     type    The XdmfTopologyType to set.
+   */
+  void setType(const shared_ptr<const XdmfTopologyType> type);
+
+  XdmfTopology(XdmfTopology &);
+
+protected:
+
+  XdmfTopology();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfTopology(const XdmfTopology &);
+  void operator=(const XdmfTopology &);  // Not implemented.
+
+  shared_ptr<const XdmfTopologyType> mType;
+
+  int mBaseOffset;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFTOPOLOGY; // Simply as a typedef to ensure correct typing
+typedef struct XDMFTOPOLOGY XDMFTOPOLOGY;
+
+XDMF_EXPORT XDMFTOPOLOGY * XdmfTopologyNew();
+
+XDMF_EXPORT unsigned int XdmfTopologyGetNumberElements(XDMFTOPOLOGY * topology, int * status);
+
+XDMF_EXPORT int XdmfTopologyGetType(XDMFTOPOLOGY * topology);
+
+XDMF_EXPORT void XdmfTopologySetType(XDMFTOPOLOGY * topology, int type, int * status);
+
+XDMF_EXPORT void XdmfTopologySetPolyType(XDMFTOPOLOGY * topology, int type, int nodes, int * status);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfTopology, XDMFTOPOLOGY, XDMF)
+XDMF_ARRAY_C_CHILD_DECLARE(XdmfTopology, XDMFTOPOLOGY, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFTOPOLOGY_HPP_ */
diff --git a/XdmfTopologyType.cpp b/XdmfTopologyType.cpp
new file mode 100644
index 0000000..3e8efad
--- /dev/null
+++ b/XdmfTopologyType.cpp
@@ -0,0 +1,1266 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopologyType.cpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cctype>
+#include <cmath>
+#include <sstream>
+#include <utility>
+#include <vector>
+#include "string.h"
+#include "XdmfError.hpp"
+#include "XdmfTopologyType.hpp"
+
+std::map<std::string, shared_ptr<const XdmfTopologyType>(*)()> XdmfTopologyType::mTopologyDefinitions;
+
+// Supported XdmfTopologyTypes
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::NoTopologyType()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(0, 0, faces, 0, "NoTopology", NoCellType, 0x0));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Polyvertex()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(1, 0, faces, 0, "Polyvertex", Linear, 0x1));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Polyline(const unsigned int nodesPerElement)
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static std::map<unsigned int, shared_ptr<const XdmfTopologyType> >
+    previousTypes;
+  std::map<unsigned int, shared_ptr<const XdmfTopologyType> >::const_iterator
+    type = previousTypes.find(nodesPerElement);
+  if(type != previousTypes.end()) {
+    return type->second;
+  }
+  shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(nodesPerElement, 0, faces, nodesPerElement - 1,
+                           "Polyline", Linear, 0x2));
+  previousTypes[nodesPerElement] = p;
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Polygon(const unsigned int nodesPerElement)
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static std::map<unsigned int, shared_ptr<const XdmfTopologyType> >
+    previousTypes;
+  std::map<unsigned int, shared_ptr<const XdmfTopologyType> >::const_iterator
+    type = previousTypes.find(nodesPerElement);
+  if(type != previousTypes.end()) {
+    return type->second;
+  }
+  shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(nodesPerElement, 1, faces, nodesPerElement,
+                           "Polygon", Linear, 0x3));
+  previousTypes[nodesPerElement] = p;
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Triangle()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(3, 1, faces, 3, "Triangle", Linear, 0x4));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Quadrilateral()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(4, 1, faces, 4, "Quadrilateral", Linear, 0x5));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Tetrahedron()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::Triangle());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(4, 4, faces, 6, "Tetrahedron", Linear, 0x6));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Pyramid()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(5, 5, faces, 8, "Pyramid", Linear, 0x7));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Wedge()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(6, 5, faces, 9, "Wedge", Linear, 0x8));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::Quadrilateral());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(8, 6, faces, 12, "Hexahedron", Linear, 0x9));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Polyhedron()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(0, 0, faces, 0, "Polyhedron", Linear, 0x10));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Edge_3()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(3, 0, faces, 1, "Edge_3", Quadratic, 0x22));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Triangle_6()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(6, 1, faces, 3, "Triangle_6", Quadratic, 0x24));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Quadrilateral_8()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(8, 1, faces, 4, "Quadrilateral_8", Quadratic, 0x25));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Quadrilateral_9()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(9, 1, faces, 4, "Quadrilateral_9", Quadratic, 0x23));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Tetrahedron_10()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  faces.push_back(XdmfTopologyType::Triangle_6());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(10, 4, faces, 6, "Tetrahedron_10", Quadratic, 0x26));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Pyramid_13()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(13, 5, faces, 8, "Pyramid_13", Quadratic, 0x27));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Wedge_15()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(15, 5, faces, 9, "Wedge_15", Quadratic, 0x28));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Wedge_18()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(18, 5, faces, 9, "Wedge_18", Quadratic, 0x29));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_20()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::Quadrilateral_8());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(20, 6, faces, 12, "Hexahedron_20", Quadratic, 0x30));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_24()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(24, 6, faces, 12, "Hexahedron_24", Quadratic, 0x31));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_27()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::Quadrilateral_9());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(27, 6, faces, 12, "Hexahedron_27", Quadratic, 0x32));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_64()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(64, 6, faces, 12, "Hexahedron_64", Cubic, 0x33));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_125()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(125, 6, faces, 12, "Hexahedron_125", Quartic, 0x34));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_216()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(216, 6, faces, 12, "Hexahedron_216", Quintic, 0x35));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_343()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(343, 6, faces, 12, "Hexahedron_343", Sextic, 0x36));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_512()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(512, 6, faces, 12, "Hexahedron_512", Septic, 0x37));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_729()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(729, 6, faces, 12, "Hexahedron_729", Octic, 0x38));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_1000()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(1000, 6, faces, 12, "Hexahedron_1000", Nonic, 0x39));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_1331()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(1331, 6, faces, 12, "Hexahedron_1331", Decic, 0x40));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_64()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(64, 6, faces, 12, "Hexahedron_Spectral_64", Cubic, 0x41));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_125()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(125, 6, faces, 12,
+                           "Hexahedron_Spectral_125", Quartic, 0x42));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_216()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(216, 6, faces, 12,
+                           "Hexahedron_Spectral_216", Quintic, 0x43));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_343()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(343, 6, faces, 12,
+                           "Hexahedron_Spectral_343", Sextic, 0x44));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_512()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(512, 6, faces, 12,
+                           "Hexahedron_Spectral_512", Septic, 0x45));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_729()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(729, 6, faces, 12,
+                           "Hexahedron_Spectral_729", Octic, 0x46));
+  return p;
+}
+
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_1000()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(1000, 6, faces, 12,
+                           "Hexahedron_Spectral_1000", Nonic, 0x47));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Hexahedron_Spectral_1331()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  faces.push_back(XdmfTopologyType::NoTopologyType());
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(1331, 6, faces, 12,
+                           "Hexahedron_Spectral_1331", Decic, 0x48));
+  return p;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::Mixed()
+{
+  std::vector<shared_ptr<const XdmfTopologyType> > faces;
+  static shared_ptr<const XdmfTopologyType>
+    p(new XdmfTopologyType(0, 0, faces, 0, "Mixed", Arbitrary, 0x70));
+  return p;
+}
+
+void
+XdmfTopologyType::InitTypes()
+{
+  mTopologyDefinitions["NOTOPOLOGY"] = NoTopologyType;
+  mTopologyDefinitions["POLYVERTEX"] = Polyvertex;
+  mTopologyDefinitions["TRIANGLE"] = Triangle;
+  mTopologyDefinitions["QUADRILATERAL"] = Quadrilateral;
+  mTopologyDefinitions["TETRAHEDRON"] = Tetrahedron;
+  mTopologyDefinitions["PYRAMID"] = Pyramid;
+  mTopologyDefinitions["WEDGE"] = Wedge;
+  mTopologyDefinitions["HEXAHEDRON"] = Hexahedron;
+  mTopologyDefinitions["POLYHEDRON"] = Polyhedron;
+  mTopologyDefinitions["EDGE_3"] = Edge_3;
+  mTopologyDefinitions["TRIANGLE_6"] = Triangle_6;
+  mTopologyDefinitions["QUADRILATERAL_8"] = Quadrilateral_8;
+  mTopologyDefinitions["QUADRILATERAL_9"] = Quadrilateral_9;
+  mTopologyDefinitions["TETRAHEDRON_10"] = Tetrahedron_10;
+  mTopologyDefinitions["PYRAMID_13"] = Pyramid_13;
+  mTopologyDefinitions["WEDGE_15"] = Wedge_15;
+  mTopologyDefinitions["WEDGE_18"] = Wedge_18;
+  mTopologyDefinitions["HEXAHEDRON_20"] = Hexahedron_20;
+  mTopologyDefinitions["HEXAHEDRON_24"] = Hexahedron_24;
+  mTopologyDefinitions["HEXAHEDRON_27"] = Hexahedron_27;
+  mTopologyDefinitions["HEXAHEDRON_64"] = Hexahedron_64;
+  mTopologyDefinitions["HEXAHEDRON_125"] = Hexahedron_125;
+  mTopologyDefinitions["HEXAHEDRON_216"] = Hexahedron_216;
+  mTopologyDefinitions["HEXAHEDRON_343"] = Hexahedron_343;
+  mTopologyDefinitions["HEXAHEDRON_512"] = Hexahedron_512;
+  mTopologyDefinitions["HEXAHEDRON_729"] = Hexahedron_729;
+  mTopologyDefinitions["HEXAHEDRON_1000"] = Hexahedron_1000;
+  mTopologyDefinitions["HEXAHEDRON_1331"] = Hexahedron_1331;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_64"] = Hexahedron_Spectral_64;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_125"] = Hexahedron_Spectral_125;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_216"] = Hexahedron_Spectral_216;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_343"] = Hexahedron_Spectral_343;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_512"] = Hexahedron_Spectral_512;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_729"] = Hexahedron_Spectral_729;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_1000"] = Hexahedron_Spectral_1000;
+  mTopologyDefinitions["HEXAHEDRON_SPECTRAL_1331"] = Hexahedron_Spectral_1331;
+  mTopologyDefinitions["MIXED"] = Mixed;
+}
+
+unsigned int
+XdmfTopologyType::calculateHypercubeNumElements(unsigned int numDims,
+                                                unsigned int elementNumDims) const
+{
+  if (elementNumDims > numDims) {
+    return 0;
+  }
+  else if (elementNumDims == numDims) {
+    return 1;
+  }
+  else {
+    // The calculation has 3 parts
+    // First is the 2 taken to the power of
+    // the object's dimensionality minus the element's dimensionality.
+    unsigned int part1 = std::pow((double)2, (double)(numDims - elementNumDims));
+    // The second part is numDims!/(numDims-elementdims)!
+    unsigned int part2 = 1;
+    for (unsigned int i = numDims; i > (numDims - elementNumDims); --i)
+    {
+      part2 *= i;
+    }
+    // The third part is elementDims!
+    unsigned int part3 = 1;
+    for (unsigned int i = 1; i <= elementNumDims; ++i)
+    {
+      part3 *= i;
+    }
+    return part1 * (part2 / part3);
+  }
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::New(const unsigned int id)
+{
+  if(id == XdmfTopologyType::NoTopologyType()->getID()) {
+    return XdmfTopologyType::NoTopologyType();
+  }
+  else if(id == XdmfTopologyType::Polyvertex()->getID()) {
+    return XdmfTopologyType::Polyvertex();
+  }
+  else if(id == XdmfTopologyType::Polyline(0)->getID()) {
+    return XdmfTopologyType::Polyline(0);
+  }
+  else if(id == XdmfTopologyType::Polygon(0)->getID()) {
+    return XdmfTopologyType::Polygon(0);
+  }
+  else if(id == XdmfTopologyType::Triangle()->getID()) {
+    return XdmfTopologyType::Triangle();
+  }
+  else if(id == XdmfTopologyType::Quadrilateral()->getID()) {
+    return XdmfTopologyType::Quadrilateral();
+  }
+  else if(id == XdmfTopologyType::Tetrahedron()->getID()) {
+    return XdmfTopologyType::Tetrahedron();
+  }
+  else if(id == XdmfTopologyType::Pyramid()->getID()) {
+    return XdmfTopologyType::Pyramid();
+  }
+  else if(id == XdmfTopologyType::Wedge()->getID()) {
+    return XdmfTopologyType::Wedge();
+  }
+  else if(id == XdmfTopologyType::Hexahedron()->getID()) {
+    return XdmfTopologyType::Hexahedron();
+  }
+  else if(id == XdmfTopologyType::Polyhedron()->getID()) {
+    return XdmfTopologyType::Polyhedron();
+  }
+  else if(id == XdmfTopologyType::Edge_3()->getID()) {
+    return XdmfTopologyType::Edge_3();
+  }
+  else if(id == XdmfTopologyType::Triangle_6()->getID()) {
+    return XdmfTopologyType::Triangle_6();
+  }
+  else if(id == XdmfTopologyType::Quadrilateral_8()->getID()) {
+    return XdmfTopologyType::Quadrilateral_8();
+  }
+  else if(id == XdmfTopologyType::Quadrilateral_9()->getID()) {
+    return XdmfTopologyType::Quadrilateral_9();
+  }
+  else if(id == XdmfTopologyType::Tetrahedron_10()->getID()) {
+    return XdmfTopologyType::Tetrahedron_10();
+  }
+  else if(id == XdmfTopologyType::Pyramid_13()->getID()) {
+    return XdmfTopologyType::Pyramid_13();
+  }
+  else if(id == XdmfTopologyType::Wedge_15()->getID()) {
+    return XdmfTopologyType::Wedge_15();
+  }
+  else if(id == XdmfTopologyType::Wedge_18()->getID()) {
+    return XdmfTopologyType::Wedge_18();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_20()->getID()) {
+    return XdmfTopologyType::Hexahedron_20();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_24()->getID()) {
+    return XdmfTopologyType::Hexahedron_24();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_27()->getID()) {
+    return XdmfTopologyType::Hexahedron_27();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_64()->getID()) {
+    return XdmfTopologyType::Hexahedron_64();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_125()->getID()) {
+    return XdmfTopologyType::Hexahedron_125();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_216()->getID()) {
+    return XdmfTopologyType::Hexahedron_216();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_343()->getID()) {
+    return XdmfTopologyType::Hexahedron_343();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_512()->getID()) {
+    return XdmfTopologyType::Hexahedron_512();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_729()->getID()) {
+    return XdmfTopologyType::Hexahedron_729();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_1000()->getID()) {
+    return XdmfTopologyType::Hexahedron_1000();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_1331()->getID()) {
+    return XdmfTopologyType::Hexahedron_1331();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_64()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_64();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_125()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_125();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_216()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_216();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_343()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_343();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_512()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_512();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_729()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_729();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_1000()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_1000();
+  }
+  else if(id == XdmfTopologyType::Hexahedron_Spectral_1331()->getID()) {
+    return XdmfTopologyType::Hexahedron_Spectral_1331();
+  }
+  else if(id == XdmfTopologyType::Mixed()->getID()) {
+    return XdmfTopologyType::Mixed();
+  }
+  return shared_ptr<const XdmfTopologyType>();
+}
+
+XdmfTopologyType::XdmfTopologyType(const unsigned int nodesPerElement,
+                                   const unsigned int facesPerElement,
+                                   const std::vector<shared_ptr<const XdmfTopologyType> > & faces,
+                                   const unsigned int edgesPerElement,
+                                   const std::string & name,
+                                   const CellType cellType,
+                                   const unsigned int id) :
+  mCellType(cellType),
+  mEdgesPerElement(edgesPerElement),
+  mFacesPerElement(facesPerElement),
+  mFaces(faces),
+  mID(id),
+  mName(name),
+  mNodesPerElement(nodesPerElement)
+{
+}
+
+XdmfTopologyType::~XdmfTopologyType()
+{
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("Type");
+  if(type == itemProperties.end()) {
+    type = itemProperties.find("TopologyType");
+  }
+  if(type == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Neither 'Type' nor 'TopologyType' found in "
+                       "itemProperties in XdmfTopologyType::New");
+  }
+  std::string typeVal = ConvertToUpper(type->second);
+
+  std::map<std::string, std::string>::const_iterator nodesPerElement =
+    itemProperties.find("NodesPerElement");
+
+  std::map<std::string, shared_ptr<const XdmfTopologyType>(*)()>::const_iterator returnType
+    = mTopologyDefinitions.find(typeVal);
+
+  if (returnType == mTopologyDefinitions.end()) {
+    if(typeVal.compare("POLYLINE") == 0) {
+      if(nodesPerElement != itemProperties.end()) {
+        return Polyline(atoi(nodesPerElement->second.c_str()));
+      }
+      XdmfError::message(XdmfError::FATAL,
+                         "'NodesPerElement' not in itemProperties and type "
+                         "'POLYLINE' selected in XdmfTopologyType::New");
+    }
+    else if(typeVal.compare("POLYGON") == 0) {
+      if(nodesPerElement != itemProperties.end()) {
+        return Polygon(atoi(nodesPerElement->second.c_str()));
+      }
+      XdmfError::message(XdmfError::FATAL,
+                         "'NodesPerElement' not in itemProperties and type "
+                         "'POLYGON' selected in XdmfTopologyType::New");
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid Type selected in XdmfTopologyType::New");
+
+    }
+  }
+  else {
+    return (*(returnType->second))();
+  }
+
+  XdmfError::message(XdmfError::FATAL,
+                     "Invalid Type selected in XdmfTopologyType::New");
+
+  // unreachable
+  return shared_ptr<const XdmfTopologyType>();
+}
+
+XdmfTopologyType::CellType
+XdmfTopologyType::getCellType() const
+{
+  return mCellType;
+}
+
+unsigned int
+XdmfTopologyType::getEdgesPerElement() const
+{
+  return mEdgesPerElement;
+}
+
+shared_ptr<const XdmfTopologyType>
+XdmfTopologyType::getFaceType() const
+{
+  if (mFaces.size() == 0) {
+    return XdmfTopologyType::NoTopologyType();
+  }
+  else {
+    return mFaces[0];
+  }
+}
+
+unsigned int
+XdmfTopologyType::getFacesPerElement() const
+{
+  return mFacesPerElement;
+}
+
+unsigned int
+XdmfTopologyType::getID() const
+{
+  return mID;
+}
+
+std::string
+XdmfTopologyType::getName() const
+{
+  return mName;
+}
+
+unsigned int
+XdmfTopologyType::getNodesPerElement() const
+{
+  return mNodesPerElement;
+}
+
+void
+XdmfTopologyType::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("Type", this->getName()));
+  if(mName.compare("Polygon") == 0 || mName.compare("Polyline") == 0) {
+    std::stringstream nodesPerElement;
+    nodesPerElement << mNodesPerElement;
+    collectedProperties.insert(std::make_pair("NodesPerElement",
+                                              nodesPerElement.str()));
+  }
+}
+
+// C Wrappers
+
+int XdmfTopologyTypePolyvertex()
+{
+  return XDMF_TOPOLOGY_TYPE_POLYVERTEX;
+}
+
+int XdmfTopologyTypePolyline()
+{
+  return XDMF_TOPOLOGY_TYPE_POLYLINE;
+}
+
+int XdmfTopologyTypePolygon()
+{
+  return XDMF_TOPOLOGY_TYPE_POLYGON;
+}
+
+int XdmfTopologyTypeTriangle()
+{
+  return XDMF_TOPOLOGY_TYPE_TRIANGLE;
+}
+
+int XdmfTopologyTypeQuadrilateral()
+{
+  return XDMF_TOPOLOGY_TYPE_QUADRILATERAL;
+}
+
+int XdmfTopologyTypeTetrahedron()
+{
+  return XDMF_TOPOLOGY_TYPE_TETRAHEDRON;
+}
+
+int XdmfTopologyTypePyramid()
+{
+  return XDMF_TOPOLOGY_TYPE_PYRAMID;
+}
+
+int XdmfTopologyTypeWedge()
+{
+  return XDMF_TOPOLOGY_TYPE_WEDGE;
+}
+
+int XdmfTopologyTypeHexahedron()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON;
+}
+
+int XdmfTopologyTypePolyhedron()
+{
+  return XDMF_TOPOLOGY_TYPE_POLYHEDRON;
+}
+
+int XdmfTopologyTypeEdge_3()
+{
+  return XDMF_TOPOLOGY_TYPE_EDGE_3;
+}
+
+int XdmfTopologyTypeTriangle_6()
+{
+  return XDMF_TOPOLOGY_TYPE_TRIANGLE_6;
+}
+
+int XdmfTopologyTypeQuadrilateral_8()
+{
+  return XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8;
+}
+
+int XdmfTopologyTypeQuadrilateral_9()
+{
+  return XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9;
+}
+
+int XdmfTopologyTypeTetrahedron_10()
+{
+  return XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10;
+}
+
+int XdmfTopologyTypePyramid_13()
+{
+  return XDMF_TOPOLOGY_TYPE_PYRAMID_13;
+}
+
+int XdmfTopologyTypeWedge_15()
+{
+  return XDMF_TOPOLOGY_TYPE_WEDGE_15;
+}
+
+int XdmfTopologyTypeWedge_18()
+{
+  return XDMF_TOPOLOGY_TYPE_WEDGE_18;
+}
+
+int XdmfTopologyTypeHexahedron_20()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20;
+}
+
+int XdmfTopologyTypeHexahedron_24()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24;
+}
+
+int XdmfTopologyTypeHexahedron_27()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27;
+}
+
+int XdmfTopologyTypeHexahedron_64()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64;
+}
+
+int XdmfTopologyTypeHexahedron_125()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125;
+}
+
+int XdmfTopologyTypeHexahedron_216()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216;
+}
+
+int XdmfTopologyTypeHexahedron_343()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343;
+}
+
+int XdmfTopologyTypeHexahedron_512()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512;
+}
+
+int XdmfTopologyTypeHexahedron_729()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729;
+}
+
+int XdmfTopologyTypeHexahedron_1000()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000;
+}
+
+int XdmfTopologyTypeHexahedron_1331()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_64()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_125()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_216()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_343()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_512()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_729()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_1000()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000;
+}
+
+int XdmfTopologyTypeHexahedron_Spectral_1331()
+{
+  return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331;
+}
+
+int XdmfTopologyTypeMixed()
+{
+  return XDMF_TOPOLOGY_TYPE_MIXED;
+}
+
+shared_ptr<const XdmfTopologyType> intToType(int type, int nodes = 0)
+{
+  switch (type) {
+    case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+      return XdmfTopologyType::Polyvertex();
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYLINE:
+      return XdmfTopologyType::Polyline(nodes);
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYGON:
+      return XdmfTopologyType::Polygon(nodes);
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+      return XdmfTopologyType::Triangle();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+      return XdmfTopologyType::Quadrilateral();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+      return XdmfTopologyType::Tetrahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID:
+      return XdmfTopologyType::Pyramid();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE:
+      return XdmfTopologyType::Wedge();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+      return XdmfTopologyType::Hexahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYHEDRON:
+      return XdmfTopologyType::Polyhedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_EDGE_3:
+      return XdmfTopologyType::Edge_3();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+      return XdmfTopologyType::Triangle_6();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+      return XdmfTopologyType::Quadrilateral_8();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+      return XdmfTopologyType::Quadrilateral_9();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+      return XdmfTopologyType::Tetrahedron_10();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+      return XdmfTopologyType::Pyramid_13();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+      return XdmfTopologyType::Wedge_15();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+      return XdmfTopologyType::Wedge_18();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+      return XdmfTopologyType::Hexahedron_20();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+      return XdmfTopologyType::Hexahedron_24();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+      return XdmfTopologyType::Hexahedron_27();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+      return XdmfTopologyType::Hexahedron_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+      return XdmfTopologyType::Hexahedron_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+      return XdmfTopologyType::Hexahedron_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+      return XdmfTopologyType::Hexahedron_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+      return XdmfTopologyType::Hexahedron_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+      return XdmfTopologyType::Hexahedron_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+      return XdmfTopologyType::Hexahedron_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+      return XdmfTopologyType::Hexahedron_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64:
+      return XdmfTopologyType::Hexahedron_Spectral_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125:
+      return XdmfTopologyType::Hexahedron_Spectral_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216:
+      return XdmfTopologyType::Hexahedron_Spectral_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343:
+      return XdmfTopologyType::Hexahedron_Spectral_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512:
+      return XdmfTopologyType::Hexahedron_Spectral_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729:
+      return XdmfTopologyType::Hexahedron_Spectral_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000:
+      return XdmfTopologyType::Hexahedron_Spectral_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331:
+      return XdmfTopologyType::Hexahedron_Spectral_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_MIXED:
+      return XdmfTopologyType::Mixed();
+      break;
+    default:
+      return shared_ptr<const XdmfTopologyType>();
+      break;
+  }
+}
+
+int typeToInt(shared_ptr<const XdmfTopologyType> type)
+{
+  if (type->getID() == XdmfTopologyType::Polyvertex()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_POLYVERTEX;
+  }
+  else if (type->getID() == XdmfTopologyType::Polyline(0)->getID()) {
+    return XDMF_TOPOLOGY_TYPE_POLYLINE;
+  }
+  else if (type->getID() == XdmfTopologyType::Polygon(0)->getID()) {
+    return XDMF_TOPOLOGY_TYPE_POLYGON;
+  }
+  else if (type->getID() == XdmfTopologyType::Triangle()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_TRIANGLE;
+  }
+  else if (type->getID() == XdmfTopologyType::Quadrilateral()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_QUADRILATERAL;
+  }
+  else if (type->getID() == XdmfTopologyType::Tetrahedron()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_TETRAHEDRON;
+  }
+  else if (type->getID() == XdmfTopologyType::Pyramid()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_PYRAMID;
+  }
+  else if (type->getID() == XdmfTopologyType::Wedge()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_WEDGE;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON;
+  }
+  else if (type->getID() == XdmfTopologyType::Polyhedron()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_POLYHEDRON;
+  }
+  else if (type->getID() == XdmfTopologyType::Edge_3()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_EDGE_3;
+  }
+  else if (type->getID() == XdmfTopologyType::Triangle_6()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_TRIANGLE_6;
+  }
+  else if (type->getID() == XdmfTopologyType::Quadrilateral_8()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8;
+  }
+  else if (type->getID() == XdmfTopologyType::Quadrilateral_9()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9;
+  }
+  else if (type->getID() == XdmfTopologyType::Tetrahedron_10()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10;
+  }
+  else if (type->getID() == XdmfTopologyType::Pyramid_13()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_PYRAMID_13;
+  }
+  else if (type->getID() == XdmfTopologyType::Wedge_15()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_WEDGE_15;
+  }
+  else if (type->getID() == XdmfTopologyType::Wedge_18()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_WEDGE_18;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_20()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_24()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_27()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_64()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_125()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_216()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_343()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_512()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_729()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_1000()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_1331()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_64()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_125()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_216()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_343()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_512()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_729()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_1000()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000;
+  }
+  else if (type->getID() == XdmfTopologyType::Hexahedron_Spectral_1331()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331;
+  }
+  else if (type->getID() == XdmfTopologyType::Mixed()->getID()) {
+    return XDMF_TOPOLOGY_TYPE_MIXED;
+  }
+  else {
+    return -1;
+  }
+}
+
+int XdmfTopologyTypeGetCellType(int type)
+{
+  return intToType(type)->getCellType();
+}
+
+unsigned int XdmfTopologyTypeGetEdgesPerElement(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return  intToType(type)->getEdgesPerElement();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+unsigned int XdmfTopologyTypeGetFacesPerElement(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return  intToType(type)->getFacesPerElement();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+int XdmfTopologyTypeGetFaceType(int type)
+{
+  return typeToInt(intToType(type)->getFaceType());
+}
+
+unsigned int XdmfTopologyTypeGetID(int type)
+{
+  return intToType(type)->getID();
+}
+
+char * XdmfTopologyTypeGetName(int type)
+{
+  char * returnPointer = strdup(intToType(type)->getName().c_str());
+  return returnPointer;
+}
+
+unsigned int XdmfTopologyTypeGetNodesPerElement(int type)
+{
+  return  intToType(type)->getNodesPerElement();
+}
diff --git a/XdmfTopologyType.hpp b/XdmfTopologyType.hpp
new file mode 100644
index 0000000..9c31547
--- /dev/null
+++ b/XdmfTopologyType.hpp
@@ -0,0 +1,506 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopologyType.hpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFTOPOLOGYTYPE_HPP_
+#define XDMFTOPOLOGYTYPE_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include "XdmfItemProperty.hpp"
+#include <map>
+#include <vector>
+
+/**
+ * @brief Property describing the types of elements stored in an
+ * XdmfTopology.
+ *
+ * XdmfTopologyType is a property used by XdmfTopology to specify the
+ * element types stored. A specific XdmfTopologyType can be created by
+ * calling one of the static methods in the class,
+ * i.e. XdmfTopologyType::Tetrahedron().
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfTopologyType.cpp
+ * @skipline //#getType
+ * @until //#getType
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleTopologyType.py
+ * @skipline #//getType
+ * @until #//getType
+ *
+ * Xdmf supports the following topology types:
+ *   NoTopologyType
+ *   Polyvertex - Unconnected Points
+ *   Polyline - Line Segments
+ *   Polygon - N Edge Polygon
+ *   Triangle - 3 Edge Polygon
+ *   Quadrilateral - 4 Edge Polygon
+ *   Tetrahedron - 4 Triangular Faces
+ *   Wedge - 4 Triangular Faces, Quadrilateral Base
+ *   Hexahedron - 6 Quadrilateral Faces
+ *   Polyhedron - N Face Cell, where each Face is a M Edge Polygon
+ *   Edge_3 - 3 Node Quadratic Line
+ *   Triangle_6 - 6 Node Quadratic Triangle
+ *   Quadrilateral_8 - 8 Node Quadratic Quadrilateral
+ *   Quadrilateral_9 - 9 Node Bi-Quadratic Quadrilateral
+ *   Tetrahedron_10 - 10 Node Quadratic Tetrahedron
+ *   Pyramid_13 - 13 Node Quadratic Pyramid
+ *   Wedge_15 - 15 Node Quadratic Wedge
+ *   Wedge_18 - 18 Node Bi-Quadratic Wedge
+ *   Hexahedron_20 - 20 Node Quadratic Hexahedron
+ *   Hexahedron_24 - 24 Node Bi-Quadratic Hexahedron
+ *   Hexahedron_27 - 27 Node Tri-Quadratic Hexahedron
+ *   Hexahedron_64 - 64 Node Tri-Cubic Hexahedron
+ *   Hexahedron_125 - 125 Node Tri-Quartic Hexahedron
+ *   Hexahedron_216 - 216 Node Tri-Quintic Hexahedron
+ *   Hexahedron_343 - 343 Node Tri-Hexic Hexahedron
+ *   Hexahedron_512 - 512 Node Tri-Septic Hexahedron
+ *   Hexahedron_729 - 729 Node Tri-Octic Hexahedron
+ *   Hexahedron_1000 - 1000 Node Tri-Nonic Hexahedron
+ *   Hexahedron_1331 - 1331 Node Tri-Decic Hexahedron
+ *   Hexahedron_Spectral_64 - 64 Node Spectral Tri-Cubic Hexahedron
+ *   Hexahedron_Spectral_125 - 125 Node Spectral Tri-Quartic Hexahedron
+ *   Hexahedron_Spectral_216 - 216 Node Spectral Tri-Quintic Hexahedron
+ *   Hexahedron_Spectral_343 - 343 Node Spectral Tri-Hexic Hexahedron
+ *   Hexahedron_Spectral_512 - 512 Node Spectral Tri-Septic Hexahedron
+ *   Hexahedron_Spectral_729 - 729 Node Spectral Tri-Octic Hexahedron
+ *   Hexahedron_Spectral_1000 - 1000 Node Spectral Tri-Nonic Hexahedron
+ *   Hexahedron_Spectral_1331 - 1331 Node Spectral Tri-Decic Hexahedron
+ *   Mixed - Mixture of Unstructured Topologies
+ */
+class XDMF_EXPORT XdmfTopologyType : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfTopologyType();
+
+  friend class XdmfTopology;
+
+  enum CellType {
+    NoCellType = 0,
+    Linear = 1,
+    Quadratic = 2,
+    Cubic = 3,
+    Quartic = 4,
+    Quintic = 5,
+    Sextic = 6,
+    Septic = 7,
+    Octic = 8,
+    Nonic = 9,
+    Decic = 10,
+    Arbitrary = 100,
+    Structured = 101
+  };
+
+  /**
+   * Supported Xdmf Topology Types
+   */
+  static shared_ptr<const XdmfTopologyType> NoTopologyType();
+  static shared_ptr<const XdmfTopologyType> Polyvertex();
+  static shared_ptr<const XdmfTopologyType>
+  Polyline(const unsigned int nodesPerElement);
+  static shared_ptr<const XdmfTopologyType>
+  Polygon(const unsigned int nodesPerElement);
+  static shared_ptr<const XdmfTopologyType> Triangle();
+  static shared_ptr<const XdmfTopologyType> Quadrilateral();
+  static shared_ptr<const XdmfTopologyType> Tetrahedron();
+  static shared_ptr<const XdmfTopologyType> Pyramid();
+  static shared_ptr<const XdmfTopologyType> Wedge();
+  static shared_ptr<const XdmfTopologyType> Hexahedron();
+  static shared_ptr<const XdmfTopologyType> Polyhedron();
+  static shared_ptr<const XdmfTopologyType> Edge_3();
+  static shared_ptr<const XdmfTopologyType> Triangle_6();
+  static shared_ptr<const XdmfTopologyType> Quadrilateral_8();
+  static shared_ptr<const XdmfTopologyType> Quadrilateral_9();
+  static shared_ptr<const XdmfTopologyType> Tetrahedron_10();
+  static shared_ptr<const XdmfTopologyType> Pyramid_13();
+  static shared_ptr<const XdmfTopologyType> Wedge_15();
+  static shared_ptr<const XdmfTopologyType> Wedge_18();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_20();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_24();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_27();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_64();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_125();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_216();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_343();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_512();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_729();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_1000();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_1331();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_64();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_125();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_216();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_343();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_512();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_729();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_1000();
+  static shared_ptr<const XdmfTopologyType> Hexahedron_Spectral_1331();
+  static shared_ptr<const XdmfTopologyType> Mixed();
+
+  /**
+   * Get a topology type from id.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param id of the topology type.
+   *
+   * @return	Topology type corresponding to id - if no topology type is found
+   * 		an NULL pointer is returned.
+   */
+  static shared_ptr<const XdmfTopologyType> New(const unsigned int id);
+
+  /**
+   * Get the cell type associated with this topology type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getCellType
+   * @until //#getCellType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//getCellType
+   * @until #//getCellType
+   *
+   * @return 	A CellType containing the cell type.
+   */
+  CellType getCellType() const;
+
+  /**
+   * Get the number of edges per element associated with this topology type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getEdgesPerElement
+   * @until //#getEdgesPerElement
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//getEdgesPerElement
+   * @until #//getEdgesPerElement
+   *
+   * @return	An unsigned int containing the number of edges per element.
+   */
+  virtual unsigned int getEdgesPerElement() const;
+
+  /**
+   * Get the number of faces per element associated with this topology type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getFacesPerElement
+   * @until //#getFacesPerElement
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//getFacesPerElement
+   * @until #//getFacesPerElement
+   *
+   * @return	An unsigned int containing the number of faces per element.
+   */
+  virtual unsigned int getFacesPerElement() const;
+
+  /**
+   * Gets the type of the faces of the topology.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getFaceType
+   * @until //#getFaceType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//getFaceType
+   * @until #//getFaceType
+   *
+   * @return	The face's topology type
+   */
+  shared_ptr<const XdmfTopologyType>  getFaceType() const;
+
+  /**
+   * Get the id of this cell type, necessary in order to create grids
+   * containing mixed cells.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getID
+   * @until //#getID
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline //#getID
+   * @until //#getID
+   *
+   * @return	The ID of the topology type.
+   */
+  virtual unsigned int getID() const;
+
+  /**
+   * Get the name of this topology type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return	The name of this topology type.
+   */
+  virtual std::string getName() const;
+
+  /**
+   * Get the number of nodes per element associated with this topology
+   * type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTopologyType.cpp
+   * @skipline //#getNodesPerElement
+   * @until //#getNodesPerElement
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTopologyType.py
+   * @skipline #//getNodesPerElement
+   * @until #//getNodesPerElement
+   *
+   * @return	An unsigned int containing number of nodes per element.
+   */
+  virtual unsigned int getNodesPerElement() const;
+
+  void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+protected:
+
+  /**
+   * Protected constructor for XdmfTopologyType. The constructor is
+   * protected because all topology types supported by Xdmf should be
+   * accessed through more specific static methods that construct
+   * XdmfTopologyType - i.e. XdmfTopologyType::Tetrahedron()
+   */
+  XdmfTopologyType(const unsigned int nodesPerElement,
+                   const unsigned int facesPerElement,
+                   const std::vector<shared_ptr<const XdmfTopologyType> > & faces,
+                   const unsigned int edgesPerElement,
+                   const std::string & name,
+                   const CellType cellType,
+                   const unsigned int id);
+
+  unsigned int calculateHypercubeNumElements(unsigned int numDims, unsigned int elementNumDims) const;
+
+  static std::map<std::string, shared_ptr<const XdmfTopologyType>(*)()> mTopologyDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfTopologyType(const XdmfTopologyType &); // Not implemented.
+  void operator=(const XdmfTopologyType &); // Not implemented.
+
+  static shared_ptr<const XdmfTopologyType>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  const CellType mCellType;
+  const unsigned int mEdgesPerElement;
+  const unsigned int mFacesPerElement;
+  std::vector<shared_ptr<const XdmfTopologyType> > mFaces;
+  const unsigned int mID;
+  const std::string mName;
+  const unsigned int mNodesPerElement;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#ifndef XDMF_C_TOPOLOGY_TYPES
+#define XDMF_C_TOPOLOGY_TYPES
+#define XDMF_TOPOLOGY_TYPE_POLYVERTEX                    500
+#define XDMF_TOPOLOGY_TYPE_POLYLINE                      501
+#define XDMF_TOPOLOGY_TYPE_POLYGON                       502
+#define XDMF_TOPOLOGY_TYPE_POLYHEDRON                    503
+#define XDMF_TOPOLOGY_TYPE_TRIANGLE                      504
+#define XDMF_TOPOLOGY_TYPE_QUADRILATERAL                 505
+#define XDMF_TOPOLOGY_TYPE_TETRAHEDRON                   506
+#define XDMF_TOPOLOGY_TYPE_PYRAMID                       507
+#define XDMF_TOPOLOGY_TYPE_WEDGE                         508
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON                    509
+#define XDMF_TOPOLOGY_TYPE_EDGE_3                        510
+#define XDMF_TOPOLOGY_TYPE_TRIANGLE_6                    511
+#define XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8               512
+#define XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9               513
+#define XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10                514
+#define XDMF_TOPOLOGY_TYPE_PYRAMID_13                    515
+#define XDMF_TOPOLOGY_TYPE_WEDGE_15                      516
+#define XDMF_TOPOLOGY_TYPE_WEDGE_18                      517
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20                 518
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24                 519
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27                 520
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64                 521
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125                522
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216                523
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343                524
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512                525
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729                526
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000               527
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331               528
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64        529
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125       530
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216       531
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343       532
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512       533
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729       534
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000      535
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331      536
+#define XDMF_TOPOLOGY_TYPE_MIXED                         537
+#endif
+
+#define XDMF_TOPOLOGY_CELL_TYPE_NO_CELL_TYPE             0
+#define XDMF_TOPOLOGY_CELL_TYPE_LINEAR                   1
+#define XDMF_TOPOLOGY_CELL_TYPE_QUADRATIC                2
+#define XDMF_TOPOLOGY_CELL_TYPE_CUBIC                    3
+#define XDMF_TOPOLOGY_CELL_TYPE_QUARTIC                  4
+#define XDMF_TOPOLOGY_CELL_TYPE_QUINTIC                  5
+#define XDMF_TOPOLOGY_CELL_TYPE_SEXTIC                   6
+#define XDMF_TOPOLOGY_CELL_TYPE_SEPTIC                   7
+#define XDMF_TOPOLOGY_CELL_TYPE_OCTIC                    8
+#define XDMF_TOPOLOGY_CELL_TYPE_NONIC                    9
+#define XDMF_TOPOLOGY_CELL_TYPE_DECIC                    10
+#define XDMF_TOPOLOGY_CELL_TYPE_ARBITRARY                100
+#define XDMF_TOPOLOGY_CELL_TYPE_STRUCTURED               101
+
+XDMF_EXPORT int XdmfTopologyTypePolyvertex();
+XDMF_EXPORT int XdmfTopologyTypePolyline();
+XDMF_EXPORT int XdmfTopologyTypePolygon();
+XDMF_EXPORT int XdmfTopologyTypeTriangle();
+XDMF_EXPORT int XdmfTopologyTypeQuadrilateral();
+XDMF_EXPORT int XdmfTopologyTypeTetrahedron();
+XDMF_EXPORT int XdmfTopologyTypePyramid();
+XDMF_EXPORT int XdmfTopologyTypeWedge();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron();
+XDMF_EXPORT int XdmfTopologyTypeEdge_3();
+XDMF_EXPORT int XdmfTopologyTypeTriangle_6();
+XDMF_EXPORT int XdmfTopologyTypeQuadrilateral_8();
+XDMF_EXPORT int XdmfTopologyTypeQuadrilateral_9();
+XDMF_EXPORT int XdmfTopologyTypeTetrahedron_10();
+XDMF_EXPORT int XdmfTopologyTypePyramid_13();
+XDMF_EXPORT int XdmfTopologyTypeWedge_15();
+XDMF_EXPORT int XdmfTopologyTypeWedge_18();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_20();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_24();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_27();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_64();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_125();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_216();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_343();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_512();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_729();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_1000();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_1331();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_64();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_125();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_216();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_343();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_512();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_729();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_1000();
+XDMF_EXPORT int XdmfTopologyTypeHexahedron_Spectral_1331();
+XDMF_EXPORT int XdmfTopologyTypeMixed();
+
+
+XDMF_EXPORT int XdmfTopologyTypeGetCellType(int type);
+
+XDMF_EXPORT unsigned int XdmfTopologyTypeGetEdgesPerElement(int type, int * status);
+
+XDMF_EXPORT unsigned int XdmfTopologyTypeGetFacesPerElement(int type, int * status);
+
+XDMF_EXPORT int XdmfTopologyTypeGetFaceType(int type);
+
+XDMF_EXPORT unsigned int XdmfTopologyTypeGetID(int type);
+
+XDMF_EXPORT char * XdmfTopologyTypeGetName(int type);
+
+XDMF_EXPORT unsigned int XdmfTopologyTypeGetNodesPerElement(int type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFTOPOLOGYTYPE_HPP_ */
diff --git a/XdmfUnstructuredGrid.cpp b/XdmfUnstructuredGrid.cpp
new file mode 100644
index 0000000..4d12ff9
--- /dev/null
+++ b/XdmfUnstructuredGrid.cpp
@@ -0,0 +1,401 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfUnstructuredGrid.cpp                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfError.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+/**
+ * local functions
+ */
+namespace {
+
+  void
+  convertRegularGeometry(unsigned int          index,
+                         shared_ptr<XdmfArray> point,
+                         shared_ptr<XdmfArray> dimensions,
+                         shared_ptr<XdmfArray> brickSize,
+                         shared_ptr<XdmfArray> mGeometry) {
+
+    const unsigned int nDim = dimensions->getValue<unsigned int>(index);
+    const double nBrickSize = brickSize->getValue<double>(index);
+    const double originalPoint = point->getValue<double>(index);
+
+    for(unsigned int i=0; i<nDim; ++i) {
+      if(index == 0) {
+        mGeometry->insert(mGeometry->getSize(),
+                          point,
+                          0,
+                          point->getSize());
+      }
+      else {
+        convertRegularGeometry(index - 1,
+                               point,
+                               dimensions,
+                               brickSize,
+                               mGeometry);
+      }
+      const double currPoint = point->getValue<double>(index);
+      point->insert(index, currPoint + nBrickSize);
+    }
+
+    point->insert(index, originalPoint);
+  }
+
+  void
+  convertRegularTopology(shared_ptr<XdmfArray> dimensions,
+                         shared_ptr<XdmfArray> mTopology) 
+  {
+
+    if(dimensions->getSize() == 2) {
+      const unsigned int nx = dimensions->getValue<unsigned int>(0);
+      const unsigned int ny = dimensions->getValue<unsigned int>(1);
+      unsigned int offset = 0;
+      for(unsigned int i=1; i<ny; ++i) {
+        for(unsigned int j=1; j<nx; ++j) {
+          mTopology->pushBack<unsigned int>(offset);
+          mTopology->pushBack<unsigned int>(offset + 1);
+          mTopology->pushBack<unsigned int>(offset + nx + 1);
+          mTopology->pushBack<unsigned int>(offset + nx);
+          ++offset;
+        }
+        ++offset;
+      }
+    }
+    else if(dimensions->getSize() == 3) {
+      const unsigned int nx = dimensions->getValue<unsigned int>(0);
+      const unsigned int ny = dimensions->getValue<unsigned int>(1);
+      const unsigned int nz = dimensions->getValue<unsigned int>(2);
+      const unsigned int zOffset = nx * ny;
+      unsigned int offset = 0;
+      for(unsigned int i=1; i<nz; ++i) {
+        for(unsigned int j=1; j<ny; ++j) {
+          for(unsigned int k=1; k<nx; ++k) {
+            mTopology->pushBack<unsigned int>(offset);
+            mTopology->pushBack<unsigned int>(offset + 1);
+            mTopology->pushBack<unsigned int>(offset + nx + 1);
+            mTopology->pushBack<unsigned int>(offset + nx);
+            mTopology->pushBack<unsigned int>(offset + zOffset);
+            mTopology->pushBack<unsigned int>(offset + zOffset + 1);
+            mTopology->pushBack<unsigned int>(offset + zOffset + nx + 1);
+            mTopology->pushBack<unsigned int>(offset + zOffset + nx);
+            ++offset;
+          }
+          ++offset;
+        }
+        offset += nx;
+      }
+    }
+  }      
+}
+
+class XdmfUnstructuredGrid::XdmfUnstructuredGridImpl : public XdmfGridImpl
+{
+  public:
+  XdmfUnstructuredGridImpl()
+  {
+    mGridType = "Unstructured";
+  }
+
+  ~XdmfUnstructuredGridImpl()
+  {
+  }
+
+  XdmfGridImpl * duplicate()
+  {
+    return new XdmfUnstructuredGridImpl();
+  }
+
+  std::string getGridType() const
+  {
+    return mGridType;
+  }
+};
+
+shared_ptr<XdmfUnstructuredGrid>
+XdmfUnstructuredGrid::New()
+{
+  shared_ptr<XdmfUnstructuredGrid> p(new XdmfUnstructuredGrid());
+  return p;
+}
+
+shared_ptr<XdmfUnstructuredGrid> 
+XdmfUnstructuredGrid::New(const shared_ptr<XdmfRegularGrid> regularGrid)
+{
+  shared_ptr<XdmfUnstructuredGrid> p(new XdmfUnstructuredGrid(regularGrid));
+  return p;
+}
+
+XdmfUnstructuredGrid::XdmfUnstructuredGrid() :
+  XdmfGrid(XdmfGeometry::New(), XdmfTopology::New())
+{
+  mImpl = new XdmfUnstructuredGridImpl();
+}
+
+XdmfUnstructuredGrid::XdmfUnstructuredGrid(const shared_ptr<XdmfRegularGrid> regularGrid) :
+  XdmfGrid(XdmfGeometry::New(), XdmfTopology::New())
+{
+  mImpl = new XdmfUnstructuredGridImpl();
+
+  const shared_ptr<XdmfArray> origin = regularGrid->getOrigin();
+
+  shared_ptr<XdmfArray> brickSize = regularGrid->getBrickSize();
+  shared_ptr<XdmfArray> dimensions = regularGrid->getDimensions();
+
+  if(dimensions->getSize() != brickSize->getSize() ||
+     dimensions->getSize() != origin->getSize()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Inconsistent brick, dimension, and origin sizes when"
+                       "converting regular grid to unstructured grid in "
+                       "XdmfUnstructuredGrid constructor");
+  }
+
+  bool releaseOrigin = false;
+  bool releaseBrickSize = false;
+  bool releaseDimensions = false;
+  if(!origin->isInitialized()) {
+    origin->read();
+    releaseOrigin = true;
+  }
+  if(!brickSize->isInitialized()) {
+    brickSize->read();
+    releaseBrickSize = true;
+  }  
+  if(!dimensions->isInitialized()) {
+    dimensions->read();
+    releaseDimensions = true;
+  }
+  
+  shared_ptr<const XdmfGeometryType> geometryType;
+  shared_ptr<const XdmfTopologyType> topologyType;
+  if(origin->getSize() == 2) {
+    geometryType = XdmfGeometryType::XY();
+    topologyType = XdmfTopologyType::Quadrilateral();
+  }
+  else if(origin->getSize() == 3) {
+    geometryType = XdmfGeometryType::XYZ();
+    topologyType = XdmfTopologyType::Hexahedron();
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, 
+                       "Cannot convert regular grid of dimensions not 2 or 3 "
+                       "to XdmfUnstructuredGrid in XdmfUnstructuredGrid "
+                       "constructor");
+  }
+  mGeometry->setType(geometryType);
+  mTopology->setType(topologyType);
+
+  shared_ptr<XdmfArray> point = XdmfArray::New();
+  point->insert(0, origin, 0, origin->getSize());
+  convertRegularGeometry(dimensions->getSize() - 1,
+                         point,
+                         dimensions,
+                         brickSize,
+                         mGeometry);
+  convertRegularTopology(dimensions,
+                         mTopology);
+  
+  if(releaseOrigin) {
+    origin->release();
+  }
+  if(releaseBrickSize) {
+    brickSize->release();
+  }
+  if(releaseDimensions) {
+    dimensions->release();
+  }  
+}
+
+XdmfUnstructuredGrid::XdmfUnstructuredGrid(XdmfUnstructuredGrid & refGrid) :
+  XdmfGrid(refGrid)
+{
+}
+
+XdmfUnstructuredGrid::~XdmfUnstructuredGrid()
+{
+  if (mImpl) {
+    delete mImpl;
+  }
+  mImpl = NULL;
+}
+
+const std::string XdmfUnstructuredGrid::ItemTag = "Grid";
+
+void
+XdmfUnstructuredGrid::copyGrid(shared_ptr<XdmfGrid> sourceGrid)
+{
+  XdmfGrid::copyGrid(sourceGrid);
+  if (shared_ptr<XdmfUnstructuredGrid> classedGrid = shared_dynamic_cast<XdmfUnstructuredGrid>(sourceGrid))
+  {
+    this->setGeometry(classedGrid->getGeometry());
+    this->setTopology(classedGrid->getTopology());
+  }
+}
+
+shared_ptr<XdmfGeometry>
+XdmfUnstructuredGrid::getGeometry()
+{
+  return boost::const_pointer_cast<XdmfGeometry>
+    (static_cast<const XdmfGrid &>(*this).getGeometry());
+}
+
+std::string
+XdmfUnstructuredGrid::getItemTag() const
+{
+  return ItemTag;
+}
+
+shared_ptr<XdmfTopology>
+XdmfUnstructuredGrid::getTopology()
+{
+  return boost::const_pointer_cast<XdmfTopology>
+    (static_cast<const XdmfGrid &>(*this).getTopology());
+}
+
+void
+XdmfUnstructuredGrid::read()
+{
+  if (mGridController)
+  {
+    if (shared_ptr<XdmfUnstructuredGrid> grid = shared_dynamic_cast<XdmfUnstructuredGrid>(mGridController->read()))
+    {
+      copyGrid(grid);
+    }
+    else if (shared_ptr<XdmfGrid> grid = shared_dynamic_cast<XdmfGrid>(mGridController->read()))
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Grid Type Mismatch");
+    }
+    else
+    {
+      XdmfError::message(XdmfError::FATAL, "Error: Invalid Grid Reference");
+    }
+  }
+}
+
+void
+XdmfUnstructuredGrid::release()
+{
+  XdmfGrid::release();
+  this->setGeometry(shared_ptr<XdmfGeometry>());
+  this->setTopology(shared_ptr<XdmfTopology>());
+}
+
+void
+XdmfUnstructuredGrid::setGeometry(const shared_ptr<XdmfGeometry> geometry)
+{
+  mGeometry = geometry;
+}
+
+void
+XdmfUnstructuredGrid::setTopology(const shared_ptr<XdmfTopology> topology)
+{
+  mTopology = topology;
+}
+
+// C Wrappers
+
+XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNew()
+{
+  try
+  {
+    shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New();
+    return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New();
+    return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
+  }
+}
+
+XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNewFromRegularGrid(XDMFREGULARGRID * regularGrid, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    // Here it works when classed directly to the grid type,
+    // in other cases this may not work.
+    XdmfItem * tempPointer = (XdmfItem *)regularGrid;
+    XdmfRegularGrid * classedPointer = dynamic_cast<XdmfRegularGrid *>(tempPointer);
+    shared_ptr<XdmfRegularGrid> originGrid = shared_ptr<XdmfRegularGrid>(classedPointer, XdmfNullDeleter());
+    shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New(originGrid);
+    return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
+  }
+  catch (...)
+  {
+    // Here it works when classed directly to the grid type,
+    // in other cases this may not work.
+    XdmfItem * tempPointer = (XdmfItem *)regularGrid;
+    XdmfRegularGrid * classedPointer = dynamic_cast<XdmfRegularGrid *>(tempPointer);
+    shared_ptr<XdmfRegularGrid> originGrid = shared_ptr<XdmfRegularGrid>(classedPointer, XdmfNullDeleter());
+    shared_ptr<XdmfUnstructuredGrid> generatedGrid = XdmfUnstructuredGrid::New(originGrid);
+    return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*generatedGrid.get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFGEOMETRY * XdmfUnstructuredGridGetGeometry(XDMFUNSTRUCTUREDGRID * grid)
+{
+  XdmfItem * tempPointer = (XdmfItem *)grid;
+  XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
+  return (XDMFGEOMETRY *)((void *)(classedPointer->getGeometry().get()));
+}
+
+XDMFTOPOLOGY * XdmfUnstructuredGridGetTopology(XDMFUNSTRUCTUREDGRID * grid)
+{
+  XdmfItem * tempPointer = (XdmfItem *)grid;
+  XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
+  return (XDMFTOPOLOGY *)((void *)(classedPointer->getTopology().get()));
+}
+
+void XdmfUnstructuredGridSetGeometry(XDMFUNSTRUCTUREDGRID * grid, XDMFGEOMETRY * geometry, int passControl)
+{
+  XdmfItem * tempPointer = (XdmfItem *)grid;
+  XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
+  if (passControl) {
+    classedPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry));
+  }
+  else {
+    classedPointer->setGeometry(shared_ptr<XdmfGeometry>((XdmfGeometry *)geometry, XdmfNullDeleter()));
+  }
+}
+
+void XdmfUnstructuredGridSetTopology(XDMFUNSTRUCTUREDGRID * grid, XDMFTOPOLOGY * topology, int passControl)
+{
+  XdmfItem * tempPointer = (XdmfItem *)grid;
+  XdmfUnstructuredGrid * classedPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
+  if (passControl) {
+    classedPointer->setTopology(shared_ptr<XdmfTopology>((XdmfTopology *)topology));
+  }
+  else {
+    classedPointer->setTopology(shared_ptr<XdmfTopology>((XdmfTopology *)topology, XdmfNullDeleter()));
+  }
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID)
+XDMF_GRID_C_CHILD_WRAPPER(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID)
diff --git a/XdmfUnstructuredGrid.hpp b/XdmfUnstructuredGrid.hpp
new file mode 100644
index 0000000..d382787
--- /dev/null
+++ b/XdmfUnstructuredGrid.hpp
@@ -0,0 +1,267 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfUnstructuredGrid.hpp                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFUNSTRUCTUREDGRID_HPP_
+#define XDMFUNSTRUCTUREDGRID_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfRegularGrid;
+
+/**
+ * @brief An unstructured grid that consists of elements, points, and
+ * fields attached to the mesh.
+ *
+ * After creating an unstructured grid, the XdmfGeometry and
+ * XdmfTopology must be set. The XdmfTopology describes the element
+ * types contained in the grid and their connectivity. The
+ * XdmfGeometry describes the positions of nodes.
+ */
+class XDMF_EXPORT XdmfUnstructuredGrid : public XdmfGrid {
+
+public:
+
+  /**
+   * Create a new XdmfUnstructuredGrid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfUnstructuredGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleUnstructuredGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfUnstructuredGrid.
+   */
+  static shared_ptr<XdmfUnstructuredGrid> New();
+
+  /**
+   * Create a new XdmfUnstructuredGrid from a XdmfRegularGrid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfUnstructuredGrid.cpp
+   * @skipline //#initializationregular
+   * @until //#initializationregular
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleUnstructuredGrid.py
+   * @skipline #//initializationregular
+   * @until #//initializationregular
+   *
+   * @param     regularGrid     The grid that the unstructured grid will be created from
+   *
+   * @return                    Constructed XdmfUnstructuredGrid.
+   */
+  static shared_ptr<XdmfUnstructuredGrid> 
+  New(const shared_ptr<XdmfRegularGrid> regularGrid);
+
+  virtual ~XdmfUnstructuredGrid();
+
+  static const std::string ItemTag;
+
+  /**
+   * Get the geometry associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfUnstructuredGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGeometry
+   * @until //#setGeometry
+   * @skipline //#getGeometry
+   * @until //#getGeometry
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleUnstructuredGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGeometry
+   * @until #//setGeometry
+   * @skipline #//getGeometry
+   * @until #//getGeometry
+   *
+   * @return    The geometry associated with this grid.
+   */
+  shared_ptr<XdmfGeometry> getGeometry();
+  using XdmfGrid::getGeometry;
+
+  virtual std::string getItemTag() const;
+
+  /**
+   * Get the topology associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfUnstructuredGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setTopology
+   * @until //#setTopology
+   * @skipline //#getTopology
+   * @until //#getTopology
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleUnstructuredGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setTopology
+   * @until #//setTopology
+   * @skipline #//getTopology
+   * @until #//getTopology
+   *
+   * @return    The topology associated with this grid.
+   */
+  shared_ptr<XdmfTopology> getTopology();
+  using XdmfGrid::getTopology;
+
+  virtual void read();
+
+  virtual void release();
+
+  /**
+   * Set the geometry associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfUnstructuredGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setGeometry
+   * @until //#setGeometry
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleUnstructuredGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setGeometry
+   * @until #//setGeometry
+   *
+   * @param     geometry        An XdmfGeometry to associate with this grid.
+   */
+  void setGeometry(const shared_ptr<XdmfGeometry> geometry);
+
+  /**
+   * Set the topology associated with this grid.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfUnstructuredGrid.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setTopology
+   * @until //#setTopology
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleUnstructuredGrid.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setTopology
+   * @until #//setTopology
+   *
+   * @param     topology        An XdmfTopology to associate with this grid.
+   */
+  void setTopology(const shared_ptr<XdmfTopology> topology);
+
+  XdmfUnstructuredGrid(XdmfUnstructuredGrid &);
+
+protected:
+
+  XdmfUnstructuredGrid();
+  XdmfUnstructuredGrid(const shared_ptr<XdmfRegularGrid> regularGrid);
+
+  virtual void
+  copyGrid(shared_ptr<XdmfGrid> sourceGrid);
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfUnstructuredGridImpl;
+
+  XdmfUnstructuredGrid(const XdmfUnstructuredGrid &);  // Not implemented.
+  void operator=(const XdmfUnstructuredGrid &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFUNSTRUCTUREDGRID; // Simply as a typedef to ensure correct typing
+typedef struct XDMFUNSTRUCTUREDGRID XDMFUNSTRUCTUREDGRID;
+
+XDMF_EXPORT XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNew();
+
+XDMF_EXPORT XDMFUNSTRUCTUREDGRID * XdmfUnstructuredGridNewFromRegularGrid(XDMFREGULARGRID * regularGrid, int * status);
+
+XDMF_EXPORT XDMFGEOMETRY * XdmfUnstructuredGridGetGeometry(XDMFUNSTRUCTUREDGRID * grid);
+
+XDMF_EXPORT XDMFTOPOLOGY * XdmfUnstructuredGridGetTopology(XDMFUNSTRUCTUREDGRID * grid);
+
+XDMF_EXPORT void XdmfUnstructuredGridSetGeometry(XDMFUNSTRUCTUREDGRID * grid, XDMFGEOMETRY * geometry, int passControl);
+
+XDMF_EXPORT void XdmfUnstructuredGridSetTopology(XDMFUNSTRUCTUREDGRID * grid, XDMFTOPOLOGY * topology, int passControl);
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID, XDMF)
+XDMF_GRID_C_CHILD_DECLARE(XdmfUnstructuredGrid, XDMFUNSTRUCTUREDGRID, XDMF)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFUNSTRUCTUREDGRID_HPP_ */
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
new file mode 100644
index 0000000..3cca99f
--- /dev/null
+++ b/core/CMakeLists.txt
@@ -0,0 +1,285 @@
+project(XdmfCore)
+cmake_minimum_required(VERSION 2.6)
+if (POLICY CMP0015)
+  cmake_policy(SET CMP0015 NEW)
+endif ()
+
+include(CheckCXXSourceCompiles)
+include(SetUpVersion)
+include(TestBigEndian)
+
+if(VERSION_CONTROL_AUTOUPDATE OR
+    NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/XdmfVersion.hpp)
+  VersionCreate("Xdmf" "3" "3" "0" "XDMFCORE_EXPORT" "XdmfCore.hpp")
+endif()
+
+if(BUILD_SHARED_LIBS)
+  set(LIBTYPE SHARED)
+  set(BUILD_SHARED 1)
+else()
+  set(LIBTYPE STATIC)
+endif()
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+#set(CMAKE_SKIP_BUILD_RPATH  FALSE)
+#set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
+#set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_PREFIX}/lib)
+#set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
+
+option(XDMF_BUILD_DSM OFF)
+
+if(XDMF_BUILD_DSM)
+  option(XDMF_BUILD_DSM_THREADS ON)
+endif()
+
+mark_as_advanced(CLEAR Boost_INCLUDE_DIR)
+find_package(Boost REQUIRED)
+if(Boost_FOUND)
+  include_directories(${Boost_INCLUDE_DIRS})
+  mark_as_advanced(FORCE Boost_INCLUDE_DIR)
+endif()
+
+# Find HDF5_ROOT if not set
+if ("$ENV{HDF5_ROOT}" STREQUAL "")
+  find_file (HDF5_LIB libhdf5.so HINTS ENV LD_LIBRARY_PATH)
+  if (NOT "${HDF5_LIB}" STREQUAL "")
+    get_filename_component(HDF5_LIBRARY_DIR "${HDF5_LIB}" PATH)
+    get_filename_component(HDF5_ROOT "${HDF5_LIBRARY_DIR}/../" ABSOLUTE)
+    set(ENV{HDF5_ROOT} ${HDF5_ROOT})
+  endif ()
+endif ()
+
+mark_as_advanced(CLEAR HDF5_C_INCLUDE_DIR)
+mark_as_advanced(CLEAR HDF5_hdf5_LIBRARY_DEBUG)
+mark_as_advanced(CLEAR HDF5_hdf5_LIBRARY_RELEASE)
+find_package(HDF5 REQUIRED)
+if(HDF5_FOUND)
+  mark_as_advanced(FORCE HDF5_C_INCLUDE_DIR)
+  mark_as_advanced(FORCE HDF5_hdf5_LIBRARY_DEBUG)
+  mark_as_advanced(FORCE HDF5_hdf5_LIBRARY_RELEASE)
+  include_directories(${HDF5_INCLUDE_DIRS})
+  include_directories(${HDF5_C_INCLUDE_DIR})
+  get_filename_component(HDF5_LIBRARY_DIR "${HDF5_hdf5_LIBRARY_RELEASE}" PATH)
+  set(XDMF_LIBRARY_DIRS ${XDMF_LIBRARY_DIRS} ${HDF5_LIBRARY_DIR})
+  set(HDF5_LIBRARIES ${HDF5_hdf5_LIBRARY_RELEASE})
+  # FIXME: Would like to get this info from HDF5 so we don't have conflicting
+  # MPI versions
+  if(HDF5_IS_PARALLEL)
+    if (NOT MPI_FOUND)
+      find_package(MPI REQUIRED)
+      if(MPI_FOUND)
+        include_directories(${MPI_INCLUDE_PATH})
+        set(XDMF_LIBRARIES ${XDMF_LIBRARIES} ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY})
+        get_filename_component(MPI_LIBRARY_DIR ${MPI_LIBRARY} PATH)
+        set(XDMF_LIBRARY_DIRS ${XDMF_LIBRARY_DIRS} ${MPI_LIBRARY_DIR})
+      endif()
+    endif ()
+  endif()
+  get_filename_component(HDF5_ROOT "${HDF5_INCLUDE_DIR}/../" REALPATH)
+  set(HDF5_BINARY_DIRS ${HDF5_ROOT}/bin ${HDF5_ROOT}/dll)
+  if (NOT HDF5_LIBRARIES)
+    find_library (HDF5_LIBRARIES hdf5 HINTS ${HDF5_ROOT} ENV LD_LIBRARY_PATH)
+  endif ()
+  set(XDMF_LIBRARIES ${XDMF_LIBRARIES} ${HDF5_LIBRARIES})
+  set(XDMF_HDF5_BINARY_DIRS ${HDF5_BINARY_DIRS} PARENT_SCOPE)
+  set(XDMF_BINARIES ${XDMF_BINARIES} ${HDF5_BINARY_DIRS})
+endif()
+
+
+find_package(LibXml2 REQUIRED)
+if(LIBXML2_FOUND)
+  include_directories(${LIBXML2_INCLUDE_DIR})
+  get_filename_component(LIBXML2_ROOT "${LIBXML2_INCLUDE_DIR}/../" REALPATH)
+  set(LIBXML2_BINARY_DIRS ${LIBXML2_ROOT}/bin)
+  set(LIBXML2_BINARY_DIRS ${LIBXML2_BINARY_DIRS} PARENT_SCOPE)
+  set(XDMF_LIBRARIES ${XDMF_LIBRARIES} ${LIBXML2_LIBRARIES})
+  set(XDMF_BINARIES ${XDMF_BINARIES} ${LIBXML2_BINARY_DIRS})
+endif()
+
+# Perform compile-time checks and generate XdmfCoreConfig.hpp
+
+TEST_BIG_ENDIAN(XDMF_BIG_ENDIAN)
+
+unset(HAVE_BOOST_SHARED_DYNAMIC_CAST CACHE)
+set(CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${Boost_INCLUDE_DIRS})
+check_cxx_source_compiles("
+#include <boost/shared_ptr.hpp>
+
+struct Base { virtual ~Base(){} };
+struct Derived : public Base {};
+
+int main(int ac, char * av[])
+{
+  boost::shared_ptr<Base> ptr(new Base());
+  boost::shared_dynamic_cast<Derived>(ptr);
+}
+"
+HAVE_BOOST_SHARED_DYNAMIC_CAST)
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/XdmfCoreConfig.hpp.in
+               ${CMAKE_CURRENT_BINARY_DIR}/XdmfCoreConfig.hpp)
+
+set(XdmfCoreSources
+  XdmfArray
+  XdmfArrayReference
+  XdmfArrayType
+  XdmfBinaryController
+  XdmfCoreItemFactory
+  XdmfCoreReader
+  XdmfError
+  XdmfFunction
+  XdmfHDF5Controller
+  XdmfHDF5Writer
+  XdmfHeavyDataController
+  XdmfHeavyDataDescription
+  XdmfHeavyDataWriter
+  XdmfInformation
+  XdmfItem
+  XdmfItemProperty
+  XdmfPlaceholder
+  XdmfSparseMatrix
+  XdmfSubset
+  XdmfSystemUtils
+  ${CMAKE_CURRENT_BINARY_DIR}/XdmfVersion
+  XdmfVisitor
+  XdmfWriter)
+
+if (TIFF_FOUND)
+  set(XdmfCoreSources
+      ${XdmfCoreSources}
+      XdmfTIFFController)
+endif()
+
+if (XDMF_STATIC_AND_SHARED)
+  add_library(XdmfCoreObjects OBJECT ${XdmfCoreSources})
+  set_target_properties(XdmfCoreObjects PROPERTIES
+    POSITION_INDEPENDENT_CODE True)
+  add_library(XdmfCore ${LIBTYPE} $<TARGET_OBJECTS:XdmfCoreObjects>)
+  if (BUILD_SHARED_LIBS)
+    add_library(XdmfCore_Static STATIC $<TARGET_OBJECTS:XdmfCoreObjects>)
+    set_target_properties(XdmfCore_Static PROPERTIES
+      OUTPUT_NAME "XdmfCore")
+  endif (BUILD_SHARED_LIBS)
+else()
+  add_library(XdmfCore ${LIBTYPE} ${XdmfCoreSources})
+endif()
+
+link_directories(${XDMF_LIBRARY_DIRS})
+
+target_link_libraries(XdmfCore ${XDMF_LIBRARIES})
+if (XDMF_STATIC_AND_SHARED AND BUILD_SHARED_LIBS)
+  target_link_libraries(XdmfCore_Static ${XDMF_LIBRARIES})
+endif()
+
+if (COMMAND vtk_target_install)
+  vtk_target_install(XdmfCore)
+endif()
+
+if(WIN32)
+  add_definitions(-D_HDF5USEDLL_ -D_HDF5USEHLDLL_)
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(XdmfCore PROPERTIES
+      DEFINE_SYMBOL XdmfCore_EXPORTS)
+    if (XDMF_STATIC_AND_SHARED)
+      set_target_properties(XdmfCore_Static PROPERTIES
+        DEFINE_SYMBOL XdmfCore_EXPORTS)
+    endif()
+  endif()
+  if(NOT MSVC10)
+    set_target_properties(XdmfCore PROPERTIES
+      PREFIX ../
+      IMPORT_PREFIX ../
+      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+      ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+    if (XDMF_STATIC_AND_SHARED AND BUILD_SHARED_LIBS)
+      set_target_properties(XdmfCore_Static PROPERTIES
+        PREFIX ../
+        IMPORT_PREFIX ../
+        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+    endif ()
+  endif()
+endif()
+
+if(XDMF_WRAP_JAVA)
+  XDMF_SWIG_JAVA(XdmfCore)
+endif()
+
+if(XDMF_WRAP_PYTHON)
+  if (NOT BUILD_SHARED_LIBS)
+    message(FATAL_ERROR "Python Wrappers do not function"
+                        " properly without shared libraries")
+  endif (NOT BUILD_SHARED_LIBS)
+  XDMF_SWIG_PYTHON(XdmfCore)
+endif()
+
+set(XDMF_LIBRARY_DIRS ${XDMF_LIBRARY_DIRS} PARENT_SCOPE)
+if(WIN32)
+    set(XDMFCORE_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/XdmfCore.lib PARENT_SCOPE)
+endif()
+
+if(UNIX)
+    if (BUILD_SHARED_LIBS)
+      set(XDMFCORE_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/libXdmfCore.so
+          PARENT_SCOPE)
+    else()
+      set(XDMFCORE_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/libXdmfCore.a
+          PARENT_SCOPE)
+    endif()
+endif()
+
+if(APPLE)
+    set(XDMFCORE_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/libXdmfCore.dylib
+        PARENT_SCOPE)
+endif()
+
+file(GLOB_RECURSE
+  XdmfCoreHeaders
+  "*.hpp" "*.tpp" "*.i"
+  "../CMake/VersionSuite/*.hpp")
+file(GLOB LokiHeaders loki/*.h)
+
+set(XdmfCoreHeaders
+      ${XdmfCoreHeaders}
+      ${CMAKE_CURRENT_BINARY_DIR}/XdmfCoreConfig.hpp)
+
+install(FILES ${XdmfCoreHeaders} DESTINATION include)
+install(FILES ${LokiHeaders} DESTINATION include/loki)
+install(TARGETS XdmfCore
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib)
+if (XDMF_STATIC_AND_SHARED AND BUILD_SHARED_LIBS)
+  install(TARGETS XdmfCore_Static
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib)
+endif ()
+
+set(XdmfCore_INCLUDE_DIRS
+  ${Boost_INCLUDE_DIRS}
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${CMAKE_CURRENT_BINARY_DIR}
+  ${HDF5_INCLUDE_DIR}
+  ${LIBXML2_INCLUDE_DIR}
+  ${PYTHON_INCLUDE_DIRS}
+  CACHE INTERNAL "")
+
+set(XDMF_INCLUDE_DIRS ${CMAKE_INSTALL_PREFIX}/include PARENT_SCOPE)
+set(XDMF_LIBRARIES ${XDMF_LIBRARIES} ${CMAKE_INSTALL_PREFIX}/lib)
+set(XDMF_DIR ${CMAKE_INSTALL_PREFIX} PARENT_SCOPE)
+set(XDMF_BINARIES ${XDMF_BINARIES} ${CMAKE_INSTALL_PREFIX}/bin)
+
+if(XDMF_BUILD_DSM)
+  add_subdirectory(dsm)
+  set(XDMF_DSM_IS_CRAY "${XDMF_DSM_IS_CRAY}" PARENT_SCOPE)
+endif(XDMF_BUILD_DSM)
+
+if(XDMF_BUILD_TESTING)
+  add_subdirectory(tests)
+endif()
+
+set(XDMF_LIBRARIES ${XDMF_LIBRARIES} PARENT_SCOPE)
+set(XDMF_BINARIES ${XDMF_BINARIES} PARENT_SCOPE)
diff --git a/core/XdmfArray.cpp b/core/XdmfArray.cpp
new file mode 100644
index 0000000..1876229
--- /dev/null
+++ b/core/XdmfArray.cpp
@@ -0,0 +1,2612 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfArray.cpp                                                       */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <boost/tokenizer.hpp>
+#include <limits>
+#include <sstream>
+#include <utility>
+#include <stack>
+#include <math.h>
+#include <string.h>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfArrayReference.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfCoreReader.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfVisitor.hpp"
+#include "XdmfError.hpp"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfArray,
+                             XdmfHeavyDataController,
+                             HeavyDataController,
+                             Name)
+
+class XdmfArray::Clear : public boost::static_visitor<void> {
+public:
+
+  Clear(XdmfArray * const array) :
+    mArray(array)
+  {
+  }
+
+  void
+  operator()(const boost::blank & array) const
+  {
+    return;
+  }
+
+  template<typename T>
+  void
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    array->clear();
+  }
+
+  template<typename T>
+  void
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private: 
+  XdmfArray * const mArray;
+};
+
+class XdmfArray::Erase : public boost::static_visitor<void> {
+public:
+
+  Erase(XdmfArray * const array,
+        const unsigned int index) :
+    mArray(array),
+    mIndex(index)
+  {
+  }
+
+  void
+  operator()(const boost::blank & array) const
+  {
+    return;
+  }
+
+  template<typename T>
+  void
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    array->erase(array->begin() + mIndex);
+  }
+
+  template<typename T>
+  void
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * const mArray;
+  const unsigned int mIndex;
+};
+
+class XdmfArray::GetArrayType :
+  public boost::static_visitor<shared_ptr<const XdmfArrayType> > {
+public:
+
+  GetArrayType(const shared_ptr<XdmfHeavyDataController> & heavyDataController) :
+    mHeavyDataController(heavyDataController)
+  {
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const char * const) const
+  {
+    return XdmfArrayType::Int8();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const short * const) const
+  {
+    return XdmfArrayType::Int16();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const int * const) const
+  {
+    return XdmfArrayType::Int32();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const long * const) const
+  {
+    return XdmfArrayType::Int64();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const float * const) const
+  {
+    return XdmfArrayType::Float32();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const double * const) const
+  {
+    return XdmfArrayType::Float64();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const unsigned char * const) const
+  {
+    return XdmfArrayType::UInt8();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const unsigned short * const) const
+  {
+    return XdmfArrayType::UInt16();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const unsigned int * const) const
+  {
+    return XdmfArrayType::UInt32();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const std::string * const) const
+  {
+    return XdmfArrayType::String();
+  }
+
+  shared_ptr<const XdmfArrayType>
+  operator()(const boost::blank & array) const
+  {
+    if(mHeavyDataController) {
+      return mHeavyDataController->getType();
+    }
+    return XdmfArrayType::Uninitialized();
+  }
+
+  template<typename T>
+  shared_ptr<const XdmfArrayType>
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    return this->getArrayType(&(array.get()->operator[](0)));
+  }
+
+  template<typename T>
+  shared_ptr<const XdmfArrayType>
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    return this->getArrayType(array.get());
+  }
+
+private:
+
+  const shared_ptr<XdmfHeavyDataController> mHeavyDataController;
+};
+
+class XdmfArray::GetCapacity : public boost::static_visitor<unsigned int> {
+public:
+
+  GetCapacity()
+  {
+  }
+
+  unsigned int
+  operator()(const boost::blank & array) const
+  {
+    return 0;
+  }
+
+  template<typename T>
+  unsigned int
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    return array->capacity();
+  }
+
+  template<typename T>
+  unsigned int
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    return 0;
+  }
+};
+
+class XdmfArray::GetValuesPointer :
+  public boost::static_visitor<const void *> {
+public:
+
+  GetValuesPointer()
+  {
+  }
+
+  const void *
+  operator()(const boost::blank & array) const
+  {
+    return NULL;
+  }
+
+  template<typename T>
+  const void *
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    return &array->operator[](0);
+  }
+
+  template<typename T>
+  const void *
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    return array.get();
+  }
+};
+
+class XdmfArray::GetValuesString : public boost::static_visitor<std::string> {
+public:
+
+  GetValuesString(const int arrayPointerNumValues) :
+    mArrayPointerNumValues(arrayPointerNumValues)
+  {
+  }
+
+  template<typename T, typename U>
+  std::string
+  getValuesString(const T * const array,
+                  const int numValues) const
+  {
+    const int lastIndex = numValues - 1;
+
+    if(lastIndex < 0) {
+      return "";
+    }
+
+    std::stringstream toReturn;
+    toReturn.precision(std::numeric_limits<U>::digits10 + 2);
+    for(int i=0; i<lastIndex; ++i) {
+      toReturn << (U)array[i] << " ";
+    }
+    toReturn << (U)array[lastIndex];
+    return toReturn.str();
+  }
+
+  std::string
+  getValuesString(const char * const array,
+                  const int numValues) const
+  {
+    return getValuesString<char, int>(array, numValues);
+  }
+
+  std::string
+  getValuesString(const unsigned char * const array,
+                  const int numValues) const
+  {
+    return getValuesString<unsigned char, int>(array, numValues);
+  }
+
+  template<typename T>
+  std::string
+  getValuesString(const T * const array,
+                  const int numValues) const
+  {
+    return getValuesString<T, T>(array, numValues);
+  }
+
+  std::string
+  operator()(const boost::blank & array) const
+  {
+    return "";
+  }
+
+  template<typename T>
+  std::string
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    return getValuesString(&(array->operator[](0)), array->size());
+  }
+
+  template<typename T>
+  std::string
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    return getValuesString(array.get(), mArrayPointerNumValues);
+  }
+
+private:
+
+  const unsigned int mArrayPointerNumValues;
+};
+
+class XdmfArray::InsertArray : public boost::static_visitor<void> {
+public:
+
+  InsertArray(XdmfArray * const array,
+              const unsigned int startIndex,
+              const unsigned int valuesStartIndex,
+              const unsigned int numValues,
+              const unsigned int arrayStride,
+              const unsigned int valuesStride,
+              std::vector<unsigned int> & dimensions,
+              const shared_ptr<const XdmfArray> & arrayToCopy) :
+    mArray(array),
+    mStartIndex(startIndex),
+    mValuesStartIndex(valuesStartIndex),
+    mNumValues(numValues),
+    mArrayStride(arrayStride),
+    mValuesStride(valuesStride),
+    mDimensions(dimensions),
+    mArrayToCopy(arrayToCopy)
+  {
+  }
+
+  void
+  operator()(const boost::blank & array) const
+  {
+    const shared_ptr<const XdmfArrayType> copyType = 
+      mArrayToCopy->getArrayType();
+    if(copyType == XdmfArrayType::Uninitialized()) {
+        return;
+    }
+    mArray->initialize(copyType);
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  template<typename T>
+  void
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    unsigned int size = mStartIndex + (mNumValues - 1) * mArrayStride + 1;
+    if(array->size() < size) {
+      array->resize(size);
+      mDimensions.clear();
+    }
+    mArrayToCopy->getValues(mValuesStartIndex,
+                            &(array->operator[](mStartIndex)),
+                            mNumValues,
+                            mValuesStride,
+                            mArrayStride);
+  }
+
+  template<typename T>
+  void
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * const mArray;
+  const unsigned int mStartIndex;
+  const unsigned int mValuesStartIndex;
+  const unsigned int mNumValues;
+  const unsigned int mArrayStride;
+  const unsigned int mValuesStride;
+  std::vector<unsigned int> & mDimensions;
+  const shared_ptr<const XdmfArray> mArrayToCopy;
+};
+
+class XdmfArray::InternalizeArrayPointer : public boost::static_visitor<void> {
+public:
+
+  InternalizeArrayPointer(XdmfArray * const array) :
+    mArray(array)
+  {
+  }
+
+  void
+  operator()(const boost::blank & array) const
+  {
+    return;
+  }
+
+  template<typename T>
+  void
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    return;
+  }
+
+  template<typename T>
+  void
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    const T * const pointer = array.get();
+    shared_ptr<std::vector<T> > newArray(new std::vector<T>(pointer,
+                                                            pointer + mArray->mArrayPointerNumValues));
+    mArray->mArray = newArray;
+    mArray->mArrayPointerNumValues = 0;
+  }
+
+private:
+
+  XdmfArray * const mArray;
+};
+
+class XdmfArray::IsInitialized : public boost::static_visitor<bool> {
+public:
+
+  IsInitialized()
+  {
+  }
+
+  bool
+  operator()(const boost::blank &) const
+  {
+    return false;
+  }
+
+  template<typename T>
+  bool
+  operator()(const shared_ptr<std::vector<T> > &) const
+  {
+    return true;
+  }
+
+  template<typename T>
+  bool
+  operator()(const T &) const
+  {
+    return true;
+  }
+};
+
+class XdmfArray::Reserve : public boost::static_visitor<void> {
+public:
+
+  Reserve(XdmfArray * const array,
+          const unsigned int size):
+    mArray(array),
+    mSize(size)
+  {
+  }
+
+  void
+  operator()(const boost::blank & array) const
+  {
+    mArray->mTmpReserveSize = mSize;
+  }
+
+  template<typename T>
+  void
+  operator()(shared_ptr<std::vector<T> > & array) const
+  {
+    array->reserve(mSize);
+  }
+
+  template<typename T>
+  void
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * const mArray;
+  const unsigned int mSize;
+};
+
+class XdmfArray::Size : public boost::static_visitor<unsigned int> {
+public:
+
+  Size(const XdmfArray * const array) :
+    mArray(array)
+  {
+  }
+
+  unsigned int
+  operator()(const boost::blank & array) const
+  {
+    unsigned int total = 0;
+    for (unsigned int i = 0; i < mArray->mHeavyDataControllers.size(); ++i) {
+      total += mArray->mHeavyDataControllers[i]->getSize();
+    }
+    return total;
+  }
+
+  template<typename T>
+  unsigned int
+  operator()(const shared_ptr<std::vector<T> > & array) const
+  {
+    return array->size();
+  }
+
+  template<typename T>
+  unsigned int
+  operator()(const boost::shared_array<const T> & array) const
+  {
+    return mArray->mArrayPointerNumValues;
+  }
+
+private:
+
+  const XdmfArray * const mArray; 
+};
+
+shared_ptr<XdmfArray>
+XdmfArray::New()
+{
+  shared_ptr<XdmfArray> p(new XdmfArray());
+  return p;
+}
+
+XdmfArray::XdmfArray() :
+  mArrayPointerNumValues(0),
+  mName(""),
+  mTmpReserveSize(0),
+  mReadMode(XdmfArray::Controller)
+{
+}
+
+XdmfArray::XdmfArray(XdmfArray & refArray):
+  XdmfItem(refArray),
+  mDimensions(refArray.getDimensions()),
+  mName(refArray.getName()),
+  mReadMode(refArray.getReadMode())
+{
+  if (refArray.getArrayType() != XdmfArrayType::Uninitialized()) {
+    this->initialize(refArray.getArrayType(), 0);
+    if (refArray.getSize() > 0) {
+      shared_ptr<const XdmfArray> tempPointer = shared_ptr<const XdmfArray>(&refArray, XdmfNullDeleter());
+      this->insert(0, tempPointer, 0, tempPointer->getSize());
+    }
+  }
+  if (refArray.getNumberHeavyDataControllers() > 0) {
+    for (unsigned int i = 0; i < refArray.getNumberHeavyDataControllers(); ++i) {
+      this->insert(refArray.getHeavyDataController(i));	
+    }
+  }
+  if (refArray.mReference) {
+    this->setReference(refArray.getReference());
+  }
+}
+
+XdmfArray::~XdmfArray()
+{
+}
+
+const std::string XdmfArray::ItemTag = "DataItem";
+
+void
+XdmfArray::clear()
+{
+  boost::apply_visitor(Clear(this), 
+                       mArray);
+  mDimensions.clear();
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::erase(const unsigned int index)
+{
+  boost::apply_visitor(Erase(this,
+                             index),
+                       mArray);
+  mDimensions.clear();
+  this->setIsChanged(true);
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArray::getArrayType() const
+{
+  if (mHeavyDataControllers.size()>0) {
+    return boost::apply_visitor(GetArrayType(mHeavyDataControllers[0]), 
+                                mArray);
+  }
+  else {
+    return boost::apply_visitor(GetArrayType(shared_ptr<XdmfHeavyDataController>()),
+                                mArray);
+  }
+}
+
+unsigned int
+XdmfArray::getCapacity() const
+{
+  return boost::apply_visitor(GetCapacity(), 
+                              mArray);
+}
+
+std::vector<unsigned int>
+XdmfArray::getDimensions() const
+{
+  if(mDimensions.size() == 0) {
+    if(!this->isInitialized() && mHeavyDataControllers.size() > 0) {
+      std::vector<unsigned int> returnDimensions;
+      std::vector<unsigned int> tempDimensions;
+      // Find the controller with the most dimensions
+      int dimControllerIndex = 0;
+      unsigned int dimSizeMax = 0;
+      unsigned int dimTotal = 0;
+      for (unsigned int i = 0; i < mHeavyDataControllers.size(); ++i) {
+        dimTotal += mHeavyDataControllers[i]->getSize();
+        if (mHeavyDataControllers[i]->getSize() > dimSizeMax) {
+          dimSizeMax = mHeavyDataControllers[i]->getSize();
+          dimControllerIndex = i;
+        }
+      }
+      // Total up the size of the lower dimensions
+      int controllerDimensionSubtotal = 1;
+      for (unsigned int i = 0;
+           i < mHeavyDataControllers[dimControllerIndex]->getDimensions().size() - 1;
+           ++i) {
+        returnDimensions.push_back(mHeavyDataControllers[dimControllerIndex]->getDimensions()[i]);
+        controllerDimensionSubtotal *= mHeavyDataControllers[dimControllerIndex]->getDimensions()[i];
+      }
+      // Divide the total contained by the dimensions by the size of the lower dimensions
+      returnDimensions.push_back(dimTotal/controllerDimensionSubtotal);
+      return returnDimensions;
+    }
+    const unsigned int size = this->getSize();
+    return std::vector<unsigned int>(1, size);
+  }
+  return mDimensions;
+}
+
+std::string
+XdmfArray::getDimensionsString() const
+{
+  const std::vector<unsigned int> dimensions = this->getDimensions();
+  return GetValuesString(dimensions.size()).getValuesString(&dimensions[0],
+                                                            dimensions.size());
+}
+
+std::map<std::string, std::string>
+XdmfArray::getItemProperties() const
+{
+  std::map<std::string, std::string> arrayProperties;
+  if(mHeavyDataControllers.size() > 0) {
+    mHeavyDataControllers[0]->getProperties(arrayProperties);
+  }
+  else {
+    arrayProperties.insert(std::make_pair("Format", "XML"));
+  }
+  arrayProperties.insert(std::make_pair("Dimensions", 
+                                        this->getDimensionsString()));
+  if(mName.compare("") != 0) {
+    arrayProperties.insert(std::make_pair("Name", mName));
+  }
+  shared_ptr<const XdmfArrayType> type = this->getArrayType();
+  type->getProperties(arrayProperties);
+  return arrayProperties;
+}
+
+std::string
+XdmfArray::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfArray::getName() const
+{
+  return mName;
+}
+
+XdmfArray::ReadMode
+XdmfArray::getReadMode() const
+{
+  return mReadMode;
+}
+
+unsigned int
+XdmfArray::getSize() const
+{
+  return boost::apply_visitor(Size(this), 
+                              mArray);
+}
+
+shared_ptr<XdmfArrayReference>
+XdmfArray::getReference()
+{
+  if (mReference) {
+    return mReference;
+  }
+  else {
+    // Returning arbitrary Reference since one isn't defined
+    return shared_ptr<XdmfArrayReference>();
+  }
+}
+
+void *
+XdmfArray::getValuesInternal()
+{
+  return const_cast<void *>
+    (static_cast<const XdmfArray &>(*this).getValuesInternal());
+}
+
+const void *
+XdmfArray::getValuesInternal() const
+{
+  return boost::apply_visitor(GetValuesPointer(), 
+                              mArray);
+}
+
+std::string
+XdmfArray::getValuesString() const
+{
+  return boost::apply_visitor(GetValuesString(mArrayPointerNumValues), 
+                              mArray);
+}
+
+shared_ptr<XdmfHeavyDataController>
+XdmfArray::getHeavyDataController()
+{
+  return boost::const_pointer_cast<XdmfHeavyDataController>
+    (static_cast<const XdmfArray &>(*this).getHeavyDataController(0));
+}
+
+shared_ptr<const XdmfHeavyDataController>
+XdmfArray::getHeavyDataController() const
+{
+  if (mHeavyDataControllers.size() > 0) {
+    return mHeavyDataControllers[0];
+  }
+  else {
+    return shared_ptr<XdmfHeavyDataController>();
+  }
+}
+
+void
+XdmfArray::initialize(const shared_ptr<const XdmfArrayType> & arrayType,
+                      const unsigned int size)
+{
+  if(arrayType == XdmfArrayType::Int8()) {
+    this->initialize<char>(size);
+  }
+  else if(arrayType == XdmfArrayType::Int16()) {
+    this->initialize<short>(size);
+  }
+  else if(arrayType == XdmfArrayType::Int32()) {
+    this->initialize<int>(size);
+  }
+  else if(arrayType == XdmfArrayType::Int64()) {
+    this->initialize<long>(size);
+  }
+  else if(arrayType == XdmfArrayType::Float32()) {
+    this->initialize<float>(size);
+  }
+  else if(arrayType == XdmfArrayType::Float64()) {
+    this->initialize<double>(size);
+  }
+  else if(arrayType == XdmfArrayType::UInt8()) {
+    this->initialize<unsigned char>(size);
+  }
+  else if(arrayType == XdmfArrayType::UInt16()) {
+    this->initialize<unsigned short>(size);
+  }
+  else if(arrayType == XdmfArrayType::UInt32()) {
+    this->initialize<unsigned int>(size);
+  }
+  else if(arrayType == XdmfArrayType::String()) {
+    this->initialize<std::string>(size);
+  }
+  else if(arrayType == XdmfArrayType::Uninitialized()) {
+    this->release();
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, 
+                       "Array of unsupported type in XdmfArray::initialize");
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::initialize(const shared_ptr<const XdmfArrayType> & arrayType,
+                      const std::vector<unsigned int> & dimensions)
+{
+  mDimensions = dimensions;
+  const unsigned int size = std::accumulate(dimensions.begin(),
+                                            dimensions.end(),
+                                            1,
+                                            std::multiplies<unsigned int>());
+  return this->initialize(arrayType, size);
+}
+
+void
+XdmfArray::insert(const unsigned int startIndex,
+                  const shared_ptr<const XdmfArray> values,
+                  const unsigned int valuesStartIndex,
+                  const unsigned int numValues,
+                  const unsigned int arrayStride,
+                  const unsigned int valuesStride)
+{
+  boost::apply_visitor(InsertArray(this,
+                                   startIndex,
+                                   valuesStartIndex,
+                                   numValues,
+                                   arrayStride,
+                                   valuesStride,
+                                   mDimensions,
+                                   values),
+                       mArray);
+  this->setIsChanged(true);
+}
+
+
+void
+XdmfArray::insert(const std::vector<unsigned int> startIndex,
+                  const shared_ptr<const XdmfArray> values,
+                  const std::vector<unsigned int> valuesStartIndex,
+                  const std::vector<unsigned int> numValues,
+                  const std::vector<unsigned int> numInserted,
+                  const std::vector<unsigned int> arrayStride,
+                  const std::vector<unsigned int> valuesStride)
+{
+  // Ensuring dimensions match up when pulling data
+  if ((values->getDimensions().size() == valuesStartIndex.size()
+      && valuesStartIndex.size() == numValues.size()
+      && numValues.size() == valuesStride.size())
+      && (numInserted.size() == startIndex.size()
+      && startIndex.size() == this->getDimensions().size()
+      && this->getDimensions().size() == arrayStride.size())) {
+    // Pull data from values
+    std::vector<unsigned int > dimTotalVector;
+    unsigned int dimTotal = 1;
+    for (unsigned int i = 0; i < values->getDimensions().size(); ++i) {
+      dimTotalVector.push_back(dimTotal);
+      dimTotal *= values->getDimensions()[i];
+    }
+    std::vector<unsigned int> indexVector;
+    for (unsigned int i = 0; i < values->getDimensions().size(); ++i) {
+      indexVector.push_back(0);
+    }
+    shared_ptr<XdmfArray> holderArray = XdmfArray::New();
+    unsigned int holderoffset = 0;
+    // End when the last index is incremented
+    while (indexVector[indexVector.size()-1] < 1) {
+      // Initialize the section of the array you're pulling from
+      unsigned int startTotal = 0;
+      dimTotal = 1;
+      for (unsigned int i = 0; i < values->getDimensions().size(); ++i) {
+        // Stride doesn't factor in to the first dimension
+        // Since it's being used with the insert call
+        if (i == 0) {
+          startTotal += valuesStartIndex[i] * dimTotal;
+        }
+        else {
+          startTotal += valuesStartIndex[i] * dimTotal
+                        + valuesStride[i] * dimTotal * indexVector[i-1];
+        }
+        dimTotal *= values->getDimensions()[i];
+      }
+      // Insert the subsection
+      holderArray->insert(holderoffset,
+                          values,
+                          startTotal,
+                          numValues[0],
+                          1,
+                          valuesStride[0]);
+      holderoffset+=numValues[0];
+      // Increment up the vector
+      bool increment = true;
+      for (unsigned int i = 0; i < indexVector.size() && increment; ++i) {
+        indexVector[i]++;
+        // To keep the loop from breaking at the end
+        if (i+1 < numValues.size()) {
+          if (indexVector[i] >= numValues[i+1]) {
+            indexVector[i] = indexVector[i] % numValues[i+1];
+          }
+          else {
+            increment = false;
+          }
+        }
+      }
+    }
+    // Values being inserted retrieved
+    // Use an variation of the last loop to insert into this array
+
+    indexVector.clear();
+    for (unsigned int i = 0; i < this->getDimensions().size(); ++i) {
+      indexVector.push_back(0);
+    }
+    holderoffset = 0;
+    // End when the last index is incremented
+    while (indexVector[indexVector.size()-1] < 1) {
+      // Initialize the section of the array you're pulling from
+      unsigned int startTotal = 0;
+      dimTotal = 1;
+      for (unsigned int i = 0; i < this->getDimensions().size(); ++i) {
+        if (i == 0) {
+          // Stride doesn't factor in to the first dimension
+          // Since it's being used with the insert call
+          startTotal += startIndex[i] * dimTotal;
+        }
+        else {
+          startTotal += startIndex[i] * dimTotal + arrayStride[i] * dimTotal * indexVector[i-1];
+        }
+        dimTotal *= this->getDimensions()[i];
+      }
+      // Insert the subsection
+      this->insert(startTotal, holderArray, holderoffset, numInserted[0], arrayStride[0], 1);
+      holderoffset+=numInserted[0];
+      // Increment up the vector
+      bool increment = true;
+      for (unsigned int i = 0; i < indexVector.size() && increment; ++i) {
+        indexVector[i]++;
+        if (i+1 < numInserted.size()) {
+          // To keep the loop from breaking at the end
+          if (indexVector[i] >= numInserted[i+1]) {
+            indexVector[i] = indexVector[i] % numInserted[i+1];
+          }
+          else {
+            increment = false;
+          }
+        }
+      }
+    }
+    this->setIsChanged(true);
+  }
+  else {
+    // Throw an error
+    if (!(values->getDimensions().size() == valuesStartIndex.size()
+          && valuesStartIndex.size() == numValues.size()
+          && numValues.size() == valuesStride.size())) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Number of starts, strides, and/or values "
+                         "retrieved does not match up with the dimensions "
+                         "of the array being retrieved from");
+    }
+    else if (!(numInserted.size() == startIndex.size()
+               && startIndex.size() == this->getDimensions().size()
+               && this->getDimensions().size() == arrayStride.size())) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Number of starts, strides, and/or values "
+                         "written does not match up with the dimensions "
+                         "of the array being inserted into");
+    }
+  }
+}
+
+bool
+XdmfArray::isInitialized() const
+{
+  return boost::apply_visitor(IsInitialized(),
+                                mArray);
+}
+
+void
+XdmfArray::internalizeArrayPointer()
+{
+  boost::apply_visitor(InternalizeArrayPointer(this), 
+                       mArray);
+}
+
+void
+XdmfArray::populateItem(const std::map<std::string, std::string> & itemProperties,
+                        const std::vector<shared_ptr<XdmfItem> > & childItems,
+                        const XdmfCoreReader * const reader)
+{
+  // This inserts any XdmfInformation in childItems into the object.
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+
+  bool filled = false;
+
+  // Check for Function
+  std::map<std::string, std::string>::const_iterator itemType =
+    itemProperties.find("ItemType");
+
+  if (itemType !=  itemProperties.end()) {
+    if (itemType->second.compare("Function") == 0) {
+      std::map<std::string, std::string>::const_iterator expressionLocation =
+        itemProperties.find("Function");
+      if (expressionLocation ==  itemProperties.end()) {
+        XdmfError::message(XdmfError::FATAL,
+                           "'Function' not found in itemProperties for Function"
+                           " ItemType in XdmfArray::populateItem");
+      }
+      std::string expression = expressionLocation->second;
+
+      // Convert from old format to new Variable format
+      // $X -> ValX
+      size_t loc = expression.find("$");
+
+      while (loc != std::string::npos) {
+        expression.replace(loc, 1, "Val");
+        loc = expression.find("$", loc);
+     }
+
+      // Create Variable list
+
+      std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+
+      unsigned int variableIndex = 0;
+      for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+            childItems.begin();
+          iter != childItems.end();
+          ++iter) {
+        if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+          std::stringstream variableKey;
+          variableKey << "Val" << variableIndex;
+          variableMap[variableKey.str()] = array;
+          variableIndex++;
+        }
+      }
+
+      shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, variableMap);
+
+      this->setReference(function);
+      this->setReadMode(XdmfArray::Reference);
+      filled = true;
+    }
+    else if (itemType->second.compare("HyperSlab") == 0) {
+
+      shared_ptr<XdmfArray> dimArray;
+      shared_ptr<XdmfArray> valArray;
+
+      unsigned int foundArrayIndex = 0;
+
+      for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+            childItems.begin();
+          iter != childItems.end();
+          ++iter) {
+        if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+          if (foundArrayIndex == 0)
+          {
+            dimArray = array;
+            foundArrayIndex++;
+          }
+          else if (foundArrayIndex == 1)
+          {
+            valArray = array;
+            foundArrayIndex++;
+          }
+        }
+      }
+
+      if (!(dimArray))
+      {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Hyperslab description missing");
+      }
+      if (!(valArray))
+      {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Hyperslab values missing");
+      }
+
+      if (dimArray->getSize() % 3 != 0)
+      {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Hyperslab description structured improperly");
+      }
+
+      // A start, stride, and dimension need to be
+      // specified for each dimension
+      unsigned int numDims = dimArray->getSize() / 3;
+
+      // Start, stride, and dims are set via the first array provided
+      std::vector<unsigned int> start;
+      std::vector<unsigned int> stride;
+      std::vector<unsigned int> dimensions;
+
+      unsigned int i = 0;
+
+      while (i < dimArray->getSize() / 3)
+      {
+        start.push_back(dimArray->getValue<unsigned int>(i));
+        ++i;
+      }
+
+      while (i < 2 * (dimArray->getSize() / 3))
+      {
+        stride.push_back(dimArray->getValue<unsigned int>(i));
+        ++i;
+      }
+
+      while (i < dimArray->getSize())
+      {
+        dimensions.push_back(dimArray->getValue<unsigned int>(i));
+        ++i;
+      }
+
+      shared_ptr<XdmfSubset> subset =
+        XdmfSubset::New(valArray,
+                        start,
+                        stride,
+                        dimensions);
+      this->setReference(subset);
+      this->setReadMode(XdmfArray::Reference);
+      filled = true;
+    }
+  }
+
+  if (!filled) {
+    std::vector<shared_ptr<XdmfHeavyDataController> > readControllers = reader->generateHeavyDataControllers(itemProperties);
+
+    mHeavyDataControllers.clear();
+
+    for (unsigned int i = 0; i < readControllers.size(); ++i) {
+      mHeavyDataControllers.push_back(readControllers[i]);
+    }
+
+    const shared_ptr<const XdmfArrayType> arrayType = 
+      XdmfArrayType::New(itemProperties);
+
+    std::map<std::string, std::string>::const_iterator content =
+      itemProperties.find("Content");
+    if(content == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "'Content' not found in itemProperties in "
+                         "XdmfArray::populateItem");
+    }
+
+    unsigned int contentIndex;
+
+    const std::string & contentVal = content->second;
+
+    std::vector<std::string> contentVals;
+
+    // Split the content based on "|" characters
+    size_t barSplit = 0;
+    std::string splitString(contentVal);
+    std::string subcontent;
+    while (barSplit != std::string::npos) {
+      barSplit = 0;
+      barSplit = splitString.find_first_of("|", barSplit);
+      if (barSplit == std::string::npos) {
+        subcontent = splitString;
+      }
+      else {
+        subcontent = splitString.substr(0, barSplit);
+        splitString = splitString.substr(barSplit+1);
+        barSplit++;
+      }
+      contentVals.push_back(subcontent);
+    }
+
+    std::map<std::string, std::string>::const_iterator dimensions =
+      itemProperties.find("Dimensions");
+    if(dimensions == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL, 
+                         "'Dimensions' not found in itemProperties in "
+                         "XdmfArray::populateItem");
+    }
+   
+    boost::tokenizer<> tokens(dimensions->second);
+    for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+        iter != tokens.end();
+        ++iter) {
+      mDimensions.push_back(atoi((*iter).c_str()));
+    }
+
+    std::map<std::string, std::string>::const_iterator format =
+      itemProperties.find("Format");
+    if(format == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL, 
+                         "'Format' not found in itemProperties in "
+                         "XdmfArray::populateItem");
+    }
+    const std::string & formatVal = format->second;
+
+    if (readControllers.size() == 0) {
+      if(formatVal.compare("XML") == 0) {
+        this->initialize(arrayType,
+                         mDimensions);
+        unsigned int index = 0;
+        boost::char_separator<char> sep(" \t\n");
+        for (contentIndex = 0; contentIndex < contentVals.size(); ++contentIndex)
+        {
+          boost::tokenizer<boost::char_separator<char> > tokens(contentVals[contentIndex], sep);
+          if(arrayType == XdmfArrayType::String()) {
+            for(boost::tokenizer<boost::char_separator<char> >::const_iterator
+                  iter = tokens.begin();
+                iter != tokens.end();
+                ++iter, ++index) {
+              this->insert(index, *iter);
+            }
+          }
+          else {
+            for(boost::tokenizer<boost::char_separator<char> >::const_iterator
+                  iter = tokens.begin();
+                iter != tokens.end();
+                ++iter, ++index) {
+              this->insert(index, atof((*iter).c_str()));
+            }
+          }
+        }
+      }
+      else
+      {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Data Format "
+                           "in XdmfArray::populateItem");
+      }
+    }
+  }
+
+  std::map<std::string, std::string>::const_iterator name =
+    itemProperties.find("Name");
+  if(name != itemProperties.end()) {
+    mName = name->second;
+  }
+  else {
+    mName = "";
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::read()
+{
+  switch (mReadMode)
+  {
+    case XdmfArray::Controller:
+      this->readController();
+      break;
+    case XdmfArray::Reference:
+      this->readReference();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Read Mode");
+  }
+}
+
+void
+XdmfArray::readController()
+{
+  if(mHeavyDataControllers.size() > 1) {
+    this->release();
+    for (unsigned int i = 0; i < mHeavyDataControllers.size(); ++i) {
+      shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+      mHeavyDataControllers[i]->read(tempArray.get());
+      unsigned int dimTotal = 1;
+      for (unsigned int j = 0; j < mHeavyDataControllers[i]->getDimensions().size(); ++j) {
+        dimTotal *= mHeavyDataControllers[i]->getDimensions()[j];
+      }
+      this->insert(mHeavyDataControllers[i]->getArrayOffset(), tempArray, 0, dimTotal, 1, 1);
+    }
+    std::vector<unsigned int> returnDimensions;
+    std::vector<unsigned int> tempDimensions;
+    // Find the controller with the most dimensions
+    int dimControllerIndex = 0;
+    unsigned int dimSizeMax = 0;
+    unsigned int dimTotal = 0;
+    for (unsigned int i = 0; i < mHeavyDataControllers.size(); ++i) {
+        dimTotal += mHeavyDataControllers[i]->getSize();
+        if (mHeavyDataControllers[i]->getSize() > dimSizeMax) {
+          dimSizeMax = mHeavyDataControllers[i]->getSize();
+          dimControllerIndex = i;
+        }
+    }
+    // Total up the size of the lower dimensions
+    int controllerDimensionSubtotal = 1;
+    for (unsigned int i = 0;
+         i < mHeavyDataControllers[dimControllerIndex]->getDimensions().size() - 1;
+         ++i) {
+      returnDimensions.push_back(mHeavyDataControllers[dimControllerIndex]->getDimensions()[i]);
+      controllerDimensionSubtotal *= mHeavyDataControllers[dimControllerIndex]->getDimensions()[i];
+    }
+    // Divide the total contained by the dimensions by the size of the lower dimensions
+    returnDimensions.push_back(dimTotal/controllerDimensionSubtotal);
+    mDimensions = returnDimensions;
+  }
+  else if (mHeavyDataControllers.size() == 1 && mHeavyDataControllers[0]->getArrayOffset() == 0) {
+    this->release();
+    mHeavyDataControllers[0]->read(this);
+    mDimensions = mHeavyDataControllers[0]->getDimensions();
+  }
+  else if (mHeavyDataControllers.size() == 1 && mHeavyDataControllers[0]->getArrayOffset() > 0) {
+    this->release();
+    shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+    mHeavyDataControllers[0]->read(tempArray.get());
+    this->insert(mHeavyDataControllers[0]->getArrayOffset(), tempArray, 0, mHeavyDataControllers[0]->getSize(), 1, 1);
+    mDimensions = mHeavyDataControllers[0]->getDimensions();
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::readReference()
+{
+  shared_ptr<XdmfArray> tempArray = mReference->read();
+  this->swap(tempArray);
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::release()
+{
+  mArray = boost::blank();
+  mArrayPointerNumValues = 0;
+  mDimensions.clear();
+}
+
+void
+XdmfArray::reserve(const unsigned int size)
+{
+  boost::apply_visitor(Reserve(this,
+                               size),
+                       mArray);
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::setHeavyDataController(shared_ptr<XdmfHeavyDataController> newController)
+{
+  // Since this is replacing the previous version which was designed to
+  // completely replace the controller of the array
+  // It will clear the current controllers before adding the new one in
+  mHeavyDataControllers.clear();
+  mHeavyDataControllers.push_back(newController);
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::setHeavyDataController(std::vector<shared_ptr<XdmfHeavyDataController> > & newControllers)
+{
+  if (mHeavyDataControllers.size() != newControllers.size()) {
+    mHeavyDataControllers.resize(newControllers.size());
+  }
+  for (unsigned int i = 0; i < newControllers.size(); ++i) {
+    mHeavyDataControllers[i] = newControllers[i];
+  }
+  this->setIsChanged(true);
+}
+
+
+void
+XdmfArray::setName(const std::string & name)
+{
+  mName = name;
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::setReadMode(XdmfArray::ReadMode newStatus)
+{
+  mReadMode = newStatus;
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::setReference(shared_ptr<XdmfArrayReference> newReference)
+{
+  mReference = newReference;
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::swap(const shared_ptr<XdmfArray> array)
+{
+  std::swap(mArray, array->mArray);
+  std::swap(mArrayPointerNumValues, array->mArrayPointerNumValues);
+  std::swap(mDimensions, array->mDimensions);
+  std::swap(mHeavyDataControllers, array->mHeavyDataControllers);
+  this->setIsChanged(true);
+}
+
+void
+XdmfArray::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+  if (mReference) {
+    mReference->accept(visitor);
+  }
+}
+
+// C wrappers
+
+XDMFARRAY *
+XdmfArrayNew()
+{
+  try
+  { 
+    XDMFARRAY * returnPointer;
+    shared_ptr<XdmfArray> generatedArray = XdmfArray::New();
+    returnPointer = (XDMFARRAY *)((void *)(new XdmfArray(*generatedArray.get())));
+    generatedArray.reset();
+    return returnPointer;
+  }
+  catch (...)
+  { 
+    XDMFARRAY * returnPointer;
+    shared_ptr<XdmfArray> generatedArray = XdmfArray::New();
+    returnPointer = (XDMFARRAY *)((void *)(new XdmfArray(*generatedArray.get())));
+    generatedArray.reset();
+    return returnPointer;
+  }
+}
+
+void XdmfArrayClear(XDMFARRAY * array)
+{
+  ((XdmfArray *)(array))->clear();
+}
+
+void XdmfArrayErase(XDMFARRAY * array, unsigned int index)
+{
+  ((XdmfArray *)(array))->erase(index);
+}
+
+int XdmfArrayGetArrayType(XDMFARRAY * array, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<const XdmfArrayType> compareType = ((XdmfArray *)(array))->getArrayType();
+  std::string typeName = compareType->getName();
+  unsigned int typePrecision = compareType->getElementSize();
+  if (typeName == XdmfArrayType::UInt8()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT8;
+  }
+  else if (typeName == XdmfArrayType::UInt16()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT16;
+  }
+  else if (typeName == XdmfArrayType::UInt32()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT32;
+  }
+  else if (typeName == XdmfArrayType::Int8()->getName())
+  {
+      return XDMF_ARRAY_TYPE_INT8;
+  }
+  else if (typeName == XdmfArrayType::Int16()->getName())
+  {
+      return XDMF_ARRAY_TYPE_INT16;
+  }
+  else if (typeName == XdmfArrayType::Int32()->getName() || typeName == XdmfArrayType::Int64()->getName())
+  {
+    if (typePrecision == 4)
+    {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (typePrecision == 8)
+    {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else
+    {
+    }
+  }
+  else if (typeName == XdmfArrayType::Float32()->getName() || typeName == XdmfArrayType::Float64()->getName())
+  {
+    if (typePrecision == 4)
+    {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (typePrecision == 8)
+    {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else
+    {
+    }
+  }
+  else if (typeName == XdmfArrayType::String()->getName())
+  {
+    //This shouldn't be used from C bindings
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: String type not usable from C.");
+  }
+  else
+  {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Invalid ArrayType.");
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+unsigned int XdmfArrayGetCapacity(XDMFARRAY * array)
+{
+  return ((XdmfArray *)(array))->getCapacity();
+}
+
+unsigned int *
+XdmfArrayGetDimensions(XDMFARRAY * array)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfArray *)(array))->getDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfArray *)(array))->getDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+char *
+XdmfArrayGetDimensionsString(XDMFARRAY * array)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfArray *)(array))->getDimensionsString().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfArray *)(array))->getDimensionsString().c_str());
+    return returnPointer;
+  }
+}
+
+XDMFHEAVYDATACONTROLLER *
+XdmfArrayGetHeavyDataController(XDMFARRAY * array, unsigned int index)
+{
+  return (XDMFHEAVYDATACONTROLLER *)((void *)(((XdmfArray *)(array))->getHeavyDataController(index).get()));
+}
+
+char *
+XdmfArrayGetName(XDMFARRAY * array)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfArray *)(array))->getName().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfArray *)(array))->getName().c_str());
+    return returnPointer;
+  }
+}
+
+unsigned int
+XdmfArrayGetNumberDimensions(XDMFARRAY * array)
+{
+  return ((XdmfArray *)(array))->getDimensions().size();
+}
+
+unsigned int
+XdmfArrayGetNumberHeavyDataControllers(XDMFARRAY * array)
+{
+  return ((XdmfArray *)(array))->getNumberHeavyDataControllers();
+}
+
+unsigned int
+XdmfArrayGetSize(XDMFARRAY * array)
+{
+  return ((XdmfArray *)(array))->getSize();
+}
+
+int
+XdmfArrayGetReadMode(XDMFARRAY * array, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  int readMode = ((XdmfArray *)(array))->getReadMode();
+  switch (readMode) {
+    case XdmfArray::Controller:
+      return XDMF_ARRAY_READ_MODE_CONTROLLER;
+      break;
+    case XdmfArray::Reference:
+      return XDMF_ARRAY_READ_MODE_REFERENCE;
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ReadMode.");
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+XDMFARRAYREFERENCE *
+XdmfArrayGetReference(XDMFARRAY * array)
+{
+  return (XDMFARRAYREFERENCE *)((void *)(((XdmfArray *)(array))->getReference().get()));
+}
+
+void *
+XdmfArrayGetValue(XDMFARRAY * array, unsigned int index, int arrayType, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    void * returnVal;
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        returnVal = new unsigned char();
+        *((unsigned char *)returnVal) = ((XdmfArray *)(array))->getValue<unsigned char>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        returnVal = new unsigned short();
+        *((unsigned short *)returnVal) = ((XdmfArray *)(array))->getValue<unsigned short>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        returnVal = new unsigned int();
+        *((unsigned int *)returnVal) = ((XdmfArray *)(array))->getValue<unsigned int>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        returnVal = new char();
+        *((char *)returnVal) = ((XdmfArray *)(array))->getValue<char>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        returnVal = new short();
+        *((short *)returnVal) = ((XdmfArray *)(array))->getValue<short>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        returnVal = new int();
+        *((int *)returnVal) = ((XdmfArray *)(array))->getValue<int>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        returnVal = new long();
+        *((long *)returnVal) = ((XdmfArray *)(array))->getValue<long>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        returnVal = new float();
+        *((float *)returnVal) = ((XdmfArray *)(array))->getValue<float>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        returnVal = new double();
+        *((double *)returnVal) = ((XdmfArray *)(array))->getValue<double>(index);
+        return returnVal;
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  catch (...)
+  {
+    void * returnVal;
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        returnVal = new unsigned char();
+        *((unsigned char *)returnVal) = ((XdmfArray *)(array))->getValue<unsigned char>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        returnVal = new unsigned short();
+        *((unsigned short *)returnVal) = ((XdmfArray *)(array))->getValue<unsigned short>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        returnVal = new unsigned int();
+        *((unsigned int *)returnVal) = ((XdmfArray *)(array))->getValue<unsigned int>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        returnVal = new char();
+        *((char *)returnVal) = ((XdmfArray *)(array))->getValue<char>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        returnVal = new short();
+        *((short *)returnVal) = ((XdmfArray *)(array))->getValue<short>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        returnVal = new int();
+        *((int *)returnVal) = ((XdmfArray *)(array))->getValue<int>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        returnVal = new long();
+        *((long *)returnVal) = ((XdmfArray *)(array))->getValue<long>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        returnVal = new float();
+        *((float *)returnVal) = ((XdmfArray *)(array))->getValue<float>(index);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        returnVal = new double();
+        *((double *)returnVal) = ((XdmfArray *)(array))->getValue<double>(index);
+        return returnVal;
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void *
+XdmfArrayGetValues(XDMFARRAY * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    void * returnVal;
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        returnVal = new unsigned char[numValues]();
+        ((XdmfArray *)(array))->getValues<unsigned char>(startIndex, (unsigned char *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        returnVal = new unsigned short[numValues]();
+        ((XdmfArray *)(array))->getValues<unsigned short>(startIndex, (unsigned short *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        returnVal = new unsigned int[numValues]();
+        ((XdmfArray *)(array))->getValues<unsigned int>(startIndex, (unsigned int *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        returnVal = new char[numValues]();
+        ((XdmfArray *)(array))->getValues<char>(startIndex, (char *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        returnVal = new short[numValues]();
+        ((XdmfArray *)(array))->getValues<short>(startIndex, (short *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        returnVal = new int[numValues]();
+        ((XdmfArray *)(array))->getValues<int>(startIndex, (int *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        returnVal = new long[numValues]();
+        ((XdmfArray *)(array))->getValues<long>(startIndex, (long *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        returnVal = new float[numValues]();
+        ((XdmfArray *)(array))->getValues<float>(startIndex, (float *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        returnVal = new double[numValues]();
+        ((XdmfArray *)(array))->getValues<double>(startIndex, (double *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  catch (...)
+  {
+    void * returnVal;
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        returnVal = new unsigned char[numValues]();
+        ((XdmfArray *)(array))->getValues<unsigned char>(startIndex, (unsigned char *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        returnVal = new unsigned short[numValues]();
+        ((XdmfArray *)(array))->getValues<unsigned short>(startIndex, (unsigned short *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        returnVal = new unsigned int[numValues]();
+        ((XdmfArray *)(array))->getValues<unsigned int>(startIndex, (unsigned int *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        returnVal = new char[numValues]();
+        ((XdmfArray *)(array))->getValues<char>(startIndex, (char *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        returnVal = new short[numValues]();
+        ((XdmfArray *)(array))->getValues<short>(startIndex, (short *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        returnVal = new int[numValues]();
+        ((XdmfArray *)(array))->getValues<int>(startIndex, (int *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        returnVal = new long[numValues]();
+        ((XdmfArray *)(array))->getValues<long>(startIndex, (long *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        returnVal = new float[numValues]();
+        ((XdmfArray *)(array))->getValues<float>(startIndex, (float *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        returnVal = new double[numValues]();
+        ((XdmfArray *)(array))->getValues<double>(startIndex, (double *)returnVal, numValues, arrayStride, valueStride);
+        return returnVal;
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void *
+XdmfArrayGetValuesInternal(XDMFARRAY * array)
+{
+  return ((XdmfArray *)(array))->getValuesInternal();
+}
+
+char *
+XdmfArrayGetValuesString(XDMFARRAY * array)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfArray *)(array))->getValuesString().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfArray *)(array))->getValuesString().c_str());
+    return returnPointer;
+  }
+}
+
+void
+XdmfArrayInitialize(XDMFARRAY * array, int * dims, int numDims, int arrayType, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> dimVector((int *)dims, (int *)dims + numDims);
+  shared_ptr<const XdmfArrayType> tempPointer = XdmfArrayType::Uninitialized();
+  switch (arrayType) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      tempPointer = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      tempPointer = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      tempPointer = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      tempPointer = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      tempPointer = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      tempPointer = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      tempPointer = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      tempPointer = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      tempPointer = XdmfArrayType::Float64();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  ((XdmfArray *)(array))->initialize(tempPointer, dimVector);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArrayInsertDataFromPointer(XDMFARRAY * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        ((XdmfArray *)(array))->insert<unsigned char>(startIndex, (unsigned char *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        ((XdmfArray *)(array))->insert<unsigned short>(startIndex, (unsigned short *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        ((XdmfArray *)(array))->insert<unsigned int>(startIndex, (unsigned int *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        ((XdmfArray *)(array))->insert<char>(startIndex, (char *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        ((XdmfArray *)(array))->insert<short>(startIndex, (short *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        ((XdmfArray *)(array))->insert<int>(startIndex, (int *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        ((XdmfArray *)(array))->insert<long>(startIndex, (long *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        ((XdmfArray *)(array))->insert<float>(startIndex, (float *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        ((XdmfArray *)(array))->insert<double>(startIndex, (double *)values, numVals, arrayStride, valueStride);
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  catch (...)
+  {
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        ((XdmfArray *)(array))->insert<unsigned char>(startIndex, (unsigned char *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        ((XdmfArray *)(array))->insert<unsigned short>(startIndex, (unsigned short *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        ((XdmfArray *)(array))->insert<unsigned int>(startIndex, (unsigned int *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        ((XdmfArray *)(array))->insert<char>(startIndex, (char *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        ((XdmfArray *)(array))->insert<short>(startIndex, (short *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        ((XdmfArray *)(array))->insert<int>(startIndex, (int *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        ((XdmfArray *)(array))->insert<long>(startIndex, (long *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        ((XdmfArray *)(array))->insert<float>(startIndex, (float *)values, numVals, arrayStride, valueStride);
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        ((XdmfArray *)(array))->insert<double>(startIndex, (double *)values, numVals, arrayStride, valueStride);
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfArrayInsertDataFromXdmfArray(XDMFARRAY * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    shared_ptr<XdmfArray> tempPointer((XdmfArray *)valArray, XdmfNullDeleter());
+    std::vector<unsigned int> arrayStartVector((int *)arrayStarts, (int *)arrayStarts + ((XdmfArray *)(array))->getDimensions().size());
+    std::vector<unsigned int> valueStartVector((int *)valueStarts, (int *)valueStarts + tempPointer->getDimensions().size());
+    std::vector<unsigned int> arrayCountVector((int *)arrayCounts, (int *)arrayCounts + ((XdmfArray *)(array))->getDimensions().size());
+    std::vector<unsigned int> valueCountVector((int *)valueCounts, (int *)valueCounts + tempPointer->getDimensions().size());
+    std::vector<unsigned int> arrayStrideVector((int *)arrayStrides, (int *)arrayStrides + ((XdmfArray *)(array))->getDimensions().size());
+    std::vector<unsigned int> valueStrideVector((int *)valueStrides, (int *)valueStrides + tempPointer->getDimensions().size());
+    ((XdmfArray *)(array))->insert(arrayStartVector, tempPointer, valueStartVector, arrayCountVector, valueCountVector, arrayStrideVector, valueStrideVector);
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfArray> tempPointer((XdmfArray *)valArray, XdmfNullDeleter());
+    std::vector<unsigned int> arrayStartVector((int *)arrayStarts, (int *)arrayStarts + ((XdmfArray *)(array))->getDimensions().size());
+    std::vector<unsigned int> valueStartVector((int *)valueStarts, (int *)valueStarts + tempPointer->getDimensions().size());
+    std::vector<unsigned int> arrayCountVector((int *)arrayCounts, (int *)arrayCounts + ((XdmfArray *)(array))->getDimensions().size());
+    std::vector<unsigned int> valueCountVector((int *)valueCounts, (int *)valueCounts + tempPointer->getDimensions().size());
+    std::vector<unsigned int> arrayStrideVector((int *)arrayStrides, (int *)arrayStrides + ((XdmfArray *)(array))->getDimensions().size());
+    std::vector<unsigned int> valueStrideVector((int *)valueStrides, (int *)valueStrides + tempPointer->getDimensions().size());
+    ((XdmfArray *)(array))->insert(arrayStartVector, tempPointer, valueStartVector, arrayCountVector, valueCountVector, arrayStrideVector, valueStrideVector);
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArrayInsertHeavyDataController(XDMFARRAY * array, XDMFHEAVYDATACONTROLLER * controller, int passControl)
+{
+  if (passControl == 0) {
+    ((XdmfArray *)(array))->insert(shared_ptr<XdmfHeavyDataController>((XdmfHeavyDataController *) controller, XdmfNullDeleter()));
+  }
+  else {
+    ((XdmfArray *)(array))->insert(shared_ptr<XdmfHeavyDataController>((XdmfHeavyDataController *) controller));
+  }
+}
+
+void
+XdmfArrayInsertValue(XDMFARRAY * array, unsigned int index, void * value, int arrayType, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        ((XdmfArray *)(array))->insert(index, *((unsigned char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        ((XdmfArray *)(array))->insert(index, *((unsigned short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        ((XdmfArray *)(array))->insert(index, *((unsigned int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        ((XdmfArray *)(array))->insert(index, *((char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        ((XdmfArray *)(array))->insert(index, *((short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        ((XdmfArray *)(array))->insert(index, *((int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        ((XdmfArray *)(array))->insert(index, *((long *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        ((XdmfArray *)(array))->insert(index, *((float *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        ((XdmfArray *)(array))->insert(index, *((double *)value));
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  catch (...)
+  {
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        ((XdmfArray *)(array))->insert(index, *((unsigned char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        ((XdmfArray *)(array))->insert(index, *((unsigned short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        ((XdmfArray *)(array))->insert(index, *((unsigned int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        ((XdmfArray *)(array))->insert(index, *((char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        ((XdmfArray *)(array))->insert(index, *((short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        ((XdmfArray *)(array))->insert(index, *((int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        ((XdmfArray *)(array))->insert(index, *((long *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        ((XdmfArray *)(array))->insert(index, *((float *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        ((XdmfArray *)(array))->insert(index, *((double *)value));
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+int
+XdmfArrayIsInitialized(XDMFARRAY * array)
+{
+  return ((XdmfArray *)(array))->isInitialized();
+}
+
+void
+XdmfArrayPushBack(XDMFARRAY * array, void * value, int arrayType, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        ((XdmfArray *)(array))->pushBack<unsigned char>(*((unsigned char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        ((XdmfArray *)(array))->pushBack<unsigned short>(*((unsigned short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        ((XdmfArray *)(array))->pushBack<unsigned int>(*((unsigned int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        ((XdmfArray *)(array))->pushBack<char>(*((char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        ((XdmfArray *)(array))->pushBack<short>(*((short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        ((XdmfArray *)(array))->pushBack<int>(*((int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        ((XdmfArray *)(array))->pushBack<long>(*((long *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        ((XdmfArray *)(array))->pushBack<float>(*((float *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        ((XdmfArray *)(array))->pushBack<double>(*((double *)value));
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  catch (...)
+  {
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        ((XdmfArray *)(array))->pushBack<unsigned char>(*((unsigned char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        ((XdmfArray *)(array))->pushBack<unsigned short>(*((unsigned short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        ((XdmfArray *)(array))->pushBack<unsigned int>(*((unsigned int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        ((XdmfArray *)(array))->pushBack<char>(*((char *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        ((XdmfArray *)(array))->pushBack<short>(*((short *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        ((XdmfArray *)(array))->pushBack<int>(*((int *)value));
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        ((XdmfArray *)(array))->pushBack<long>(*((long *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        ((XdmfArray *)(array))->pushBack<float>(*((float *)value));
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        ((XdmfArray *)(array))->pushBack<double>(*((double *)value));
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArrayRead(XDMFARRAY * array, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    ((XdmfArray *)(array))->read();
+  }
+  catch (...)
+  {
+    ((XdmfArray *)(array))->read();
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArrayReadController(XDMFARRAY * array, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    ((XdmfArray *)(array))->readController();
+  }
+  catch (...)
+  {
+    ((XdmfArray *)(array))->readController();
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArrayReadReference(XDMFARRAY * array, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    ((XdmfArray *)(array))->readReference();
+  }
+  catch (...)
+  {
+    ((XdmfArray *)(array))->readReference();
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArrayRelease(XDMFARRAY * array)
+{
+  ((XdmfArray *)(array))->release();
+}
+
+void
+XdmfArrayRemoveHeavyDataController(XDMFARRAY * array, unsigned int index)
+{
+  ((XdmfArray *)(array))->removeHeavyDataController(index);
+}
+
+void
+XdmfArrayReserve(XDMFARRAY * array, int size)
+{
+  ((XdmfArray *)(array))->reserve(size);
+}
+
+void
+XdmfArrayResize(XDMFARRAY * array, int * dims, int numDims, int arrayType, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<unsigned int> dimVector((int *)dims, (int *)dims + numDims);
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (unsigned char) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_UINT16:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (unsigned short) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_UINT32:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (unsigned int) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT8:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (char) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT16:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (short) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT32:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (int) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT64:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (long) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_FLOAT32:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (float) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_FLOAT64:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (double) 0);
+        break;
+      }
+      default:
+      {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+      }
+    }
+    dimVector.clear();
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> dimVector((int *)dims, (int *)dims + numDims);
+    switch (arrayType) {
+      case XDMF_ARRAY_TYPE_UINT8:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (unsigned char) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_UINT16:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (unsigned short) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_UINT32:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (unsigned int) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT8:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (char) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT16:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (short) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT32:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (int) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_INT64:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (long) 0);
+        break;
+      }
+      case XDMF_ARRAY_TYPE_FLOAT32:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (float) 0);
+        break;
+      }
+
+      case XDMF_ARRAY_TYPE_FLOAT64:
+      {
+        XdmfArray * classedArray = (XdmfArray *)((void *) array);
+        classedArray->resize(dimVector, (double) 0);
+        break;
+      }
+      default:
+      {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+      }
+    }
+    dimVector.clear();
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArraySetReadMode(XDMFARRAY * array, int readMode, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (readMode) {
+    case XDMF_ARRAY_READ_MODE_CONTROLLER:
+      ((XdmfArray *)(array))->setReadMode(XdmfArray::Controller);
+      break;
+    case XDMF_ARRAY_READ_MODE_REFERENCE:
+      ((XdmfArray *)(array))->setReadMode(XdmfArray::Reference);
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ReadMode.");
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArraySetReference(XDMFARRAY * array, XDMFARRAYREFERENCE * reference, int passControl)
+{
+  if (passControl) {
+    ((XdmfArray *)(array))->setReference(shared_ptr<XdmfArrayReference>((XdmfArrayReference *)reference));
+  }
+  else {
+    ((XdmfArray *)(array))->setReference(shared_ptr<XdmfArrayReference>((XdmfArrayReference *)reference, XdmfNullDeleter()));
+  }
+}
+
+void
+XdmfArraySetName(XDMFARRAY * array, char * name, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfArray *)(array))->setName(name);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArraySetValuesInternal(XDMFARRAY * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (arrayType) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      ((XdmfArray *)array)->setValuesInternal((unsigned char *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      ((XdmfArray *)array)->setValuesInternal((unsigned short *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      ((XdmfArray *)array)->setValuesInternal((unsigned int *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      ((XdmfArray *)array)->setValuesInternal((char *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      ((XdmfArray *)array)->setValuesInternal((short *)pointer, numValues, transferOwnership);
+     break;
+    case XDMF_ARRAY_TYPE_INT32:
+      ((XdmfArray *)array)->setValuesInternal((int *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      ((XdmfArray *)array)->setValuesInternal((long *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      ((XdmfArray *)array)->setValuesInternal((float *)pointer, numValues, transferOwnership);
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      ((XdmfArray *)array)->setValuesInternal((double *)pointer, numValues, transferOwnership);
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfArraySwapWithXdmfArray(XDMFARRAY * array, XDMFARRAY * swapArray)
+{
+  shared_ptr<XdmfArray> pointerToSwap((XdmfArray *) swapArray, XdmfNullDeleter());
+  ((XdmfArray *)array)->swap(pointerToSwap);
+}
+
+void
+XdmfArraySwapWithArray(XDMFARRAY * array, void ** pointer, int numValues, int arrayType, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (arrayType) {
+    case XDMF_ARRAY_TYPE_UINT8: {
+      std::vector<unsigned char> swapVector((unsigned char *)(*pointer), (unsigned char *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new unsigned char[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((unsigned char *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_UINT16: {
+      std::vector<unsigned short> swapVector((unsigned short *)(*pointer), (unsigned short *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new unsigned short[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((unsigned short *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_UINT32: {
+      std::vector<unsigned int> swapVector((unsigned int *)(*pointer), (unsigned int *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new unsigned int[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((unsigned int *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_INT8: {
+      std::vector<char> swapVector((char *)(*pointer), (char *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new char[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((char *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_INT16: {
+      std::vector<short> swapVector((short *)(*pointer), (short *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new short[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((short *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_INT32: {
+      std::vector<int> swapVector((int *)(*pointer), (int *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new int[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((int *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_INT64: {
+      std::vector<long> swapVector((long *)(*pointer), (long *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new long[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((long *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_FLOAT32: {
+      std::vector<float> swapVector((float *)(*pointer), (float *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new float[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((float *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    case XDMF_ARRAY_TYPE_FLOAT64: {
+      std::vector<double> swapVector((double *)(*pointer), (double *)(*pointer) + numValues);
+      ((XdmfArray *)array)->swap(swapVector);
+      *pointer = new double[swapVector.size()];
+      for (unsigned int i = 0; i < swapVector.size(); ++i)
+      {
+        ((double *) (*pointer))[i] = swapVector[i];
+      }
+      break;
+    }
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfArray, XDMFARRAY)
diff --git a/core/XdmfArray.hpp b/core/XdmfArray.hpp
new file mode 100644
index 0000000..691d4d3
--- /dev/null
+++ b/core/XdmfArray.hpp
@@ -0,0 +1,2008 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfArray.hpp                                                       */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFARRAY_HPP_
+#define XDMFARRAY_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfArrayReference.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArrayType;
+class XdmfHeavyDataController;
+
+// Includes
+#include <boost/shared_array.hpp>
+#include <boost/variant.hpp>
+
+/**
+ * @brief Provides storage for data values that are read in or will be
+ * written to heavy data on disk.
+ *
+ * XdmfArray provides a single interface for storing a variety of data
+ * types.  The data type stored is determined by the type initially
+ * inserted into the array.  An array can be initialized with a
+ * specific data type before insertion of values by calling
+ * initialize().
+ *
+ * An XdmfArray is associated with heavy data files on disk through an
+ * XdmfHeavyDataController. When an Xdmf file is read from disk,
+ * XdmfHeavyDataControllers are attached to all created XdmfArrays
+ * that contain values stored in heavy data. These values are not read
+ * into memory when the Xdmf file is parsed. The array is
+ * uninitialized and the return value of isInitialized() is false.  In
+ * order to read the heavy data values into memory, read() must be
+ * called. This will cause the array to ask for values to be read from
+ * disk using the XdmfHeavyDataController. After the values have been
+ * read from heavy data on disk, isInitialized() will return true.
+ *
+ * This version of Xdmf allows for multiple controllers to be added to
+ * a single array. Be aware that doing this makes the files written
+ * incompatible with previous editions.
+ *
+ * XdmfArray allows for insertion and retrieval of data in two
+ * fundamental ways:
+ *
+ * By Copy:
+ *
+ *   getValue
+ *   getValues
+ *   insert
+ *   pushBack
+ *
+ * XdmfArray stores its own copy of the data.  Modifications to the
+ * data stored in the XdmfArray will not change values stored in the
+ * original array.
+ *
+ * By Shared Reference:
+ *
+ *   getValuesInternal
+ *   setValuesInternal
+ *
+ * XdmfArray shares a reference to the data.  No copy is
+ * made. XdmfArray holds a shared pointer to the original data.
+ * Modifications to the data stored in the XdmfArray also causes
+ * modification to values stored in the original array.
+ *
+ * Xdmf supports the following datatypes:
+ *   Int8
+ *   Int16
+ *   Int32
+ *   Int64
+ *   Float32
+ *   Float64
+ *   UInt8
+ *   UInt16
+ *   UInt32
+ *   String
+ */
+class XDMFCORE_EXPORT XdmfArray : public XdmfItem {
+
+public:
+
+  enum ReadMode {
+    Controller,
+    Reference
+  };
+
+  /**
+   * Create a new XdmfArray.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfArray.
+   */
+  static shared_ptr<XdmfArray> New();
+
+  virtual ~XdmfArray();
+
+  LOKI_DEFINE_VISITABLE(XdmfArray, XdmfItem)
+  XDMF_CHILDREN(XdmfArray, XdmfHeavyDataController, HeavyDataController, Name)
+  static const std::string ItemTag;
+
+  /**
+   * Remove all values from this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#clear
+   * @until //#clear
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//clear
+   * @until #//clear
+   */
+  void clear();
+
+  /**
+   * Remove a value from this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#erase
+   * @until //#erase
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//arraydefaultvalues
+   * @until #//arraydefaultvalues
+   * @skipline #//erase
+   * @until #//erase
+   *
+   * @param     index   The index of the value to be removed
+   */
+  void erase(const unsigned int index);
+
+  /**
+   * Get the data type of this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getArrayType
+   * @until //#getArrayType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getArrayType
+   * @until #//getArrayType
+   *
+   * @return    An XdmfArrayType containing the data type for the array.
+   */
+  shared_ptr<const XdmfArrayType> getArrayType() const;
+
+  /**
+   * Get the capacity of this array, the number of values the array
+   * can store without reallocation.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getCapacity
+   * @until //#getCapacity
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getCapacity
+   * @until #//getCapacity
+   *
+   * @return    The capacity of this array.
+   */
+  unsigned int getCapacity() const;
+
+  /**
+   * Get the dimensions of the array.
+   * If the array isn't initialized the dimensions
+   * will be based on the heavyDataControllers it has, if any.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    The dimensions of the array.
+   */
+  std::vector<unsigned int> getDimensions() const;
+
+  /**
+   * Get the dimensions of the array as a string.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDimensionsString
+   * @until //#getDimensionsString
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDimensionsString
+   * @until #//getDimensionsString
+   *
+   * @return    The dimensions of the array as a string.
+   */
+  std::string getDimensionsString() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the name of the array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    A string containing the name of the array.
+   */
+  virtual std::string getName() const;
+
+  /**
+   * Gets the method this array will be written/read.
+   * Possible choices are: Controller, and Reference
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setReference
+   * @until //#setReference
+   * @skipline //#setReadMode
+   * @until //#setReadMode
+   * @skipline //#getReadMode
+   * @until //#getReadMode
+   *
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setReference
+   * @until #//setReference
+   * @skipline #//setReadMode
+   * @until #//setReadMode
+   * @skipline #//getReadMode
+   * @until #//getReadMode
+   *
+   * @return    What method will be used when reading/writing the array
+   */
+  ReadMode getReadMode() const;
+
+  /**
+   * Get the number of values stored in this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getSize
+   * @until //#getSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getSize
+   * @until #//getSize
+   *
+   * @return    The number of values stored in this array.
+   */
+  unsigned int getSize() const;
+
+  /**
+   * Gets the array reference that the array will pull from when reading from a reference.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setReference
+   * @until //#setReference
+   * @skipline //#getReference
+   * @until //#getReference
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setReference
+   * @until #//setReference
+   * @skipline #//getReference
+   * @until #//getReference
+   *
+   * @return    The reference being pulled from
+   */
+  shared_ptr<XdmfArrayReference> getReference();
+
+  /**
+   * Get a copy of a single value stored in this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#datapointersetup
+   * @until //#datapointersetup
+   * @skipline //#initsharedvector
+   * @until //#initsharedvector
+   * @skipline //#getValueindex
+   * @until //#getValueindex
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//arraydefaultvalues
+   * @until #//arraydefaultvalues
+   * @skipline #//getValueindex
+   * @until #//getValueindex
+   *
+   * @return    The requested value.
+   */
+  template <typename T>
+  T getValue(const unsigned int index) const;
+
+  /**
+   * Get a copy of the values stored in this array
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getValues
+   * @until //#getValues
+   *
+   * Python: 
+   * This function is not supported in Python,
+   * it is replaced by the getNumpyArray function
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//arraydefaultvalues
+   * @until #//arraydefaultvalues
+   * @skipline #//getNumpyArray
+   * @until #//getNumpyArray
+   *
+   * @param     startIndex      The index in this array to begin copying from.
+   * @param     valuesPointer   A pointer to an array to copy into.
+   * @param     numValues       The number of values to copy.
+   * @param     arrayStride     Number of values to stride in this array
+   *                            between each copy.
+   * @param     valuesStride    Number of values to stride in the pointer
+   *                            between each copy.
+   */
+  template <typename T> void
+  getValues(const unsigned int startIndex,
+            T * const valuesPointer,
+            const unsigned int numValues = 1,
+            const unsigned int arrayStride = 1,
+            const unsigned int valuesStride = 1) const;
+
+  /**
+   * Get a smart pointer to the internal values stored in this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getValuesInternalvector
+   * @until //#getValuesInternalvector
+   *
+   * Python:
+   * Python does not support this version of the getValuesInternal function,
+   * it defaults to the version that returns a void pointer
+   *
+   * @return    A smart pointer to the internal vector of values stored
+   *            in this array.
+   */
+  template <typename T>
+  shared_ptr<std::vector<T> > getValuesInternal();
+
+  /**
+   * Get a pointer to the internal values stored in this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getValuesInternalvoid
+   * @until //#getValuesInternalvoid
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline #//getValuesInternal
+   * @until #//getValuesInternal
+   *
+   * @return    A void pointer to the first value stored in this array.
+   */
+  void * getValuesInternal();
+
+  /**
+   * Get a pointer to the internal values stored in this array (const
+   * version).
+   *
+   * Example of use:
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getValuesInternalvoidconst
+   * @until //#getValuesInternalvoidconst
+   *
+   * Python:
+   * Python does not support this version of the getValuesInternal function,
+   * it defaults to the version that returns a void pointer
+   *
+   * @return    A void pointer to the first value stored in this array.
+   */
+  const void * getValuesInternal() const;
+
+  /**
+   * Get the values stored in this array as a string.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getValuesString
+   * @until //#getValuesString
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getValuesparse
+   * @until #//getValuesparse
+   *
+   * @return    A string containing the contents of the array.
+   */
+  std::string getValuesString() const;
+
+  /**
+   * Initialize the array to a specific size.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizedeclaration
+   * @until //#sizedeclaration
+   * @skipline //#initializesingletemplate
+   * @until //#initializesingletemplate
+   *
+   * Python: Does not support this version of initialize
+   *
+   * @param     size    The number of values in the initialized array.
+   *
+   * @return            A smart pointer to the internal vector of values
+   *                    initialized in this array.
+   */
+  template <typename T>
+  shared_ptr<std::vector<T> > initialize(const unsigned int size = 0);
+
+  /**
+   * Initialize the array to specific dimensions.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizevectordeclaration
+   * @until //#sizevectordeclaration
+   * @skipline //#initializevectortemplate
+   * @until //#initializevectortemplate
+   *
+   * Python: Does not support this version of initialize
+   *
+   * @param     dimensions      The dimensions of the initialized array.
+   *
+   * @return                    A smart pointer to the internal vector of values
+   *                            initialized in this array.
+   */
+  template <typename T>
+  shared_ptr<std::vector<T> >
+  initialize(const std::vector<unsigned int> & dimensions);
+
+  /**
+   * Initialize the array to contain a specified amount of a particular type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizedeclaration
+   * @until //#sizedeclaration
+   * @skipline //#initializesingletype
+   * @until //#initializesingletype
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//initializesingle
+   * @until #//initializesingle
+   *
+   * @param     arrayType       The type of array to initialize.
+   * @param     size            The number of values in the initialized array.
+   */
+  void initialize(const shared_ptr<const XdmfArrayType> & arrayType,
+                  const unsigned int size = 0);
+
+  /**
+   * Initialize the array with specified dimensions to contain a particular type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizevectordeclaration
+   * @until //#sizevectordeclaration
+   * @skipline //#initializevectortype
+   * @until //#initializevectortype
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//initializevector
+   * @until #//initializevector
+   *
+   * @param     arrayType       The type of array to initialize.
+   * @param     dimensions      The number dimensions of the initialized array.
+   */
+  void initialize(const shared_ptr<const XdmfArrayType> & arrayType,
+                  const std::vector<unsigned int> & dimensions);
+
+  using XdmfItem::insert;
+
+  /**
+   * Insert value into this array
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#pointinsertvalues
+   * @until //#pointinsertvalues
+   * @skipline //#pointinsert
+   * @until //#pointinsert
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//pointinsert
+   * @until #//pointinsert
+   *
+   * @param     index   The index in this array to insert.
+   * @param     value   The value to insert
+   */
+  template<typename T>
+  void insert(const unsigned int index,
+              const T & value);
+
+  /**
+   * Insert values from an XdmfArray into this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#datapointersetup
+   * @until //#datapointersetup
+   * @skipline //#pointerinsert
+   * @until //#pointerinsert
+   * @skipline //#arrayinsert
+   * @until //#arrayinsert
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//insertarray
+   * @until #//insertarray
+   *
+   * @param     startIndex              The index in this array to begin insertion.
+   * @param     values                  A shared pointer to an XdmfArray to copy
+   *                                    into this array.
+   * @param     valuesStartIndex        The index in the XdmfArray to begin copying.
+   * @param     numValues               The number of values to copy into this array.
+   * @param     arrayStride             Number of values to stride in this array
+   *                                    between each copy.
+   * @param     valuesStride            Number of values to stride in the XdmfArray
+   *                                    between each copy.
+   */
+  void insert(const unsigned int startIndex,
+              const shared_ptr<const XdmfArray> values,
+              const unsigned int valuesStartIndex = 0,
+              const unsigned int numValues = 1,
+              const unsigned int arrayStride = 1,
+              const unsigned int valuesStride = 1);
+
+  /**
+   * Insert values from an XdmfArray into this array. This is the multidimensional version.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#insertmultidim
+   * @until //#insertmultidim
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//insertmultidim
+   * @until #//insertmultidim
+   *
+   * @param     startIndex              The index in this array to begin
+   *                                    insertion for each dimension
+   * @param     values                  A shared pointer to an XdmfArray
+   *                                    to copy into this array.
+   * @param     valuesStartIndex        The index in the XdmfArray to begin
+   *                                    copying for each dimension of the
+   *                                    source array
+   * @param     numValues               The number of values to copy into this
+   *                                    array for each dimension on the
+   *                                    source array
+   * @param     numInserted             The number of strides to make across
+   *                                    the array being written to for each
+   *                                    dimension
+   * @param     arrayStride             Number of values to stride in this array
+   *                                    between each copy for each dimension
+   * @param     valuesStride            Number of values to stride in the
+   *                                    XdmfArray between each copy for each
+   *                                    dimension of the source array
+   */
+  void insert(const std::vector<unsigned int> startIndex,
+              const shared_ptr<const XdmfArray> values,
+              const std::vector<unsigned int> valuesStartIndex,
+              const std::vector<unsigned int> numValues,
+              const std::vector<unsigned int> numInserted,
+              const std::vector<unsigned int> arrayStride,
+              const std::vector<unsigned int> valuesStride);
+
+  /**
+   * Insert values into this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#datapointersetup
+   * @until //#datapointersetup
+   * @skipline //#pointerinsert
+   * @until //#pointerinsert
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//insertlist
+   * @until #//insertlist
+   *
+   * @param     startIndex      The index in this array to begin insertion.
+   * @param     valuesPointer   A pointer to the values to copy into this array.
+   * @param     numValues       The number of values to copy into this array.
+   * @param     arrayStride     Number of values to stride in this array between
+   *                            each copy.
+   * @param     valuesStride    Number of values to stride in the pointer between
+   *                            each copy.
+   */
+  template<typename T>
+  void insert(const unsigned int startIndex,
+              const T * const valuesPointer,
+              const unsigned int numValues,
+              const unsigned int arrayStride = 1,
+              const unsigned int valuesStride = 1);
+
+  /**
+   * Returns whether the array is initialized (contains values in
+   * memory).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#isInitialized
+   * @until //#isInitialized
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//isInitialized
+   * @until #//isInitialized
+   */
+  virtual bool isInitialized() const;
+
+  /**
+   * Copy a value to the back of this array
+   *
+   * Example of use;
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#pointinsertvalues
+   * @until //#pointinsertvalues
+   * @skipline //#pushBack
+   * @until //#pushBack
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//pushBack
+   * @until #//pushBack
+   *
+   * @param     value   The value to be inserted
+   */
+  template <typename T>
+  void pushBack(const T & value);
+
+  /**
+   * Get the first heavy data controller attached to this array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getHeavyDataController
+   * @until //#getHeavyDataController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getHeavyDataController
+   * @until #//getHeavyDataController
+   *
+   * @return    The heavy data controller attached to this array.
+   */
+  shared_ptr<XdmfHeavyDataController>
+  getHeavyDataController();
+
+  /**
+   * Get the first heavy data controller attached to this array. (const version)
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getHeavyDataControllerconst
+   * @until //#getHeavyDataControllerconst
+   *
+   * Python: Doesn't support a constant version of this function
+   *
+   * @return    The heavy data controller attached to this array.
+   */
+  shared_ptr<const XdmfHeavyDataController>
+  getHeavyDataController() const;
+
+  /**
+   * Replace all controllers attached to this array with the controller provided.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getHeavyDataController
+   * @until //#getHeavyDataController
+   * @skipline //#setHeavyDataController
+   * @until //#setHeavyDataController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getHeavyDataController
+   * @until #//getHeavyDataController
+   * @skipline #//setHeavyDataController
+   * @until #//setHeavyDataController
+   *
+   * @param     newController   The heavy data controller to attach to this array.
+   */
+  void
+  setHeavyDataController(shared_ptr<XdmfHeavyDataController> newController);
+
+  /**
+   * Sets the controllers attached to this array to the ones contained
+   * in the provided vector.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setHeavyDataControllerVector
+   * @until //#setHeavyDataControllerVector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setHeavyDataControllerVector
+   * @until #//setHeavyDataControllerVector
+   *
+   * @param     newControllers  The controllers to be set to the array.
+   */
+  void
+  setHeavyDataController(std::vector<shared_ptr<XdmfHeavyDataController> > & newControllers);
+
+
+  /**
+   * Read data from disk into memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//isInitialized
+   * @until #//isInitialized
+   */
+  void read();
+
+  /**
+   * Reads data from the attached controllers to the internal data storage.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getHeavyDataController
+   * @until //#getHeavyDataController
+   * @skipline //#setHeavyDataController
+   * @until //#setHeavyDataController
+   * @skipline //#readController
+   * @until //#readController
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getHeavyDataController
+   * @until #//getHeavyDataController
+   * @skipline #//setHeavyDataController
+   * @until #//setHeavyDataController
+   * @skipline #//readController
+   * @until #//readController
+   */
+  void readController();
+
+  /**
+   * Reads the data pointed to by the array reference into the array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setReference
+   * @until //#setReference
+   * @skipline //#readReference
+   * @until //#readReference
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setReference
+   * @until #//setReference
+   * @skipline #//readReference
+   * @until #//readReference
+   */
+  void readReference();
+
+  /**
+   * Release all data currently held in memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#release
+   * @until //#release
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//release
+   * @until #//release
+   */
+  void release();
+
+  /**
+   * Set the capacity of the array to at least size.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizedeclaration
+   * @until //#sizedeclaration
+   * @skipline //#reserve
+   * @until //#reserve
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//reserve
+   * @until #//reserve
+   *
+   * @param     size    The capacity to set this array to.
+   */
+  void reserve(const unsigned int size);
+
+  /**
+   * Resizes the array to contain a number of values. If numValues is
+   * larger than the current size, values are appended to the end of
+   * the array equal to value. If numValues is less than the current
+   * size, values at indices larger than numValues are removed.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizedeclaration
+   * @until //#sizedeclaration
+   * @skipline //#resizesingle
+   * @until //#resizesingle
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//arraydefaultvalues
+   * @until #//arraydefaultvalues
+   * @skipline #//resizesingle
+   * @until #//resizesingle
+   *
+   * @param     numValues       The number of values to resize this array to.
+   * @param     value           The number to initialize newly created
+   *                            values to, if needed.
+   */
+  template<typename T>
+  void resize(const unsigned int numValues,
+              const T & value = 0);
+
+  /**
+   * Resizes the array to specified dimensions. If the number of
+   * values specified by the dimensions is larger than the current
+   * size, values are appended to the end of the array equal to
+   * value. If numValues is less than the current size, values at
+   * indices larger than numValues are removed.
+   *
+   * Example of use:
+   * 
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#sizevectordeclaration
+   * @until //#sizevectordeclaration
+   * @skipline //#resizevector
+   * @until //#resizevector
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//arraydefaultvalues
+   * @until #//arraydefaultvalues
+   * @skipline #//resizevector
+   * @until #//resizevector
+   *
+   * @param     dimensions      The dimensions to resize the array to.
+   * @param     value           The number to intialize newly created values to,
+   *                            if needed.
+   */
+  template<typename T>
+  void resize(const std::vector<unsigned int> & dimensions,
+              const T & value = 0);
+
+  /**
+   * Sets the array reference from which the Array will fill when readReference is called.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setReference
+   * @until //#setReference
+   *
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setReference
+   * @until #//setReference
+   *
+   * @param     newReference     The reference to be associated with this array
+   */
+  void setReference(shared_ptr<XdmfArrayReference> newReference);
+
+  /**
+   * Set the name of the array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   *
+   * @param     name    Name of the array to set.
+   */
+  virtual void setName(const std::string & name);
+
+  /**
+   * Sets the method this array will be written/read.
+   * Possible choices are: Controller, and Reference
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setReference
+   * @until //#setReference
+   * @skipline //#setReadMode
+   * @until //#setReadMode
+   *
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setReference
+   * @until #//setReference
+   * @skipline #//setReadMode
+   * @until #//setReadMode
+   *
+   * @param     newStatus       The method that the array will be read/written
+   */
+  void setReadMode(ReadMode newStatus = XdmfArray::Controller);
+
+  /**
+   * Sets the values of this array to the values stored in the
+   * arrayPointer array. No copy is made. Modifications to the array
+   * are not permitted through the XdmfArray API. Any calls through
+   * the XdmfArray API to modify the array (i.e. any non-const
+   * function) will result in the array being copied into internal
+   * storage. The internal copy is then modified.  This prevents
+   * situations where a realloc of the pointer could cause other
+   * references to become invalid. The caller of this method can
+   * continue to modify the values stored in arrayPointer on its
+   * own. This function is meant for applications that have their own
+   * array data structures that merely use Xdmf to output the data, an
+   * operation that should not require a copy. Other applications that
+   * use Xdmf for in memory data storage should avoid this function.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#datapointersetup
+   * @until //#datapointersetup
+   * @skipline //#setValuesInternalpointer
+   * @until //#setValuesInternalpointer
+   *
+   * Python: does not support setValuesInternal
+   *
+   * @param     arrayPointer            A pointer to an array to store in
+   *                                    this XdmfArray.
+   * @param     numValues               The number of values in the array.
+   * @param     transferOwnership       Whether to transfer responsibility for
+   *                                    deletion of the array to XdmfArray.
+   */
+  template<typename T>
+  void setValuesInternal(const T * const arrayPointer,
+                         const unsigned int numValues,
+                         const bool transferOwnership = 0);
+
+  /**
+   * Sets the values of this array to the values stored in the
+   * vector. No copy is made. The caller of this method retains
+   * ownership of the data and must ensure that the array is still
+   * valid for the entire time Xdmf needs it.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#initinternalvector
+   * @until //#initinternalvector
+   * @skipline //#setValuesInternalvector
+   * @until //#setValuesInternalvector
+   *
+   * Python: does not support setValuesInternal
+   *
+   * @param     array                   A vector to store in this XdmfArray.
+   * @param     transferOwnership       Whether to transfer responsibility for
+   *                                    deletion of the array to XdmfArray.
+   */
+  template<typename T>
+  void setValuesInternal(std::vector<T> & array,
+                         const bool transferOwnership = 0);
+
+  /**
+   * Sets the values of this array to the values stored in the
+   * vector. No copy is made. This array shares ownership with other
+   * references to the smart pointer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#initinternalvector
+   * @until //#initinternalvector
+   * @skipline //#initsharedvector
+   * @until //#initsharedvector
+   * @skipline //#setValuesInternalsharedvector
+   * @until //#setValuesInternalsharedvector
+   *
+   * Python: does not support setValuesInternal
+   *
+   * @param     array   A smart pointer to a vector to store in this array.
+   */
+  template<typename T>
+  void setValuesInternal(const shared_ptr<std::vector<T> > array);
+
+  /**
+   * Exchange the contents of the vector with the contents of this
+   * array. No copy is made. The internal arrays are swapped.
+   *
+   * Example of use
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#initinternalvector
+   * @until //#initinternalvector
+   * @skipline //#swapvector
+   * @until //#swapvector
+   *
+   * Python: The Python version only supports swapping XdmfArrays
+   *
+   * @param     array   A vector to exchange values with.
+   * @return            bool whether the swap was successful.
+   */
+  template<typename T>
+  bool swap(std::vector<T> & array);
+
+  /**
+   * Exchange the contents of the vector with the contents of this
+   * array. No copy is made. The internal arrays are swapped.
+   *
+   * Example of use
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#initinternalvector
+   * @until //#initinternalvector
+   * @skipline //#initsharedvector
+   * @until //#initsharedvector
+   * @skipline //#swapsharedvector
+   * @until //#swapsharedvector
+   *
+   * Python: The Python version only supports swapping XdmfArrays
+   *
+   * @param     array   A smart pointer to a vector to exchange values with.
+   * @return            bool whether the swap was successful.
+   */
+  template<typename T>
+  bool swap(const shared_ptr<std::vector<T> > array);
+
+  /**
+   * Exchange the contents of an XdmfArray with the contents of this
+   * array. No copy is made. The internal arrays are swapped.
+   *
+   * Example of use
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArray.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#swaparray
+   * @until //#swaparray
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArray.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//arraydefaultvalues
+   * @until #//arraydefaultvalues
+   * @skipline //#swap
+   * @until //#swap
+   *
+   * @param     array   A smart pointer to a vector to exchange values with.
+   */
+  void swap(const shared_ptr<XdmfArray> array);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfArray(XdmfArray &);
+
+protected:
+
+  XdmfArray();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfArray(const XdmfArray &);  // Not implemented.
+  void operator=(const XdmfArray &);  // Not implemented.
+
+  // Variant Visitor Operations
+  class Clear;
+  class Erase;
+  class GetArrayType;
+  class GetCapacity;
+  template <typename T> class GetValue;
+  template <typename T> class GetValues;
+  class GetValuesPointer;
+  class GetValuesString;
+  template <typename T> class Insert;
+  class InsertArray;
+  class InternalizeArrayPointer;
+  class IsInitialized;
+  struct NullDeleter;
+  template <typename T> class PushBack;
+  class Reserve;
+  template <typename T> class Resize;
+  class Size;
+
+  /**
+   * After setValues() is called, XdmfArray stores a pointer that is
+   * not allowed to be modified through the XdmfArray API. If the user
+   * desires to modify the contents of the pointer, they must do so
+   * without calling any non-const functions of XdmfArray. If they do
+   * call non-const functions of XdmfArray, we attempt to accommodate
+   * by copying the array pointer into internal data structures.
+   */
+  void internalizeArrayPointer();
+
+  typedef boost::variant<
+    boost::blank,
+    shared_ptr<std::vector<char> >,
+    shared_ptr<std::vector<short> >,
+    shared_ptr<std::vector<int> >,
+    shared_ptr<std::vector<long> >,
+    shared_ptr<std::vector<float> >,
+    shared_ptr<std::vector<double> >,
+    shared_ptr<std::vector<unsigned char> >,
+    shared_ptr<std::vector<unsigned short> >,
+    shared_ptr<std::vector<unsigned int> >,
+    shared_ptr<std::vector<std::string> >,
+    boost::shared_array<const char>,
+    boost::shared_array<const short>,
+    boost::shared_array<const int>,
+    boost::shared_array<const long>,
+    boost::shared_array<const float>,
+    boost::shared_array<const double>,
+    boost::shared_array<const unsigned char>,
+    boost::shared_array<const unsigned short>,
+    boost::shared_array<const unsigned int>  > ArrayVariant;
+  
+  unsigned int mArrayPointerNumValues;
+  std::vector<unsigned int> mDimensions;
+  std::string mName;
+  unsigned int mTmpReserveSize;
+  ReadMode mReadMode;
+  shared_ptr<XdmfArrayReference> mReference;
+  ArrayVariant mArray;
+};
+
+#include "XdmfArray.tpp"
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XDMF_ARRAY_READ_MODE_CONTROLLER  10
+#define XDMF_ARRAY_READ_MODE_REFERENCE   11
+
+// C wrappers go here
+
+struct XDMFARRAY; // Simply as a typedef to ensure correct typing
+typedef struct XDMFARRAY XDMFARRAY;
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfArrayNew();
+
+XDMFCORE_EXPORT void XdmfArrayClear(XDMFARRAY * array);
+
+XDMFCORE_EXPORT void XdmfArrayErase(XDMFARRAY * array, unsigned int index);
+
+XDMFCORE_EXPORT int XdmfArrayGetArrayType(XDMFARRAY * array, int * status);
+
+XDMFCORE_EXPORT unsigned int XdmfArrayGetCapacity(XDMFARRAY * array);
+
+XDMFCORE_EXPORT unsigned int * XdmfArrayGetDimensions(XDMFARRAY * array);
+
+XDMFCORE_EXPORT char * XdmfArrayGetDimensionsString(XDMFARRAY * array);
+
+XDMFCORE_EXPORT XDMFHEAVYDATACONTROLLER * XdmfArrayGetHeavyDataController(XDMFARRAY * array, unsigned int index);
+
+XDMFCORE_EXPORT int XdmfArrayGetReadMode(XDMFARRAY * array, int * status);
+
+XDMFCORE_EXPORT char * XdmfArrayGetName(XDMFARRAY * array);
+
+XDMFCORE_EXPORT unsigned int XdmfArrayGetNumberDimensions(XDMFARRAY * array);
+
+XDMFCORE_EXPORT unsigned int XdmfArrayGetNumberHeavyDataControllers(XDMFARRAY * array);
+
+XDMFCORE_EXPORT unsigned int XdmfArrayGetSize(XDMFARRAY * array);
+
+XDMFCORE_EXPORT XDMFARRAYREFERENCE * XdmfArrayGetReference(XDMFARRAY * array);
+
+XDMFCORE_EXPORT void * XdmfArrayGetValue(XDMFARRAY * array, unsigned int index, int arrayType, int * status);
+
+XDMFCORE_EXPORT void * XdmfArrayGetValues(XDMFARRAY * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status);
+
+XDMFCORE_EXPORT void * XdmfArrayGetValuesInternal(XDMFARRAY * array);
+
+XDMFCORE_EXPORT char * XdmfArrayGetValuesString(XDMFARRAY * array);
+
+XDMFCORE_EXPORT void XdmfArrayInitialize(XDMFARRAY * array, int * dims, int numDims, int arrayType, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayInsertDataFromPointer(XDMFARRAY * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayInsertDataFromXdmfArray(XDMFARRAY * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayInsertHeavyDataController(XDMFARRAY * array, XDMFHEAVYDATACONTROLLER * controller, int passControl);
+
+XDMFCORE_EXPORT void XdmfArrayInsertValue(XDMFARRAY * array, unsigned int index, void * value, int arrayType, int * status);
+
+XDMFCORE_EXPORT int XdmfArrayIsInitialized(XDMFARRAY * array);
+
+XDMFCORE_EXPORT void XdmfArrayPushBack(XDMFARRAY * array, void * value, int arrayType, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayRead(XDMFARRAY * array, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayReadController(XDMFARRAY * array, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayReadReference(XDMFARRAY * array, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayRelease(XDMFARRAY * array);
+
+XDMFCORE_EXPORT void XdmfArrayRemoveHeavyDataController(XDMFARRAY * array, unsigned int index);
+
+XDMFCORE_EXPORT void XdmfArrayReserve(XDMFARRAY * array, int size);
+
+XDMFCORE_EXPORT void XdmfArrayResize(XDMFARRAY * array, int * dims, int numDims, int arrayType, int * status);
+
+XDMFCORE_EXPORT void XdmfArraySetReadMode(XDMFARRAY * array, int readMode, int * status);
+
+XDMFCORE_EXPORT void XdmfArraySetReference(XDMFARRAY * array, XDMFARRAYREFERENCE * reference, int passControl);
+
+XDMFCORE_EXPORT void XdmfArraySetName(XDMFARRAY * array, char * name, int * status);
+
+XDMFCORE_EXPORT void XdmfArraySetValuesInternal(XDMFARRAY * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status);
+
+XDMFCORE_EXPORT void XdmfArraySwapWithXdmfArray(XDMFARRAY * array, XDMFARRAY * swapArray);
+
+XDMFCORE_EXPORT void XdmfArraySwapWithArray(XDMFARRAY * array, void ** pointer, int numValues, int arrayType, int * status);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfArray, XDMFARRAY, XDMFCORE)
+
+
+#define XDMF_ARRAY_C_CHILD_DECLARE(ClassName, CClassName, Level)                                                     \
+                                                                                                                     \
+Level##_EXPORT void ClassName##Clear( CClassName * array);                                                           \
+Level##_EXPORT void ClassName##Erase( CClassName * array, unsigned int index);                                       \
+Level##_EXPORT int ClassName##GetArrayType( CClassName * array, int * status);                                       \
+Level##_EXPORT unsigned int ClassName##GetCapacity( CClassName * array);                                             \
+Level##_EXPORT unsigned int * ClassName##GetDimensions( CClassName * array);                                         \
+Level##_EXPORT char * ClassName##GetDimensionsString( CClassName * array);                                           \
+Level##_EXPORT XDMFHEAVYDATACONTROLLER * ClassName##GetHeavyDataController( CClassName * array, unsigned int index); \
+Level##_EXPORT int ClassName##GetReadMode( CClassName * array, int * status);                                        \
+Level##_EXPORT char * ClassName##GetName( CClassName * array);                                                       \
+Level##_EXPORT unsigned int ClassName##GetNumberDimensions( CClassName * array);                                     \
+Level##_EXPORT unsigned int ClassName##GetNumberHeavyDataControllers( CClassName * array);                           \
+Level##_EXPORT unsigned int ClassName##GetSize( CClassName * array);                                                 \
+Level##_EXPORT XDMFARRAYREFERENCE * ClassName##GetReference( CClassName * array);                                    \
+Level##_EXPORT void * ClassName##GetValue( CClassName * array,                                                       \
+                                           unsigned int index,                                                       \
+                                           int arrayType,                                                            \
+                                           int * status);                                                            \
+Level##_EXPORT void * ClassName##GetValues( CClassName * array,                                                      \
+                                            unsigned int startIndex,                                                 \
+                                            int arrayType,                                                           \
+                                            unsigned int numValues,                                                  \
+                                            unsigned int arrayStride,                                                \
+                                            unsigned int valueStride,                                                \
+                                            int * status);                                                           \
+Level##_EXPORT void * ClassName##GetValuesInternal( CClassName * array);                                             \
+Level##_EXPORT char * ClassName##GetValuesString( CClassName * array);                                               \
+Level##_EXPORT void ClassName##Initialize( CClassName * array,                                                       \
+                                           int * dims,                                                               \
+                                           int numDims,                                                              \
+                                           int arrayType,                                                            \
+                                           int * status);                                                            \
+Level##_EXPORT void ClassName##InsertDataFromPointer( CClassName * array,                                            \
+                                                      void * values,                                                 \
+                                                      int arrayType,                                                 \
+                                                      unsigned int startIndex,                                       \
+                                                      unsigned int numVals,                                          \
+                                                      unsigned int arrayStride,                                      \
+                                                      unsigned int valueStride,                                      \
+                                                      int * status);                                                 \
+Level##_EXPORT void ClassName##InsertDataFromXdmfArray( CClassName * array,                                          \
+                                                        XDMFARRAY * valArray,                                        \
+                                                        int * arrayStarts,                                           \
+                                                        int * valueStarts,                                           \
+                                                        int * arrayCounts,                                           \
+                                                        int * valueCounts,                                           \
+                                                        int * arrayStrides,                                          \
+                                                        int * valueStrides,                                          \
+                                                        int * status);                                               \
+Level##_EXPORT void ClassName##InsertHeavyDataController( CClassName * array,                                        \
+                                                          XDMFHEAVYDATACONTROLLER * controller,                      \
+                                                         int passControl);                                           \
+Level##_EXPORT void ClassName##InsertValue( CClassName * array,                                                      \
+                                            unsigned int index,                                                      \
+                                            void * value,                                                            \
+                                            int arrayType,                                                           \
+                                            int * status);                                                           \
+Level##_EXPORT int ClassName##IsInitialized( CClassName * array);                                                    \
+Level##_EXPORT void ClassName##PushBack( CClassName * array,                                                         \
+                                         void * value,                                                               \
+                                         int arrayType,                                                              \
+                                         int * status);                                                              \
+Level##_EXPORT void ClassName##Read( CClassName * array, int * status);                                              \
+Level##_EXPORT void ClassName##ReadController( CClassName * array, int * status);                                    \
+Level##_EXPORT void ClassName##ReadReference( CClassName * array, int * status);                                     \
+Level##_EXPORT void ClassName##Release( CClassName * array);                                                         \
+Level##_EXPORT void ClassName##RemoveHeavyDataController( CClassName * array, unsigned int index);                   \
+Level##_EXPORT void ClassName##Reserve( CClassName * array, int size);                                               \
+Level##_EXPORT void ClassName##Resize( CClassName * array,                                                           \
+                                       int * dims,                                                                   \
+                                       int numDims,                                                                  \
+                                       int arrayType,                                                                \
+                                       int * status);                                                                \
+Level##_EXPORT void ClassName##SetReadMode( CClassName * array, int readMode, int * status);                         \
+Level##_EXPORT void ClassName##SetReference( CClassName * array, XDMFARRAYREFERENCE * reference, int passControl);   \
+Level##_EXPORT void ClassName##SetName( CClassName * array, char * name, int * status);                              \
+Level##_EXPORT void ClassName##SetValuesInternal( CClassName * array,                                                \
+                                                  void * pointer,                                                    \
+                                                  unsigned int numValues,                                            \
+                                                  int arrayType,                                                     \
+                                                  int transferOwnership,                                             \
+                                                  int * status);                                                     \
+Level##_EXPORT void ClassName##SwapWithXdmfArray( CClassName * array, XDMFARRAY * swapArray);                        \
+Level##_EXPORT void ClassName##SwapWithArray( CClassName * array,                                                    \
+                                              void ** pointer,                                                       \
+                                              int numValues,                                                         \
+                                              int arrayType,                                                         \
+                                              int * status);
+
+
+#define XDMF_ARRAY_C_CHILD_WRAPPER(ClassName, CClassName)                                                            \
+                                                                                                                     \
+void ClassName##Clear( CClassName * array)                                                                           \
+{                                                                                                                    \
+  XdmfArrayClear((XDMFARRAY *)((void *)array));                                                                      \
+}                                                                                                                    \
+                                                                                                                     \
+void ClassName##Erase( CClassName * array, unsigned int index)                                                       \
+{                                                                                                                    \
+  XdmfArrayErase((XDMFARRAY *)((void *)array), index);                                                               \
+}                                                                                                                    \
+                                                                                                                     \
+int ClassName##GetArrayType( CClassName * array, int * status)                                                       \
+{                                                                                                                    \
+  return XdmfArrayGetArrayType((XDMFARRAY *)((void *)array), status);                                                \
+}                                                                                                                    \
+                                                                                                                     \
+unsigned int ClassName##GetCapacity( CClassName * array)                                                             \
+{                                                                                                                    \
+  return XdmfArrayGetCapacity((XDMFARRAY *)((void *)array));                                                         \
+}                                                                                                                    \
+                                                                                                                     \
+unsigned int *                                                                                                       \
+ClassName##GetDimensions( CClassName * array)                                                                        \
+{                                                                                                                    \
+  return XdmfArrayGetDimensions((XDMFARRAY *)((void *)array));                                                       \
+}                                                                                                                    \
+                                                                                                                     \
+char *                                                                                                               \
+ClassName##GetDimensionsString( CClassName * array)                                                                  \
+{                                                                                                                    \
+  return XdmfArrayGetDimensionsString((XDMFARRAY *)((void *)array));                                                 \
+}                                                                                                                    \
+                                                                                                                     \
+XDMFHEAVYDATACONTROLLER *                                                                                            \
+ClassName##GetHeavyDataController( CClassName * array, unsigned int index)                                           \
+{                                                                                                                    \
+  return XdmfArrayGetHeavyDataController((XDMFARRAY *)((void *)array), index);                                       \
+}                                                                                                                    \
+                                                                                                                     \
+char *                                                                                                               \
+ClassName##GetName( CClassName * array)                                                                              \
+{                                                                                                                    \
+  return XdmfArrayGetName((XDMFARRAY *)((void *)array));                                                             \
+}                                                                                                                    \
+                                                                                                                     \
+unsigned int                                                                                                         \
+ClassName##GetNumberDimensions( CClassName * array)                                                                  \
+{                                                                                                                    \
+  return XdmfArrayGetNumberDimensions((XDMFARRAY *)((void *)array));                                                 \
+}                                                                                                                    \
+                                                                                                                     \
+unsigned int                                                                                                         \
+ClassName##GetNumberHeavyDataControllers( CClassName * array)                                                        \
+{                                                                                                                    \
+  return XdmfArrayGetNumberHeavyDataControllers((XDMFARRAY *)((void *)array));                                       \
+}                                                                                                                    \
+                                                                                                                     \
+unsigned int                                                                                                         \
+ClassName##GetSize( CClassName * array)                                                                              \
+{                                                                                                                    \
+  return XdmfArrayGetSize((XDMFARRAY *)((void *)array));                                                             \
+}                                                                                                                    \
+                                                                                                                     \
+int                                                                                                                  \
+ClassName##GetReadMode( CClassName * array, int * status)                                                            \
+{                                                                                                                    \
+  return XdmfArrayGetReadMode((XDMFARRAY *)((void *)array), status);                                                 \
+}                                                                                                                    \
+                                                                                                                     \
+XDMFARRAYREFERENCE *                                                                                                 \
+ClassName##GetReference( CClassName * array)                                                                         \
+{                                                                                                                    \
+  return XdmfArrayGetReference((XDMFARRAY *)((void *)array));                                                        \
+}                                                                                                                    \
+                                                                                                                     \
+void *                                                                                                               \
+ClassName##GetValue( CClassName * array, unsigned int index, int arrayType, int * status)                            \
+{                                                                                                                    \
+  return XdmfArrayGetValue((XDMFARRAY *)((void *)array), index, arrayType, status);                                  \
+}                                                                                                                    \
+                                                                                                                     \
+void *                                                                                                               \
+ClassName##GetValues( CClassName * array,                                                                            \
+                      unsigned int startIndex,                                                                       \
+                      int arrayType,                                                                                 \
+                      unsigned int numValues,                                                                        \
+                      unsigned int arrayStride,                                                                      \
+                      unsigned int valueStride,                                                                      \
+                      int * status)                                                                                  \
+{                                                                                                                    \
+  return  XdmfArrayGetValues((XDMFARRAY *)((void *)array),                                                           \
+                             startIndex,                                                                             \
+                             arrayType,                                                                              \
+                             numValues,                                                                              \
+                             arrayStride,                                                                            \
+                             valueStride,                                                                            \
+                             status);                                                                                \
+}                                                                                                                    \
+                                                                                                                     \
+void *                                                                                                               \
+ClassName##GetValuesInternal( CClassName * array)                                                                    \
+{                                                                                                                    \
+  return XdmfArrayGetValuesInternal((XDMFARRAY *)((void *)array));                                                   \
+}                                                                                                                    \
+                                                                                                                     \
+char *                                                                                                               \
+ClassName##GetValuesString( CClassName * array)                                                                      \
+{                                                                                                                    \
+  return XdmfArrayGetValuesString((XDMFARRAY *)((void *)array));                                                     \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##Initialize( CClassName * array, int * dims, int numDims, int arrayType, int * status)                     \
+{                                                                                                                    \
+  XdmfArrayInitialize((XDMFARRAY *)((void *)array), dims, numDims, arrayType, status);                               \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##InsertDataFromPointer( CClassName * array,                                                                \
+                                  void * values,                                                                     \
+                                  int arrayType,                                                                     \
+                                  unsigned int startIndex,                                                           \
+                                  unsigned int numVals,                                                              \
+                                  unsigned int arrayStride,                                                          \
+                                  unsigned int valueStride,                                                          \
+                                  int * status)                                                                      \
+{                                                                                                                    \
+  XdmfArrayInsertDataFromPointer((XDMFARRAY *)((void *)array),                                                       \
+                                 values,                                                                             \
+                                 arrayType,                                                                          \
+                                 startIndex,                                                                         \
+                                 numVals,                                                                            \
+                                 arrayStride,                                                                        \
+                                 valueStride,                                                                        \
+                                 status);                                                                            \
+}                                                                                                                    \
+                                                                                                                     \
+void ClassName##InsertDataFromXdmfArray( CClassName * array,                                                         \
+                                         XDMFARRAY * valArray,                                                       \
+                                         int * arrayStarts,                                                          \
+                                         int * valueStarts,                                                          \
+                                         int * arrayCounts,                                                          \
+                                         int * valueCounts,                                                          \
+                                         int * arrayStrides,                                                         \
+                                         int * valueStrides,                                                         \
+                                         int * status)                                                               \
+{                                                                                                                    \
+  XdmfArrayInsertDataFromXdmfArray((XDMFARRAY *)((void *)array),                                                     \
+                                   valArray,                                                                         \
+                                   arrayStarts,                                                                      \
+                                   valueStarts,                                                                      \
+                                   arrayCounts,                                                                      \
+                                   valueCounts,                                                                      \
+                                   arrayStrides,                                                                     \
+                                   valueStrides,                                                                     \
+                                   status);                                                                          \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##InsertHeavyDataController( CClassName * array, XDMFHEAVYDATACONTROLLER * controller, int passControl)     \
+{                                                                                                                    \
+  XdmfArrayInsertHeavyDataController((XDMFARRAY *)((void *)array), controller, passControl);                         \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##InsertValue( CClassName * array,                                                                          \
+                        unsigned int index,                                                                          \
+                        void * value,                                                                                \
+                        int arrayType,                                                                               \
+                        int * status)                                                                                \
+{                                                                                                                    \
+  XdmfArrayInsertValue((XDMFARRAY *)((void *)array), index, value, arrayType, status);                               \
+}                                                                                                                    \
+                                                                                                                     \
+int                                                                                                                  \
+ClassName##IsInitialized( CClassName * array)                                                                        \
+{                                                                                                                    \
+  return XdmfArrayIsInitialized((XDMFARRAY *)((void *)array));                                                       \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##PushBack( CClassName * array, void * value, int arrayType, int * status)                                  \
+{                                                                                                                    \
+  XdmfArrayPushBack((XDMFARRAY *)((void *)array), value, arrayType, status);                                         \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##Read( CClassName * array, int * status)                                                                   \
+{                                                                                                                    \
+  XdmfArrayRead((XDMFARRAY *)((void *)array), status);                                                               \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##ReadController( CClassName * array, int * status)                                                         \
+{                                                                                                                    \
+  XdmfArrayReadController((XDMFARRAY *)((void *)array), status);                                                     \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##ReadReference( CClassName * array, int * status)                                                          \
+{                                                                                                                    \
+  XdmfArrayReadReference((XDMFARRAY *)((void *)array), status);                                                      \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##Release( CClassName * array)                                                                              \
+{                                                                                                                    \
+  XdmfArrayRelease((XDMFARRAY *)((void *)array));                                                                    \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##RemoveHeavyDataController( CClassName * array, unsigned int index)                                        \
+{                                                                                                                    \
+  XdmfArrayRemoveHeavyDataController((XDMFARRAY *)((void *)array), index);                                           \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##Reserve( CClassName * array, int size)                                                                    \
+{                                                                                                                    \
+  XdmfArrayReserve((XDMFARRAY *)((void *)array), size);                                                              \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##Resize( CClassName * array, int * dims, int numDims, int arrayType, int * status)                         \
+{                                                                                                                    \
+  XdmfArrayResize((XDMFARRAY *)((void *)array), dims, numDims, arrayType, status);                                   \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##SetReadMode( CClassName * array, int readMode, int * status)                                              \
+{                                                                                                                    \
+  XdmfArraySetReadMode((XDMFARRAY *)((void *)array), readMode, status);                                              \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##SetReference( CClassName * array, XDMFARRAYREFERENCE * reference, int passControl)                        \
+{                                                                                                                    \
+  XdmfArraySetReference((XDMFARRAY *)((void *)array), reference, passControl);                                       \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##SetName( CClassName * array, char * name, int * status)                                                   \
+{                                                                                                                    \
+  XdmfArraySetName((XDMFARRAY *)((void *)array), name, status);                                                      \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##SetValuesInternal( CClassName * array,                                                                    \
+                              void * pointer,                                                                        \
+                              unsigned int numValues,                                                                \
+                              int arrayType,                                                                         \
+                              int transferOwnership,                                                                 \
+                              int * status)                                                                          \
+{                                                                                                                    \
+  XdmfArraySetValuesInternal((XDMFARRAY *)((void *)array),                                                           \
+                             pointer,                                                                                \
+                             numValues,                                                                              \
+                             arrayType,                                                                              \
+                             transferOwnership,                                                                      \
+                             status);                                                                                \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##SwapWithXdmfArray( CClassName * array, XDMFARRAY * swapArray)                                             \
+{                                                                                                                    \
+  XdmfArraySwapWithXdmfArray((XDMFARRAY *)((void *)array), swapArray);                                               \
+}                                                                                                                    \
+                                                                                                                     \
+void                                                                                                                 \
+ClassName##SwapWithArray( CClassName * array,                                                                        \
+                          void ** pointer,                                                                           \
+                          int numValues,                                                                             \
+                          int arrayType,                                                                             \
+                          int * status)                                                                              \
+{                                                                                                                    \
+  XdmfArraySwapWithArray((XDMFARRAY *)((void *)array), pointer, numValues, arrayType, status);                       \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFARRAY_HPP_ */
diff --git a/core/XdmfArray.tpp b/core/XdmfArray.tpp
new file mode 100644
index 0000000..e217986
--- /dev/null
+++ b/core/XdmfArray.tpp
@@ -0,0 +1,812 @@
+/*****************************************************************************/
+/*                                    Xdmf                                   */
+/*                       Extensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfArray.tpp                                                       */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <functional>
+#include <numeric>
+#include <sstream>
+#include "XdmfArray.hpp"
+
+template <typename T>
+class XdmfArray::GetValue : public boost::static_visitor<T> {
+public:
+
+  GetValue(const unsigned int index) :
+    mIndex(index)
+  {
+  }
+
+  T
+  operator()(const boost::blank &) const
+  {
+    return 0;
+  }
+
+  T
+  operator()(const shared_ptr<std::vector<std::string> > & array) const
+  {
+    return (T)atof(array->operator[](mIndex).c_str());
+  }
+
+  template<typename U>
+  T
+  operator()(const shared_ptr<std::vector<U> > & array) const
+  {
+    return (T)array->operator[](mIndex);
+  }
+
+  template<typename U>
+  T
+  operator()(const boost::shared_array<const U> & array) const
+  {
+    return (T)array[mIndex];
+  }
+
+private:
+
+  const unsigned int mIndex;
+};
+
+template <>
+class XdmfArray::GetValue<std::string> :
+  public boost::static_visitor<std::string> {
+public:
+
+  GetValue(const unsigned int index) :
+    mIndex(index)
+  {
+  }
+
+  std::string
+  operator()(const boost::blank &) const
+  {
+    return "";
+  }
+
+  std::string
+  operator()(const shared_ptr<std::vector<std::string> > & array) const
+  {
+    return array->operator[](mIndex);
+  }
+
+  template<typename U>
+  std::string
+  operator()(const shared_ptr<std::vector<U> > & array) const
+  {
+    std::stringstream value;
+    value << array->operator[](mIndex);
+    return value.str();
+  }
+
+  std::string
+  operator()(const boost::shared_array<const std::string> & array) const
+  {
+    return array[mIndex];
+  }
+
+  template<typename U>
+  std::string
+  operator()(const boost::shared_array<const U> & array) const
+  {
+    std::stringstream value;
+    value << array[mIndex];
+    return value.str();
+  }
+
+private:
+
+  const unsigned int mIndex;
+};
+
+template <typename T>
+class XdmfArray::GetValues : public boost::static_visitor<void> {
+public:
+
+  GetValues(const unsigned int startIndex,
+            T * valuesPointer,
+            const unsigned int numValues,
+            const unsigned int arrayStride,
+            const unsigned int valuesStride) :
+    mStartIndex(startIndex),
+    mValuesPointer(valuesPointer),
+    mNumValues(numValues),
+    mArrayStride(arrayStride),
+    mValuesStride(valuesStride)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    return;
+  }
+
+  void
+  operator()(const shared_ptr<std::vector<std::string> > & array) const
+  {
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      mValuesPointer[i*mValuesStride] =
+        (T)atof(array->operator[](mStartIndex + i*mArrayStride).c_str());
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(const shared_ptr<std::vector<U> > & array) const
+  {
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      mValuesPointer[i*mValuesStride] =
+        (T)array->operator[](mStartIndex + i*mArrayStride);
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(const boost::shared_array<const U> & array) const
+  {
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      mValuesPointer[i*mValuesStride] = (T)array[mStartIndex + i*mArrayStride];
+    }
+  }
+
+private:
+
+  const unsigned int mStartIndex;
+  T * mValuesPointer;
+  const unsigned int mNumValues;
+  const unsigned int mArrayStride;
+  const unsigned int mValuesStride;
+};
+
+template <>
+class XdmfArray::GetValues<std::string> : public boost::static_visitor<void> {
+public:
+
+  GetValues(const unsigned int startIndex,
+            std::string * valuesPointer,
+            const unsigned int numValues,
+            const unsigned int arrayStride,
+            const unsigned int valuesStride) :
+    mStartIndex(startIndex),
+    mValuesPointer(valuesPointer),
+    mNumValues(numValues),
+    mArrayStride(arrayStride),
+    mValuesStride(valuesStride)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    return;
+  }
+
+  template<typename U>
+  void
+  operator()(const shared_ptr<std::vector<U> > & array) const
+  {
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      std::stringstream value;
+      value << array->operator[](mStartIndex + i*mArrayStride);
+      mValuesPointer[i*mValuesStride] = value.str();
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(const boost::shared_array<const U> & array) const
+  {
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      std::stringstream value;
+      value << array[mStartIndex + i*mArrayStride];
+      mValuesPointer[i*mValuesStride] = value.str();
+    }
+  }
+
+private:
+
+  const unsigned int mStartIndex;
+  std::string * mValuesPointer;
+  const unsigned int mNumValues;
+  const unsigned int mArrayStride;
+  const unsigned int mValuesStride;
+};
+
+template <typename T>
+class XdmfArray::Insert : public boost::static_visitor<void> {
+public:
+
+  Insert(XdmfArray * const array,
+         const unsigned int startIndex,
+         const T * const valuesPointer,
+         const unsigned int numValues,
+         const unsigned int arrayStride,
+         const unsigned int valuesStride,
+         std::vector<unsigned int> & dimensions) :
+    mArray(array),
+    mStartIndex(startIndex),
+    mValuesPointer(valuesPointer),
+    mNumValues(numValues),
+    mArrayStride(arrayStride),
+    mValuesStride(valuesStride),
+    mDimensions(dimensions)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    mArray->initialize<T>();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  void
+  operator()(shared_ptr<std::vector<std::string> > & array) const
+  {
+    unsigned int size = mStartIndex + (mNumValues - 1) * mArrayStride + 1;
+    if(array->size() < size) {
+      array->resize(size);
+      mDimensions.clear();
+    }
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      std::stringstream value;
+      value << mValuesPointer[i*mValuesStride];
+      array->operator[](mStartIndex + i*mArrayStride) = value.str();
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(shared_ptr<std::vector<U> > & array) const
+  {
+    unsigned int size = mStartIndex + (mNumValues - 1) * mArrayStride + 1;
+    if(array->size() < size) {
+      array->resize(size);
+      mDimensions.clear();
+    }
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      array->operator[](mStartIndex + i*mArrayStride) =
+        (U)mValuesPointer[i*mValuesStride];
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(boost::shared_array<const U> &) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * const mArray;
+  const unsigned int mStartIndex;
+  const T * const mValuesPointer;
+  const unsigned int mNumValues;
+  const unsigned int mArrayStride;
+  const unsigned int mValuesStride;
+  std::vector<unsigned int> & mDimensions;
+};
+
+template <>
+class XdmfArray::Insert<std::string> : public boost::static_visitor<void> {
+public:
+
+  Insert(XdmfArray * const array,
+         const unsigned int startIndex,
+         const std::string * const valuesPointer,
+         const unsigned int numValues,
+         const unsigned int arrayStride,
+         const unsigned int valuesStride,
+         std::vector<unsigned int> & dimensions) :
+    mArray(array),
+    mStartIndex(startIndex),
+    mValuesPointer(valuesPointer),
+    mNumValues(numValues),
+    mArrayStride(arrayStride),
+    mValuesStride(valuesStride),
+    mDimensions(dimensions)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    mArray->initialize<std::string>();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  void
+  operator()(shared_ptr<std::vector<std::string> > & array) const
+  {
+    unsigned int size = mStartIndex + (mNumValues - 1) * mArrayStride + 1;
+    if(array->size() < size) {
+      array->resize(size);
+      mDimensions.clear();
+    }
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      array->operator[](mStartIndex + i*mArrayStride) =
+        mValuesPointer[i*mValuesStride].c_str();
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(shared_ptr<std::vector<U> > & array) const
+  {
+    unsigned int size = mStartIndex + (mNumValues - 1) * mArrayStride + 1;
+    if(array->size() < size) {
+      array->resize(size);
+      mDimensions.clear();
+    }
+    for(unsigned int i=0; i<mNumValues; ++i) {
+      array->operator[](mStartIndex + i*mArrayStride) =
+        (U)atof(mValuesPointer[i*mValuesStride].c_str());
+    }
+  }
+
+  template<typename U>
+  void
+  operator()(boost::shared_array<const U> &) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * const mArray;
+  const unsigned int mStartIndex;
+  const std::string * const mValuesPointer;
+  const unsigned int mNumValues;
+  const unsigned int mArrayStride;
+  const unsigned int mValuesStride;
+  std::vector<unsigned int> & mDimensions;
+};
+
+template <typename T>
+class XdmfArray::PushBack : public boost::static_visitor<void> {
+public:
+
+  PushBack(const T & val,
+           XdmfArray * const array) :
+    mVal(val),
+    mArray(array)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    mArray->initialize<T>();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  void
+  operator()(shared_ptr<std::vector<std::string> > & array) const
+  {
+    std::stringstream value;
+    value << mVal;
+    array->push_back(value.str());
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(shared_ptr<std::vector<U> > & array) const
+  {
+    array->push_back((U)mVal);
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(const boost::shared_array<const U> &) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  const T & mVal;
+  XdmfArray * const mArray;
+};
+
+template <>
+class XdmfArray::PushBack<std::string> : public boost::static_visitor<void> {
+public:
+
+  PushBack(const std::string & val,
+           XdmfArray * const array) :
+    mVal(val),
+    mArray(array)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    mArray->initialize<std::string>();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  void
+  operator()(shared_ptr<std::vector<std::string> > & array) const
+  {
+    array->push_back(mVal);
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(shared_ptr<std::vector<U> > & array) const
+  {
+    array->push_back((U)atof(mVal.c_str()));
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(const boost::shared_array<const U> &) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  const std::string & mVal;
+  XdmfArray * const mArray;
+};
+
+template <typename T>
+class XdmfArray::Resize : public boost::static_visitor<void> {
+public:
+
+  Resize(XdmfArray * const array,
+         const unsigned int numValues,
+         const T & val) :
+    mArray(array),
+    mNumValues(numValues),
+    mVal(val)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    mArray->initialize<T>();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  void
+  operator()(shared_ptr<std::vector<std::string> > & array) const
+  {
+    std::stringstream value;
+    value << mVal;
+    array->resize(mNumValues, value.str());
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(shared_ptr<std::vector<U> > & array) const
+  {
+    array->resize(mNumValues, (U)mVal);
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(const boost::shared_array<const U> &) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * mArray;
+  const unsigned int mNumValues;
+  const T & mVal;
+};
+
+template <>
+class XdmfArray::Resize<std::string> : public boost::static_visitor<void> {
+public:
+
+  Resize(XdmfArray * const array,
+         const unsigned int numValues,
+         const std::string & val) :
+    mArray(array),
+    mNumValues(numValues),
+    mVal(val)
+  {
+  }
+
+  void
+  operator()(const boost::blank &) const
+  {
+    mArray->initialize<std::string>();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+  void
+  operator()(shared_ptr<std::vector<std::string> > & array) const
+  {
+    array->resize(mNumValues, mVal);
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(shared_ptr<std::vector<U> > & array) const
+  {
+    array->resize(mNumValues, (U)atof(mVal.c_str()));
+    mArray->mDimensions.clear();
+  }
+
+  template<typename U>
+  void
+  operator()(const boost::shared_array<const U> &) const
+  {
+    mArray->internalizeArrayPointer();
+    boost::apply_visitor(*this,
+                         mArray->mArray);
+  }
+
+private:
+
+  XdmfArray * mArray;
+  const unsigned int mNumValues;
+  const std::string & mVal;
+};
+
+struct XdmfArray::NullDeleter
+{
+  void
+  operator()(void const *) const
+  {
+  }
+};
+
+template <typename T>
+T
+XdmfArray::getValue(const unsigned int index) const
+{
+  return boost::apply_visitor(GetValue<T>(index),
+                              mArray);
+}
+
+template <typename T>
+void
+XdmfArray::getValues(const unsigned int startIndex,
+                     T * const valuesPointer,
+                     const unsigned int numValues,
+                     const unsigned int arrayStride,
+                     const unsigned int valuesStride) const
+{
+  boost::apply_visitor(GetValues<T>(startIndex,
+                                    valuesPointer,
+                                    numValues,
+                                    arrayStride,
+                                    valuesStride),
+                       mArray);
+}
+
+template <typename T>
+shared_ptr<std::vector<T> >
+XdmfArray::getValuesInternal()
+{
+  this->internalizeArrayPointer();
+  try {
+    shared_ptr<std::vector<T> > currArray =
+      boost::get<shared_ptr<std::vector<T> > >(mArray);
+    return currArray;
+  }
+  catch(const boost::bad_get & exception) {
+    return shared_ptr<std::vector<T> >();
+  }
+}
+
+template <typename T>
+shared_ptr<std::vector<T> >
+XdmfArray::initialize(const unsigned int size)
+{
+  // Set type of variant to type of pointer
+  shared_ptr<std::vector<T> > newArray(new std::vector<T>(size));
+  if(mTmpReserveSize > 0) {
+    newArray->reserve(mTmpReserveSize);
+    mTmpReserveSize = 0;
+  }
+  mArray = newArray;
+  this->setIsChanged(true);
+  return newArray;
+}
+
+template <typename T>
+shared_ptr<std::vector<T> >
+XdmfArray::initialize(const std::vector<unsigned int> & dimensions)
+{
+  mDimensions = dimensions;
+  const unsigned int size = static_cast<unsigned int>(
+    std::accumulate(dimensions.begin(),
+                                            dimensions.end(),
+                                            1,
+                    std::multiplies<unsigned int>()));
+  return this->initialize<T>(size);
+}
+
+template<typename T>
+void
+XdmfArray::insert(const unsigned int index,
+                  const T & value)
+{
+  boost::apply_visitor(Insert<T>(this,
+                                 index,
+                                 &value,
+                                 1,
+                                 0,
+                                 0,
+                                 mDimensions),
+                       mArray);
+}
+
+template <typename T>
+void
+XdmfArray::insert(const unsigned int startIndex,
+                  const T * const valuesPointer,
+                  const unsigned int numValues,
+                  const unsigned int arrayStride,
+                  const unsigned int valuesStride)
+{
+  boost::apply_visitor(Insert<T>(this,
+                                 startIndex,
+                                 valuesPointer,
+                                 numValues,
+                                 arrayStride,
+                                 valuesStride,
+                                 mDimensions),
+                       mArray);
+  this->setIsChanged(true);
+}
+
+template <typename T>
+void
+XdmfArray::pushBack(const T & value)
+{
+  return boost::apply_visitor(PushBack<T>(value,
+                                          this),
+                              mArray);
+  this->setIsChanged(true);
+}
+
+template<typename T>
+void
+XdmfArray::resize(const unsigned int numValues,
+                  const T & value)
+{
+  return boost::apply_visitor(Resize<T>(this,
+                                        numValues,
+                                        value),
+                              mArray);
+  this->setIsChanged(true);
+}
+
+template<typename T>
+void
+XdmfArray::resize(const std::vector<unsigned int> & dimensions,
+                  const T & value)
+{
+  const unsigned int size = static_cast<unsigned int>(
+    std::accumulate(dimensions.begin(),
+                                            dimensions.end(),
+                                            1,
+                    std::multiplies<unsigned int>()));
+  this->resize(size, value);
+  mDimensions = dimensions;
+  this->setIsChanged(true);
+}
+
+template <typename T>
+void
+XdmfArray::setValuesInternal(const T * const arrayPointer,
+                             const unsigned int numValues,
+                             const bool transferOwnership)
+{
+  // Remove contents of internal array.
+  if(transferOwnership) {
+    const boost::shared_array<const T> newArrayPointer(arrayPointer);
+    mArray = newArrayPointer;
+  }
+  else {
+    const boost::shared_array<const T> newArrayPointer(arrayPointer,
+                                                       NullDeleter());
+    mArray = newArrayPointer;
+  }
+  mArrayPointerNumValues = numValues;
+  this->setIsChanged(true);
+}
+
+template <typename T>
+void
+XdmfArray::setValuesInternal(std::vector<T> & array,
+                             const bool transferOwnership)
+{
+  if(transferOwnership) {
+    shared_ptr<std::vector<T> > newArray(&array);
+    mArray = newArray;
+  }
+  else {
+    shared_ptr<std::vector<T> > newArray(&array, NullDeleter());
+    mArray = newArray;
+  }
+  this->setIsChanged(true);
+}
+
+template <typename T>
+void
+XdmfArray::setValuesInternal(const shared_ptr<std::vector<T> > array)
+{
+  mArray = array;
+  this->setIsChanged(true);
+}
+
+template <typename T>
+bool
+XdmfArray::swap(std::vector<T> & array)
+{
+  this->internalizeArrayPointer();
+  if(!this->isInitialized()) {
+    this->initialize<T>();
+  }
+  try {
+    shared_ptr<std::vector<T> > currArray =
+      boost::get<shared_ptr<std::vector<T> > >(mArray);
+    currArray->swap(array);
+    return true;
+  }
+  catch(const boost::bad_get & exception) {
+    return false;
+  }
+  this->setIsChanged(true);
+}
+
+template <typename T>
+bool
+XdmfArray::swap(const shared_ptr<std::vector<T> > array)
+{
+  return this->swap(*array.get());
+}
diff --git a/core/XdmfArrayReference.cpp b/core/XdmfArrayReference.cpp
new file mode 100644
index 0000000..7b27774
--- /dev/null
+++ b/core/XdmfArrayReference.cpp
@@ -0,0 +1,156 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfFunction.cpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfArrayReference.hpp"
+#include <stack>
+#include <math.h>
+#include <boost/assign.hpp>
+#include "XdmfError.hpp"
+
+XdmfArrayReference::XdmfArrayReference():
+  mConstructedType("")
+{
+}
+
+XdmfArrayReference::XdmfArrayReference(XdmfArrayReference & refReference) :
+  XdmfItem(refReference),
+  mConstructedType(refReference.mConstructedType),
+  mConstructedProperties(refReference.mConstructedProperties)
+{
+}
+
+XdmfArrayReference::~XdmfArrayReference()
+{
+}
+
+std::map<std::string, std::string>
+XdmfArrayReference::getConstructedProperties()
+{
+  return mConstructedProperties;
+}
+
+std::string
+XdmfArrayReference::getConstructedType() const
+{
+  if (mConstructedType.c_str() != NULL) {
+    return mConstructedType;
+  }
+  else {
+    return "";
+  }
+}
+
+std::map<std::string, std::string>
+XdmfArrayReference::getItemProperties() const
+{
+  std::map<std::string, std::string> referenceProperties;
+
+  referenceProperties["ConstructedType"] = mConstructedType;
+
+  for (std::map<std::string, std::string>::const_iterator constructedIt = mConstructedProperties.begin();
+       constructedIt != mConstructedProperties.end();
+       ++constructedIt) {
+    referenceProperties[constructedIt->first] = constructedIt->second;
+  }
+
+  // An array is missing a lot of data if not read first
+  if (mConstructedType.compare(XdmfArray::ItemTag) == 0) {
+    shared_ptr<XdmfArray> resultArray = this->read();
+    shared_ptr<const XdmfArrayType> resultArrayType = resultArray->getArrayType();
+    std::map<std::string, std::string> arrayTypeProperties;
+    resultArrayType->getProperties(arrayTypeProperties);
+    for (std::map<std::string, std::string>::const_iterator arrayTypeIt = arrayTypeProperties.begin();
+         arrayTypeIt != arrayTypeProperties.end();
+         ++arrayTypeIt) {
+      referenceProperties[arrayTypeIt->first] = arrayTypeIt->second;
+    }
+    referenceProperties["Format"] = "XML";
+    referenceProperties["Dimensions"] = resultArray->getDimensionsString();
+  }
+
+  return referenceProperties;
+}
+
+void
+XdmfArrayReference::setConstructedProperties(std::map<std::string, std::string> newProperties)
+{
+  mConstructedProperties = newProperties;
+  this->setIsChanged(true);
+}
+
+void
+XdmfArrayReference::setConstructedType(std::string newType)
+{
+  mConstructedType = newType;
+  this->setIsChanged(true);
+}
+
+// C Wrappers
+
+char * XdmfArrayReferenceGetConstructedType(XDMFARRAYREFERENCE * arrayReference)
+{
+  try
+  {
+    char * returnPointer = strdup((*((XdmfArrayReference *)arrayReference)).getConstructedType().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup((*((XdmfArrayReference *)arrayReference)).getConstructedType().c_str());
+    return returnPointer;
+  }
+}
+
+void * XdmfArrayReferenceRead(XDMFARRAYREFERENCE * arrayReference, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    shared_ptr<XdmfArray> returnItem = ((XdmfArrayReference *)arrayReference)->read();
+    return new XdmfArray(*returnItem.get());
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfArray> returnItem = ((XdmfArrayReference *)arrayReference)->read();
+    return new XdmfArray(*returnItem.get());
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void XdmfArrayReferenceSetConstructedProperties(XDMFARRAYREFERENCE * arrayReference, void * referenceobject)
+{
+  ((XdmfArrayReference *)arrayReference)->setConstructedProperties(((XdmfItem *)referenceobject)->getItemProperties());
+}
+
+void XdmfArrayReferenceSetConstructedType(XDMFARRAYREFERENCE * arrayReference, char * newType)
+{
+  ((XdmfArrayReference *)arrayReference)->setConstructedType(newType);
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfArrayReference, XDMFARRAYREFERENCE)
diff --git a/core/XdmfArrayReference.hpp b/core/XdmfArrayReference.hpp
new file mode 100644
index 0000000..b2d05e9
--- /dev/null
+++ b/core/XdmfArrayReference.hpp
@@ -0,0 +1,262 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfArrayReference.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFARRAYREFERENCE_HPP_
+#define XDMFARRAYREFERENCE_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+class XdmfArray;
+
+/**
+ * @brief Serves as a link between an array and one or more arrays containing data it pulls from.
+ *
+ * The Array Reference class provides the basic framework for the writing and
+ * reading of the Function and Subset classes by allowing properties and tags
+ * to be migrated to them.
+ */
+class XDMFCORE_EXPORT XdmfArrayReference : public XdmfItem {
+
+public:
+
+  virtual ~XdmfArrayReference();
+
+  LOKI_DEFINE_VISITABLE(XdmfArrayReference, XdmfItem)
+
+  /**
+   * Gets the properties of the array that the reference will generate when read from file.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#setConstructedProperties
+   * @until //#setConstructedProperties
+   * @skipline //#getConstructedProperties
+   * @until //#getConstructedProperties
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//setConstructedProperties
+   * @until #//setConstructedProperties
+   * @skipline #//getConstructedProperties
+   * @until #//getConstructedProperties
+   *
+   * @return    The properties of the array to be generated
+   */
+  std::map<std::string, std::string> getConstructedProperties();
+
+  /**
+   * Gets the type of array that the reference will generate when read from file.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#setConstructedType
+   * @until //#setConstructedType
+   * @skipline //#getConstructedType
+   * @until //#getConstructedType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//setConstructedType
+   * @until #//setConstructedType
+   * @skipline #//getConstructedType
+   * @until #//getConstructedType
+   *
+   * @return    The tag of the type to be generated
+   */
+  std::string getConstructedType() const;
+
+  virtual std::map<std::string, std::string> getItemProperties() const;
+
+  /**
+   * Parses the reference and generates an array containing the values that
+   * the reference produces.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//read
+   * @until #//read
+   *
+   * @return    The array generated by the reference
+   */
+  virtual shared_ptr<XdmfArray> read() const = 0;
+
+  /**
+   * Sets the properties of array that the reference will generate when read from file.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#setConstructedProperties
+   * @until //#setConstructedProperties
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//setConstructedProperties
+   * @until #//setConstructedProperties
+   *
+   * @param     newProperties   The properties of the array to be generated
+   */
+  void
+  setConstructedProperties(std::map<std::string, std::string> newProperties);
+
+  /**
+   * Sets the type of array that the reference will generate when read from file.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#setConstructedType
+   * @until //#setConstructedType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//setConstructedType
+   * @until #//setConstructedType
+   *
+   * @param     newType         The tag of the type to be generated
+   */
+  void setConstructedType(std::string newType);
+
+  XdmfArrayReference(XdmfArrayReference &);
+
+protected:
+
+  XdmfArrayReference();
+
+  std::string mConstructedType;
+  std::map<std::string, std::string> mConstructedProperties;
+
+private:
+
+  XdmfArrayReference(const XdmfArrayReference &);  // Not implemented.
+  void operator=(const XdmfArrayReference &);  // Not implemented.
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFARRAYREFERENCE; // Simply as a typedef to ensure correct typing
+typedef struct XDMFARRAYREFERENCE XDMFARRAYREFERENCE; 
+
+XDMFCORE_EXPORT char * XdmfArrayReferenceGetConstructedType(XDMFARRAYREFERENCE * arrayReference);
+
+XDMFCORE_EXPORT void * XdmfArrayReferenceRead(XDMFARRAYREFERENCE * arrayReference, int * status);
+
+XDMFCORE_EXPORT void XdmfArrayReferenceSetConstructedProperties(XDMFARRAYREFERENCE * arrayReference, void * referenceobject);
+
+XDMFCORE_EXPORT void XdmfArrayReferenceSetConstructedType(XDMFARRAYREFERENCE * arrayReference, char * newType);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfArrayReference, XDMFARRAYREFERENCE, XDMFCORE)
+
+#define XDMF_ARRAYREFERENCE_C_CHILD_DECLARE(ClassName, CClassName, Level)                                      \
+                                                                                                               \
+Level##_EXPORT char * ClassName##GetConstructedType( CClassName * arrayReference);                             \
+Level##_EXPORT void * ClassName##Read( CClassName * arrayReference, int * status);                             \
+Level##_EXPORT void ClassName##SetConstructedProperties( CClassName * arrayReference, void * referenceobject); \
+Level##_EXPORT void ClassName##SetConstructedType( CClassName * arrayReference, char * newType);
+
+
+
+#define XDMF_ARRAYREFERENCE_C_CHILD_WRAPPER(ClassName, CClassName)                                             \
+                                                                                                               \
+                                                                                                               \
+char * ClassName##GetConstructedType(CClassName * arrayReference)                                              \
+{                                                                                                              \
+  return XdmfArrayReferenceGetConstructedType((XDMFARRAYREFERENCE *)((void *)arrayReference));                 \
+}                                                                                                              \
+                                                                                                               \
+void * ClassName##Read(CClassName * arrayReference, int * status)                                              \
+{                                                                                                              \
+  return XdmfArrayReferenceRead((XDMFARRAYREFERENCE *)((void *)arrayReference), status);                       \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##SetConstructedProperties(CClassName * arrayReference, void * referenceobject)                  \
+{                                                                                                              \
+  XdmfArrayReferenceSetConstructedProperties((XDMFARRAYREFERENCE *)((void *)arrayReference), referenceobject); \
+}                                                                                                              \
+                                                                                                               \
+void ClassName##SetConstructedType(CClassName * arrayReference, char * newType)                                \
+{                                                                                                              \
+  XdmfArrayReferenceSetConstructedType((XDMFARRAYREFERENCE *)((void *)arrayReference), newType);               \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFARRAYREFERENCE_HPP_ */
diff --git a/core/XdmfArrayType.cpp b/core/XdmfArrayType.cpp
new file mode 100644
index 0000000..0c04fd8
--- /dev/null
+++ b/core/XdmfArrayType.cpp
@@ -0,0 +1,615 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfArrayType.cpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <sstream>
+#include <utility>
+#include <boost/assign.hpp>
+#include "string.h"
+#include "XdmfArrayType.hpp"
+#include "XdmfError.hpp"
+
+std::map<std::string, std::map<unsigned int ,shared_ptr<const XdmfArrayType>(*)()> >
+  XdmfArrayType::mArrayDefinitions;
+
+// Supported XdmfArrayTypes
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Uninitialized()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("None", 0, XdmfArrayType::Unsigned));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Int8()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("Char", 1, XdmfArrayType::Signed));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Int16()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("Short", 2, XdmfArrayType::Signed));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Int32()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("Int", 4, XdmfArrayType::Signed));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Int64()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("Int", 8, XdmfArrayType::Signed));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Float32()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("Float", 4, XdmfArrayType::Float));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::Float64()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("Float", 8, XdmfArrayType::Float));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::UInt8()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("UChar", 1, XdmfArrayType::Unsigned));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::UInt16()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("UShort", 2, XdmfArrayType::Unsigned));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::UInt32()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("UInt", 4, XdmfArrayType::Unsigned));
+  return p;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::String()
+{
+  static shared_ptr<const XdmfArrayType> p(new XdmfArrayType("String", 0, XdmfArrayType::Unsigned));
+  return p;
+}
+
+void
+XdmfArrayType::InitTypes()
+{
+  mArrayDefinitions["NONE"][0] = Uninitialized;
+  mArrayDefinitions["CHAR"][1] = Int8;
+  mArrayDefinitions["SHORT"][2] = Int16;
+  mArrayDefinitions["INT"][4] = Int32;
+  mArrayDefinitions["INT"][8] = Int64;
+  mArrayDefinitions["FLOAT"][4] = Float32;
+  mArrayDefinitions["FLOAT"][8] = Float64;
+  mArrayDefinitions["UCHAR"][1] = UInt8;
+  mArrayDefinitions["USHORT"][2] = UInt16;
+  mArrayDefinitions["UINT"][4] = UInt32;
+  mArrayDefinitions["STRING"][0] = String;
+}
+
+XdmfArrayType::XdmfArrayType(const std::string & name,
+                             const unsigned int precision,
+                             const Format typeFormat) :
+  mName(name),
+  mPrecision(precision),
+  mTypeFormat(typeFormat)
+{
+  std::stringstream precisionString;
+  precisionString << precision;
+  mPrecisionString = precisionString.str();
+}
+
+XdmfArrayType::~XdmfArrayType()
+{
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::New(const std::map<std::string, std::string> & itemProperties)
+{
+  InitTypes();
+  std::map<std::string, std::string>::const_iterator type =
+    itemProperties.find("DataType");
+  if(type == itemProperties.end()) {
+    type = itemProperties.find("NumberType");
+  }
+  if(type == itemProperties.end()) {
+    // to support old xdmf defaults, return Float32()
+    return Float32();
+  }
+  const std::string & typeVal = ConvertToUpper(type->second);
+  std::map<std::string, std::string>::const_iterator precision =
+    itemProperties.find("Precision");
+  const unsigned int precisionVal =
+    (precision == itemProperties.end()) ? 0 : atoi(precision->second.c_str());
+  std::map<std::string, std::map<unsigned int ,shared_ptr<const XdmfArrayType>(*)()> >::const_iterator returnType = mArrayDefinitions.find(typeVal);
+  if (returnType == mArrayDefinitions.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Type not one of accepted values: " + typeVal +
+                       " in XdmfArrayType::New");
+  }
+  else {
+    std::map<unsigned int ,shared_ptr<const XdmfArrayType>(*)()>::const_iterator returnPrecision = returnType->second.find(precisionVal);
+
+    // If only one precision is available, assume that if not specified.
+    if (returnType->second.size() == 1 && precisionVal == 0)
+    {
+      return (*((returnType->second.begin())->second))();
+    }
+
+    if (returnPrecision == returnType->second.end()) {
+      // Default to 32bit types if not specified otherwise
+      returnPrecision = returnType->second.find(4);
+    }
+
+    if (returnPrecision == returnType->second.end()) {
+      std::string errorVal = "";
+      if (precision == itemProperties.end()) {
+        errorVal = "0";
+      }
+      else {
+        errorVal = precision->second;
+      }
+      XdmfError::message(XdmfError::FATAL,
+                         "Type not one of accepted precision: " + errorVal +
+                         " in XdmfArrayType::New");
+    }
+    else {
+      return (*(returnPrecision->second))();
+    }
+  }
+
+  XdmfError::message(XdmfError::FATAL,
+                     "Type not one of accepted values: " + typeVal +
+                     " in XdmfArrayType::New");
+  
+  // unreachable
+  return shared_ptr<const XdmfArrayType>();
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfArrayType::comparePrecision(shared_ptr<const XdmfArrayType> type1,
+                                shared_ptr<const XdmfArrayType> type2)
+{
+  std::string type1Name = type1->getName();
+  std::string type2Name = type2->getName();
+
+  if (type2Name.compare(type1Name) == 0) {
+    if (type1->getElementSize() >= type2->getElementSize()) {
+      return type1;
+    }
+    else {
+      return type2;
+    }
+  }
+
+  bool firstIsSigned = false;
+  if (type1Name.compare("UChar") != 0 &&
+      type1Name.compare("UShort") != 0 &&
+      type1Name.compare("UInt") != 0) {
+    firstIsSigned = true;
+  }
+
+  bool secondIsSigned = false;
+  if (type2Name.compare("UChar") != 0 &&
+      type2Name.compare("UShort") != 0 &&
+      type2Name.compare("UInt") != 0) {
+    secondIsSigned = true;
+  }
+
+  std::map<std::string, int> controlmap;
+  controlmap["Char"] = 1;
+  controlmap["UChar"] = 2;
+  controlmap["Short"] = 3;
+  controlmap["UShort"] = 4;
+  controlmap["Int"] = 5;
+  controlmap["UInt"] = 6;
+  controlmap["Float"] = 7;
+  controlmap["String"] = 8;
+
+  int control = controlmap[type1Name];
+
+
+  // In this switch the starting location is determined by
+  // the first type and then the algorithm cascades
+  // until it finds the second type
+  switch (control) {
+    case 1:
+      // Char
+    case 2:
+      // UChar
+      if (type2Name.compare("Char") == 0 ||
+          type2Name.compare("UChar") == 0) {
+        // This statement would be called in the case
+        // where there is a mixed type of Char and UChar
+        // The resulting type should be a Short
+        return Int16();
+      }
+    case 3:
+      // Short
+      if (type2Name.compare("Char") == 0 ||
+          type2Name.compare("UChar") == 0 ||
+          type2Name.compare("Short") == 0) {
+        // This will be called for any combination of
+        // Char/UChar and Short
+        // In all of these cases the result shoule be a Short
+        return Int16();
+      }
+    case 4:
+      // UShort
+      if (type2Name.compare("Char") == 0 ||
+          type2Name.compare("Short") == 0) {
+        // When mixing UShort with a signed type that has a lower precision
+        // the resulting type should be an int
+        return Int32();
+      }
+      else if (type2Name.compare("UChar") == 0 ||
+               type2Name.compare("UShort") == 0) {
+        // When mixing UShort with an unsigned type that has a lower precision
+        // a Ushort should be the resulting type
+        if (!firstIsSigned) {
+          return UInt16();
+        }
+        else {
+          return Int32();
+        }
+      }
+    case 5:
+      // Int
+      if (type2Name.compare("Int") != 0 &&
+          type2Name.compare("UInt") != 0 &&
+          type2Name.compare("Float") != 0 &&
+          type2Name.compare("String") != 0) {
+        // When mixing an Int with a type of lower precision
+        // the resulting type should match the Int's precision
+        if (type1->getElementSize() == 4) {
+          return Int32();
+        }
+        else {
+          return Int64();
+        }
+      }
+      if (type2Name.compare("Int") == 0) {
+        if (type2->getElementSize() == 4) {
+          return Int32();
+        }
+        else {
+          return Int64();
+        }
+      }
+    case 6:
+      // UInt
+      if (type2Name.compare("UInt") != 0 &&
+          type2Name.compare("Int") != 0 &&
+          type2Name.compare("Float") != 0 &&
+          type2Name.compare("String") != 0) {
+        // When mixing UInt with another non-floating-point type
+        // the result should be either long or unsigned int
+        // depending on the if the mixed type is signed or not
+        if (!secondIsSigned) {
+          return UInt32();
+        }
+        else {
+          return Int64();
+        }
+      }
+      else if (type2Name.compare("UInt") == 0) {
+        if (firstIsSigned) {
+          return Int64();
+        }
+        else {
+          return UInt32();
+        }
+      }
+      else if (type2Name.compare("Int") == 0) {
+        return Int64();
+      }
+    case 7:
+      // Float
+      if (type2Name.compare("String") != 0 &&
+          type2Name.compare("Float") != 0 &&
+          type2Name.compare("UInt") != 0) {
+        // String is the only type that has priority over a float
+        // This case occurs when type1 is a float
+        return type1;
+      }
+      else if (type2Name.compare("UInt") == 0) {
+        return Float64();
+      }
+      else if (type2Name.compare("Float") == 0) {
+        // Since there was a check earlier to see if the type names matched
+        // This is the case when type2 is a float
+        if (type1Name.compare("UInt") == 0) {
+          return Float64();
+        }
+	else {
+          return type2;
+        }
+      }
+    case 8:
+      // String
+      // String has priority over everything
+      return String();
+    default:
+      break;
+  }
+  // Double is the default value
+  // Should all of the above manage to fail to return a value
+  return Float64();
+}
+
+unsigned int
+XdmfArrayType::getElementSize() const
+{
+  return mPrecision;
+}
+
+std::string
+XdmfArrayType::getName() const
+{
+  return mName;
+}
+
+bool
+XdmfArrayType::getIsFloat() const
+{
+  if (mTypeFormat == XdmfArrayType::Float) {
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+bool
+XdmfArrayType::getIsSigned() const
+{
+  if (mTypeFormat == XdmfArrayType::Float ||
+      mTypeFormat == XdmfArrayType::Signed) {
+    return true;
+  }
+  else {
+    return false;
+  }
+}
+
+void
+XdmfArrayType::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties.insert(std::make_pair("DataType", mName));
+  collectedProperties.insert(std::make_pair("Precision", mPrecisionString));
+}
+
+// C Wrappers
+
+shared_ptr<const XdmfArrayType>
+intToType(int type)
+{
+    switch (type) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      return XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      return XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      return XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      return XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      return XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      return XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      return XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      return XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      return XdmfArrayType::Float64();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  return shared_ptr<const XdmfArrayType>();
+}
+
+int
+typeToInt(shared_ptr<const XdmfArrayType> type)
+{
+  std::string typeName = type->getName();
+  unsigned int typePrecision = type->getElementSize();
+  if (typeName == XdmfArrayType::UInt8()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT8;
+  }
+  else if (typeName == XdmfArrayType::UInt16()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT16;
+  }
+  else if (typeName == XdmfArrayType::UInt32()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT32;
+  }
+  else if (typeName == XdmfArrayType::Int8()->getName())
+  {
+      return XDMF_ARRAY_TYPE_INT8;
+  }
+  else if (typeName == XdmfArrayType::Int16()->getName())
+  {
+      return XDMF_ARRAY_TYPE_INT16;
+  }
+  else if (typeName == XdmfArrayType::Int32()->getName() || typeName == XdmfArrayType::Int64()->getName())
+  {
+    if (typePrecision == 4)
+    {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (typePrecision == 8)
+    {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else
+    {
+    }
+  }
+  else if (typeName == XdmfArrayType::Float32()->getName() || typeName == XdmfArrayType::Float64()->getName())
+  {
+    if (typePrecision == 4)
+    {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (typePrecision == 8)
+    {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else
+    {
+    }
+  }
+  else if (typeName == XdmfArrayType::String()->getName())
+  {
+    //This shouldn't be used from C bindings
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: String type not usable from C.");
+  }
+  else
+  {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Invalid ArrayType.");
+  }
+  return -1;
+}
+
+int XdmfArrayTypeInt8()
+{
+  return XDMF_ARRAY_TYPE_INT8;
+}
+
+int XdmfArrayTypeInt16()
+{
+  return XDMF_ARRAY_TYPE_INT16;
+}
+
+int XdmfArrayTypeInt32()
+{
+  return XDMF_ARRAY_TYPE_INT32;
+}
+
+int XdmfArrayTypeInt64()
+{
+  return XDMF_ARRAY_TYPE_INT64;
+}
+
+int XdmfArrayTypeFloat32()
+{
+  return XDMF_ARRAY_TYPE_FLOAT32;
+}
+
+int XdmfArrayTypeFloat64()
+{
+  return XDMF_ARRAY_TYPE_FLOAT64;
+}
+
+int XdmfArrayTypeUInt8()
+{
+  return XDMF_ARRAY_TYPE_UINT8;
+}
+
+int XdmfArrayTypeUInt16()
+{
+  return XDMF_ARRAY_TYPE_UINT16;
+}
+
+int XdmfArrayTypeUInt32()
+{
+  return XDMF_ARRAY_TYPE_UINT32;
+}
+
+int XdmfArrayTypeComparePrecision(int type1, int type2, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<const XdmfArrayType> tempType1 = intToType(type1);
+  shared_ptr<const XdmfArrayType> tempType2 = intToType(type2);
+  shared_ptr<const XdmfArrayType> returnType = XdmfArrayType::comparePrecision(tempType1, tempType2);
+  return typeToInt(returnType);
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+int XdmfArrayTypeGetElementSize(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return intToType(type)->getElementSize();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+int XdmfArrayTypeGetIsFloat(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return intToType(type)->getIsFloat();
+  XDMF_ERROR_WRAP_END(status)
+  return false;
+}
+
+int XdmfArrayTypeGetIsSigned(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return intToType(type)->getIsSigned();
+  XDMF_ERROR_WRAP_END(status)
+  return false;
+}
+
+char * XdmfArrayTypeGetName(int type, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  char * returnPointer = strdup(intToType(type)->getName().c_str());
+  return returnPointer;
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
diff --git a/core/XdmfArrayType.hpp b/core/XdmfArrayType.hpp
new file mode 100644
index 0000000..1409a9e
--- /dev/null
+++ b/core/XdmfArrayType.hpp
@@ -0,0 +1,293 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfArrayType.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFARRAYTYPE_HPP_
+#define XDMFARRAYTYPE_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include "XdmfItemProperty.hpp"
+#include <vector>
+
+/**
+ * @brief Property describing what types of values an XdmfArray
+ * contains.
+ *
+ * XdmfArrayType specifies the types of values stored in an XdmfArray.
+ * A specific XdmfArrayType can be created by calling one of the
+ * static methods in the class, i.e. XdmfArrayType::Int32().
+ *
+ * Example of use:
+ *
+ * C++
+ *
+ * @dontinclude ExampleXdmfArrayType.cpp
+ * @skipline //#getType
+ * @until //#getType
+ *
+ * Python
+ *
+ * @dontinclude XdmfExampleArrayType.py
+ * @skipline #//getType
+ * @until #//getType
+ *
+ * Xdmf supports the following attribute types:
+ *   Uninitialized
+ *   Int8
+ *   Int16
+ *   Int32
+ *   Int64
+ *   Float32
+ *   Float64
+ *   UInt8
+ *   UInt16
+ *   UInt32
+ *   String
+ */
+class XDMFCORE_EXPORT XdmfArrayType : public XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfArrayType();
+
+  friend class XdmfArray;
+  friend class XdmfCoreItemFactory;
+
+  enum Format {
+    Unsigned,
+    Signed,
+    Float
+  };
+
+  // Supported XdmfArrayTypes
+  static shared_ptr<const XdmfArrayType> Uninitialized();
+  static shared_ptr<const XdmfArrayType> Int8();
+  static shared_ptr<const XdmfArrayType> Int16();
+  static shared_ptr<const XdmfArrayType> Int32();
+  static shared_ptr<const XdmfArrayType> Int64();
+  static shared_ptr<const XdmfArrayType> Float32();
+  static shared_ptr<const XdmfArrayType> Float64();
+  static shared_ptr<const XdmfArrayType> UInt8();
+  static shared_ptr<const XdmfArrayType> UInt16();
+  static shared_ptr<const XdmfArrayType> UInt32();
+  static shared_ptr<const XdmfArrayType> String();
+
+  /**
+   * Compares the two types given and returns a type that is compatible with both.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @skipline //#comparePrecision
+   * @until //#comparePrecision
+   *
+   * Python
+   *
+   * @skipline #//comparePrecision
+   * @until #//comparePrecision
+   *
+   * @param     type1   The first type to be compared
+   * @param     type2   The second type to be compared
+   * @return            The type that is compatible with both provided types
+   */
+  static shared_ptr<const XdmfArrayType> comparePrecision(shared_ptr<const XdmfArrayType> type1, shared_ptr<const XdmfArrayType> type2);
+
+  /**
+   * Get the data size, in bytes, of the value associated with this
+   * array type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArrayType.cpp
+   * @skipline //#getElementSize
+   * @until //#getElementSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArrayType.py
+   * @skipline #//getElementSize
+   * @until #//getElementSize
+   *
+   * @return    The data size, in bytes.
+   */
+  unsigned int getElementSize() const;
+
+  /**
+   * Gets whether the data type is floating point or not.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArrayType.cpp
+   * @skipline //#getIsFloat
+   * @until //#getIsFloat
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArrayType.py
+   * @skipline #//getIsFloat
+   * @until #//getIsFloat
+   *
+   * @return    Whether the data type is signed.
+   */
+  bool getIsFloat() const;
+
+  /**
+   * Gets whether the data type is signed or not.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArrayType.cpp
+   * @skipline //#getIsSigned
+   * @until //#getIsSigned
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArrayType.py
+   * @skipline #//getIsSigned
+   * @until #//getIsSigned
+   *
+   * @return    Whether the data type is signed.
+   */
+  bool getIsSigned() const;
+
+  /**
+   * Get the name of the data type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfArrayType.cpp
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleArrayType.py
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    The name of the data type.
+   */
+  std::string getName() const;
+
+  void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+protected:
+
+  /**
+   * Protected constructor for XdmfArrayType. The constructor is
+   * protected because all array types supported by Xdmf should be
+   * accessed through more specific static methods that construct
+   * XdmfArrayTypes - i.e. XdmfArrayType::Float64().
+   *
+   * @param name the name of the XdmfArrayType to construct.
+   * @param precision the precision, in bytes, of the XdmfArrayType to
+   * construct.
+   * @param typeFormat The format description of the XdmfArrayType.
+   */
+  XdmfArrayType(const std::string & name,
+                const unsigned int precision,
+                const Format typeFormat);
+
+  static std::map<std::string, std::map<unsigned int ,shared_ptr<const XdmfArrayType>(*)()> > mArrayDefinitions;
+
+  static void InitTypes();
+
+private:
+
+  XdmfArrayType(const XdmfArrayType &); // Not implemented.
+  void operator=(const XdmfArrayType &); // Not implemented.
+
+  static shared_ptr<const XdmfArrayType>
+  New(const std::map<std::string, std::string> & itemProperties);
+
+  const std::string mName;
+  const unsigned int mPrecision;
+  std::string mPrecisionString;
+  Format mTypeFormat;
+  const char * mTypeId;
+
+  // Allows for up to 16 byte sizes for unsigned, signed, and floating point types
+  // The vector is actually larger than that to allow for the string and uninitialized types
+  static std::vector<shared_ptr<const XdmfArrayType> > mTypes;
+  // Due to uninitialized taking position 0 the size of the array is actually one over the max size
+  static unsigned int mCurrentMaxSize;
+  // Map of typeid to index in mTypes
+  static std::map<std::string, shared_ptr<const XdmfArrayType> > mTypeIdMap;
+};
+
+#endif
+
+#define XDMF_ARRAY_TYPE_INT8    0
+#define XDMF_ARRAY_TYPE_INT16   1
+#define XDMF_ARRAY_TYPE_INT32   2
+#define XDMF_ARRAY_TYPE_INT64   3
+#define XDMF_ARRAY_TYPE_UINT8   4
+#define XDMF_ARRAY_TYPE_UINT16  5
+#define XDMF_ARRAY_TYPE_UINT32  6
+#define XDMF_ARRAY_TYPE_FLOAT32 7
+#define XDMF_ARRAY_TYPE_FLOAT64 8
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// These simply return the values defined above
+XDMFCORE_EXPORT int XdmfArrayTypeInt8();
+XDMFCORE_EXPORT int XdmfArrayTypeInt16();
+XDMFCORE_EXPORT int XdmfArrayTypeInt32();
+XDMFCORE_EXPORT int XdmfArrayTypeInt64();
+XDMFCORE_EXPORT int XdmfArrayTypeFloat32();
+XDMFCORE_EXPORT int XdmfArrayTypeFloat64();
+XDMFCORE_EXPORT int XdmfArrayTypeUInt8();
+XDMFCORE_EXPORT int XdmfArrayTypeUInt16();
+XDMFCORE_EXPORT int XdmfArrayTypeUInt32();
+
+XDMFCORE_EXPORT int XdmfArrayTypeComparePrecision(int type1, int type2, int * status);
+
+XDMFCORE_EXPORT int XdmfArrayTypeGetElementSize(int type, int * status);
+
+XDMFCORE_EXPORT int XdmfArrayTypeGetIsFloat(int type, int * status);
+
+XDMFCORE_EXPORT int XdmfArrayTypeGetIsSigned(int type, int * status);
+
+XDMFCORE_EXPORT char * XdmfArrayTypeGetName(int type, int * status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFARRAYTYPE_HPP_ */
diff --git a/core/XdmfBinaryController.cpp b/core/XdmfBinaryController.cpp
new file mode 100644
index 0000000..75f887b
--- /dev/null
+++ b/core/XdmfBinaryController.cpp
@@ -0,0 +1,404 @@
+/*****************************************************************************/
+/*                                    Xdmf                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfBinaryController.cpp                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <fstream>
+#include <sstream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfError.hpp"
+
+namespace {
+
+  template<size_t T>
+  struct ByteSwaper {
+    static inline void swap(void * p){}
+    static inline void swap(void * p,
+                            unsigned int length)
+    {
+      char * data = static_cast<char *>(p);
+      for(unsigned int i=0; i<length; ++i, data+=T){
+        ByteSwaper<T>::swap(data);
+      }
+    }
+  };
+
+  template<>
+  void ByteSwaper<2>::swap(void * p){
+    char one_byte;
+    char* data = static_cast<char*>(p);
+    one_byte = data[0]; data[0] = data[1]; data[1] = one_byte;
+  }
+
+  template<>
+  void ByteSwaper<4>::swap(void * p){
+    char one_byte;
+    char* data = static_cast<char*>(p);
+    one_byte = data[0]; data[0] = data[3]; data[3] = one_byte;
+    one_byte = data[1]; data[1] = data[2]; data[2] = one_byte;
+  
+  }
+
+  template<>
+  void ByteSwaper<8>::swap(void * p){
+    char one_byte;
+    char* data = static_cast<char*>(p);
+    one_byte = data[0]; data[0] = data[7]; data[7] = one_byte;
+    one_byte = data[1]; data[1] = data[6]; data[6] = one_byte;
+    one_byte = data[2]; data[2] = data[5]; data[5] = one_byte;
+    one_byte = data[3]; data[3] = data[4]; data[4] = one_byte;
+  }
+
+}
+
+shared_ptr<XdmfBinaryController>
+XdmfBinaryController::New(const std::string & filePath,
+                          const shared_ptr<const XdmfArrayType> & type,
+                          const Endian & endian,
+                          const unsigned int seek,
+                          const std::vector<unsigned int> & dimensions)
+{
+  shared_ptr<XdmfBinaryController> p(new XdmfBinaryController(filePath,
+                                                              type,
+                                                              endian,
+                                                              seek,
+                                                              std::vector<unsigned int>(dimensions.size(), 0),
+                                                              std::vector<unsigned int>(dimensions.size(), 1),
+                                                              dimensions,
+                                                              dimensions));
+  return p;
+}
+
+shared_ptr<XdmfBinaryController>
+XdmfBinaryController::New(const std::string & filePath,
+                          const shared_ptr<const XdmfArrayType> & type,
+                          const Endian & endian,
+                          const unsigned int seek,
+                          const std::vector<unsigned int> & starts,
+                          const std::vector<unsigned int> & strides,
+                          const std::vector<unsigned int> & dimensions,
+                          const std::vector<unsigned int> & dataspaces)
+{
+  shared_ptr<XdmfBinaryController> p(new XdmfBinaryController(filePath,
+                                                              type,
+                                                              endian,
+                                                              seek,
+                                                              starts,
+                                                              strides,
+                                                              dimensions,
+                                                              dataspaces));
+  return p;
+}
+
+XdmfBinaryController::XdmfBinaryController(const std::string & filePath,
+                                           const shared_ptr<const XdmfArrayType> & type,
+                                           const Endian & endian,
+                                           const unsigned int seek,
+                                           const std::vector<unsigned int> & starts,
+                                           const std::vector<unsigned int> & strides,
+                                           const std::vector<unsigned int> & dimensions,
+                                           const std::vector<unsigned int> & dataspaces) :
+  XdmfHeavyDataController(filePath,
+                          type,
+                          starts,
+                          strides,
+                          dimensions,
+                          dataspaces),
+  mEndian(endian),
+  mSeek(seek)
+{
+}
+
+XdmfBinaryController::XdmfBinaryController(const XdmfBinaryController & refController):
+  XdmfHeavyDataController(refController),
+  mEndian(refController.mEndian),
+  mSeek(refController.mSeek)
+{
+}
+
+XdmfBinaryController::~XdmfBinaryController()
+{
+}
+
+std::string
+XdmfBinaryController::getDataspaceDescription() const
+{
+  std::stringstream descstream;
+  descstream << mSeek << ":" << XdmfHeavyDataController::getDataspaceDescription();
+  return descstream.str();
+}
+
+XdmfBinaryController::Endian
+XdmfBinaryController::getEndian() const
+{
+  return mEndian;
+}
+
+std::string
+XdmfBinaryController::getName() const
+{
+  return "Binary";
+}
+
+void
+XdmfBinaryController::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties["Format"] = this->getName();
+
+  if(mEndian == BIG) {
+    collectedProperties["Endian"] = "Big";
+  }
+  else if(mEndian == LITTLE) {
+    collectedProperties["Endian"] = "Little";
+  }
+}
+
+unsigned int
+XdmfBinaryController::getSeek() const
+{
+  return mSeek;
+}
+
+void
+XdmfBinaryController::read(XdmfArray * const array)
+{
+  array->initialize(mType, mDimensions);
+
+  shared_ptr<XdmfArray> dataspaceArray = XdmfArray::New();
+
+  dataspaceArray->initialize(mType, mDataspaceDimensions);
+
+  std::ifstream fileStream(mFilePath.c_str(),
+                           std::ifstream::binary);
+
+  if(!fileStream.good()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error reading " + mFilePath + 
+                       " in XdmfBinaryController::read");
+  }
+
+  fileStream.seekg(mSeek);
+  
+  if(!fileStream.good()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error seeking " + mFilePath + 
+                       " in XdmfBinaryController::read");
+  }
+  
+  fileStream.read(static_cast<char *>(dataspaceArray->getValuesInternal()),
+                  dataspaceArray->getSize() * mType->getElementSize());
+  
+#if defined(XDMF_BIG_ENDIAN)
+  const bool needByteSwap = mEndian == LITTLE;
+#else
+  const bool needByteSwap = mEndian == BIG;
+#endif // XDMF_BIG_ENDIAN
+  
+  if(needByteSwap) {
+    switch(mType->getElementSize()){
+    case 1:
+      break;
+    case 2:
+      ByteSwaper<2>::swap(dataspaceArray->getValuesInternal(),
+                          dataspaceArray->getSize());
+        break;
+    case 4:
+      ByteSwaper<4>::swap(dataspaceArray->getValuesInternal(),
+                          dataspaceArray->getSize());
+      break;
+    case 8:
+      ByteSwaper<8>::swap(dataspaceArray->getValuesInternal(),
+                          dataspaceArray->getSize());
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Cannot perform endianness swap for datatype");
+      break;
+    }
+  }
+  array->insert(std::vector<unsigned int>(mDimensions.size(), 0),
+                dataspaceArray,
+                mStart,
+                mDataspaceDimensions,
+                mDimensions,
+                std::vector<unsigned int>(mDimensions.size(), 1),
+                mStride);
+}
+
+// C Wrappers
+
+XDMFBINARYCONTROLLER *
+XdmfBinaryControllerNew(char * filePath,
+                        int type,
+                        int endian,
+                        unsigned int seek,
+                        unsigned int * dimensions,
+                        unsigned int numDims,
+                        int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+  shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+  switch (type) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      buildType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      buildType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      buildType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      buildType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      buildType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      buildType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      buildType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      buildType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      buildType = XdmfArrayType::Float64();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  XdmfBinaryController::Endian buildEndian = XdmfBinaryController::NATIVE;
+  printf("switch endian = %u\n", endian);
+  switch (endian) {
+    case XDMF_BINARY_CONTROLLER_ENDIAN_BIG:
+      buildEndian = XdmfBinaryController::BIG;
+      break;
+    case XDMF_BINARY_CONTROLLER_ENDIAN_LITTLE:
+      buildEndian = XdmfBinaryController::LITTLE;
+      break;
+    case XDMF_BINARY_CONTROLLER_ENDIAN_NATIVE:
+      buildEndian = XdmfBinaryController::NATIVE;
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Endian.");
+      break;
+  }
+  shared_ptr<XdmfBinaryController> generatedController = XdmfBinaryController::New(std::string(filePath), buildType, buildEndian, seek, dimVector);
+  return (XDMFBINARYCONTROLLER *)((void *)(new XdmfBinaryController(*generatedController.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFBINARYCONTROLLER *
+XdmfBinaryControllerNewHyperslab(char * filePath,
+                                 int type,
+                                 int endian,
+                                 unsigned int seek,
+                                 unsigned int * start,
+                                 unsigned int * stride,
+                                 unsigned int * dimensions,
+                                 unsigned int * dataspaceDimensions,
+                                 unsigned int numDims,
+                                 int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> startVector(start, start + numDims);
+  std::vector<unsigned int> strideVector(stride, stride + numDims);
+  std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+  std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+  shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+  switch (type) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      buildType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      buildType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      buildType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      buildType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      buildType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      buildType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      buildType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      buildType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      buildType = XdmfArrayType::Float64();
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid ArrayType.");
+      break;
+  }
+  XdmfBinaryController::Endian buildEndian = XdmfBinaryController::NATIVE;
+  switch (endian) {
+    case XDMF_BINARY_CONTROLLER_ENDIAN_BIG:
+      buildEndian = XdmfBinaryController::BIG;
+      break;
+    case XDMF_BINARY_CONTROLLER_ENDIAN_LITTLE:
+      buildEndian = XdmfBinaryController::LITTLE;
+      break;
+    case XDMF_BINARY_CONTROLLER_ENDIAN_NATIVE:
+      buildEndian = XdmfBinaryController::NATIVE;
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Endian.");
+      break;
+  }
+  shared_ptr<XdmfBinaryController> generatedController = XdmfBinaryController::New(std::string(filePath), buildType, buildEndian, seek, startVector, strideVector, dimVector, dataspaceVector);
+  return (XDMFBINARYCONTROLLER *)((void *)(new XdmfBinaryController(*generatedController.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+int
+XdmfBinaryControllerGetEndian(XDMFBINARYCONTROLLER * controller)
+{
+  return ((XdmfBinaryController *)(controller))->getEndian();
+}
+
+unsigned int
+XdmfBinaryControllerGetSeek(XDMFBINARYCONTROLLER * controller)
+{
+  return ((XdmfBinaryController *)(controller))->getSeek();
+}
+
+// C Wrappers for parent classes are generated by macros
+XDMF_HEAVYCONTROLLER_C_CHILD_WRAPPER(XdmfBinaryController, XDMFBINARYCONTROLLER)
diff --git a/core/XdmfBinaryController.hpp b/core/XdmfBinaryController.hpp
new file mode 100644
index 0000000..0d41104
--- /dev/null
+++ b/core/XdmfBinaryController.hpp
@@ -0,0 +1,247 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfBinaryController.hpp                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFBinaryCONTROLLER_HPP_
+#define XDMFBinaryCONTROLLER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataController.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Couples an XdmfArray with Binary data stored on disk.
+ *
+ * Serves as an interface between data stored in XdmfArrays and data
+ * stored in binary files on disk. When an Xdmf file is read from or
+ * written to disk an XdmfBinaryController is attached to
+ * XdmfArrays. This allows data to be released from memory but still
+ * be accessible or have its location written to light data.
+ */
+class XDMFCORE_EXPORT XdmfBinaryController : public XdmfHeavyDataController {
+
+public:
+
+  typedef enum Endian {
+    BIG,
+    LITTLE,
+    NATIVE
+  } Endian;
+
+  virtual ~XdmfBinaryController();
+
+  /**
+   * Create a new controller for an binary data set on disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfBinaryController.cpp
+   * @skipline //#initializationsimplified
+   * @until //#initializationsimplified
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleBinaryController.py
+   * @skipline #//initializationsimplified
+   * @until #//initializationsimplified
+   *
+   * @param     filePath        Location of the binary file.
+   * @param     type            Data type of the dataset to read.
+   * @param     endian          Endianness of the data.
+   * @param     seek            Distance in bytes to begin reading in file.
+   * @param     dimensions      Number of elements to select in each from the total
+   *
+   * @return New Binary Controller.
+   */
+  static shared_ptr<XdmfBinaryController>
+  New(const std::string & filePath,
+      const shared_ptr<const XdmfArrayType> & type,
+      const Endian & endian,
+      const unsigned int seek,
+      const std::vector<unsigned int> & dimensions);
+
+  /**
+   * Create a new controller for an binary data set on disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfBinaryController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleBinaryController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     filePath        Location of the binary file.
+   * @param     type            Data type of the dataset to read.
+   * @param     endian          Endianness of the data.
+   * @param     seek            Distance in bytes to begin reading in file.
+   * @param     starts          Starting index for each dimension
+   * @param     strides         Distance between read values across the dataspace
+   * @param     dimensions      Number of elements to select in each from the total
+   * @param     dataspaces      Total number of elements to select in each
+   *
+   * @return New Binary Controller.
+   */
+  static shared_ptr<XdmfBinaryController>
+  New(const std::string & filePath,
+      const shared_ptr<const XdmfArrayType> & type,
+      const Endian & endian,
+      const unsigned int seek,
+      const std::vector<unsigned int> & starts,
+      const std::vector<unsigned int> & strides,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaces);
+
+  virtual std::string getDataspaceDescription() const;
+
+  /**
+   * Gets the endianness of the dataset that the controller points to.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfBinaryController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getEndian
+   * @until //#getEndian
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleBinaryController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getEndian
+   * @until #//getEndian
+   *
+   * @return    The endianness of the dataset.
+   */
+  virtual Endian getEndian() const;
+
+  virtual std::string getName() const;
+
+  virtual void 
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+  /**
+   * Gets the offset in bytes of the dataset that the controller points to in the file.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfBinaryController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getSeek
+   * @until //#getSeek
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleBinaryController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getSeek
+   * @until #//getSeek
+   *
+   * @return    The offset in bytes.
+   */
+  virtual unsigned int getSeek() const;
+
+  virtual void read(XdmfArray * const array);
+
+  XdmfBinaryController(const XdmfBinaryController &);
+
+protected:
+
+  XdmfBinaryController(const std::string & filePath,
+                       const shared_ptr<const XdmfArrayType> & type,
+                       const Endian & endian,
+                       const unsigned int seek,
+                       const std::vector<unsigned int> & starts,
+                       const std::vector<unsigned int> & strides,
+                       const std::vector<unsigned int> & dimensions,
+                       const std::vector<unsigned int> & dataspaces);
+
+private:
+
+  void operator=(const XdmfBinaryController &);  // Not implemented.
+
+  const Endian mEndian;
+  const unsigned int mSeek;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XDMF_BINARY_CONTROLLER_ENDIAN_BIG    50
+#define XDMF_BINARY_CONTROLLER_ENDIAN_LITTLE 51
+#define XDMF_BINARY_CONTROLLER_ENDIAN_NATIVE 52
+
+struct XDMFBINARYCONTROLLER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFBINARYCONTROLLER XDMFBINARYCONTROLLER;
+
+XDMFCORE_EXPORT XDMFBINARYCONTROLLER * XdmfBinaryControllerNew(char * filePath,
+                                                               int type,
+                                                               int endian,
+                                                               unsigned int seek,
+                                                               unsigned int * dimensions,
+                                                               unsigned int numDims,
+                                                               int * status);
+
+XDMFCORE_EXPORT XDMFBINARYCONTROLLER * XdmfBinaryControllerNewHyperslab(char * filePath,
+                                                                        int type,
+                                                                        int endian,
+                                                                        unsigned int seek,
+                                                                        unsigned int * starts,
+                                                                        unsigned int * strides,
+                                                                        unsigned int * dimensions,
+                                                                        unsigned int * dataspaces,
+                                                                        unsigned int numDims,
+                                                                        int * status);
+
+XDMFCORE_EXPORT int XdmfBinaryControllerGetEndian(XDMFBINARYCONTROLLER * controller);
+
+XDMFCORE_EXPORT unsigned int XdmfBinaryControllerGetSeek(XDMFBINARYCONTROLLER * controller);
+
+XDMF_HEAVYCONTROLLER_C_CHILD_DECLARE(XdmfBinaryController, XDMFBINARYCONTROLLER, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFBinaryCONTROLLER_HPP_ */
diff --git a/core/XdmfConfig.hpp.in b/core/XdmfConfig.hpp.in
new file mode 100644
index 0000000..67cf82f
--- /dev/null
+++ b/core/XdmfConfig.hpp.in
@@ -0,0 +1,31 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfConfig.hpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFCONFIG_HPP_
+#define XDMFCONFIG_HPP_
+
+#cmakedefine HAVE_BOOST_SHARED_DYNAMIC_CAST
+#cmakedefine HAVE_CXX11_ENABLE_IF
+#cmakedefine XDMF_BIG_ENDIAN
+
+#endif /* XDMFSHAREDPTR_HPP_ */
diff --git a/core/XdmfCore.hpp b/core/XdmfCore.hpp
new file mode 100644
index 0000000..7d3b9a4
--- /dev/null
+++ b/core/XdmfCore.hpp
@@ -0,0 +1,73 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCore.hpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef _XDMF_HPP
+#ifndef _XDMFCORE_HPP
+#define _XDMFCORE_HPP
+
+#include "XdmfCoreConfig.hpp"
+
+/* Keep all our Win32 Conversions here */
+#ifdef _WIN32
+# ifdef XDMFSTATIC
+#   define XDMFCORE_EXPORT
+#   define XDMFCORE_TEMPLATE
+# else
+  /* Used to export/import from the dlls */
+#  ifdef XdmfCore_EXPORTS
+#    define XDMFCORE_EXPORT __declspec(dllexport)
+#    define XDMFCORE_TEMPLATE
+#   else /* Xdmf_EXPORTS */
+#    define XDMFCORE_EXPORT __declspec(dllimport)
+#    define XDMFCORE_TEMPLATE extern
+#   endif /* Xdmf_EXPORTS */
+# endif
+
+/* Used in XdmfSystemUtils */
+#define PATH_MAX _MAX_PATH
+#define realpath(x,y) _fullpath((char *) y,x, _MAX_PATH)
+
+/* Compiler Warnings */
+#ifndef XDMF_DEBUG
+#pragma warning( disable : 4231 ) /* nonstandard extension used : 'extern' before template explicit instantiation */
+#pragma warning( disable : 4251 ) /* needs to have dll-interface to be used by clients (Most of these guys are in private */
+#pragma warning( disable : 4275 ) /* non dll-interface class 'std::_Container_base_aux' used as base for dll-interface class */
+#pragma warning( disable : 4373 ) /* virtual function overrides,  parameters only differed by const/volatile qualifiers */
+#pragma warning( disable : 4101 ) /* 'exception' : unreferenced local variable */
+#pragma warning( disable : 4355 ) /* 'this' : used in base member initializer list */
+#pragma warning( disable : 4748 ) /* /GS can not protect parameters and local variables from local buffer overrun (turned off op)*/
+#endif /* XDMF_DEBUG */
+
+/* Compiler Optimizations will result in an 'internal compiler error', so turn them off */
+#pragma optimize("g", off)
+
+#else /* _WIN32 */
+
+/* We don't need to export/import since there are no dlls */
+#define XDMFCORE_EXPORT
+#define XDMFCORE_TEMPLATE
+
+#endif /* _WIN32 */
+
+#endif /* _XDMFCORE_HPP */
+#endif /*_XDMF_HPP */
diff --git a/core/XdmfCore.i b/core/XdmfCore.i
new file mode 100644
index 0000000..00f6401
--- /dev/null
+++ b/core/XdmfCore.i
@@ -0,0 +1,1382 @@
+/*
+XdmfCorePython.cpp:
+swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
+*/
+
+
+%module XdmfCore
+%{
+    #include <XdmfArray.hpp>
+    #include <XdmfArrayReference.hpp>
+    #include <XdmfArrayType.hpp>
+    #include <XdmfCore.hpp>
+    #include <XdmfCoreItemFactory.hpp>
+    #include <XdmfCoreReader.hpp>
+    #include <XdmfError.hpp>
+    #include <XdmfFunction.hpp>
+    #include <XdmfHeavyDataController.hpp>
+    #include <XdmfHeavyDataWriter.hpp>
+    #include <XdmfHDF5Controller.hpp>
+    #include <XdmfHDF5Writer.hpp>
+    #include <XdmfInformation.hpp>
+    #include <XdmfItem.hpp>
+    #include <XdmfItemProperty.hpp>
+    #include <XdmfSharedPtr.hpp>
+    #include <XdmfSparseMatrix.hpp>
+    #include <XdmfSubset.hpp>
+    #include <XdmfSystemUtils.hpp>
+    #include <XdmfTIFFController.hpp>
+    #include <XdmfVersion.hpp>
+    #include <XdmfVisitor.hpp>
+    #include <XdmfWriter.hpp>
+
+    #include <ProjectVersion.hpp>
+%}
+
+// Ignoring C Wrappers
+
+// XdmfItem
+
+%ignore XdmfItemAccept(XDMFITEM * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfItemFree(void * item);
+%ignore XdmfItemGetInformation(XDMFITEM * item, unsigned int index);
+%ignore XdmfItemGetInformationByKey(XDMFITEM * item, char * key);
+%ignore XdmfItemGetNumberInformations(XDMFITEM * item);
+%ignore XdmfItemInsertInformation(XDMFITEM * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfItemRemoveInformation(XDMFITEM * item, unsigned int index);
+%ignore XdmfItemRemoveInformationByKey(XDMFITEM * item, char * key);
+%ignore XdmfItemGetItemTag(XDMFITEM * item);
+
+// XdmfArray
+
+%ignore XdmfArrayNew();
+%ignore XdmfArrayClear(XDMFARRAY * array);
+%ignore XdmfArrayErase(XDMFARRAY * array, unsigned int index);
+%ignore XdmfArrayGetArrayType(XDMFARRAY * array, int * status);
+%ignore XdmfArrayGetCapacity(XDMFARRAY * array);
+%ignore XdmfArrayGetDimensions(XDMFARRAY * array);
+%ignore XdmfArrayGetDimensionsString(XDMFARRAY * array);
+%ignore XdmfArrayGetHeavyDataController(XDMFARRAY * array, unsigned int index);
+%ignore XdmfArrayGetReadMode(XDMFARRAY * array, int * status);
+%ignore XdmfArrayGetName(XDMFARRAY * array);
+%ignore XdmfArrayGetNumberDimensions(XDMFARRAY * array);
+%ignore XdmfArrayGetNumberHeavyDataControllers(XDMFARRAY * array);
+%ignore XdmfArrayGetSize(XDMFARRAY * array);
+%ignore XdmfArrayGetReference(XDMFARRAY * array);
+%ignore XdmfArrayGetValue(XDMFARRAY * array, unsigned int index, int arrayType, int * status);
+%ignore XdmfArrayGetValues(XDMFARRAY * array, unsigned int startIndex, int arrayType, unsigned int numValues, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfArrayGetValuesInternal(XDMFARRAY * array);
+%ignore XdmfArrayGetValuesString(XDMFARRAY * array);
+%ignore XdmfArrayInitialize(XDMFARRAY * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfArrayInsertDataFromPointer(XDMFARRAY * array, void * values, int arrayType, unsigned int startIndex, unsigned int numVals, unsigned int arrayStride, unsigned int valueStride, int * status);
+%ignore XdmfArrayInsertDataFromXdmfArray(XDMFARRAY * array, XDMFARRAY * valArray, int * arrayStarts, int * valueStarts, int * arrayCounts, int * valueCounts, int * arrayStrides, int * valueStrides, int * status);
+%ignore XdmfArrayInsertHeavyDataController(XDMFARRAY * array, XDMFHEAVYDATACONTROLLER * controller, int passControl);
+%ignore XdmfArrayInsertValue(XDMFARRAY * array, unsigned int index, void * value, int arrayType, int * status);
+%ignore XdmfArrayIsInitialized(XDMFARRAY * array);
+%ignore XdmfArrayPushBack(XDMFARRAY * array, void * value, int arrayType, int * status);
+%ignore XdmfArrayRead(XDMFARRAY * array, int * status);
+%ignore XdmfArrayReadController(XDMFARRAY * array, int * status);
+%ignore XdmfArrayReadReference(XDMFARRAY * array, int * status);
+%ignore XdmfArrayRelease(XDMFARRAY * array);
+%ignore XdmfArrayRemoveHeavyDataController(XDMFARRAY * array, unsigned int index);
+%ignore XdmfArrayReserve(XDMFARRAY * array, int size);
+%ignore XdmfArrayResize(XDMFARRAY * array, int * dims, int numDims, int arrayType, int * status);
+%ignore XdmfArraySetReadMode(XDMFARRAY * array, int readMode, int * status);
+%ignore XdmfArraySetReference(XDMFARRAY * array, XDMFARRAYREFERENCE * reference, int passControl);
+%ignore XdmfArraySetName(XDMFARRAY * array, char * name, int * status);
+%ignore XdmfArraySetValuesInternal(XDMFARRAY * array, void * pointer, unsigned int numValues, int arrayType, int transferOwnership, int * status);
+%ignore XdmfArraySwapWithXdmfArray(XDMFARRAY * array, XDMFARRAY * swapArray);
+%ignore XdmfArraySwapWithArray(XDMFARRAY * array, void ** pointer, int numValues, int arrayType, int * status);
+// XdmfArray inherited from XdmfItem
+%ignore XdmfArrayAccept(XDMFARRAY * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfArrayFree(void * item);
+%ignore XdmfArrayGetInformation(XDMFARRAY * item, unsigned int index);
+%ignore XdmfArrayGetInformationByKey(XDMFARRAY * item, char * key);
+%ignore XdmfArrayGetNumberInformations(XDMFARRAY * item);
+%ignore XdmfArrayInsertInformation(XDMFARRAY * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfArrayRemoveInformation(XDMFARRAY * item, unsigned int index);
+%ignore XdmfArrayRemoveInformationByKey(XDMFARRAY * item, char * key);
+%ignore XdmfArrayGetItemTag(XDMFARRAY * item);
+
+// XdmfArrayReference
+
+%ignore XdmfArrayReferenceGetConstructedType(XDMFARRAYREFERENCE * arrayReference);
+%ignore XdmfArrayReferenceRead(XDMFARRAYREFERENCE * arrayReference, int * status);
+%ignore XdmfArrayReferenceSetConstructedProperties(XDMFARRAYREFERENCE * arrayReference, void * referenceobject);
+%ignore XdmfArrayReferenceSetConstructedType(XDMFARRAYREFERENCE * arrayReference, char * newType);
+// XdmfArrayReference inherited from XdmfItem
+%ignore XdmfArrayReferenceAccept(XDMFARRAYREFERENCE * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfArrayReferenceFree(void * item);
+%ignore XdmfArrayReferenceGetInformation(XDMFARRAYREFERENCE * item, unsigned int index);
+%ignore XdmfArrayReferenceGetInformationByKey(XDMFARRAYREFERENCE * item, char * key);
+%ignore XdmfArrayReferenceGetNumberInformations(XDMFARRAYREFERENCE * item);
+%ignore XdmfArrayReferenceInsertInformation(XDMFARRAYREFERENCE * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfArrayReferenceRemoveInformation(XDMFARRAYREFERENCE * item, unsigned int index);
+%ignore XdmfArrayReferenceRemoveInformationByKey(XDMFARRAYREFERENCE * item, char * key);
+%ignore XdmfArrayReferenceGetItemTag(XDMFARRAYREFERENCE * item);
+
+// XdmfArrayType
+
+%ignore XdmfArrayTypeInt8();
+%ignore XdmfArrayTypeInt16();
+%ignore XdmfArrayTypeInt32();
+%ignore XdmfArrayTypeInt64();
+%ignore XdmfArrayTypeFloat32();
+%ignore XdmfArrayTypeFloat64();
+%ignore XdmfArrayTypeUInt8();
+%ignore XdmfArrayTypeUInt16();
+%ignore XdmfArrayTypeUInt32();
+%ignore XdmfArrayTypeComparePrecision(int type1, int type2, oint * status);
+%ignore XdmfArrayTypeGetElementSize(int type, int * status);
+%ignore XdmfArrayTypeGetIsSigned(int type, int * status);
+%ignore XdmfArrayTypeGetName(int type, int * status);
+
+// XdmfCoreReader
+
+%ignore XdmfCoreReaderRead(XDMFCOREREADER * reader, char * filePath, int * status);
+
+// XdmfError
+
+%ignore XdmfErrorSetCErrorsAreFatal(int status);
+%ignore XdmfErrorSetLevelLimit(int level, int * status);
+%ignore XdmfErrorSetSuppressionLevel(int level, int * status);
+%ignore XdmfErrorGetCErrorsAreFatal();
+%ignore XdmfErrorGetLevelLimit();
+%ignore XdmfErrorGetSuppressionLevel();
+
+// XdmfFunction
+
+%ignore XdmfFunctionNew();
+%ignore XdmfFunctionNewInit(char * newExpression,  char ** keys, XDMFARRAY ** values, int numVariables);
+%ignore XdmfFunctionAddFunction(char * name, XDMFARRAY *(*functionref)(XDMFARRAY **, unsigned int), int * status);
+%ignore XdmfFunctionAddOperation(char newoperator, XDMFARRAY *(*operationref)(XDMFARRAY *, XDMFARRAY *), int priority, int * status);
+%ignore XdmfFunctionAverage(XDMFARRAY ** values, int numValues);
+%ignore XdmfFunctionChunk(XDMFARRAY * val1, XDMFARRAY * val2, int * status);
+%ignore XdmfFunctionEvaluateExpression(char * expression, char ** keys, XDMFARRAY ** values, int numVariables, int * status);
+%ignore XdmfFunctionEvaluateOperation(XDMFARRAY * val1, XDMFARRAY * val2, char operation, int * status);
+%ignore XdmfFunctionEvaluateFunction(XDMFARRAY ** valueVector, int numValues, char * functionName, int * status);
+%ignore XdmfFunctionGetExpression(XDMFFUNCTION * function);
+%ignore XdmfFunctionGetNumberVariables(XDMFFUNCTION * function);
+%ignore XdmfFunctionGetOperationPriority(char operation);
+%ignore XdmfFunctionGetSupportedOperations();
+%ignore XdmfFunctionGetSupportedFunctions();
+%ignore XdmfFunctionGetNumberSupportedFunctions();
+%ignore XdmfFunctionGetValidDigitChars();
+%ignore XdmfFunctionGetValidVariableChars();
+%ignore XdmfFunctionGetVariable(XDMFFUNCTION * function, char * key);
+%ignore XdmfFunctionGetVariableList(XDMFFUNCTION * function);
+%ignore XdmfFunctionInterlace(XDMFARRAY * val1, XDMFARRAY * val2, int * status);
+%ignore XdmfFunctionInsertVariable(XDMFFUNCTION * function, char * key, XDMFARRAY * value, int passControl);
+%ignore XdmfFunctionRemoveVariable(XDMFFUNCTION * function, char * key);
+%ignore XdmfFunctionSetExpression(XDMFFUNCTION * function, char * newExpression, int * status);
+%ignore XdmfFunctionSum(XDMFARRAY ** values, int numValues);
+// XdmfFunction inherited from XdmfItem
+%ignore XdmfFunctionAccept(XDMFFUNCTION * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfFunctionFree(void * item);
+%ignore XdmfFunctionGetInformation(XDMFFUNCTION * item, unsigned int index);
+%ignore XdmfFunctionGetInformationByKey(XDMFFUNCTION * item, char * key);
+%ignore XdmfFunctionGetNumberInformations(XDMFFUNCTION * item);
+%ignore XdmfFunctionInsertInformation(XDMFFUNCTION * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfFunctionRemoveInformation(XDMFFUNCTION * item, unsigned int index);
+%ignore XdmfFunctionRemoveInformationByKey(XDMFFUNCTION * item, char * key);
+%ignore XdmfFunctionGetItemTag(XDMFFUNCTION * item);
+// XdmfFunction inherited from XdmfArrayReference
+%ignore XdmfFunctionGetConstructedType(XDMFFUNCTION * arrayReference);
+%ignore XdmfFunctionRead(XDMFFUNCTION * arrayReference, int * status);
+%ignore XdmfFunctionSetConstructedProperties(XDMFFUNCTION * arrayReference, void * referenceobject);
+%ignore XdmfFunctionSetConstructedType(XDMFFUNCTION * arrayReference, char * newType);
+
+// XdmfHDF5Controller
+
+%ignore XdmfHDF5ControllerNew(char * hdf5FilePath, char * dataSetPath, int type, unsigned int * start, unsigned int * stride, unsigned int * dimensions, unsigned int * dataspaceDimensions, unsigned int numDims, int * status);
+%ignore XdmfHDF5ControllerGetDataSetPath(XDMFHDF5CONTROLLER * controller);
+// XdmfHDF5Controller inherited from XdmfHeavyDataController
+%ignore XdmfHDF5ControllerFree(XDMFHDF5CONTROLLER * item);
+%ignore XdmfHDF5ControllerGetDataspaceDimensions(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetDimensions(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetFilePath(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetName(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetNumberDimensions(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetSize(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetStart(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetStride(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerSetArrayOffset(XDMFHDF5CONTROLLER * controller, unsigned int newOffset);
+%ignore XdmfHDF5ControllerGetArrayOffset(XDMFHDF5CONTROLLER * controller);
+%ignore XdmfHDF5ControllerGetType(XDMFHDF5CONTROLLER * controller, int * status);
+%ignore XdmfHDF5ControllerRead(XDMFHDF5CONTROLLER * controller, void * array, int * status);
+
+// XdmfHDF5Writer
+
+%ignore XdmfHDF5WriterNew(char * fileName, int clobberFile);
+%ignore XdmfHDF5WriterCloseFile(XDMFHDF5WRITER * writer, int * status);
+%ignore XdmfHDF5WriterGetChunkSize(XDMFHDF5WRITER * writer, int * status);
+%ignore XdmfHDF5WriterOpenFile(XDMFHDF5WRITER * writer, int * status);
+%ignore XdmfHDF5WriterSetChunkSize(XDMFHDF5WRITER * writer, unsigned int chunkSize, int * status);
+// XdmfHDF5Writer inherited from XdmfHeavyDataWriter
+%ignore XdmfHDF5WriterFree(XDMFHDF5WRITER * item);
+%ignore XdmfHDF5WriterGetAllowSetSplitting(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterGetFileIndex(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterGetFileOverhead(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterGetFilePath(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterGetFileSizeLimit(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterGetMode(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterGetReleaseData(XDMFHDF5WRITER * writer);
+%ignore XdmfHDF5WriterSetAllowSetSplitting(XDMFHDF5WRITER * writer, int newAllow);
+%ignore XdmfHDF5WriterSetFileIndex(XDMFHDF5WRITER * writer, int newIndex);
+%ignore XdmfHDF5WriterSetFileSizeLimit(XDMFHDF5WRITER * writer, int newSize);
+%ignore XdmfHDF5WriterSetMode(XDMFHDF5WRITER * writer, int mode, int * status);
+%ignore XdmfHDF5WriterSetReleaseData(XDMFHDF5WRITER * writer, int releaseData);
+
+// XdmfHeavyDataController
+
+%ignore XdmfHeavyDataControllerFree(XDMFHEAVYDATACONTROLLER * item);
+%ignore XdmfHeavyDataControllerGetDataspaceDimensions(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetDimensions(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetFilePath(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetName(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetNumberDimensions(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetSize(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetStart(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetStride(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerSetArrayOffset(XDMFHEAVYDATACONTROLLER * controller, unsigned int newOffset);
+%ignore XdmfHeavyDataControllerGetArrayOffset(XDMFHEAVYDATACONTROLLER * controller);
+%ignore XdmfHeavyDataControllerGetType(XDMFHEAVYDATACONTROLLER * controller, int * status);
+%ignore XdmfHeavyDataControllerRead(XDMFHEAVYDATACONTROLLER * controller, void * array, int * status);
+
+// XdmfHeavyDataWriter
+
+%ignore XdmfHeavyDataWriterFree(XDMFHEAVYDATAWRITER * item);
+%ignore XdmfHeavyDataWriterGetAllowSetSplitting(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterGetFileIndex(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterGetFileOverhead(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterGetFilePath(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterGetFileSizeLimit(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterGetMode(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterGetReleaseData(XDMFHEAVYDATAWRITER * writer);
+%ignore XdmfHeavyDataWriterSetAllowSetSplitting(XDMFHEAVYDATAWRITER * writer, int newAllow);
+%ignore XdmfHeavyDataWriterSetFileIndex(XDMFHEAVYDATAWRITER * writer, int newIndex);
+%ignore XdmfHeavyDataWriterSetFileSizeLimit(XDMFHEAVYDATAWRITER * writer, int newSize);
+%ignore XdmfHeavyDataWriterSetMode(XDMFHEAVYDATAWRITER * writer, int mode, int * status);
+%ignore XdmfHeavyDataWriterSetReleaseData(XDMFHEAVYDATAWRITER * writer, int releaseData);
+
+// XdmfInformation
+
+%ignore XdmfInformationNew(char * key, char * value);
+%ignore XdmfInformationGetArray(XDMFINFORMATION * information, unsigned int index);
+%ignore XdmfInformationGetArrayByName(XDMFINFORMATION * information, char * name);
+%ignore XdmfInformationGetKey(XDMFINFORMATION * information);
+%ignore XdmfInformationGetNumberArrays(XDMFINFORMATION * information);
+%ignore XdmfInformationGetValue(XDMFINFORMATION * information);
+%ignore XdmfInformationInsertArray(XDMFINFORMATION * information, XDMFARRAY * array, int transferOwnership);
+%ignore XdmfInformationRemoveArray(XDMFINFORMATION * information, unsigned int index);
+%ignore XdmfInformationRemoveArrayByName(XDMFINFORMATION * information, char * name);
+%ignore XdmfInformationSetKey(XDMFINFORMATION * information, char * key, int * status);
+%ignore XdmfInformationSetValue(XDMFINFORMATION * information, char * value, int * status);
+// XdmfInformation inherited from XdmfItem
+%ignore XdmfInformationAccept(XDMFINFORMATION * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfInformationFree(void * item);
+%ignore XdmfInformationGetInformation(XDMFINFORMATION * item, unsigned int index);
+%ignore XdmfInformationGetInformationByKey(XDMFINFORMATION * item, char * key);
+%ignore XdmfInformationGetNumberInformations(XDMFINFORMATION * item);
+%ignore XdmfInformationInsertInformation(XDMFINFORMATION * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfInformationRemoveInformation(XDMFINFORMATION * item, unsigned int index);
+%ignore XdmfInformationRemoveInformationByKey(XDMFINFORMATION * item, char * key);
+%ignore XdmfInformationGetItemTag(XDMFINFORMATION * item);
+
+// XdmfSparseMatrix
+
+%ignore XdmfSparseMatrixNew(unsigned int numberRows, unsigned int numberColumns);
+%ignore XdmfSparseMatrixGetColumnIndex(XDMFSPARSEMATRIX * matrix, int * status);
+%ignore XdmfSparseMatrixGetName(XDMFSPARSEMATRIX * matrix);
+%ignore XdmfSparseMatrixGetNumberColumns(XDMFSPARSEMATRIX * matrix);
+%ignore XdmfSparseMatrixGetNumberRows(XDMFSPARSEMATRIX * matrix);
+%ignore XdmfSparseMatrixGetRowPointer(XDMFSPARSEMATRIX * matrix, int * status);
+%ignore XdmfSparseMatrixGetValues(XDMFSPARSEMATRIX * matrix, int * status);
+%ignore XdmfSparseMatrixGetValuesString(XDMFSPARSEMATRIX * matrix, int * status);
+%ignore XdmfSparseMatrixSetColumnIndex(XDMFSPARSEMATRIX * matrix,
+                                       XDMFARRAY * columnIndex,
+                                       int passControl,
+                                       int * status);
+%ignore XdmfSparseMatrixSetName(XDMFSPARSEMATRIX * matrix, char * name, int * status);
+%ignore XdmfSparseMatrixSetRowPointer(XDMFSPARSEMATRIX * matrix,
+                                      XDMFARRAY * rowPointer,
+                                      int passControl,
+                                      int * status);
+%ignore XdmfSparseMatrixSetValues(XDMFSPARSEMATRIX * matrix,
+                                  XDMFARRAY * values,
+                                  int passControl,
+                                  int * status);
+// XdmfSparseMatrix inherited from XdmfItem
+%ignore XdmfSparseMatrixAccept(XDMFSPARSEMATRIX * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfSparseMatrixFree(void * item);
+%ignore XdmfSparseMatrixGetInformation(XDMFSPARSEMATRIX * item, unsigned int index);
+%ignore XdmfSparseMatrixGetInformationByKey(XDMFSPARSEMATRIX * item, char * key);
+%ignore XdmfSparseMatrixGetNumberInformations(XDMFSPARSEMATRIX * item);
+%ignore XdmfSparseMatrixInsertInformation(XDMFSPARSEMATRIX * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfSparseMatrixRemoveInformation(XDMFSPARSEMATRIX * item, unsigned int index);
+%ignore XdmfSparseMatrixRemoveInformationByKey(XDMFSPARSEMATRIX * item, char * key);
+%ignore XdmfSparseMatrixGetItemTag(XDMFSPARSEMATRIX * item);
+
+// XdmfSubset
+
+%ignore XdmfSubsetNew(void * referenceArray,
+                      unsigned int * start,
+                      unsigned int * stride,
+                      unsigned int * dimensions,
+                      unsigned int numDims,
+                      int passControl,
+                      int * status);
+%ignore XdmfSubsetGetDimensions(XDMFSUBSET * subset);
+%ignore XdmfSubsetGetNumberDimensions(XDMFSUBSET * subset);
+%ignore XdmfSubsetGetReferenceArray(XDMFSUBSET * subset);
+%ignore XdmfSubsetGetSize(XDMFSUBSET * subset);
+%ignore XdmfSubsetGetStart(XDMFSUBSET * subset);
+%ignore XdmfSubsetGetStride(XDMFSUBSET * subset);
+%ignore XdmfSubsetSetDimensions(XDMFSUBSET * subset,
+                                unsigned int * newDimensions,
+                                unsigned int numDims,
+                                int * status);
+%ignore XdmfSubsetSetReferenceArray(XDMFSUBSET * subset,
+                                    XDMFARRAY * referenceArray,
+                                    int passControl);
+%ignore XdmfSubsetSetStart(XDMFSUBSET * subset,
+                           unsigned int * newStarts,
+                           unsigned int numDims,
+                           int * status);
+%ignore XdmfSubsetSetStride(XDMFSUBSET * subset,
+                            unsigned int * newStrides,
+                            unsigned int numDims,
+                            int * status);
+// XdmfSubset inherited from XdmfItem
+%ignore XdmfSubsetAccept(XDMFSUBSET * item, XDMFVISITOR * visitor, int * status);
+%ignore XdmfSubsetFree(void * item);
+%ignore XdmfSubsetGetInformation(XDMFSUBSET * item, unsigned int index);
+%ignore XdmfSubsetGetInformationByKey(XDMFSUBSET * item, char * key);
+%ignore XdmfSubsetGetNumberInformations(XDMFSUBSET * item);
+%ignore XdmfSubsetInsertInformation(XDMFSUBSET * item, XDMFINFORMATION * information, int passControl);
+%ignore XdmfSubsetRemoveInformation(XDMFSUBSET * item, unsigned int index);
+%ignore XdmfSubsetRemoveInformationByKey(XDMFSUBSET * item, char * key);
+%ignore XdmfSubsetGetItemTag(XDMFSUBSET * item);
+// XdmfSubset inherited from XdmfArrayReference
+%ignore XdmfSubsetGetConstructedType(XDMFSUBSET * arrayReference);
+%ignore XdmfSubsetRead(XDMFSUBSET * arrayReference, int * status);
+%ignore XdmfSubsetSetConstructedProperties(XDMFSUBSET * arrayReference, void * referenceobject);
+%ignore XdmfSubsetSetConstructedType(XDMFSUBSET * arrayReference, char * newType);
+
+// XdmfWriter
+
+%ignore XdmfWriterNew(char * fileName);
+%ignore XdmfWriterNewSpecifyHeavyDataWriter(char * fileName, XDMFHEAVYDATAWRITER * heavyDataWriter);
+%ignore XdmfWriterFree(XDMFWRITER * item);
+%ignore XdmfWriterGetFilePath(XDMFWRITER * writer, int * status);
+%ignore XdmfWriterGetHeavyDataWriter(XDMFWRITER * writer, int * status);
+%ignore XdmfWriterGetLightDataLimit(XDMFWRITER * writer, int * status);
+%ignore XdmfWriterGetMode(XDMFWRITER * writer, int * status);
+%ignore XdmfWriterGetWriteXPaths(XDMFWRITER * writer, int * status);
+%ignore XdmfWriterGetXPathParse(XDMFWRITER * writer, int * status);
+%ignore XdmfWriterSetHeavyDataWriter(XDMFWRITER * writer,
+                                     XDMFHEAVYDATAWRITER * heavyDataWriter,
+                                     int transferOwnership,
+                                     int * status);
+%ignore XdmfWriterSetLightDataLimit(XDMFWRITER * writer, unsigned int numValues, int * status);
+%ignore XdmfWriterSetMode(XDMFWRITER * writer, int mode, int * status);
+%ignore XdmfWriterSetWriteXPaths(XDMFWRITER * writer, int writeXPaths, int * status);
+%ignore XdmfWriterSetXPathParse(XDMFWRITER * writer, int xPathParse, int * status);
+
+#ifdef SWIGJAVA
+
+// Ignore const overloaded methods
+%ignore XdmfArray::getHeavyDataController() const;
+%ignore XdmfArray::getValuesInternal() const;
+%ignore XdmfItem::getInformation(const unsigned int) const;
+%ignore XdmfItem::getInformation(const std::string &) const;
+%ignore XdmfWriter::getHeavyDataWriter() const;
+%ignore XdmfInformation::getArray(unsigned int const) const;
+%ignore XdmfInformation::getArray(std::string const &) const;
+
+// Ignore ItemTags
+%ignore XdmfArray::ItemTag;
+%ignore XdmfInformation::ItemTag;
+
+// Define equality operators
+%extend XdmfItem {
+
+    bool equals(boost::shared_ptr<XdmfItem> item) {
+        if (item == NULL) {
+            return false;
+        }
+        return self == item.get();
+    }
+
+    bool IsEqual(boost::shared_ptr<XdmfItem> item) {
+        if (item == NULL) {
+            return false;
+        }
+        return self == item.get();
+    }
+};
+
+%extend XdmfItemProperty {
+
+    bool equals(boost::shared_ptr<XdmfItemProperty> itemProperty) {
+        if (itemProperty == NULL) {
+            return false;
+        }
+        return self == itemProperty.get();
+    }
+
+    bool IsEqual(boost::shared_ptr<XdmfItemProperty> itemProperty) {
+        if (itemProperty == NULL) {
+            return false;
+        }
+        return self == itemProperty.get();
+    }
+
+};
+
+%typemap(javacode) XdmfArray %{
+    public void insertValuesAsInt8(int index, char[] values) {
+        for(int i = 0; i < values.length; i++)
+            this.insertValueAsInt8(index+i, values[i]);
+    }
+
+    public void insertValuesAsInt16(int index, short[] values) {
+        for(int i = 0; i < values.length; i++)
+            this.insertValueAsInt16(index+i, values[i]);
+    }
+
+    public void insertValuesAsInt32(int index, int[] values) {
+        for(int i = 0; i < values.length; i++)
+            this.insertValueAsInt32(index+i, values[i]);
+    }
+
+    public void insertValuesAsFloat32(int index, float[] values) {
+        for(int i = 0; i < values.length; i++)
+            this.insertValueAsFloat32(index+i, values[i]);
+    }
+
+    public void insertValuesAsFloat64(int index, double[] values) {
+        for(int i = 0; i < values.length; i++)
+            this.insertValueAsFloat64(index+i, values[i]);
+    }
+%}
+
+%pragma(java) jniclasscode=%{
+    static {
+        try {
+            System.loadLibrary("XdmfCoreJava");
+        }
+        catch (UnsatisfiedLinkError e) {
+            System.err.println("Native code library failed to load for" +
+                               "XdmfCoreJava\n" + e);
+            System.exit(1);
+        }
+    }
+%}
+
+#endif /* SWIGJAVA */
+
+#ifdef SWIGPYTHON
+
+%ignore XdmfArray::insert(const unsigned int startIndex, const T * const valuesPointer, const unsigned int numValues, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1);
+%ignore XdmfArray::pushBack(const T & value);
+
+/*This converts XdmfErrors to Python RuntimeErrors*/
+%exception
+{
+        try
+        {
+                $action
+        }
+        catch (XdmfError e)
+        {
+                PyErr_SetString(PyExc_RuntimeError, e.what());
+                return NULL;
+        }
+}
+
+/*This causes it to avoid throwing a warning about overloaded functions.
+  We are doing this intentionally so suppressing the warning makes sense.*/
+#pragma SWIG nowarn=509
+
+%extend XdmfItem {
+    bool __eq__(const XdmfItem * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfItemProperty {
+    bool __eq__(const XdmfItemProperty * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfVisitor {
+    bool __eq__(const XdmfVisitor * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfHeavyDataWriter {
+    bool __eq__(const XdmfHeavyDataWriter * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfHeavyDataController {
+    bool __eq__(const XdmfHeavyDataController * item) {
+        return $self == item;
+    }
+
+    static shared_ptr<XdmfHDF5Controller> XdmfHDF5ControllerCast(PyObject * obj)
+    {
+      void * resultPointer = 0;
+      swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfHeavyDataController_t");
+      SWIG_ConvertPtr(obj, &resultPointer, returnType, 0);
+      shared_ptr<XdmfHeavyDataController> * returnControllerPointer =
+        reinterpret_cast<shared_ptr<XdmfHeavyDataController> *>(resultPointer);
+      shared_ptr<XdmfHeavyDataController> returnController = returnControllerPointer[0];
+      if (shared_ptr<XdmfHDF5Controller> returnHDF5Controller = shared_dynamic_cast<XdmfHDF5Controller>(returnController)) {
+        return returnHDF5Controller;
+      }
+      else {
+        XdmfError::message(XdmfError::FATAL, "Error: Attempting to cast a non HDF5 Controller to HDF5");
+        return shared_ptr<XdmfHDF5Controller>();
+      }
+    }
+};
+
+%extend XdmfCoreReader {
+    bool __eq__(const XdmfCoreReader * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfWriter {
+    bool __eq__(const XdmfWriter * item) {
+        return $self == item;
+    }
+};
+
+// Provide accessors from python lists to XdmfArrays
+%extend XdmfArray {
+
+    PyObject * getBuffer() {
+        void *vp = $self->getValuesInternal();
+        Py_ssize_t sz =
+            $self->getSize() * $self->getArrayType()->getElementSize();
+        PyObject * c = PyBuffer_FromMemory(vp, sz);
+        return(c);
+    }
+
+    %pythoncode {
+        def getNumpyArray(self):
+            h5ctl = self.getHeavyDataController()
+            if h5ctl == None :
+                try :
+                    from numpy import frombuffer as ___frombuffer
+                except :
+                    return None
+                buf = self.getBuffer()
+                aType = self.getArrayType()
+                if aType == XdmfArrayType.Int8() :
+                    return(___frombuffer(buf, 'int8'))
+                if aType == XdmfArrayType.Int16() :
+                    return(___frombuffer(buf, 'int16'))
+                if aType == XdmfArrayType.Int32() :
+                    return(___frombuffer(buf, 'int32'))
+                if aType == XdmfArrayType.Int64() :
+                    return(___frombuffer(buf, 'int64'))
+                if aType == XdmfArrayType.Float32() :
+                    return(___frombuffer(buf, 'float32'))
+                if aType == XdmfArrayType.Float64() :
+                    return(___frombuffer(buf, 'float64'))
+                if aType == XdmfArrayType.UInt8() :
+                    return(___frombuffer(buf, 'uint8'))
+                if aType == XdmfArrayType.UInt16() :
+                    return(___frombuffer(buf, 'uint16'))
+                if aType == XdmfArrayType.UInt32() :
+                    return(___frombuffer(buf, 'uint32'))
+                return None
+            else :
+                if  h5ctl.getName() == "HDF":
+                  controller = XdmfHeavyDataController.XdmfHDF5ControllerCast(h5ctl)
+                  h5FileName = controller.getFilePath()
+                  h5DataSetName = controller.getDataSetPath()
+                  if (h5FileName == None) | (h5DataSetName == None) :
+                      return None
+                  try :
+                      from h5py import File as ___File
+                      from numpy import array as ___array
+                      f = ___File(h5FileName, 'r')
+                      if h5DataSetName in f.keys() :
+                          return(___array(f[h5DataSetName]))
+                  except :
+                      pass
+                  return None
+                else:
+                  return None
+
+    };
+
+    void getValues(unsigned int startIndex, PyObject * list, unsigned int numValues = 1, unsigned int arrayStride = 1, unsigned int valuesStride = 1)
+    {
+      Py_ssize_t size = PyList_Size(list);
+      PyObject * placeholderVal;
+      if (valuesStride * numValues > size)
+      {
+        if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int8())
+        {
+          placeholderVal = PyLong_FromLong((char)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int16())
+        {
+          placeholderVal = PyLong_FromLong((short)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int32())
+        {
+          placeholderVal = PyLong_FromLong((int)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int64())
+        {
+          placeholderVal = PyLong_FromLong((long)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Float32())
+        {
+          placeholderVal = PyFloat_FromDouble((float)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Float64())
+        {
+          placeholderVal = PyFloat_FromDouble((double)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::UInt8())
+        {
+          placeholderVal = PyLong_FromUnsignedLong((unsigned char)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::UInt16())
+        {
+          placeholderVal = PyLong_FromUnsignedLong((unsigned short)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::UInt32())
+        {
+          placeholderVal = PyLong_FromUnsignedLong((unsigned int)0);
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::String())
+        {
+          placeholderVal = PyString_FromString("");
+        }
+      }
+      for (unsigned int i = 0; i < numValues; ++i)
+      {
+        unsigned int index = startIndex + (i * arrayStride);
+        unsigned int insertIndex = i * valuesStride;
+        PyObject * insertedVal;
+        if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int8())
+        {
+          insertedVal = PyLong_FromLong($self->XdmfArray::getValue<char>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int16())
+        {
+          insertedVal = PyLong_FromLong($self->XdmfArray::getValue<short>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int32())
+        {
+          insertedVal = PyLong_FromLong($self->XdmfArray::getValue<int>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Int64())
+        {
+          insertedVal = PyLong_FromLong($self->XdmfArray::getValue<long>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Float32())
+        {
+          insertedVal = PyFloat_FromDouble($self->XdmfArray::getValue<float>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::Float64())
+        {
+          insertedVal = PyFloat_FromDouble($self->XdmfArray::getValue<double>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::UInt8())
+        {
+          insertedVal = PyLong_FromUnsignedLong($self->XdmfArray::getValue<unsigned char>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::UInt16())
+        {
+          insertedVal = PyLong_FromUnsignedLong($self->XdmfArray::getValue<unsigned short>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::UInt32())
+        {
+          insertedVal = PyLong_FromUnsignedLong($self->XdmfArray::getValue<unsigned int>(index));
+        }
+        else if ($self->XdmfArray::getArrayType() == XdmfArrayType::String())
+        {
+          insertedVal = PyString_FromString($self->XdmfArray::getValue<std::string>(index).c_str());
+        }
+        if (insertIndex < size)
+        {
+          PyList_SetItem(list, insertIndex, insertedVal);
+        }
+        else
+        {
+          for (unsigned int padding = size; padding < insertIndex; ++padding)
+          {
+            PyList_Append(list, placeholderVal);
+            ++size;
+          }
+          PyList_Append(list, insertedVal);
+          ++size;
+        }
+      }
+    }
+
+    void insertAsInt8(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (char) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (char)PyLong_AsLong(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    void insertAsInt16(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (short) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (short)PyLong_AsLong(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    void insertAsInt32(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (int) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (int)PyLong_AsLong(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    void insertAsInt64(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (long) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, PyLong_AsLong(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    void insertAsFloat32(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (float) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (float)PyFloat_AsDouble(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    void insertAsFloat64(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (double) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, PyFloat_AsDouble(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    void insertAsUInt8(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (unsigned char) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (unsigned char)(PyLong_AsUnsignedLong(PyList_GetItem(list, listStartIndex + (i * listStride)))));
+            }
+        }
+    }
+
+    void insertAsUInt16(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (unsigned short) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (unsigned short)(PyLong_AsUnsignedLong(PyList_GetItem(list, listStartIndex + (i * listStride)))));
+            }
+        }
+    }
+
+    void insertAsUInt32(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert(i+startIndex, (unsigned int) 0);
+            }
+            else {
+              $self->insert((i * arrayStride) + startIndex, (unsigned int)(PyLong_AsUnsignedLong(PyList_GetItem(list, listStartIndex + (i * listStride)))));
+            }
+        }
+    }
+
+    void insertAsString(int startIndex, PyObject * list, int listStartIndex = 0, int numValues = -1, int arrayStride = 1, int listStride = 1) {
+        Py_ssize_t size;
+        if (numValues <= 0) {
+          size = PyList_Size(list);
+        }
+        else {
+          size = numValues;
+        }
+        for(Py_ssize_t i = 0; i < size; ++i) {
+            if (listStartIndex + (i * listStride) >= PyList_Size(list)) {
+              $self->insert<std::string>(i+startIndex, "");
+            }
+            else {
+              $self->insert<std::string>((i * arrayStride) + startIndex, PyString_AsString(PyList_GetItem(list, listStartIndex + (i * listStride))));
+            }
+        }
+    }
+
+    static shared_ptr<XdmfArray> XdmfArrayPtr(PyObject * obj)
+    {
+      void * resultPointer = 0;
+      swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
+      SWIG_ConvertPtr(obj, &resultPointer, returnType, 0);
+      shared_ptr<XdmfArray> * returnArrayPointer = reinterpret_cast<shared_ptr<XdmfArray> *>(resultPointer);
+      shared_ptr<XdmfArray> returnArray = returnArrayPointer[0];
+      return returnArray;
+    }
+
+    void
+    pushBackAsInt8(const char & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsInt16(const short & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsInt32(const int & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsInt64(const long & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsUInt8(const unsigned char & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsUInt16(const unsigned short & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsUInt32(const unsigned int & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsFloat32(const float & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsFloat64(const double & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    pushBackAsString(const std::string & value)
+    {
+      $self->XdmfArray::pushBack(value);
+    }
+
+    void
+    insertValueAsInt8(const unsigned int startIndex, const char * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, valuesPointer, numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsInt8(const unsigned int startIndex, const char value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsInt16(const unsigned int startIndex, const short * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, valuesPointer, numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsInt16(const unsigned int startIndex, const short value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsInt32(const unsigned int startIndex, const int * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, valuesPointer, numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsInt32(const unsigned int startIndex, const int value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsInt64(const unsigned int startIndex, const long * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, valuesPointer, numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsInt64(const unsigned int startIndex, const long value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsUInt8(const unsigned int startIndex, const unsigned char * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, valuesPointer, numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsUInt8(const unsigned int startIndex, const unsigned char value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsUInt16(const unsigned int startIndex, const unsigned short * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, valuesPointer, numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsUInt16(const unsigned int startIndex, const unsigned short value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsUInt32(const unsigned int startIndex, const unsigned int * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, (unsigned int *)(valuesPointer), numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsUInt32(const unsigned int startIndex, const unsigned int value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsFloat32(const unsigned int startIndex, const float * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, (float *)(&valuesPointer), numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsFloat32(const unsigned int startIndex, const float value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsFloat64(const unsigned int startIndex, const double * const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      $self->XdmfArray::insert(startIndex, (double *)(valuesPointer), numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsFloat64(const unsigned int startIndex, const double value)
+    {
+      $self->XdmfArray::insert(startIndex, value);
+    }
+
+    void
+    insertValueAsString(const unsigned int startIndex, const char ** const valuesPointer, const unsigned int numValues = 1, const unsigned int arrayStride = 1, const unsigned int valuesStride = 1)
+    {
+      std::string * tempPointer = new std::string[numValues]();
+      for (unsigned int i = 0; i < numValues; ++i)
+      {
+        tempPointer[i] = std::string(valuesPointer[i]);
+      }
+      $self->XdmfArray::insert(startIndex, (std::string *)(tempPointer), numValues, arrayStride, valuesStride);
+    }
+
+    void
+    insertValueAsString(const unsigned int startIndex, const char * value)
+    {
+      $self->XdmfArray::insert(startIndex, std::string(value));
+    }
+};
+
+/*This causes it to avoid throwing a warning for redefining fuctions that are defined for XdmfArray.
+  I do this because doing so was intentional.*/
+#pragma SWIG nowarn=302
+/*Warning 325 is due to having nested classes in XdmfFunction that are not accessible when wrapped.
+  As of right now, this is acceptable behavior. So, the warning is suppressed*/
+#pragma SWIG nowarn=325
+
+%extend XdmfFunction {
+
+%{
+    /*trying to transfer python functions*/
+    /*note, accessing private members is impossible from swig.*/
+
+
+    /*Class to wrap python functions to be compatible with the XdmfFunction code.
+      This version has an execute that takes a vector of XdmfArrays as parameters,
+      so it is used for functions.*/
+    class PythonFunction : public XdmfFunction::XdmfFunctionInternal {
+      public:
+        static shared_ptr<PythonFunction>
+        New(PyObject * functionref)
+        {
+          shared_ptr<PythonFunction> p (new PythonFunction(functionref));
+          return p;
+        }
+
+        ~PythonFunction()
+        {
+        }
+
+        virtual shared_ptr<XdmfArray> execute(std::vector<shared_ptr<XdmfArray> > valueVector)
+        {
+          swig_type_info * paramType = SWIG_TypeQuery("_p_std__vectorT_boost__shared_ptrT_XdmfArray_t_std__allocatorT_boost__shared_ptrT_XdmfArray_t_t_t");
+          PyObject * pyVector = SWIG_NewPointerObj(static_cast<void*>(& valueVector), paramType, SWIG_POINTER_NEW);
+          PyObject * args = PyTuple_New(1);
+          /* In this case you could also cast a pointer to the vector
+             into the PyObject * type, but that doesn't work for all types*/
+          PyTuple_SetItem(args, 0, pyVector);
+          PyObject * resultObject = PyObject_CallObject(mInternalFunction, args);
+          void * resultPointer = 0;
+          swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
+          SWIG_ConvertPtr(resultObject, &resultPointer, returnType, 0);
+          shared_ptr<XdmfArray> * returnArrayPointer = reinterpret_cast<shared_ptr<XdmfArray> *>(resultPointer);
+          shared_ptr<XdmfArray> returnArray = returnArrayPointer[0];
+          return returnArray;
+        }
+      private:
+        PythonFunction(PyObject * functionref)
+        {
+          if (PyCallable_Check(functionref) == 1) {
+            mInternalFunction = functionref;
+          }
+          else {
+            XdmfError::message(XdmfError::FATAL,
+                               "Error: Function is not callable");
+          }
+        }
+
+        PyObject * mInternalFunction;
+    };
+
+    /*Class to wrap python functions to be compatible with the XdmfFunction Operation code.
+      This version has an execute that takes two XdmfArrays as parameters,
+      so it is used for binary operators.*/
+    class PythonOperation : public XdmfFunction::XdmfOperationInternal {
+      public:
+        static shared_ptr<PythonOperation>
+        New(PyObject * operationref)
+        {
+          shared_ptr<PythonOperation> p (new PythonOperation(operationref));
+          return p;
+        }
+
+        ~PythonOperation()
+        {
+        }
+
+        virtual shared_ptr<XdmfArray> execute(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+        {
+          swig_type_info * paramType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
+          PyObject * pyVal1 = SWIG_NewPointerObj(static_cast<void*>(& val1), paramType, SWIG_POINTER_NEW);
+          PyObject * pyVal2 = SWIG_NewPointerObj(static_cast<void*>(& val2), paramType, SWIG_POINTER_NEW);
+          PyObject * args = PyTuple_New(2);
+          PyTuple_SetItem(args, 0, pyVal1);
+          PyTuple_SetItem(args, 1, pyVal2);
+          PyObject * resultObject = PyObject_CallObject(mInternalOperation, args);
+          void * resultPointer = 0;
+          swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfArray_t");
+          SWIG_ConvertPtr(resultObject, &resultPointer, returnType, 0);
+          shared_ptr<XdmfArray> * returnArrayPointer = reinterpret_cast<shared_ptr<XdmfArray> *>(resultPointer);
+          shared_ptr<XdmfArray> returnArray = returnArrayPointer[0];
+          return returnArray;
+        }
+      private:
+        PythonOperation(PyObject * operationref)
+        {
+          if (PyCallable_Check(operationref) == 1) {
+            mInternalOperation = operationref;
+          }
+          else {
+            XdmfError::message(XdmfError::FATAL,
+                               "Error: Operation is not callable");
+          }
+        }
+
+        PyObject * mInternalOperation;
+    };
+%}
+
+    static int addFunction(std::string newName, PyObject * functionref)
+    {
+      shared_ptr<PythonFunction> newFunction = PythonFunction::New(functionref);
+      return XdmfFunction::addFunction(newName, newFunction);
+    }
+
+    static int addOperation(char newName, PyObject * calcref, int priority)
+    {
+      shared_ptr<PythonOperation> newOperation = PythonOperation::New(calcref);
+      return XdmfFunction::addOperation(newName, newOperation, priority);
+    }
+};
+
+#endif /* SWIGPYTHON */
+
+%include boost_shared_ptr.i
+
+%inline
+%{
+    #include <boost/shared_ptr.hpp>
+    using namespace boost;
+%}
+
+%include std_string.i
+%include std_vector.i
+%include std_map.i
+
+%shared_ptr(Loki::BaseVisitor)
+%shared_ptr(Loki::BaseVisitable<void>)
+%shared_ptr(Loki::Visitor<XdmfItem>)
+%shared_ptr(Loki::Visitor<XdmfArray>)
+
+%include loki/Visitor.h
+
+// Shared Pointer Templates
+%shared_ptr(XdmfArray)
+%shared_ptr(XdmfArrayReference)
+%shared_ptr(XdmfArrayType)
+%shared_ptr(XdmfCoreItemFactory)
+%shared_ptr(XdmfCoreReader)
+%shared_ptr(XdmfFunction)
+%shared_ptr(XdmfHDF5Controller)
+%shared_ptr(XdmfHDF5Writer)
+%shared_ptr(XdmfHeavyDataController)
+%shared_ptr(XdmfHeavyDataWriter)
+%shared_ptr(XdmfInformation)
+%shared_ptr(XdmfItem)
+%shared_ptr(XdmfItemProperty)
+%shared_ptr(XdmfSparseMatrix)
+%shared_ptr(XdmfSubset)
+%shared_ptr(XdmfTIFFController)
+%shared_ptr(XdmfVisitor)
+%shared_ptr(XdmfWriter)
+
+%shared_ptr(std::vector<int>)
+
+// Abstract Base Classes
+%template(BaseVisitable) Loki::BaseVisitable<void>;
+%template() Loki::Visitor<XdmfArray>;
+%template() Loki::Visitor<XdmfItem>;
+
+%include XdmfCore.hpp
+%include XdmfError.hpp
+%include XdmfItem.hpp
+%include XdmfItemProperty.hpp
+%include XdmfSparseMatrix.hpp
+%include XdmfSystemUtils.hpp
+%include XdmfVisitor.hpp
+%include XdmfArrayReference.hpp
+%include XdmfFunction.hpp
+%include XdmfHeavyDataController.hpp
+%include XdmfHeavyDataWriter.hpp
+%include XdmfSubset.hpp
+
+%include XdmfCoreItemFactory.hpp
+%include XdmfCoreReader.hpp
+%include XdmfInformation.hpp
+%include XdmfHDF5Controller.hpp
+%include XdmfHDF5Writer.hpp
+%include XdmfTIFFController.hpp
+%include XdmfWriter.hpp
+
+%include CMake/VersionSuite/ProjectVersion.hpp
+%include XdmfVersion.hpp
+
+%include XdmfArray.hpp
+%include XdmfArrayType.hpp
+
+#ifdef SWIGPYTHON
+
+%pythoncode {
+    XdmfVersion = _XdmfCore.cvar.XdmfVersion
+};
+
+#endif /* SWIGPYTHON */
+
+%template(getValueAsInt8) XdmfArray::getValue<char>;
+%template(getValueAsInt16) XdmfArray::getValue<short>;
+%template(getValueAsInt32) XdmfArray::getValue<int>;
+%template(getValueAsInt64) XdmfArray::getValue<long>;
+%template(getValueAsFloat32) XdmfArray::getValue<float>;
+%template(getValueAsFloat64) XdmfArray::getValue<double>;
+%template(getValueAsUInt8) XdmfArray::getValue<unsigned char>;
+%template(getValueAsUInt16) XdmfArray::getValue<unsigned short>;
+%template(getValueAsUInt32) XdmfArray::getValue<unsigned int>;
+%template(getValueAsString) XdmfArray::getValue<std::string>;
+
+%template(initializeAsInt8) XdmfArray::initialize<char>;
+%template(initializeAsInt16) XdmfArray::initialize<short>;
+%template(initializeAsInt32) XdmfArray::initialize<int>;
+%template(initializeAsInt64) XdmfArray::initialize<long>;
+%template(initializeAsFloat32) XdmfArray::initialize<float>;
+%template(initializeAsFloat64) XdmfArray::initialize<double>;
+%template(initializeAsUInt8) XdmfArray::initialize<unsigned char>;
+%template(initializeAsUInt16) XdmfArray::initialize<unsigned short>;
+%template(initializeAsUInt32) XdmfArray::initialize<unsigned int>;
+%template(initializeAsString) XdmfArray::initialize<std::string>;
+
+%template(insertValueAsInt8) XdmfArray::insert<char>;
+%template(insertValueAsInt16) XdmfArray::insert<short>;
+%template(insertValueAsInt32) XdmfArray::insert<int>;
+%template(insertValueAsInt64) XdmfArray::insert<long>;
+%template(insertValueAsFloat32) XdmfArray::insert<float>;
+%template(insertValueAsFloat64) XdmfArray::insert<double>;
+%template(insertValueAsUInt8) XdmfArray::insert<unsigned char>;
+%template(insertValueAsUInt16) XdmfArray::insert<unsigned short>;
+%template(insertValueAsUInt32) XdmfArray::insert<unsigned int>;
+%template(insertValueAsString) XdmfArray::insert<std::string>;
+
+%template(pushBackAsInt8) XdmfArray::pushBack<char>;
+%template(pushBackAsInt16) XdmfArray::pushBack<short>;
+%template(pushBackAsInt32) XdmfArray::pushBack<int>;
+%template(pushBackAsInt64) XdmfArray::pushBack<long>;
+%template(pushBackAsFloat32) XdmfArray::pushBack<float>;
+%template(pushBackAsFloat64) XdmfArray::pushBack<double>;
+%template(pushBackAsUInt8) XdmfArray::pushBack<unsigned char>;
+%template(pushBackAsUInt16) XdmfArray::pushBack<unsigned short>;
+%template(pushBackAsUInt32) XdmfArray::pushBack<unsigned int>;
+%template(pushBackAsString) XdmfArray::pushBack<std::string>;
+
+%template(resizeAsInt8) XdmfArray::resize<char>;
+%template(resizeAsInt16) XdmfArray::resize<short>;
+%template(resizeAsInt32) XdmfArray::resize<int>;
+%template(resizeAsInt64) XdmfArray::resize<long>;
+%template(resizeAsFloat32) XdmfArray::resize<float>;
+%template(resizeAsFloat64) XdmfArray::resize<double>;
+%template(resizeAsUInt8) XdmfArray::resize<unsigned char>;
+%template(resizeAsUInt16) XdmfArray::resize<unsigned short>;
+%template(resizeAsUInt32) XdmfArray::resize<unsigned int>;
+%template(resizeAsString) XdmfArray::resize<std::string>;
+
+%template(UInt8Vector) std::vector<unsigned char>;
+%template(UInt16Vector) std::vector<unsigned short>;
+%template(UInt32Vector) std::vector<unsigned int>;
+%template(Int8Vector) std::vector<char>;
+%template(Int16Vector) std::vector<short>;
+%template(Int32Vector) std::vector<int>;
+%template(Int64Vector) std::vector<long>;
+%template(Float32Vector) std::vector<float>;
+%template(Float64Vector) std::vector<double>;
+%template(StringVector) std::vector<std::string>;
+%template(ItemVector) std::vector<boost::shared_ptr<XdmfItem> >;
+%template(HeavyControllerVector) std::vector<boost::shared_ptr<XdmfHeavyDataController> >;
+%template(ArrayMap) std::map<std::string, boost::shared_ptr<XdmfArray> >;
+%template(StringMap) std::map<std::string, std::string>;
+%template(DSMStructreVector) std::vector<std::pair<std::string, unsigned int> >;
+%template(DSMApplicationPair) std::pair<std::string, unsigned int>;
diff --git a/core/XdmfCoreConfig.hpp.in b/core/XdmfCoreConfig.hpp.in
new file mode 100644
index 0000000..9880a73
--- /dev/null
+++ b/core/XdmfCoreConfig.hpp.in
@@ -0,0 +1,37 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCoreConfig.hpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFCORECONFIG_HPP_
+#define XDMFCORECONFIG_HPP_
+
+#cmakedefine HAVE_BOOST_SHARED_DYNAMIC_CAST
+#cmakedefine XDMF_BIG_ENDIAN
+
+#cmakedefine BUILD_SHARED
+#ifndef BUILD_SHARED
+#  define XDMFSTATIC
+#endif
+
+#cmakedefine XDMF_NO_REALPATH
+
+#endif /* XDMFCORECONFIG_HPP_ */
diff --git a/core/XdmfCoreItemFactory.cpp b/core/XdmfCoreItemFactory.cpp
new file mode 100644
index 0000000..8838781
--- /dev/null
+++ b/core/XdmfCoreItemFactory.cpp
@@ -0,0 +1,756 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCoreItemFactory.cpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfArray.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfCoreItemFactory.hpp"
+#include "XdmfError.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfTIFFController.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfSparseMatrix.hpp"
+#include <boost/tokenizer.hpp>
+#include <string.h>
+
+std::string
+XdmfCoreItemFactory::getFullHeavyDataPath(const std::string & filePath,
+                       const std::map<std::string, std::string> & itemProperties) const
+{
+  // FIXME: for other OS (e.g. windows)
+  if(filePath.size() > 0 && filePath[0] != '/') {
+    // Dealing with a relative path for heavyData location
+    std::map<std::string, std::string>::const_iterator xmlDir =
+      itemProperties.find("XMLDir");
+    if(xmlDir == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "'XMLDir' not found in itemProperties when "
+                         "building full heavy data path");
+    }
+    std::stringstream newHeavyDataPath;
+    newHeavyDataPath << xmlDir->second << filePath;
+    return newHeavyDataPath.str();
+  }
+  return filePath;
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfCoreItemFactory::getArrayType(const std::map<std::string, std::string> & itemProperties) const
+{
+  return XdmfArrayType::New(itemProperties);
+}
+
+XdmfCoreItemFactory::XdmfCoreItemFactory()
+{
+}
+
+XdmfCoreItemFactory::~XdmfCoreItemFactory()
+{
+}
+
+shared_ptr<XdmfItem>
+XdmfCoreItemFactory::createItem(const std::string & itemTag,
+                                const std::map<std::string, std::string> & itemProperties,
+                                const std::vector<shared_ptr<XdmfItem> > & childItems) const
+{
+  if(itemTag.compare(XdmfArray::ItemTag) == 0) {
+    return XdmfArray::New();
+  }
+  else if(itemTag.compare("DataStructure") == 0) {
+    // to support old xdmf DataStructure tag
+    return XdmfArray::New();
+  }
+  else if (itemTag.compare(XdmfFunction::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("ConstructedType");
+    std::string arraySubType;
+    if(type == itemProperties.end()) {
+      // If no type is specified an array is generated
+      arraySubType = XdmfArray::ItemTag;
+    }
+    else {
+      arraySubType = type->second;
+    }
+    std::map<std::string, std::string>::const_iterator expression =
+      itemProperties.find("Expression");
+    std::string expressionToParse;
+    if(expression == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Function found no expression");
+    }
+    else {
+      expressionToParse = expression->second;
+    }
+
+    std::map<std::string, std::string>::const_iterator variableNames =
+      itemProperties.find("VariableNames");
+    std::vector<std::string> nameVector;
+
+    std::string variableList = variableNames->second;
+
+    size_t barSplit = 0;
+    std::string subcontent;
+    while (barSplit != std::string::npos) {
+      barSplit = 0;
+      barSplit = variableList.find_first_of("|", barSplit);
+      if (barSplit == std::string::npos) {
+        subcontent = variableList;
+      }
+      else {
+        subcontent = variableList.substr(0, barSplit);
+        variableList = variableList.substr(barSplit+1);
+        barSplit++;
+      }
+      nameVector.push_back(subcontent);
+    }
+
+
+    std::map<std::string, shared_ptr<XdmfArray> > variableCollection;
+    for (unsigned int i = 0; i < childItems.size() && i < nameVector.size(); ++i) {
+      if (nameVector[i].compare("") != 0) {
+        if (shared_ptr<XdmfArray> array =
+          shared_dynamic_cast<XdmfArray>(childItems[i])) {
+
+          variableCollection[nameVector[i]] = array;
+          array->read();
+        }
+        else {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Function passed non-Array item");
+        }
+      }
+    }
+
+    shared_ptr<XdmfArray> parsedArray = shared_ptr<XdmfArray>();
+    parsedArray = XdmfFunction::evaluateExpression(expressionToParse,
+                                                   variableCollection);
+    if (arraySubType != XdmfArray::ItemTag) {
+      // The properties and children aren't really needed
+      // to generate the object, but the factory still requires them.
+      std::vector<shared_ptr<XdmfItem> > newArrayChildren;
+      shared_ptr<XdmfArray> returnArray = shared_ptr<XdmfArray>();
+
+      // This should generate an item that corresponds to the tag provided
+      // the casting ensures that it is a subtype of array
+      // Using a factory to be able to build things outside of core
+      returnArray = shared_dynamic_cast<XdmfArray>(createItem(
+                                                     arraySubType,
+                                                     itemProperties,
+                                                     newArrayChildren));
+
+      returnArray->insert(0, parsedArray, 0, parsedArray->getSize());
+      returnArray->setReference(XdmfFunction::New(expressionToParse,
+                                                  variableCollection));
+      returnArray->setReadMode(XdmfArray::Reference);
+      return returnArray;
+    }
+    else {
+      parsedArray->setReference(XdmfFunction::New(expressionToParse,
+                                                  variableCollection));
+      parsedArray->setReadMode(XdmfArray::Reference);
+      return parsedArray;
+    }
+  }
+  else if(itemTag.compare(XdmfSubset::ItemTag) == 0) {
+    std::map<std::string, std::string>::const_iterator type =
+      itemProperties.find("ConstructedType");
+    std::string arraySubType;
+    if(type == itemProperties.end()) {
+      // If no type is specified an array is generated
+      arraySubType = XdmfArray::ItemTag;
+    }
+    else {
+      arraySubType = type->second;
+    }
+
+    std::vector<shared_ptr<XdmfItem> > newArrayChildren;
+    shared_ptr<XdmfArray> returnArray = shared_ptr<XdmfArray>();
+
+    returnArray = shared_dynamic_cast<XdmfArray>(createItem(
+                                                   arraySubType,
+                                                   itemProperties,
+                                                   newArrayChildren));
+
+    std::vector<unsigned int> startVector;
+    std::vector<unsigned int> strideVector;
+    std::vector<unsigned int> dimensionVector;
+    shared_ptr<XdmfArray> referenceArray;
+
+    std::map<std::string, std::string>::const_iterator starts =
+      itemProperties.find("SubsetStarts");
+
+    boost::tokenizer<> tokens(starts->second);
+    for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+        iter != tokens.end();
+        ++iter) {
+      startVector.push_back(atoi((*iter).c_str()));
+    }
+
+    std::map<std::string, std::string>::const_iterator strides =
+      itemProperties.find("SubsetStrides");
+
+    boost::tokenizer<> stridetokens(strides->second);
+    for(boost::tokenizer<>::const_iterator iter = stridetokens.begin();
+        iter != stridetokens.end();
+        ++iter) {
+      strideVector.push_back(atoi((*iter).c_str()));
+    }
+
+    std::map<std::string, std::string>::const_iterator dimensions =
+      itemProperties.find("SubsetDimensions");
+
+    boost::tokenizer<> dimtokens(dimensions->second);
+    for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+        iter != dimtokens.end();
+        ++iter) {
+      dimensionVector.push_back(atoi((*iter).c_str()));
+    }
+
+    bool foundspacer = false;
+
+    for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+          childItems.begin();
+        iter != childItems.end();
+        ++iter) {
+      if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+        if (foundspacer) {
+          referenceArray = shared_dynamic_cast<XdmfArray>(array);
+          break;
+        }
+        else {
+          foundspacer = true;
+        }
+      }
+    }
+
+    shared_ptr<XdmfSubset> newSubset = XdmfSubset::New(referenceArray,
+                                                       startVector,
+                                                       strideVector,
+                                                       dimensionVector);
+
+    returnArray->setReference(newSubset);
+    returnArray->setReadMode(XdmfArray::Reference);
+
+    return returnArray;
+
+  }
+  return shared_ptr<XdmfItem>();
+}
+
+std::vector<shared_ptr<XdmfHeavyDataController> >
+XdmfCoreItemFactory::generateHeavyDataControllers(const std::map<std::string, std::string> & itemProperties,
+                                                  const std::vector<unsigned int> & passedDimensions,
+                                                  shared_ptr<const XdmfArrayType> passedArrayType,
+                                                  const std::string & passedFormat) const
+{
+  std::vector<shared_ptr<XdmfHeavyDataController> > returnControllers;
+
+  std::string formatVal;
+
+  if (passedFormat.size() > 0)
+  {
+    formatVal = passedFormat;
+  }
+  else
+  {
+    // create a version that passes these in directly
+    std::map<std::string, std::string>::const_iterator format =
+      itemProperties.find("Format");
+    if(format == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "'Format' not found in generateHeavyControllers in "
+                         "XdmfCoreItemFactory");
+    }
+    formatVal = format->second;
+  }
+
+
+  std::map<std::string, std::string>::const_iterator content =
+  itemProperties.find("Content");
+  if(content == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "'Content' not found in generateHeavyControllers in "
+                       "XdmfCoreItemFactory");
+  }
+
+  unsigned int contentIndex;
+
+  const std::string & contentVal = content->second;
+
+  std::vector<std::string> contentVals;
+
+  // Split the content based on "|" characters
+  size_t barSplit = 0;
+  std::string splitString(contentVal);
+  std::string subcontent;
+  while (barSplit != std::string::npos) {
+    barSplit = 0;
+    barSplit = splitString.find_first_of("|", barSplit);
+    if (barSplit == std::string::npos) {
+      subcontent = splitString;
+    }
+    else {
+      subcontent = splitString.substr(0, barSplit);
+      splitString = splitString.substr(barSplit+1);
+      barSplit++;
+    }
+    contentVals.push_back(subcontent);
+  }
+
+  std::vector<unsigned int> dimVector;
+
+  if (passedDimensions.size() > 0)
+  {
+    dimVector = passedDimensions;
+  }
+  else
+  {
+    std::map<std::string, std::string>::const_iterator dimensions =
+      itemProperties.find("Dimensions");
+    if(dimensions == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "'Dimensions' not found in generateHeavyControllers in "
+                         "XdmfCoreItemFactory");
+    }
+
+    boost::tokenizer<> tokens(dimensions->second);
+    for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+        iter != tokens.end();
+        ++iter) {
+      dimVector.push_back(atoi((*iter).c_str()));
+    }
+  }
+
+  shared_ptr<const XdmfArrayType> arrayType;
+  if (passedArrayType)
+  {
+    arrayType = passedArrayType;
+  }
+  else
+  {
+    arrayType = XdmfArrayType::New(itemProperties);
+  }
+
+  if (contentVals.size() == 0) {
+    return returnControllers;
+  }
+
+  if(formatVal.compare("Binary") == 0) {
+    contentIndex = 0;
+    int contentStep = 2;
+    while (contentIndex < contentVals.size()) {
+      XdmfBinaryController::Endian endian = XdmfBinaryController::NATIVE;
+      std::map<std::string, std::string>::const_iterator endianIter =
+        itemProperties.find("Endian");
+      if(endianIter != itemProperties.end()) {
+        if(endianIter->second.compare("Big") == 0) {
+          endian =  XdmfBinaryController::BIG;
+        }
+        else if(endianIter->second.compare("Little") == 0) {
+          endian =  XdmfBinaryController::LITTLE;
+        }
+        else if(endianIter->second.compare("Native") == 0) {
+          endian =  XdmfBinaryController::NATIVE;
+        }
+        else {
+          XdmfError(XdmfError::FATAL,
+                    "Invalid endianness type: " + endianIter->second);
+        }
+      }
+
+      unsigned int seek = 0;
+      std::map<std::string, std::string>::const_iterator seekIter =
+        itemProperties.find("Seek");
+      if(seekIter != itemProperties.end()) {
+        seek = std::atoi(seekIter->second.c_str());
+      }
+
+      const std::string binaryPath = getFullHeavyDataPath(contentVals[contentIndex],
+                                                          itemProperties);
+
+      // Parse dimensions from the content
+      std::vector<unsigned int> contentStarts;
+      std::vector<unsigned int> contentStrides;
+      std::vector<unsigned int> contentDims;
+      std::vector<unsigned int> contentDataspaces;
+      if (contentVals.size() > contentIndex+1) {
+        // This is the string that contains the dimensions
+        std::string dataspaceDescription = contentVals[contentIndex+1];
+        std::vector<std::string> dataspaceVector;
+        size_t colonSplit = 0;
+        while (colonSplit != std::string::npos) {
+          colonSplit = 0;
+          colonSplit = dataspaceDescription.find_first_of(":", colonSplit);
+          if (colonSplit == std::string::npos) {
+            subcontent = dataspaceDescription;
+          }
+          else {
+            subcontent = dataspaceDescription.substr(0, colonSplit);
+            dataspaceDescription = dataspaceDescription.substr(colonSplit+1);
+            colonSplit++;
+          }
+          dataspaceVector.push_back(subcontent);
+        }
+
+        // split the description based on tokens
+        boost::tokenizer<> dimtokens(std::string(""));
+        if (dataspaceVector.size() == 1) {
+          dimtokens = boost::tokenizer<>(dataspaceDescription);
+        }
+        else if (dataspaceVector.size() == 5) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[3]);
+        }
+        for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+            iter != dimtokens.end();
+            ++iter) {
+          contentDims.push_back(atoi((*iter).c_str()));
+        }
+
+        if (dataspaceVector.size() == 5) {
+          seek = atoi(dataspaceVector[0].c_str());
+          dimtokens = boost::tokenizer<>(dataspaceVector[1]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStarts.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[2]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStrides.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[4]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentDataspaces.push_back(atoi((*iter).c_str()));
+          }
+        }
+
+        contentStep = 2;
+        // If this works then the dimension content should be skipped over
+      }
+      else {
+        // If it fails then it means that the next content is not a dimension string
+        // In this case it is assumed that the controller will have
+        // dimensions equal to the array
+        for (unsigned int j = 0; j < dimVector.size(); ++j) {
+          contentDims.push_back(dimVector[j]);
+        }
+        contentStep = 1;
+      }
+      if (contentDataspaces.size() == 0) {
+        returnControllers.push_back(XdmfBinaryController::New(binaryPath,
+                                                              arrayType,
+                                                              endian,
+                                                              seek,
+                                                              contentDims));
+      }
+      else {
+        returnControllers.push_back(
+          XdmfBinaryController::New(binaryPath,
+                                    arrayType,
+                                    endian,
+                                    seek,
+                                    contentStarts,
+                                    contentStrides,
+                                    contentDims,
+                                    contentDataspaces)
+          );
+      }
+      contentIndex+=contentStep;
+    }
+  }
+  else if(formatVal.compare("HDF") == 0) {
+    contentIndex = 0;
+    int contentStep = 2;
+    while (contentIndex < contentVals.size()) {
+      size_t colonLocation = contentVals[contentIndex].find(":");
+      if(colonLocation == std::string::npos) {
+        XdmfError::message(XdmfError::FATAL,
+                           "':' not found in content generateHeavyControllers in "
+                           "XdmfCoreItemFactory -- double check an HDF5 "
+                           "data set is specified for the file");
+      }
+
+      std::string hdf5Path =
+        contentVals[contentIndex].substr(0, colonLocation);
+      std::string dataSetPath =
+        contentVals[contentIndex].substr(colonLocation+1);
+
+      hdf5Path = getFullHeavyDataPath(hdf5Path,
+                                      itemProperties);
+
+      // Parse dimensions from the content
+      std::vector<unsigned int> contentStarts;
+      std::vector<unsigned int> contentStrides;
+      std::vector<unsigned int> contentDims;
+      std::vector<unsigned int> contentDataspaces;
+      if (contentVals.size() > contentIndex+1) {
+        // This is the string that contains the dimensions
+        std::string dataspaceDescription = contentVals[contentIndex+1];
+        std::vector<std::string> dataspaceVector;
+        size_t colonSplit = 0;
+        while (colonSplit != std::string::npos) {
+          colonSplit = 0;
+          colonSplit = dataspaceDescription.find_first_of(":", colonSplit);
+          if (colonSplit == std::string::npos) {
+            subcontent = dataspaceDescription;
+          }
+          else {
+            subcontent = dataspaceDescription.substr(0, colonSplit);
+            dataspaceDescription = dataspaceDescription.substr(colonSplit+1);
+            colonSplit++;
+          }
+          dataspaceVector.push_back(subcontent);
+        }
+
+        // split the description based on tokens
+        boost::tokenizer<> dimtokens(std::string(""));
+        if (dataspaceVector.size() == 1) {
+          dimtokens = boost::tokenizer<>(dataspaceDescription);
+        }
+        else if (dataspaceVector.size() == 4) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[2]);
+        }
+        for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+            iter != dimtokens.end();
+            ++iter) {
+          contentDims.push_back(atoi((*iter).c_str()));
+        }
+
+        if (dataspaceVector.size() == 4) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[0]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStarts.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[1]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStrides.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[3]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentDataspaces.push_back(atoi((*iter).c_str()));
+          }
+        }
+
+        contentStep = 2;
+        // If this works then the dimension content should be skipped over
+      }
+      else {
+        // If it fails then it means that the next content is not a dimension string
+        // In this case it is assumed that the controller will have
+        // dimensions equal to the array
+        for (unsigned int j = 0; j < dimVector.size(); ++j) {
+          contentDims.push_back(dimVector[j]);
+        }
+        contentStep = 1;
+      }
+      if (contentDataspaces.size() == 0) {
+        returnControllers.push_back(
+          XdmfHDF5Controller::New(hdf5Path,
+                                  dataSetPath,
+                                  arrayType,
+                                  std::vector<unsigned int>(contentDims.size(),
+                                                            0),
+                                  std::vector<unsigned int>(contentDims.size(),
+                                                            1),
+                                  contentDims,
+                                  contentDims)
+          );
+      }
+      else {
+        returnControllers.push_back(
+          XdmfHDF5Controller::New(hdf5Path,
+                                  dataSetPath,
+                                  arrayType,
+                                  contentStarts,
+                                  contentStrides,
+                                  contentDims,
+                                  contentDataspaces)
+          );
+      }
+      contentIndex+=contentStep;
+    }
+  }
+#ifdef XDMF_BUILD_TIFF
+  else if(formatVal.compare("TIFF") == 0) {
+    contentIndex = 0;
+    int contentStep = 2;
+    while (contentIndex < contentVals.size()) {
+      const std::string tiffPath = getFullHeavyDataPath(contentVals[contentIndex],
+                                                        itemProperties);
+
+      // Parse dimensions from the content
+      std::vector<unsigned int> contentStarts;
+      std::vector<unsigned int> contentStrides;
+      std::vector<unsigned int> contentDims;
+      std::vector<unsigned int> contentDataspaces;
+      if (contentVals.size() > contentIndex+1) {
+        // This is the string that contains the dimensions
+        std::string dataspaceDescription = contentVals[contentIndex+1];
+        std::vector<std::string> dataspaceVector;
+        size_t colonSplit = 0;
+        while (colonSplit != std::string::npos) {
+          colonSplit = 0;
+          colonSplit = dataspaceDescription.find_first_of(":", colonSplit);
+          if (colonSplit == std::string::npos) {
+            subcontent = dataspaceDescription;
+          }
+          else {
+            subcontent = dataspaceDescription.substr(0, colonSplit);
+            dataspaceDescription = dataspaceDescription.substr(colonSplit+1);
+            colonSplit++;
+          }
+          dataspaceVector.push_back(subcontent);
+        }
+
+        // split the description based on tokens
+        boost::tokenizer<> dimtokens(std::string(""));
+        if (dataspaceVector.size() == 1) {
+          dimtokens = boost::tokenizer<>(dataspaceDescription);
+        }
+        else if (dataspaceVector.size() == 4) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[2]);
+        }
+        for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+            iter != dimtokens.end();
+            ++iter) {
+          contentDims.push_back(atoi((*iter).c_str()));
+        }
+
+        if (dataspaceVector.size() == 4) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[0]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStarts.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[1]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStrides.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[3]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentDataspaces.push_back(atoi((*iter).c_str()));
+          }
+        }
+
+        contentStep = 2;
+        // If this works then the dimension content should be skipped over
+      }
+      else {
+        // If it fails then it means that the next content is not a dimension string
+        // In this case it is assumed that the controller will have
+        // dimensions equal to the array
+        for (unsigned int j = 0; j < dimVector.size(); ++j) {
+          contentDims.push_back(dimVector[j]);
+        }
+        contentStep = 1;
+      }
+      if (contentDataspaces.size() == 0) {
+        returnControllers.push_back(
+          XdmfTIFFController::New(tiffPath,
+                                  arrayType,
+                                  std::vector<unsigned int>(contentDims.size(),
+                                                            0),
+                                  std::vector<unsigned int>(contentDims.size(),
+                                                            1),
+                                  contentDims,
+                                  contentDims)
+          );
+      }
+      else {
+        returnControllers.push_back(
+          XdmfTIFFController::New(tiffPath,
+                                  arrayType,
+                                  contentStarts,
+                                  contentStrides,
+                                  contentDims,
+                                  contentDataspaces)
+          );
+      }
+      contentIndex+=contentStep;
+    }
+  }
+#endif /* XDMF_BUILD_TIFF */
+
+  return returnControllers;
+}
+
+shared_ptr<XdmfHeavyDataWriter>
+XdmfCoreItemFactory::generateHeavyDataWriter(std::string typeName, std::string path) const
+{
+  if (typeName.compare("HDF") == 0) {
+    return XdmfHDF5Writer::New(path);
+  }
+  return shared_ptr<XdmfHeavyDataWriter>();
+}
+
+bool
+XdmfCoreItemFactory::isArrayTag(char * tag) const
+{
+  if (XdmfArray::ItemTag.compare(tag) == 0 ||
+      strcmp("DataStructure", tag) == 0 ||
+      XdmfFunction::ItemTag.compare(tag) == 0 ||
+      XdmfSubset::ItemTag.compare(tag) == 0) {
+    return true;
+  }
+  return false;
+}
+
+XdmfItem *
+XdmfCoreItemFactory::DuplicatePointer(shared_ptr<XdmfItem> original) const
+{
+  if (original->getItemTag() == XdmfArray::ItemTag) {
+    return (XdmfItem *)(new XdmfArray(*((XdmfArray *)original.get())));
+  }
+  else if (original->getItemTag() == XdmfInformation::ItemTag) {
+    return (XdmfItem *)(new XdmfInformation(*((XdmfInformation *)original.get())));
+  }
+  else if (original->getItemTag() == XdmfFunction::ItemTag) {
+    return (XdmfItem *)(new XdmfFunction(*((XdmfFunction *)original.get())));
+  }
+  else if (original->getItemTag() == XdmfSubset::ItemTag) {
+    return (XdmfItem *)(new XdmfSubset(*((XdmfSubset *)original.get())));
+  }
+  else if (original->getItemTag() == XdmfSparseMatrix::ItemTag) {
+   return (XdmfItem *)(new XdmfSparseMatrix(*((XdmfSparseMatrix *)original.get())));
+  }
+  else {
+    return NULL;
+  }
+}
diff --git a/core/XdmfCoreItemFactory.hpp b/core/XdmfCoreItemFactory.hpp
new file mode 100644
index 0000000..f8096cf
--- /dev/null
+++ b/core/XdmfCoreItemFactory.hpp
@@ -0,0 +1,118 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCoreItemFactory.hpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFCOREITEMFACTORY_HPP_
+#define XDMFCOREITEMFACTORY_HPP_
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfItem;
+
+// Includes
+#include <map>
+#include <vector>
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Factory that constructs XdmfItems using tags and properties.
+ *
+ * XdmfCoreItemFactory is an abstract base class.
+ */
+class XDMFCORE_EXPORT XdmfCoreItemFactory {
+
+public:
+
+  virtual ~XdmfCoreItemFactory() = 0;
+
+  /**
+   * Create a new XdmfItem.
+   *
+   * Example of use:
+   *
+   * @dontinclude ExampleXdmfCoreItemFactory.cpp
+   * @skipline //#createItem
+   * @until //#createItem
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCoreItemFactory.py
+   * @skipline #//createItem
+   * @until #//createItem
+   *
+   * @param     itemTag         A string containing the tag of the XdmfItem to create.
+   * @param     itemProperties  A map of key/value properties for the the XdmfItem.
+   * @param     childItems      The children of the XdmfItem to create.
+   *
+   * @return                    Constructed XdmfItem. If no XdmfItem can be constructed,
+   *                            return NULL.
+   */
+  virtual shared_ptr<XdmfItem>
+  createItem(const std::string & itemTag,
+             const std::map<std::string, std::string> & itemProperties,
+             const std::vector<shared_ptr<XdmfItem> > & childItems) const;
+
+  virtual std::vector<shared_ptr<XdmfHeavyDataController> >
+  generateHeavyDataControllers(const std::map<std::string, std::string> & itemProperties,
+                               const std::vector<unsigned int> & passedDimensions = std::vector<unsigned int>(),
+                               shared_ptr<const XdmfArrayType> passedArrayType = shared_ptr<const XdmfArrayType>(),
+                               const std::string & passedFormat = std::string()) const;
+
+  virtual shared_ptr<XdmfHeavyDataWriter>
+  generateHeavyDataWriter(std::string typeName, std::string path) const;
+
+  virtual bool isArrayTag(char * tag) const;
+
+  /**
+   * Extracts the pointer from the provided shared pointer. Primarily used for C interface.
+   *
+   * @param     original        The source shared pointer that the pointer will be pulled from.
+   * @return                    A duplicate of the object contained in the pointer.
+   */
+  virtual XdmfItem *
+  DuplicatePointer(shared_ptr<XdmfItem> original) const;
+
+protected:
+
+  shared_ptr<const XdmfArrayType>
+  getArrayType(const std::map<std::string, std::string> & itemProperties) const;
+
+  std::string
+  getFullHeavyDataPath(const std::string & filePath,
+                       const std::map<std::string, std::string> & itemProperties) const;
+
+  XdmfCoreItemFactory();
+
+private:
+
+  XdmfCoreItemFactory(const XdmfCoreItemFactory &);  // Not implemented.
+  void operator=(const XdmfCoreItemFactory &);  // Not implemented.
+
+};
+
+#endif
+
+#endif /* XDMFCOREITEMFACTORY_HPP_ */
diff --git a/core/XdmfCoreReader.cpp b/core/XdmfCoreReader.cpp
new file mode 100644
index 0000000..30464be
--- /dev/null
+++ b/core/XdmfCoreReader.cpp
@@ -0,0 +1,416 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCoreReader.cpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <libxml/uri.h>
+#include <libxml/xpointer.h>
+#include <libxml/xmlreader.h>
+#include <boost/algorithm/string/trim.hpp>
+#include <boost/tokenizer.hpp>
+#include <cstring>
+#include <map>
+#include <sstream>
+#include <utility>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfCoreItemFactory.hpp"
+#include "XdmfCoreReader.hpp"
+#include "XdmfError.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfSystemUtils.hpp"
+
+/**
+ * PIMPL
+ */
+class XdmfCoreReader::XdmfCoreReaderImpl {
+
+public:
+
+  XdmfCoreReaderImpl(const shared_ptr<const XdmfCoreItemFactory> itemFactory,
+                     const XdmfCoreReader * const coreReader) :
+    mCoreReader(coreReader),
+    mItemFactory(itemFactory)
+  {
+  };
+
+  ~XdmfCoreReaderImpl()
+  {
+  };
+
+  void
+  closeFile()
+  {
+    mXPathMap.clear();
+    xmlXPathFreeContext(mXPathContext);
+    for(std::map<std::string, xmlDocPtr>::const_iterator iter = 
+	  mDocuments.begin(); iter != mDocuments.end(); ++iter) {
+      xmlFreeDoc(iter->second);
+    }
+    mDocuments.clear();
+    
+    xmlCleanupParser();
+  }
+
+  void
+  openFile(const std::string & filePath)
+  {
+    mXMLDir = XdmfSystemUtils::getRealPath(filePath);
+    size_t index = mXMLDir.find_last_of("/\\");
+    if(index != std::string::npos) {
+      mXMLDir = mXMLDir.substr(0, index + 1);
+    }
+
+    mDocument = xmlReadFile(filePath.c_str(), NULL, XML_PARSE_NOENT);
+
+    if(mDocument == NULL) {
+      XdmfError::message(XdmfError::FATAL,
+                         "xmlReadFile could not read " + filePath +
+                         " in XdmfCoreReader::XdmfCoreReaderImpl::openFile");
+    }
+
+    mDocuments.insert(std::make_pair((char*)mDocument->URL, mDocument));
+
+    mXPathContext = xmlXPtrNewContext(mDocument, NULL, NULL);
+    mXPathMap.clear();
+  }
+
+  void
+  parse(const std::string & lightData) 
+  {
+    mDocument = xmlParseDoc((const xmlChar*)lightData.c_str());
+                               
+    if(mDocument == NULL) {
+      XdmfError::message(XdmfError::FATAL,
+                         "xmlReadFile could not parse passed light data string"
+                         " in XdmfCoreReader::XdmfCoreReaderImpl::parse");
+    }
+    
+    //mDocuments.insert(std::make_pair((char*)mDocument->URL, mDocument));
+    mXPathContext = xmlXPtrNewContext(mDocument, NULL, NULL);
+    mXPathMap.clear();
+  }
+
+  /**
+   * Constructs XdmfItems for all nodes in currNode's tree.
+   * XdmfItems are constructed by recursively calling this function for all
+   * children of currNode.
+   */
+  std::vector<shared_ptr<XdmfItem> >
+  read(xmlNodePtr currNode)
+  {
+    std::vector<shared_ptr<XdmfItem> > myItems;
+
+    while(currNode != NULL) {
+      if(currNode->type == XML_ELEMENT_NODE) {
+        // Normal reading
+        this->readSingleNode(currNode, myItems);
+      }
+      currNode = currNode->next;
+    }
+    return myItems;
+  }
+
+  /**
+   * Reads a single xmlNode into an XdmfItem object in memory. The constructed
+   * XdmfItem is added to myItems and an entry is added mapping the xmlNodePtr
+   * to the new XdmfItem in the mXPathMap.
+   */
+  void
+  readSingleNode(const xmlNodePtr currNode,
+                 std::vector<shared_ptr<XdmfItem> > & myItems)
+  {
+    // Deal with proper resolution of XIncludes
+    if(xmlStrcmp(currNode->name, (xmlChar*)"include") == 0) {
+      
+      xmlChar * xpointer = NULL;
+      xmlChar * href = NULL;
+      
+      xmlAttrPtr currAttribute = currNode->properties;
+      while(currAttribute != NULL) {
+        if(xmlStrcmp(currAttribute->name, (xmlChar*)"xpointer") == 0) {
+          xpointer = currAttribute->children->content;
+        }
+        if(xmlStrcmp(currAttribute->name, (xmlChar*)"href") == 0) {
+          href = currAttribute->children->content;
+        }
+        currAttribute = currAttribute->next;
+      }
+
+      xmlXPathContextPtr oldContext = mXPathContext;
+      if(href) {
+        xmlDocPtr document;
+        xmlChar * filePath = xmlBuildURI(href, mDocument->URL);
+        std::map<std::string, xmlDocPtr>::const_iterator iter = 
+          mDocuments.find((char*)filePath);
+        if(iter == mDocuments.end()) {
+          document = xmlReadFile((char*)filePath, NULL, 0);
+          mDocuments.insert(std::make_pair((char*)document->URL, 
+                                           document));
+        }
+        else {
+          document = iter->second;
+        }
+        
+        mXPathContext = xmlXPtrNewContext(document, NULL, NULL);           
+      }
+      
+      if(xpointer) {
+        xmlXPathObjectPtr result = xmlXPtrEval(xpointer, mXPathContext);
+        if(result && !xmlXPathNodeSetIsEmpty(result->nodesetval)) {
+          for(int i=0; i<result->nodesetval->nodeNr; ++i) {
+            this->readSingleNode(result->nodesetval->nodeTab[i],
+                                 myItems);
+          }
+        }
+        else {
+          XdmfError::message(XdmfError::FATAL,
+                             "Invalid xpointer encountered.");
+        }
+        xmlXPathFreeObject(result);
+      }
+      
+      if(href) {
+        xmlXPathFreeContext(mXPathContext);
+      }
+      
+      mXPathContext = oldContext;
+      
+    }
+    else {
+
+      // Check to see if the node is already in the XPath Map (seen previously)
+      std::map<xmlNodePtr, shared_ptr<XdmfItem> >::const_iterator iter =
+        mXPathMap.find(currNode);
+      // If it is grab it from the previously stored items
+      if(iter != mXPathMap.end()) {
+        myItems.push_back(iter->second);
+      }
+      else {
+        // Otherwise, generate a new XdmfItem from the node
+        std::map<std::string, std::string> itemProperties;
+
+        xmlNodePtr childNode = currNode->children;
+        // generate content if an array or arrayReference
+        if (mItemFactory->isArrayTag((char *)currNode->name)) {
+          while(childNode != NULL) {
+            if(childNode->type == XML_TEXT_NODE && childNode->content) {
+#if 1 //ARL's side
+              const char * content = (char*)childNode->content;
+
+              // Determine if content is whitespace
+              bool whitespace = true;
+
+              const char * contentPtr = content;
+              // Step through to end of pointer
+              while(contentPtr != NULL) {
+                // If not a whitespace character, break
+                if(!isspace(*contentPtr++)) {
+                  whitespace = false;
+                  break;
+                }
+              }
+              if(!whitespace) {
+                std::string contentString(content);
+                boost::algorithm::trim(contentString);
+                itemProperties.insert(std::make_pair("Content", contentString));
+                itemProperties.insert(std::make_pair("XMLDir", mXMLDir));
+                break;
+              }
+#else //VTK's side, breaks XDMF's tests, revisit if problematic in VTK
+              std::string content((char *)childNode->content);
+              boost::algorithm::trim(content);
+
+              if(content.size() != 0) {
+                itemProperties.insert(std::make_pair("Content", content));
+                itemProperties.insert(std::make_pair("XMLDir", mXMLDir));
+                break;
+              }
+#endif
+            }
+            childNode = childNode->next;
+          }
+        }
+
+        // Pull attributes from node
+        xmlAttrPtr currAttribute = currNode->properties;
+        while(currAttribute != NULL) {
+          itemProperties.insert(std::make_pair((char *)currAttribute->name,
+                                               (char *)currAttribute->children->content));
+          currAttribute = currAttribute->next;
+        }
+
+        // Build XdmfItem
+        const std::vector<shared_ptr<XdmfItem> > childItems =
+          this->read(currNode->children);
+        shared_ptr<XdmfItem> newItem =
+          mItemFactory->createItem((const char *)currNode->name,
+                                   itemProperties,
+                                   childItems);
+
+        if(newItem == NULL) {
+          XdmfError::message(XdmfError::FATAL,
+                             "mItemFactory failed to createItem in "
+                             "XdmfCoreReader::XdmfCoreReaderImpl::readSingleNode");
+        }
+
+
+        // Populate built XdmfItem
+        newItem->populateItem(itemProperties,
+                              childItems,
+                              mCoreReader);
+
+        myItems.push_back(newItem);
+        mXPathMap.insert(std::make_pair(currNode, newItem));
+      }
+    }
+  }
+
+  void
+  readPathObjects(const std::string & xPath,
+                  std::vector<shared_ptr<XdmfItem> > & myItems)
+  {
+    xmlXPathObjectPtr xPathObject =
+      xmlXPathEvalExpression((xmlChar*)xPath.c_str(), mXPathContext);
+    if(xPathObject && xPathObject->nodesetval) {
+      for(int i=0; i<xPathObject->nodesetval->nodeNr; ++i) {
+        this->readSingleNode(xPathObject->nodesetval->nodeTab[i], myItems);
+      }
+    }
+    xmlXPathFreeObject(xPathObject);
+  }
+
+  xmlDocPtr mDocument;
+  std::map<std::string, xmlDocPtr> mDocuments;
+  const XdmfCoreReader * const mCoreReader;
+  const shared_ptr<const XdmfCoreItemFactory> mItemFactory;
+  std::string mXMLDir;
+  xmlXPathContextPtr mXPathContext;
+  std::map<xmlNodePtr, shared_ptr<XdmfItem> > mXPathMap;
+};
+
+XdmfCoreReader::XdmfCoreReader(const shared_ptr<const XdmfCoreItemFactory> itemFactory) :
+  mImpl(new XdmfCoreReaderImpl(itemFactory, this))
+{
+}
+
+XdmfCoreReader::~XdmfCoreReader()
+{
+  delete mImpl;
+}
+
+XdmfItem *
+XdmfCoreReader::DuplicatePointer(shared_ptr<XdmfItem> original) const
+{
+  if (mImpl == NULL) {
+    XdmfError::message(XdmfError::FATAL, "Error: Reader Internal Object is NULL");
+  }
+  return mImpl->mItemFactory->DuplicatePointer(original);
+}
+
+std::vector<shared_ptr<XdmfHeavyDataController> >
+XdmfCoreReader::generateHeavyDataControllers(std::map<std::string, std::string> controllerProperties,
+                                             const std::vector<unsigned int> & passedDimensions,
+                                             shared_ptr<const XdmfArrayType> passedArrayType,
+                                             const std::string & passedFormat) const
+{
+  return mImpl->mItemFactory->generateHeavyDataControllers(controllerProperties,
+                                                           passedDimensions,
+                                                           passedArrayType,
+                                                           passedFormat);
+}
+
+shared_ptr<XdmfHeavyDataWriter>
+XdmfCoreReader::generateHeavyDataWriter(std::string typeName, std::string path) const
+{
+  return mImpl->mItemFactory->generateHeavyDataWriter(typeName, path);
+}
+
+shared_ptr<XdmfItem >
+XdmfCoreReader::parse(const std::string & lightData) const
+{
+  mImpl->parse(lightData);
+  const xmlNodePtr currNode = xmlDocGetRootElement(mImpl->mDocument);
+  std::vector<shared_ptr<XdmfItem> > toReturn;
+  if(mImpl->mItemFactory->createItem((const char*)currNode->name,
+                                     std::map<std::string, std::string>(),
+                                     std::vector<shared_ptr<XdmfItem> >()) == NULL) {
+    toReturn = mImpl->read(currNode->children);
+  }
+  else {
+    toReturn = mImpl->read(currNode);
+  }
+  mImpl->closeFile();
+  return(toReturn[0]);
+}
+
+std::vector<shared_ptr<XdmfItem> >
+XdmfCoreReader::readItems(const std::string & filePath) const
+{
+  mImpl->openFile(filePath);
+  const xmlNodePtr currNode = xmlDocGetRootElement(mImpl->mDocument);
+  const std::vector<shared_ptr<XdmfItem> > toReturn =
+    mImpl->read(currNode->children);
+  mImpl->closeFile();
+  return toReturn;
+}
+
+shared_ptr<XdmfItem>
+XdmfCoreReader::read(const std::string & filePath) const
+{
+  const std::vector<shared_ptr<XdmfItem> > toReturn = readItems(filePath);
+  if (toReturn.size() == 0) {
+    return(shared_ptr<XdmfItem>());
+  }
+  return(toReturn[0]);
+}
+
+std::vector<shared_ptr<XdmfItem> >
+XdmfCoreReader::read(const std::string & filePath,
+                     const std::string & xPath) const
+{
+  mImpl->openFile(filePath);
+  std::vector<shared_ptr<XdmfItem> > toReturn = this->readPathObjects(xPath);
+  mImpl->closeFile();
+  return toReturn;
+}
+
+std::vector<shared_ptr<XdmfItem> >
+XdmfCoreReader::readPathObjects(const std::string & xPath) const
+{
+  std::vector<shared_ptr<XdmfItem> > toReturn;
+  mImpl->readPathObjects(xPath, toReturn);
+  return toReturn;
+}
+
+// C Wrappers
+
+XDMFITEM *
+XdmfCoreReaderRead(XDMFCOREREADER * reader, char * filePath, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfItem> returnItem = ((XdmfCoreReader *)reader)->read(filePath);
+  return (XDMFITEM *)((void *)((XdmfItem *)((XdmfCoreReader *)reader)->DuplicatePointer(returnItem)));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
diff --git a/core/XdmfCoreReader.hpp b/core/XdmfCoreReader.hpp
new file mode 100644
index 0000000..0821a62
--- /dev/null
+++ b/core/XdmfCoreReader.hpp
@@ -0,0 +1,269 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCoreReader.hpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFCOREREADER_HPP_
+#define XDMFCOREREADER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfCoreItemFactory;
+
+// Includes
+#include <string>
+#include <vector>
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Reads an Xdmf file stored on disk into memory.
+ *
+ * Reads an Xdmf file stored on disk into an Xdmf structure in memory.
+ * All light data is parsed in order to create appropriate Xdmf
+ * objects.  Heavy data controllers are created and attached to
+ * XdmfArrays but no heavy data is read into memory.
+ *
+ * XdmfCoreReader is an abstract base class.
+ */
+class XDMFCORE_EXPORT XdmfCoreReader {
+
+public:
+
+  virtual ~XdmfCoreReader() = 0;
+
+  /**
+   * Uses the internal item factory to create a copy of the internal pointer
+   * of the provided shared pointer. Primarily used for C wrapping.
+   *
+   * @param     original        The source shared pointer that the pointer will be pulled from.
+   * @return                    A duplicate of the object contained in the pointer.
+   */
+  virtual XdmfItem * DuplicatePointer(shared_ptr<XdmfItem> original) const;
+
+  virtual std::vector<shared_ptr<XdmfHeavyDataController> >
+  generateHeavyDataControllers(std::map<std::string, std::string> controllerProperties,
+                               const std::vector<unsigned int> & passedDimensions = std::vector<unsigned int>(),
+                               shared_ptr<const XdmfArrayType> passedArrayType = shared_ptr<const XdmfArrayType>(),
+                               const std::string & passedFormat = std::string()) const;
+
+  virtual shared_ptr<XdmfHeavyDataWriter>
+  generateHeavyDataWriter(std::string typeName, std::string path) const;
+
+  /**
+   * Parse a string containing light data into an Xdmf structure in
+   * memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCoreReader.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#parse
+   * @until //#parse
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCoreReader.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//parse
+   * @until #//parse
+   *
+   * @param     lightData       A string containing light data description of an
+   *                            Xdmf file.
+   *
+   * @return                    An XdmfItem at the root of the Xdmf tree.
+   */  
+  virtual shared_ptr<XdmfItem> parse(const std::string & lightData) const;
+
+  /**
+   * Read an Xdmf file from disk into memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCoreReader.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#readpath
+   * @until //#readpath
+   * @skipline //#readroot
+   * @until //#readroot
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCoreReader.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//readpath
+   * @until #//readpath
+   * @skipline #//readroot
+   * @until #//readroot
+   *
+   * @param     filePath        The path of the Xdmf file to read in from disk.
+   *
+   * @return                    An XdmfItem at the root of the Xdmf tree.
+   */
+  virtual shared_ptr<XdmfItem> read(const std::string & filePath) const;
+
+  /**
+   * Read part of an Xdmf file from disk into memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCoreReader.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#readpath
+   * @until //#readpath
+   * @skipline //#readXPath
+   * @until //#readXPath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCoreReader.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//readpath
+   * @until #//readpath
+   * @skipline #//readXPath
+   * @until #//readXPath
+   *
+   * @param     filePath        The path of the Xdmf file to read in from disk.
+   * @param     xPath           An XPath corresponding to the portion of the
+   *                            file to read.
+   *
+   * @return                    A vector of XdmfItems that are included
+   *                            in the XPath.
+   */
+  virtual std::vector<shared_ptr<XdmfItem> >
+  read(const std::string & filePath,
+       const std::string & xPath) const;
+
+  /**
+   * Read an Xdmf file from disk into memory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfCoreReader.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#readpath
+   * @until //#readpath
+   * @skipline //#readItems
+   * @until //#readItems
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleCoreReader.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//readpath
+   * @until #//readpath
+   * @skipline #//readItems
+   * @until #//readItems
+   *
+   * @param     filePath        The path of the Xdmf file to read in from disk.
+   *
+   * @return                    A vector of XdmfItems at the root of the Xdmf tree.
+   */
+  virtual std::vector<shared_ptr<XdmfItem> >
+  readItems(const std::string & filePath) const;
+
+  /**
+   * Used by the other functions to read items from an open file.
+   *
+   * Since files are closed between reads, this does nothing by itself.
+   *
+   * @param     xPath   An XPath corresponding to the portion of the file to read.
+   *
+   * @return            A vector of items at the X path provided.
+   */
+  std::vector<shared_ptr<XdmfItem> >
+  readPathObjects(const std::string & xPath) const;
+
+protected:
+
+  /**
+   * Constructor
+   *
+   * @param itemFactory an XdmfCoreItemFactory to construct XdmfItems
+   * for a specific language.
+   */
+  XdmfCoreReader(const shared_ptr<const XdmfCoreItemFactory> itemFactory);
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfCoreReaderImpl;
+
+  XdmfCoreReader(const XdmfCoreReader &);  // Not implemented.
+  void operator=(const XdmfCoreReader &);  // Not implemented.
+
+  XdmfCoreReaderImpl * const mImpl;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFCOREREADER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFCOREREADER XDMFCOREREADER;
+
+XDMFCORE_EXPORT XDMFITEM * XdmfCoreReaderRead(XDMFCOREREADER * reader, char * filePath, int * status);
+
+#define XDMF_CORE_READER_C_CHILD_DECLARE(ClassName, CClassName, Level)                      \
+                                                                                            \
+Level##_EXPORT XDMFITEM * ClassName##Read( CClassName * reader, char * filePath, int * status);
+
+#define XDMF_CORE_READER_C_CHILD_WRAPPER(ClassName, CClassName)                             \
+                                                                                            \
+XDMFITEM * ClassName##Read( CClassName * reader, char * filePath, int * status)                 \
+{                                                                                           \
+  return XdmfCoreReaderRead((XDMFCOREREADER *)((void *)reader), filePath, status);          \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFCOREREADER_HPP_ */
diff --git a/core/XdmfError.cpp b/core/XdmfError.cpp
new file mode 100644
index 0000000..72a37f2
--- /dev/null
+++ b/core/XdmfError.cpp
@@ -0,0 +1,207 @@
+#include <XdmfError.hpp>
+#include <cstdlib>
+#include <iostream>
+
+XdmfError::XdmfError(Level level, std::string message) :
+  mLevel(level),
+  mMessage(message)
+{
+}
+
+XdmfError::~XdmfError() throw()
+{
+}
+
+/************************
+ *** Public Functions ***
+ ************************/
+
+XdmfError::Level
+XdmfError::getLevel() const
+{
+  return XdmfError::mLevel;
+}
+
+void
+XdmfError::setLevel(Level l)
+{
+  XdmfError::mLevel = l;
+}
+
+const char *
+XdmfError::what() const throw()
+{
+  return XdmfError::mMessage.c_str();
+}
+
+/*******************************
+ *** Public Static Functions ***
+ *******************************/
+
+bool
+XdmfError::getCErrorsAreFatal()
+{
+  return XdmfError::mCErrorsAreFatal;
+}
+
+XdmfError::Level
+XdmfError::getLevelLimit()
+{
+  return XdmfError::mLevelLimit;
+}
+
+XdmfError::Level
+XdmfError::getSuppressionLevel()
+{
+  return XdmfError::mSuppressLevel;
+}
+
+void
+XdmfError::setCErrorsAreFatal(bool status)
+{
+  XdmfError::mCErrorsAreFatal = status;
+}
+
+void
+XdmfError::setLevelLimit(Level l)
+{
+  XdmfError::mLevelLimit = l;
+}
+
+void
+XdmfError::setSuppressionLevel(Level l)
+{
+  XdmfError::mSuppressLevel = l;
+}
+
+void
+XdmfError::message(Level level, std::string msg)
+{
+  if (level<=XdmfError::getSuppressionLevel())
+  {
+    XdmfError::WriteToStream(msg);
+  }
+  if(level<=XdmfError::getLevelLimit()) {
+    throw XdmfError(level, msg);
+  }
+}
+
+void
+XdmfError::setBuffer(std::streambuf* buf)
+{
+  XdmfError::mBuf = buf;
+}
+
+/********************************
+ *** Private Static Functions ***
+ ********************************/
+
+// automatically writes the message to the provided buffer
+// by default this is basically a print statement
+void
+XdmfError::WriteToStream(std::string msg)
+{
+  if(msg[msg.length()-1] != '\n') {
+    // using \r\n for windows compatiblity
+    msg+="\r\n";
+  }
+  XdmfError::mBuf->sputn(msg.c_str(),msg.length());
+}
+
+/******************************************
+ *** Initialize Static Member Variables ***
+ ******************************************/
+
+XdmfError::Level XdmfError::mLevelLimit = XdmfError::FATAL;
+XdmfError::Level XdmfError::mSuppressLevel = XdmfError::WARNING;
+std::streambuf* XdmfError::mBuf=std::cout.rdbuf();
+bool XdmfError::mCErrorsAreFatal = false;
+
+// C Wrappers
+
+void XdmfErrorSetCErrorsAreFatal(int status)
+{
+  XdmfError::setCErrorsAreFatal(status);
+}
+
+void XdmfErrorSetLevelLimit(int level, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (level) {
+    case XDMF_ERROR_FATAL:
+      XdmfError::setLevelLimit(XdmfError::FATAL);
+      break;
+    case XDMF_ERROR_WARNING:
+      XdmfError::setLevelLimit(XdmfError::WARNING);
+      break;
+    case XDMF_ERROR_DEBUG:
+      XdmfError::setLevelLimit(XdmfError::DEBUG);
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL, "Error: Invalid Error Level");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfErrorSetSuppressionLevel(int level, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (level) {
+    case XDMF_ERROR_FATAL:
+      XdmfError::setSuppressionLevel(XdmfError::FATAL);
+      break;
+    case XDMF_ERROR_WARNING:
+      XdmfError::setSuppressionLevel(XdmfError::WARNING);
+      break;
+    case XDMF_ERROR_DEBUG:
+      XdmfError::setSuppressionLevel(XdmfError::DEBUG);
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL, "Error: Invalid Error Level");
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+int XdmfErrorGetCErrorsAreFatal()
+{
+  return XdmfError::getCErrorsAreFatal();
+}
+
+int XdmfErrorGetLevelLimit()
+{
+  if (XdmfError::getLevelLimit() == XdmfError::FATAL) {
+    return XDMF_ERROR_FATAL;
+  }
+  else if (XdmfError::getLevelLimit() == XdmfError::WARNING) {
+    return XDMF_ERROR_WARNING;
+  }
+  else if (XdmfError::getLevelLimit() == XdmfError::DEBUG) {
+    return XDMF_ERROR_DEBUG;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Invalid Error Level");
+  }
+  return -1;
+}
+
+int XdmfErrorGetSuppressionLevel()
+{
+  if (XdmfError::getSuppressionLevel() == XdmfError::FATAL) {
+    return XDMF_ERROR_FATAL;
+  }
+  else if (XdmfError::getSuppressionLevel() == XdmfError::WARNING) {
+    return XDMF_ERROR_WARNING;
+  }
+  else if (XdmfError::getSuppressionLevel() == XdmfError::DEBUG) {
+    return XDMF_ERROR_DEBUG;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Invalid Error Level");
+  }
+  return -1;
+}
diff --git a/core/XdmfError.hpp b/core/XdmfError.hpp
new file mode 100644
index 0000000..6f900c7
--- /dev/null
+++ b/core/XdmfError.hpp
@@ -0,0 +1,326 @@
+#ifndef XDMFERROR_HPP_
+#define XDMFERROR_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include <iosfwd>
+#include <sstream>
+#include <exception>
+
+class XDMFCORE_EXPORT XdmfError  : public std::exception
+{
+public:
+    enum Level {FATAL, WARNING, DEBUG};
+
+    /**
+     * One of the constructors for XdmfError, this one doesn't print to the buffer.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     *
+     * Python:
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//initialization
+     * @until #//initialization
+     *
+     * @param   level           The error level of the exception being constructed
+     * @param   message         The message to be attached to the exception
+     */
+    XdmfError(Level level, std::string message);
+
+    ~XdmfError() throw();
+
+    /**
+     * Sets the error level of the exception.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#setLevel
+     * @until //#setLevel
+     *
+     * Python:
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//setLevel
+     * @until #//setLevel
+     *
+     * @param   l       The new level of the exception
+     */
+    void setLevel(Level l);
+
+    /**
+     * Gets the error level of the exception.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#getLevel
+     * @until //#getLevel
+     *
+     * Python:
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//getLevel
+     * @until #//getLevel
+     *
+     * @return  The error level of the exception
+     */
+    Level getLevel() const;
+
+    /**
+     * Gets whether C errors are Fatal. If set to false a status will be returned
+     * to C when an error is thrown. Otherwise there will be no handling and the
+     * program will exit since C cannot handle exceptions.
+     *
+     * @param   status  Whether the C wrappers are to pass an integer value to
+     *                  C on failure instead of exiting.
+     */
+    static void setCErrorsAreFatal(bool status);
+
+    /**
+     * Sets the level limit for Errors. This determines what level of errors will be thrown with message.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#setLevelLimit
+     * @until //#setLevelLimit
+     *
+     * Python
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//setLevelLimit
+     * @until #//setLevelLimit
+     *
+     * @param   l       The cutoff level for sending exceptions via message
+     */
+    static void setLevelLimit(Level l);
+
+    /**
+     * Sets the minimum Error level that displays messages with the message function.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#setSuppressionLevel
+     * @until //#setSuppressionLevel
+     *
+     * Python
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//setSuppressionLevel
+     * @until #//setSuppressionLevel
+     *
+     * @param   l       The new minimum error level to display a message
+     */
+    static void setSuppressionLevel(Level l);
+
+    /**
+     * Gets whether C errors are Fatal. If set to false a status will be returned
+     * to C when an error is thrown. Otherwise there will be no handling and the
+     * program will exit since C cannot handle exceptions.
+     *
+     * @return  Whether the C wrappers with pass an integer value to C
+     *          instead of stopping the program
+     */
+    static bool getCErrorsAreFatal();
+
+    /**
+     * Gets the level limit for Errors.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#getLevelLimit
+     * @until //#getLevelLimit
+     *
+     * Python
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//getLevelLimit
+     * @until #//getLevelLimit
+     *
+     * @return  The cuttof level for sending exceptions via message
+     */
+    static Level getLevelLimit();
+
+    /**
+     * Gets the minimum Error level that displays messages with the message function.
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#getSuppressionLevel
+     * @until //#getSuppressionLevel
+     *
+     * Python
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//getSuppressionLevel
+     * @until #//getSuppressionLevel
+     *
+     * @return  The minimum error level to display a message
+     */
+    static Level getSuppressionLevel();
+
+    /**
+     * Alternate constructor for XdmfError exceptions.
+     * This one automatically prints out the message provided if the error level
+     * above the suppression level. If the error level is not above the
+     * level limit an exception will not be thrown.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#message
+     * @until //#message
+     *
+     * Python: Generates a RuntimeError instead of an XdmfError in Python
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//message
+     * @until #//message
+     *
+     * @param   l       The level of the error to be generated
+     * @param   msg     The message to be associated with the error generated and printed out
+     */
+    static void message(Level l, std::string msg);
+
+    /**
+     * Sets which buffer the error messages are printed to with the message function.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#setBuffer
+     * @until //#setBuffer
+     *
+     * Python: Not supported in Python
+     *
+     * @param   buf     The buffer that the error messages will be printed to
+     */
+    static void setBuffer(std::streambuf* buf);
+
+    /**
+     * Gets the message associated with this exception.
+     *
+     * Example of use:
+     *
+     * C++
+     *
+     * @dontinclude ExampleXdmfError.cpp
+     * @skipline //#initialization
+     * @until //#initialization
+     * @skipline //#what
+     * @until //#what
+     *
+     * Python
+     *
+     * @dontinclude XdmfExampleError.py
+     * @skipline #//what
+     * @until #//what
+     *
+     * @return  The message associated with the exception
+     */
+    virtual const char * what() const throw();
+
+private:
+    Level mLevel;
+    static Level mLevelLimit;
+    static Level mSuppressLevel;
+    static std::streambuf* mBuf;
+    static bool mCErrorsAreFatal;
+    std::string mMessage;
+
+    static void WriteToStream(std::string msg);
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#define XDMF_SUCCESS  1
+#define XDMF_FAIL    -1
+
+#define XDMF_ERROR_FATAL   40
+#define XDMF_ERROR_WARNING 41
+#define XDMF_ERROR_DEBUG   42
+
+XDMFCORE_EXPORT void XdmfErrorSetCErrorsAreFatal(int status);
+
+XDMFCORE_EXPORT void XdmfErrorSetLevelLimit(int level, int * status);
+
+XDMFCORE_EXPORT void XdmfErrorSetSuppressionLevel(int level, int * status);
+
+XDMFCORE_EXPORT int XdmfErrorGetCErrorsAreFatal();
+
+XDMFCORE_EXPORT int XdmfErrorGetLevelLimit();
+
+XDMFCORE_EXPORT int XdmfErrorGetSuppressionLevel();
+
+#ifdef __cplusplus
+
+//Use these macros to catch Exceptions for C code
+
+#define XDMF_ERROR_WRAP_START(status)    \
+if (status) {                            \
+  *status = XDMF_SUCCESS;                \
+}                                        \
+try {
+
+#define XDMF_ERROR_WRAP_END(status)      \
+}                                        \
+catch (XdmfError & e) {                  \
+  if (XdmfError::getCErrorsAreFatal()) { \
+    throw e;                             \
+  }                                      \
+  else {                                 \
+    if (status) {                        \
+    *status = XDMF_FAIL;                 \
+    }                                    \
+  }                                      \
+}
+
+}
+#endif
+
+#endif
diff --git a/core/XdmfFunction.cpp b/core/XdmfFunction.cpp
new file mode 100644
index 0000000..a9429b4
--- /dev/null
+++ b/core/XdmfFunction.cpp
@@ -0,0 +1,1827 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfFunction.cpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfWriter.hpp"
+#include <stack>
+#include <cmath>
+#include <boost/assign.hpp>
+#include "XdmfError.hpp"
+
+class XdmfFunctionInternalImpl : public XdmfFunction::XdmfFunctionInternal {
+  public:
+    static shared_ptr<XdmfFunctionInternalImpl>
+    New(shared_ptr<XdmfArray> (*newInternal)(std::vector<shared_ptr<XdmfArray> >))
+    {
+      shared_ptr<XdmfFunctionInternalImpl> p (new XdmfFunctionInternalImpl(newInternal));
+      return p;
+    }
+
+    ~XdmfFunctionInternalImpl()
+    {
+    }
+
+    virtual shared_ptr<XdmfArray> execute(std::vector<shared_ptr<XdmfArray> > valueVector)
+    {
+      return (*mInternalFunction)(valueVector);
+    }
+  private:
+    XdmfFunctionInternalImpl(shared_ptr<XdmfArray> (*newInternal)(std::vector<shared_ptr<XdmfArray> >))
+    {
+      mInternalFunction = newInternal;
+    }
+
+    shared_ptr<XdmfArray> (*mInternalFunction)(std::vector<shared_ptr<XdmfArray> >);
+};
+
+class XdmfOperationInternalImpl : public XdmfFunction::XdmfOperationInternal {
+  public:
+    static shared_ptr<XdmfOperationInternalImpl>
+    New(shared_ptr<XdmfArray> (*newInternal)(shared_ptr<XdmfArray>, shared_ptr<XdmfArray>))
+    {
+      shared_ptr<XdmfOperationInternalImpl> p (new XdmfOperationInternalImpl(newInternal));
+      return p;
+    }
+
+    ~XdmfOperationInternalImpl()
+    {
+    }
+
+    virtual shared_ptr<XdmfArray> execute(shared_ptr<XdmfArray> val1,
+                                          shared_ptr<XdmfArray> val2)
+    {
+      return (*mInternalOperation)(val1, val2);
+    }
+  private:
+    XdmfOperationInternalImpl(shared_ptr<XdmfArray> (*newInternal)(shared_ptr<XdmfArray>,
+                                                                   shared_ptr<XdmfArray>))
+    {
+      mInternalOperation = newInternal;
+    }
+
+    shared_ptr<XdmfArray> (*mInternalOperation)(shared_ptr<XdmfArray>, shared_ptr<XdmfArray>);
+};
+
+std::string XdmfFunction::mSupportedOperations = "-+/*|#()";
+const std::string XdmfFunction::mValidVariableChars =
+  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_:.";
+const std::string XdmfFunction::mValidDigitChars = "1234567890.";
+// List the priorities for the operations, based on the order of operations
+// The index of the corresponding operation in validOperationChars
+// is the same as the index of its priority in this array
+std::map<char, int> XdmfFunction::mOperationPriority = 
+	boost::assign::map_list_of ('-', 4)
+                                   ('+', 4)
+                                   ('/', 3)
+                                   ('*', 3)
+                                   ('|', 2)
+                                   ('#', 1)
+                                   ('(', 0)
+                                   (')', 0);
+// The higher the value, the earlier the operation is
+// evaluated in the order of operations
+// With the exception of parenthesis which are evaluated
+// as soon as the closing parenthesis is found
+
+// Note, it doesn't handle overloaded functions well.
+// Will generate errors unless overload methods are typecast.
+std::map<std::string, shared_ptr<XdmfFunction::XdmfFunctionInternal> >
+  XdmfFunction::arrayFunctions =
+    boost::assign::map_list_of
+      ("ABS", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::abs))
+      ("ABS_TOKEN", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::abs))
+      ("ACOS", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::arccos))
+      ("ASIN", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::arcsin))
+      ("ATAN", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::arctan))
+      ("AVE", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::average))
+      ("COS", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::cos))
+      ("EXP", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::exponent))
+      ("JOIN", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::join))
+      ("LOG", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::log))
+      ("SIN", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::sin))
+      ("SQRT", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::sqrt))
+      ("SUM", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::sum))
+      ("TAN", XdmfFunctionInternalImpl::New((shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))
+                                            XdmfFunction::tan));
+
+std::map<char, shared_ptr<XdmfFunction::XdmfOperationInternal> >
+  XdmfFunction::operations =
+    boost::assign::map_list_of
+      ('-', XdmfOperationInternalImpl::New(XdmfFunction::subtraction))
+      ('+', XdmfOperationInternalImpl::New(XdmfFunction::addition))
+      ('*', XdmfOperationInternalImpl::New(XdmfFunction::multiplication))
+      ('/', XdmfOperationInternalImpl::New(XdmfFunction::division))
+      ('|', XdmfOperationInternalImpl::New(XdmfFunction::chunk))
+      ('#', XdmfOperationInternalImpl::New(XdmfFunction::interlace));
+
+shared_ptr<XdmfFunction>
+XdmfFunction::New()
+{
+  shared_ptr<XdmfFunction> p(new XdmfFunction());
+  return p;
+}
+
+shared_ptr<XdmfFunction>
+XdmfFunction::New(std::string newExpression,
+                  std::map<std::string, shared_ptr<XdmfArray> > newVariables)
+{
+  shared_ptr<XdmfFunction> p(new XdmfFunction(newExpression, newVariables));
+  return p;
+}
+
+XdmfFunction::XdmfFunction():
+  mExpression("")
+{
+}
+
+XdmfFunction::XdmfFunction(std::string newExpression,
+                           std::map<std::string, shared_ptr<XdmfArray> > newVariables):
+  mVariableList(newVariables),
+  mExpression(newExpression)
+{
+}
+
+XdmfFunction::XdmfFunction(XdmfFunction & refFunction) :
+  XdmfArrayReference(refFunction),
+  mExpression(refFunction.getExpression())
+{
+  std::vector<std::string> copyVariables = refFunction.getVariableList();
+  for (unsigned int i = 0; i < copyVariables.size(); ++i) {
+    mVariableList[copyVariables[i]] = refFunction.getVariable(copyVariables[i]);
+  }
+}
+
+XdmfFunction::~XdmfFunction()
+{
+}
+
+const std::string XdmfFunction::ItemTag = "Function";
+
+shared_ptr<XdmfArray>
+XdmfFunction::abs(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function abs");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(std::abs(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+int
+XdmfFunction::addFunction(std::string name,
+                          shared_ptr<XdmfArray>(*functionref)(std::vector<shared_ptr<XdmfArray> >))
+{
+  shared_ptr<XdmfFunctionInternalImpl> newFunction =
+     XdmfFunctionInternalImpl::New(functionref);
+  return XdmfFunction::addFunction(name, newFunction);
+}
+
+int
+XdmfFunction::addFunction(std::string name,
+                          shared_ptr<XdmfFunctionInternal> newFunction)
+{
+  // Check to ensure that the name has valid characters
+  for (unsigned int i = 0; i < name.size(); ++i) {
+    // If the character is not found in the list of valid characters
+    if (mValidVariableChars.find(name[i]) == std::string::npos) {
+      // Then throw an error
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Function Name Contains Invalid Character(s)");
+    }
+  }
+  size_t origsize = arrayFunctions.size();
+  arrayFunctions[name] = newFunction;
+  // If no new functions were added
+  if (origsize == arrayFunctions.size()) {
+    // Toss a warning, it's nice to let people know that they're doing this
+    XdmfError::message(XdmfError::WARNING,
+                       "Warning: Function Overwritten");
+  }
+  return arrayFunctions.size();
+}
+
+int
+XdmfFunction::addOperation(char newoperator,
+                           shared_ptr<XdmfArray>(*operationref)(shared_ptr<XdmfArray>,
+                                                                shared_ptr<XdmfArray>),
+                           int priority)
+{
+  shared_ptr<XdmfOperationInternalImpl> newOperation =
+     XdmfOperationInternalImpl::New(operationref);
+  return XdmfFunction::addOperation(newoperator,
+                                    newOperation,
+                                    priority);
+}
+
+int
+XdmfFunction::addOperation(char newoperator,
+                           shared_ptr<XdmfOperationInternal> newOperation,
+                           int priority)
+{
+  if (newoperator == '(' || newoperator == ')') {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Parenthesis can not be redefined");
+  }
+  if (mValidVariableChars.find(newoperator) != std::string::npos
+      || mValidDigitChars.find(newoperator) != std::string::npos) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Operation Overlaps with Variables");
+  }
+  // Give warning if the operation already exists
+  size_t origsize = operations.size();
+  // Place reference in the associated location
+  operations[newoperator] = newOperation;
+  if (origsize == operations.size()) {
+    // It's nice to let people know they're doing this
+    // So they don't get surprised about changes in behavior
+    XdmfError::message(XdmfError::WARNING,
+                       "Warning: Operation Overwritten");
+    // Overwrite the existing info for that operation
+    // Add the priority to the specified location in the priority array
+    mOperationPriority[newoperator] = priority;
+  }
+  else {
+    // Create new operation
+    // Add operation to the supported character string
+    mSupportedOperations.push_back(newoperator);
+    mOperationPriority[newoperator] = priority;
+  }
+  return operations.size();
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::addition(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  bool release1 = false;
+  bool release2 = false;
+  if (!val1->isInitialized()) {
+    val1->read();
+    release1 = true;
+  }
+  if (!val2->isInitialized()) {
+    val2->read();
+    release2 = true;
+  }
+  for (unsigned int i = 0; i < val1->getSize() || i < val2->getSize(); ++i) {
+    if (val1->getSize() == val2->getSize()) {
+      returnArray->pushBack(val1->getValue<double>(i) + val2->getValue<double>(i));
+    }
+    else if (val1->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(0) + val2->getValue<double>(i));
+    }
+    else if (val2->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(i) + val2->getValue<double>(0));
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Array Size Mismatch in Function addition");
+    }
+  }
+  if (release1) {
+    val1->release();
+  }
+  if (release2) {
+    val2->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::arcsin(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function arcsin");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(asin(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::arccos(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function arccos");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(acos(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::arctan(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function arctan");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(atan(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::average(std::vector<shared_ptr<XdmfArray> > values)
+{
+  double total = sum(values)->getValue<double>(0);;
+  int totalSize = 0;
+  bool release = false;
+  for (unsigned int i = 0; i < values.size(); ++i)
+  {
+    release = false;
+    if (!values[i]->isInitialized()) {
+      values[i]->read();
+      release = true;
+    }
+    totalSize += values[i]->getSize();
+    if (release) {
+      values[i]->release();
+    }
+  }
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  returnArray->insert(0, total/totalSize);
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::cos(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function cos");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(std::cos(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::chunk(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+  // Join chunk (add the new array to the end of the first one)
+  // Joins into new array and returns it
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Determining what type to class it as in order to not lose data
+  // and to still have the smallest data type of the two
+  shared_ptr<const XdmfArrayType> resultType =
+    XdmfArrayType::comparePrecision(val1->getArrayType(),
+                                    val2->getArrayType());
+  bool release1 = false;
+  bool release2 = false;
+  if (!val1->isInitialized()) {
+    val1->read();
+    release1 = true;
+  }
+  if (!val2->isInitialized()) {
+    val2->read();
+    release2 = true;
+  }
+  if (resultType == XdmfArrayType::Int8()) {
+    char sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Int16()) {
+    short sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Int32()) {
+    int sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Int64()) {
+    long sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::UInt8()) {
+    unsigned char sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::UInt16()) {
+    unsigned short sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::UInt32()) {
+    unsigned int sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Float32()) {
+    float sampleValue = 0.0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Float64()) {
+    double sampleValue = 0.0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::String()) {
+    std::string sampleValue = "";
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else {
+    // error type not supported
+    XdmfError::message(XdmfError::FATAL, "Invalid type during Chunk");
+  }
+  returnArray->insert(0, val1, 0, val1->getSize(),  1, 1);
+  returnArray->insert(val1->getSize(), val2, 0, val2->getSize(), 1, 1);
+  if (release1) {
+    val1->release();
+  }
+  if (release2) {
+    val2->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::exponent(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 2) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Two Arrays Needed for Function exponent");
+  }
+  bool release1 = false;
+  bool release2 = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release1 = true;
+  }
+  if (!values[1]->isInitialized()) {
+    values[1]->read();
+    release2 = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize() || i < values[1]->getSize(); ++i) {
+    if (values[0]->getSize() == values[1]->getSize()) {
+      returnArray->pushBack(std::pow(values[0]->getValue<double>(i), values[1]->getValue<double>(i)));
+    }
+    else if (values[0]->getSize() == 1) {
+      returnArray->pushBack(std::pow(values[0]->getValue<double>(0), values[1]->getValue<double>(i)));
+    }
+    else if (values[1]->getSize() == 1) {
+      returnArray->pushBack(std::pow(values[0]->getValue<double>(i), values[1]->getValue<double>(0)));
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Array Size Mismatch in Function exponent");
+    }
+  }
+  if (release1) {
+    values[0]->release();
+  }
+  if (release2) {
+    values[1]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::division(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+  bool release1 = false;
+  bool release2 = false;
+  if (!val1->isInitialized()) {
+    val1->read();
+    release1 = true;
+  }
+  if (!val2->isInitialized()) {
+    val2->read();
+    release2 = true;
+  }
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  for (unsigned int i = 0; i < val1->getSize() || i < val2->getSize(); ++i) {
+    if (val1->getSize() == val2->getSize()) {
+      returnArray->pushBack(val1->getValue<double>(i) / val2->getValue<double>(i));
+    }
+    else if (val1->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(0) / val2->getValue<double>(i));
+    }
+    else if (val2->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(i) / val2->getValue<double>(0));
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Array Size Mismatch in Function division");
+    }
+  }
+  if (release1) {
+    val1->release();
+  }
+  if (release2) {
+    val2->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::evaluateExpression(std::string expression,
+                                 std::map<std::string,
+                                   shared_ptr<XdmfArray> > variables)
+{
+  std::stack<shared_ptr<XdmfArray> > valueStack;
+  std::stack<char> operationStack;
+
+  // String is parsed left to right
+  // Elements of the same priority are evaluated right to left
+  for (unsigned int i = 0; i < expression.size(); ++i) {
+    bool hyphenIsDigit = false;
+    // hyphen is a special case since it can be used to annotate negative numbers
+    if (expression[i] == '-') {
+      if (i == 0) {
+        //would have to be a digit, otherwise it would be a unpaired operation
+        hyphenIsDigit = true;
+      }
+      else if (mValidDigitChars.find(expression[i+1]) != std::string::npos) {
+        // If value after is a valid digit,
+        // check value before
+        // If a digit, it's an operation
+        // If a variable, it's an operation
+        // If an operation, it's a digit character
+        if (mSupportedOperations.find(expression[i-1]) != std::string::npos) {
+          hyphenIsDigit = true;
+        }
+        else if (expression[i-1] <= ' ') {
+          // If whitespace is in front of the hyphen it is presumed to be a negative sign
+          // This is to handle passing negative values to functions properly
+          hyphenIsDigit = true;
+        }
+      }
+    }
+    // Found to be a digit
+    if (mValidDigitChars.find(expression[i]) != std::string::npos ||
+        (expression[i] == '-' && hyphenIsDigit)) {
+      // Progress until a non-digit is found
+      int valueStart = i;
+      if (i + 1 < expression.size()) {
+        while (mValidDigitChars.find(expression[i+1]) != std::string::npos) {
+          i++;
+        }
+      }
+      // Push back to the value stack
+      shared_ptr<XdmfArray> valueArray = XdmfArray::New();
+      // Use this to convert to double
+      valueArray->insert(0, atof(expression.substr(valueStart, i + 1 - valueStart).c_str()));
+      valueStack.push(valueArray);
+    }
+    else if (mValidVariableChars.find(expression[i]) != std::string::npos) {
+      // Found to be a variable
+      int valueStart = i;
+      // Progress until a nonvariable value is found
+      if (i+1 < expression.size()){
+        while (mValidVariableChars.find(expression[i+1]) != std::string::npos) {
+          i++;
+        }
+      }
+      // Convert to equivalent
+      if (variables.find(expression.substr(valueStart, i + 1 - valueStart))
+          == variables.end()) {
+        if (arrayFunctions.find(expression.substr(valueStart, i + 1 - valueStart))
+            == arrayFunctions.end()) {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Invalid Variable in evaluateExpression "
+                             + expression.substr(valueStart, i + 1 - valueStart));
+        }
+        else {
+          std::string currentFunction =
+            expression.substr(valueStart, i + 1 - valueStart);
+          // Check if next character is an open parenthesis
+          if (i+1 >= expression.size()) {
+            if (expression[i+1] != '(') {
+              XdmfError::message(XdmfError::FATAL,
+                                 "Error: No values supplied to function "
+                                 + expression.substr(valueStart, i + 1 - valueStart));
+            }
+          }
+          // If it is grab the string between paranthesis
+
+          if (i + 2 >= expression.size()) {
+            XdmfError::message(XdmfError::FATAL,
+                               "Error: Missing closing parethesis to function "
+                               + expression.substr(valueStart, i + 1 - valueStart));
+          }
+          i = i + 2;
+          valueStart = i;
+          int numOpenParenthesis = 0;
+          while ((expression[i] != ')' || numOpenParenthesis) && i < expression.size()) {
+            if (expression[i] == '(') {
+              numOpenParenthesis++;
+            }
+            else if (expression[i] == ')') {
+              numOpenParenthesis--;
+            }
+            i++;
+          }
+          std::string functionParameters = expression.substr(valueStart, i - valueStart);
+          std::vector<shared_ptr<XdmfArray> > parameterVector;
+          // Split that string at commas
+          size_t parameterSplit = 0;
+          while (parameterSplit != std::string::npos) {
+            parameterSplit = 0;
+            parameterSplit = functionParameters.find_first_of(",", parameterSplit);
+            // Feed the substrings to the parse function
+            if (parameterSplit == std::string::npos) {
+              parameterVector.push_back(evaluateExpression(functionParameters, variables));
+            }
+            else {
+              parameterVector.push_back(
+                evaluateExpression(functionParameters.substr(0, parameterSplit),
+                                   variables));
+              functionParameters = functionParameters.substr(parameterSplit+1);
+            }
+          }
+          valueStack.push(evaluateFunction(parameterVector, currentFunction));
+        }
+      }
+      else {
+        // Push equivalent to value stack
+        valueStack.push(variables.find(expression.substr(valueStart, i + 1 - valueStart))->second);
+      }
+    }
+    else if (mSupportedOperations.find(expression[i]) != std::string::npos) {
+      // Found to be an operation
+      // Pop operations off the stack until one of a lower or equal importance is found
+      if (operationStack.size() > 0) {
+        if (expression[i] == ')') {
+          // To close a parenthesis pop off all operations until another parentheis is found
+          while (operationStack.size() > 0 && operationStack.top() != '(') {
+            // Must be at least two values for this loop to work properly
+            if (valueStack.size() < 2) {
+              XdmfError::message(XdmfError::FATAL,
+                                 "Error: Not Enough Values in evaluateExpression");
+            }
+            else {
+              shared_ptr<XdmfArray> val2 = valueStack.top();
+              valueStack.pop();
+              shared_ptr<XdmfArray> val1 = valueStack.top();
+              valueStack.pop();
+              valueStack.push(evaluateOperation(val1, val2, operationStack.top()));
+              operationStack.pop();
+            }
+          }
+          operationStack.pop();
+        }
+        else if (expression[i] == '(') {
+          // Just add it if it's a start parenthesis
+          // Nothing happens here in that case
+          // Addition happens after the if statement
+        }
+        else {
+          int operationLocation = getOperationPriority(expression[i]);
+          int topOperationLocation = getOperationPriority(operationStack.top());
+          // See order of operations to determine importance
+          while (operationStack.size() > 0 && operationLocation < topOperationLocation) {
+            // Must be at least two values for this loop to work properly
+            if (valueStack.size() < 2) {
+              XdmfError::message(XdmfError::FATAL,
+                                 "Error: Not Enough Values in evaluateExpression");
+            }
+            else {
+              shared_ptr<XdmfArray> val2 = valueStack.top();
+              valueStack.pop();
+              shared_ptr<XdmfArray> val1 = valueStack.top();
+              valueStack.pop();
+              valueStack.push(evaluateOperation(val1, val2, operationStack.top()));
+              operationStack.pop();
+              if (operationStack.size() == 0) {
+                break;
+              }
+              topOperationLocation = getOperationPriority(operationStack.top());
+            }
+          }
+        }
+      }
+      if (expression[i] != ')') {
+        // Add the operation to the operation stack
+        operationStack.push(expression[i]);
+      }
+    }
+    // If not a value or operation the character is ignored
+  }
+
+  // Empty what's left in the stacks before finishing
+  while (valueStack.size() > 1 && operationStack.size() > 0) {
+    if (valueStack.size() < 2) {
+      // Must be at least two values for this loop to work properly
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Not Enough Values in evaluateExpression");
+    }
+    else {
+      if(operationStack.top() == '(') {
+        XdmfError::message(XdmfError::WARNING,
+                           "Warning: Unpaired Parenthesis");
+      }
+      else {
+        shared_ptr<XdmfArray> val2 = valueStack.top();
+        valueStack.pop();
+        shared_ptr<XdmfArray> val1 = valueStack.top();
+        valueStack.pop();
+        if (operationStack.size() == 0) {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Not Enough Operators in evaluateExpression");
+        }
+        else {
+          valueStack.push(evaluateOperation(val1, val2, operationStack.top()));
+          operationStack.pop();
+        }
+      }
+    }
+  }
+
+  // Throw error if there's extra operations
+  if (operationStack.size() > 0) {
+    XdmfError::message(XdmfError::WARNING,
+                       "Warning: Left Over Operators in evaluateExpression");
+  }
+
+  if (valueStack.size() > 1) {
+    XdmfError::message(XdmfError::WARNING,
+                       "Warning: Left Over Values in evaluateExpression");
+  }
+
+  // Ensure that an array is returned
+  // Will error out if this is not done.
+  if (valueStack.size() > 0) {
+    return valueStack.top();
+  }
+  else {
+    return XdmfArray::New();
+  }
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::evaluateOperation(shared_ptr<XdmfArray> val1,
+                             shared_ptr<XdmfArray> val2,
+                             char operation)
+{
+  if (operations.find(operation) != operations.end()) {
+    return operations[operation]->execute(val1, val2);
+  }
+  else {
+    return shared_ptr<XdmfArray>();
+  }
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::evaluateFunction(std::vector<shared_ptr<XdmfArray> > valueVector,
+                            std::string functionName)
+{
+  if (arrayFunctions.find(functionName) != arrayFunctions.end()) {
+    return arrayFunctions[functionName]->execute(valueVector);
+  }
+  else {
+    return shared_ptr<XdmfArray>();
+  }
+}
+
+std::string
+XdmfFunction::getExpression() const
+{
+  return mExpression;
+}
+
+std::string
+XdmfFunction::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::map<std::string, std::string>
+XdmfFunction::getItemProperties() const
+{
+  std::map<std::string, std::string> functionProperties = XdmfArrayReference::getItemProperties();
+
+  functionProperties["Expression"] = mExpression;
+
+  std::stringstream variableStream;
+
+  for (std::map<std::string, shared_ptr<XdmfArray> >::const_iterator variableIter = mVariableList.begin();
+       variableIter != mVariableList.end();
+       ++variableIter) {
+    variableStream << "|" << variableIter->first;
+  }
+
+  functionProperties["VariableNames"] = variableStream.str();
+
+  return functionProperties;
+}
+
+int
+XdmfFunction::getOperationPriority(char operation)
+{
+  size_t operationLocation = mSupportedOperations.find(operation);
+  if (operationLocation != std::string::npos) {
+    return mOperationPriority[operation];
+  }
+  else {
+    return -1;
+  }
+}
+
+
+const std::string
+XdmfFunction::getSupportedOperations()
+{
+        return mSupportedOperations;
+}
+
+const std::vector<std::string>
+XdmfFunction::getSupportedFunctions()
+{
+  std::vector<std::string> returnVector;
+  for (std::map<std::string, shared_ptr<XdmfFunctionInternal> >::iterator functionWalker
+       = arrayFunctions.begin();
+       functionWalker != arrayFunctions.end();
+       ++functionWalker) {
+    returnVector.push_back(functionWalker->first);
+  }
+  return returnVector;
+}
+
+const std::string
+XdmfFunction::getValidDigitChars()
+{
+        return mValidDigitChars;
+}
+
+const std::string
+XdmfFunction::getValidVariableChars()
+{
+        return mValidVariableChars;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::getVariable(std::string key)
+{
+  if (mVariableList.count(key) > 0) {
+    return mVariableList[key];
+  }
+  else {
+    return shared_ptr<XdmfArray>();
+  }
+}
+
+std::vector<std::string>
+XdmfFunction::getVariableList()
+{
+  std::vector<std::string> keyAccumulator;
+  for (std::map<std::string, shared_ptr<XdmfArray> >::iterator it = mVariableList.begin();
+       it != mVariableList.end();
+       ++it) {
+    keyAccumulator.push_back(it->first);
+  }
+  return keyAccumulator;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::interlace(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+  // Join interlace (evenly space the second array within the first one)
+  // Builds a new array
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Resize to the combined size of both arrays
+  // Determining what type to class it as in order to not lose data
+  // and to still have the smallest data type of the two
+  shared_ptr<const XdmfArrayType> resultType =
+    XdmfArrayType::comparePrecision(val1->getArrayType(), val2->getArrayType());
+  bool release1 = false;
+  bool release2 = false;
+  if (!val1->isInitialized()) {
+    val1->read();
+    release1 = true;
+  }
+  if (!val2->isInitialized()) {
+    val2->read();
+    release2 = true;
+  }
+  if (resultType == XdmfArrayType::Int8()) {
+    char sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Int16()) {
+    short sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Int32()) {
+    int sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Int64()) {
+    long sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::UInt8()) {
+    unsigned char sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::UInt16()) {
+    unsigned short sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::UInt32()) {
+    unsigned int sampleValue = 0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Float32()) {
+    float sampleValue = 0.0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::Float64()) {
+    double sampleValue = 0.0;
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else if (resultType == XdmfArrayType::String()) {
+    std::string sampleValue = "";
+    returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+  }
+  else {
+    // error type not supported
+    XdmfError::message(XdmfError::FATAL, "Invalid type during Interlace");
+  }
+
+  // Determine ratio of array sizes
+  int arrayRatio1 = (int)floor(static_cast<double>(val1->getSize())/val2->getSize());
+  int arrayRatio2 = (int)floor(static_cast<double>(val2->getSize())/val1->getSize());
+  if (arrayRatio1 < 1) {
+    arrayRatio1 = 1;
+  }
+  if (arrayRatio2 < 1) {
+    arrayRatio2 = 1;
+  }
+  // Stride is equal to the ratios rounded up and added together
+  int stride = arrayRatio1+arrayRatio2;
+  int arrayExcess1 = 0;
+  int arrayExcess2 = 0;
+  for (int i = 0; i < stride; ++i) {
+    // Add the values of each array
+    // using strides to interlace and starting index to offset
+    // first array gets the first value of the new array
+    if (i<arrayRatio1) {
+      int amountWritten = val1->getSize()/arrayRatio1;
+      if (((amountWritten * arrayRatio1) + i) < (int)val1->getSize()) {
+        amountWritten++;
+      }
+      if (amountWritten > floor(static_cast<double>(val2->getSize())/arrayRatio2)) {
+        arrayExcess1 += amountWritten - (int)floor(static_cast<double>(val2->getSize())/arrayRatio2);
+        amountWritten = (int)floor(static_cast<double>(val2->getSize())/arrayRatio2);
+      }
+      returnArray->insert(i, val1, i, amountWritten, stride, arrayRatio1);
+    }
+    else {
+      // Second array takes the rest
+      int amountWritten = val2->getSize()/arrayRatio2;
+      if (((amountWritten * arrayRatio2) + i) < (int)val2->getSize()) {
+        amountWritten++;
+      }
+      if (amountWritten > floor(static_cast<double>(val1->getSize())/arrayRatio1)) {
+        arrayExcess2 += amountWritten - (int)floor(static_cast<double>(val1->getSize())/arrayRatio1);
+        amountWritten = (int)floor(static_cast<double>(val1->getSize())/arrayRatio1);
+      }
+      returnArray->insert(i, val2, i-arrayRatio1, amountWritten, stride, arrayRatio2);
+    }
+  }
+  if (arrayExcess1 > 0) {
+    returnArray->insert(val1->getSize()+val2->getSize()-arrayExcess1,
+                        val1,
+                        val1->getSize()-arrayExcess1,
+                        arrayExcess1,
+                        1,
+                        1);
+  }
+  else if (arrayExcess2 > 0) {
+    returnArray->insert(val1->getSize()+val2->getSize()-arrayExcess2,
+                        val2,
+                        val2->getSize()-arrayExcess2,
+                        arrayExcess2,
+                        1,
+                        1);
+  }
+  // After all inserts are done, add the excess values to the end of the array
+  if (release1) {
+    val1->release();
+  }
+  if (release2) {
+    val2->release();
+  }
+  return returnArray;
+}
+
+void
+XdmfFunction::insertVariable(std::string key, shared_ptr<XdmfArray> value)
+{
+  mVariableList[key] = value;
+  this->setIsChanged(true);
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::join(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  bool release = false;
+  for (unsigned int i = 0; i < values.size(); ++i) {
+    release = false;
+    if (!values[i]->isInitialized()) {
+      values[i]->read();
+      release = true;
+    }
+    returnArray->insert(returnArray->getSize(),
+                        values[i],
+                        0,
+                        values[i]->getSize(),
+                        1,
+                        1);
+    if (release) {
+      values[i]->release();
+    }
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::log(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function log");
+  }
+  bool release1 = false;
+  bool release2 = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release1 = true;
+  }
+  if (values.size() > 1) {
+    if (!values[1]->isInitialized()) {
+      values[1]->read();
+      release2 = true;
+    }
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    if (values.size() > 1) {
+      if (values[0]->getSize() == values[1]->getSize()) {
+        returnArray->pushBack(std::log(values[0]->getValue<double>(i))/std::log(values[1]->getValue<double>(i)));
+      }
+      else if (values[1]->getSize() == 1) {
+        returnArray->pushBack(std::log(values[0]->getValue<double>(i))/std::log(values[1]->getValue<double>(0)));
+      }
+      else {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Array Size Missmatch in Function Log");
+      }
+    }
+    else {
+      returnArray->pushBack(std::log(values[0]->getValue<double>(i)));
+    }
+  }
+  if (release1) {
+    values[0]->release();
+  }
+  if (release2) {
+    values[1]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::multiplication(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  bool release1 = false;
+  bool release2 = false;
+  if (!val1->isInitialized()) {
+    val1->read();
+    release1 = true;
+  }
+  if (!val2->isInitialized()) {
+    val2->read();
+    release2 = true;
+  }
+  for (unsigned int i = 0; i < val1->getSize() || i < val2->getSize(); ++i) {
+    if (val1->getSize() == val2->getSize()) {
+      returnArray->pushBack(val1->getValue<double>(i) * val2->getValue<double>(i));
+    }
+    else if (val1->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(0) * val2->getValue<double>(i));
+    }
+    else if (val2->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(i) * val2->getValue<double>(0));
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Array Size Mismatch in Function multiplication");
+    }
+  }
+  if (release1) {
+    val1->release();
+  }
+  if (release2) {
+    val2->release();
+  }
+  return returnArray;
+}
+
+
+shared_ptr<XdmfArray>
+XdmfFunction::read() const
+{
+  return evaluateExpression(mExpression, mVariableList);
+}
+
+void
+XdmfFunction::removeVariable(std::string key)
+{
+  std::map<std::string, shared_ptr<XdmfArray> >::iterator removeWalker =
+    mVariableList.find(key);
+  if (removeWalker != mVariableList.end()) {
+    mVariableList.erase(removeWalker);
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfFunction::setExpression(std::string newExpression)
+{
+  mExpression = newExpression;
+  this->setIsChanged(true);
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::sin(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function sin");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(std::sin(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::sqrt(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function sqrt");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(std::sqrt(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::subtraction(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  bool release1 = false;
+  bool release2 = false;
+  if (!val1->isInitialized()) {
+    val1->read();
+    release1 = true;
+  }
+  if (!val2->isInitialized()) {
+    val2->read();
+    release2 = true;
+  }
+  for (unsigned int i = 0; i < val1->getSize() || i < val2->getSize(); ++i) {
+    if (val1->getSize() == val2->getSize()) {
+      returnArray->pushBack(val1->getValue<double>(i) - val2->getValue<double>(i));
+    }
+    else if (val1->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(0) - val2->getValue<double>(i));
+    }
+    else if (val2->getSize() == 1) {
+      returnArray->pushBack(val1->getValue<double>(i) - val2->getValue<double>(0));
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Array Size Mismatch in Function subtraction");
+    }
+  }
+  if (release1) {
+    val1->release();
+  }
+  if (release2) {
+    val2->release();
+  }
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::sum(std::vector<shared_ptr<XdmfArray> > values)
+{
+  double total = 0.0;
+  bool release = false;
+  for (unsigned int i = 0; i < values.size(); ++i) {
+    release = false;
+    if (!values[i]->isInitialized()) {
+      values[i]->read();
+      release = true;
+    }
+    for (unsigned int j = 0; j < values[i]->getSize(); ++j) {
+      total += values[i]->getValue<double>(j);
+    }
+    if (release) {
+      values[i]->release();
+    }
+  }
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  returnArray->insert(0, total);
+  return returnArray;
+}
+
+shared_ptr<XdmfArray>
+XdmfFunction::tan(std::vector<shared_ptr<XdmfArray> > values)
+{
+  shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+  // Only working with the first array provided
+  if (values.size() < 1) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: No Array Passed to Function tan");
+  }
+  bool release = false;
+  if (!values[0]->isInitialized()) {
+    values[0]->read();
+    release = true;
+  }
+  for (unsigned int i = 0; i < values[0]->getSize(); ++i) {
+    returnArray->pushBack(std::tan(values[0]->getValue<double>(i)));
+  }
+  if (release) {
+    values[0]->release();
+  }
+  return returnArray;
+}
+
+void
+XdmfFunction::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+
+  bool originalXPath;
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    originalXPath = writer->getWriteXPaths();
+    writer->setWriteXPaths(false);
+  }
+
+  shared_ptr<XdmfArray> spacerarray = XdmfArray::New();
+  spacerarray->pushBack((int)0);
+  spacerarray->accept(visitor);
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    writer->setWriteXPaths(originalXPath);
+  } 
+
+  for (std::map<std::string, shared_ptr<XdmfArray> >::iterator it = mVariableList.begin();
+       it != mVariableList.end();
+       ++it) {
+    it->second->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+class XdmfCFunctionInternalImpl : public XdmfFunction::XdmfFunctionInternal {
+  public:
+    static shared_ptr<XdmfCFunctionInternalImpl>
+    New(XDMFARRAY * (*newInternal)(XDMFARRAY **, unsigned int))
+    {
+      shared_ptr<XdmfCFunctionInternalImpl> p (new XdmfCFunctionInternalImpl(newInternal));
+      return p;
+    }
+
+    ~XdmfCFunctionInternalImpl()
+    {
+    }
+
+    virtual shared_ptr<XdmfArray> execute(std::vector<shared_ptr<XdmfArray> > valueVector)
+    {
+      XDMFARRAY ** valueArray = new XDMFARRAY *[valueVector.size()]();
+      for (unsigned int i = 0; i < valueVector.size(); ++i) {
+        valueArray[i] = (XDMFARRAY *)((void *)(valueVector[i].get()));
+      }
+      return shared_ptr<XdmfArray>((XdmfArray *)((*mInternalFunction)(valueArray, valueVector.size())));
+    }
+  private:
+    XdmfCFunctionInternalImpl(XDMFARRAY * (*newInternal)(XDMFARRAY **, unsigned int))
+    {
+      mInternalFunction = newInternal;
+    }
+
+    XDMFARRAY * (*mInternalFunction)(XDMFARRAY **, unsigned int);
+};
+
+class XdmfCOperationInternalImpl : public XdmfFunction::XdmfOperationInternal {
+  public:
+    static shared_ptr<XdmfCOperationInternalImpl>
+    New(XDMFARRAY * (*newInternal)(XDMFARRAY *, XDMFARRAY *))
+    {
+      shared_ptr<XdmfCOperationInternalImpl> p (new XdmfCOperationInternalImpl(newInternal));
+      return p;
+    }
+
+    ~XdmfCOperationInternalImpl()
+    {
+    }
+
+    virtual shared_ptr<XdmfArray> execute(shared_ptr<XdmfArray> val1,
+                                          shared_ptr<XdmfArray> val2)
+    {
+      return shared_ptr<XdmfArray>((XdmfArray *)((*mInternalOperation)((XDMFARRAY *)((void *)(val1.get())), (XDMFARRAY *)((void *)(val2.get())))));
+    }
+  private:
+    XdmfCOperationInternalImpl(XDMFARRAY * (*newInternal)(XDMFARRAY *, XDMFARRAY *))
+    {
+      mInternalOperation = newInternal;
+    }
+
+    XDMFARRAY * (*mInternalOperation)(XDMFARRAY *, XDMFARRAY *);
+};
+
+XDMFFUNCTION * XdmfFunctionNew()
+{
+  try
+  {
+    shared_ptr<XdmfFunction> generatedFunction = XdmfFunction::New();
+    return (XDMFFUNCTION *)((void *)(new XdmfFunction(*generatedFunction.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfFunction> generatedFunction = XdmfFunction::New();
+    return (XDMFFUNCTION *)((void *)(new XdmfFunction(*generatedFunction.get())));
+  }
+}
+
+XDMFFUNCTION * XdmfFunctionNewInit(char * newExpression,  char ** keys, XDMFARRAY ** values, int numVariables)
+{
+  try
+  {
+    std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+    for (int i = 0; i < numVariables; ++i) {
+      variableMap[keys[i]] = shared_ptr<XdmfArray>((XdmfArray *)(values[i]), XdmfNullDeleter());
+    }
+    shared_ptr<XdmfFunction> generatedFunction = XdmfFunction::New(std::string(newExpression), variableMap);
+    return (XDMFFUNCTION *)((void *)(new XdmfFunction(*generatedFunction.get())));
+  }
+  catch (...)
+  {
+    std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+    for (int i = 0; i < numVariables; ++i) {
+      variableMap[keys[i]] = shared_ptr<XdmfArray>((XdmfArray *)(values[i]), XdmfNullDeleter());
+    }
+    shared_ptr<XdmfFunction> generatedFunction = XdmfFunction::New(std::string(newExpression), variableMap);
+    return (XDMFFUNCTION *)((void *)(new XdmfFunction(*generatedFunction.get())));
+  }
+}
+
+int XdmfFunctionAddFunction(char * name, XDMFARRAY *(*functionref)(XDMFARRAY **, unsigned int), int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    shared_ptr<XdmfCFunctionInternalImpl> newFunction =
+       XdmfCFunctionInternalImpl::New(functionref);
+    return XdmfFunction::addFunction(name, newFunction);
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfCFunctionInternalImpl> newFunction =
+       XdmfCFunctionInternalImpl::New(functionref);
+    return XdmfFunction::addFunction(name, newFunction);
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+int XdmfFunctionAddOperation(char newoperator, XDMFARRAY *(*operationref)(XDMFARRAY *, XDMFARRAY *), int priority, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    shared_ptr<XdmfCOperationInternalImpl> newOperation =
+       XdmfCOperationInternalImpl::New(operationref);
+    return XdmfFunction::addOperation(newoperator,
+                                      newOperation,
+                                      priority);
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfCOperationInternalImpl> newOperation =
+       XdmfCOperationInternalImpl::New(operationref);
+    return XdmfFunction::addOperation(newoperator,
+                                      newOperation,
+                                      priority);
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+XDMFARRAY * XdmfFunctionAverage(XDMFARRAY ** values, int numValues)
+{
+  try
+  {
+    std::vector<shared_ptr<XdmfArray> > valueVector;
+    for (int i = 0; i < numValues; ++i) {
+      valueVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)values[i], XdmfNullDeleter()));
+    }
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::average(valueVector).get()))));
+  }
+  catch (...)
+  {
+    std::vector<shared_ptr<XdmfArray> > valueVector;
+    for (int i = 0; i < numValues; ++i) {
+      valueVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)values[i], XdmfNullDeleter()));
+    }
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::average(valueVector).get()))));
+  }
+}
+
+XDMFARRAY * XdmfFunctionChunk(XDMFARRAY * val1, XDMFARRAY * val2, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::chunk(shared_ptr<XdmfArray>((XdmfArray *)val1, XdmfNullDeleter()), shared_ptr<XdmfArray>((XdmfArray *)val2, XdmfNullDeleter())).get()))));
+  }
+  catch (...)
+  {
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::chunk(shared_ptr<XdmfArray>((XdmfArray *)val1, XdmfNullDeleter()), shared_ptr<XdmfArray>((XdmfArray *)val2, XdmfNullDeleter())).get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfFunctionEvaluateExpression(char * expression, char ** keys, XDMFARRAY ** values, int numVariables, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+    for (int i = 0; i < numVariables; ++i) {
+      variableMap[keys[i]] = shared_ptr<XdmfArray>((XdmfArray *)(values[i]), XdmfNullDeleter());
+    }
+    shared_ptr<XdmfArray> generatedArray = XdmfFunction::evaluateExpression(std::string(expression), variableMap);
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(generatedArray.get()))));
+  }
+  catch (...)
+  {
+    std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+    for (int i = 0; i < numVariables; ++i) {
+      variableMap[keys[i]] = shared_ptr<XdmfArray>((XdmfArray *)(values[i]), XdmfNullDeleter());
+    }
+    shared_ptr<XdmfArray> generatedArray = XdmfFunction::evaluateExpression(std::string(expression), variableMap);
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(generatedArray.get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfFunctionEvaluateOperation(XDMFARRAY * val1, XDMFARRAY * val2, char operation, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    shared_ptr<XdmfArray> generatedArray = XdmfFunction::evaluateOperation(shared_ptr<XdmfArray>((XdmfArray *)(val1), XdmfNullDeleter()), shared_ptr<XdmfArray>((XdmfArray *)(val2), XdmfNullDeleter()), operation);
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(generatedArray.get()))));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfArray> generatedArray = XdmfFunction::evaluateOperation(shared_ptr<XdmfArray>((XdmfArray *)(val1), XdmfNullDeleter()), shared_ptr<XdmfArray>((XdmfArray *)(val2), XdmfNullDeleter()), operation);
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(generatedArray.get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfFunctionEvaluateFunction(XDMFARRAY ** valueVector, int numValues, char * functionName, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<shared_ptr<XdmfArray> > evaluatedVector;
+    for (int i = 0; i < numValues; ++i) {
+      evaluatedVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)valueVector[i], XdmfNullDeleter()));
+    }
+    shared_ptr<XdmfArray> generatedArray = XdmfFunction::evaluateFunction(evaluatedVector, std::string(functionName));
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(generatedArray.get()))));
+  }
+  catch (...)
+  {
+    std::vector<shared_ptr<XdmfArray> > evaluatedVector;
+    for (int i = 0; i < numValues; ++i) {
+      evaluatedVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)valueVector[i], XdmfNullDeleter()));
+    }
+    shared_ptr<XdmfArray> generatedArray = XdmfFunction::evaluateFunction(evaluatedVector, std::string(functionName));
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(generatedArray.get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+char * XdmfFunctionGetExpression(XDMFFUNCTION * function)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfFunction *)(function))->getExpression().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfFunction *)(function))->getExpression().c_str());
+    return returnPointer;
+  }
+}
+
+unsigned int XdmfFunctionGetNumberVariables(XDMFFUNCTION * function)
+{
+  return ((XdmfFunction *)(function))->getVariableList().size();
+}
+
+int XdmfFunctionGetOperationPriority(char operation)
+{
+  return XdmfFunction::getOperationPriority(operation);
+}
+
+char * XdmfFunctionGetSupportedOperations()
+{
+  try
+  {
+    return strdup(XdmfFunction::getSupportedOperations().c_str());
+  }
+  catch (...)
+  {
+    return strdup(XdmfFunction::getSupportedOperations().c_str());
+  }
+}
+
+char ** XdmfFunctionGetSupportedFunctions()
+{
+  try
+  {
+    std::vector<std::string> supportedFunctions = XdmfFunction::getSupportedFunctions();
+    char ** returnPointer = new char *[supportedFunctions.size()]();
+    for (unsigned int i = 0; i < supportedFunctions.size(); ++i) {
+      returnPointer[i] = strdup(supportedFunctions[i].c_str());
+    }
+    return returnPointer;
+  }
+  catch (...)
+  {
+    std::vector<std::string> supportedFunctions = XdmfFunction::getSupportedFunctions();
+    char ** returnPointer = new char *[supportedFunctions.size()]();
+    for (unsigned int i = 0; i < supportedFunctions.size(); ++i) {
+      returnPointer[i] = strdup(supportedFunctions[i].c_str());
+    }
+    return returnPointer;
+  }
+}
+
+unsigned int XdmfFunctionGetNumberSupportedFunctions()
+{
+  return XdmfFunction::getSupportedFunctions().size();
+}
+
+char * XdmfFunctionGetValidDigitChars()
+{
+  try
+  {
+    return strdup(XdmfFunction::getValidDigitChars().c_str());
+  }
+  catch (...)
+  {
+    return strdup(XdmfFunction::getValidDigitChars().c_str());
+  }
+}
+
+char * XdmfFunctionGetValidVariableChars()
+{
+  try
+  {
+    return strdup(XdmfFunction::getValidVariableChars().c_str());
+  }
+  catch (...)
+  {
+    return strdup(XdmfFunction::getValidVariableChars().c_str());
+  }
+}
+
+XDMFARRAY * XdmfFunctionGetVariable(XDMFFUNCTION * function, char * key)
+{
+  try
+  {
+    shared_ptr<XdmfArray> returnArray = ((XdmfFunction *)function)->getVariable(std::string(key));
+    return (XDMFARRAY *)((void *)(new XdmfArray(*returnArray.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfArray> returnArray = ((XdmfFunction *)function)->getVariable(std::string(key));
+    return (XDMFARRAY *)((void *)(new XdmfArray(*returnArray.get())));
+  }
+}
+
+char ** XdmfFunctionGetVariableList(XDMFFUNCTION * function)
+{
+  try
+  {
+    std::vector<std::string> variablelist = ((XdmfFunction *)(function))->getVariableList();
+    char ** returnpointer = new char *[variablelist.size()]();
+    for (unsigned int i = 0; i < variablelist.size(); ++i) {
+      returnpointer[i] = strdup(variablelist[i].c_str());
+    }
+    return returnpointer;
+  }
+  catch (...)
+  {
+    std::vector<std::string> variablelist = ((XdmfFunction *)(function))->getVariableList();
+    char ** returnpointer = new char *[variablelist.size()]();
+    for (unsigned int i = 0; i < variablelist.size(); ++i) {
+      returnpointer[i] = strdup(variablelist[i].c_str());
+    }
+    return returnpointer;
+  }
+}
+
+XDMFARRAY * XdmfFunctionInterlace(XDMFARRAY * val1, XDMFARRAY * val2, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::interlace(shared_ptr<XdmfArray>((XdmfArray *)val1, XdmfNullDeleter()), shared_ptr<XdmfArray>((XdmfArray *)val2, XdmfNullDeleter())).get()))));
+  }
+  catch (...)
+  {
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::interlace(shared_ptr<XdmfArray>((XdmfArray *)val1, XdmfNullDeleter()), shared_ptr<XdmfArray>((XdmfArray *)val2, XdmfNullDeleter())).get()))));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void XdmfFunctionInsertVariable(XDMFFUNCTION * function, char * key, XDMFARRAY * value, int passControl)
+{
+  shared_ptr<XdmfArray> insertedValue;
+  if (passControl == 0) {
+    insertedValue = shared_ptr<XdmfArray>((XdmfArray *)value, XdmfNullDeleter());
+  }
+  else {
+    insertedValue = shared_ptr<XdmfArray>((XdmfArray *)value);
+  }
+  ((XdmfFunction *)function)->insertVariable(std::string(key), insertedValue);
+}
+
+void XdmfFunctionRemoveVariable(XDMFFUNCTION * function, char * key)
+{
+  ((XdmfFunction *)(function))->removeVariable(std::string(key));
+}
+
+void XdmfFunctionSetExpression(XDMFFUNCTION * function, char * newExpression, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfFunction *)(function))->setExpression(std::string(newExpression));
+  XDMF_ERROR_WRAP_END(status)
+}
+
+XDMFARRAY * XdmfFunctionSum(XDMFARRAY ** values, int numValues)
+{
+  try
+  {
+    std::vector<shared_ptr<XdmfArray> > valueVector;
+    for (int i = 0; i < numValues; ++i) {
+      valueVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)values[i], XdmfNullDeleter()));
+    }
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::sum(valueVector).get()))));
+  }
+  catch (...)
+  {
+    std::vector<shared_ptr<XdmfArray> > valueVector;
+    for (int i = 0; i < numValues; ++i) {
+      valueVector.push_back(shared_ptr<XdmfArray>((XdmfArray *)values[i], XdmfNullDeleter()));
+    }
+    return (XDMFARRAY *)((void *)(new XdmfArray(*(XdmfFunction::sum(valueVector).get()))));
+  }
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfFunction, XDMFFUNCTION)
+XDMF_ARRAYREFERENCE_C_CHILD_WRAPPER(XdmfFunction, XDMFFUNCTION)
diff --git a/core/XdmfFunction.hpp b/core/XdmfFunction.hpp
new file mode 100644
index 0000000..e63d66d
--- /dev/null
+++ b/core/XdmfFunction.hpp
@@ -0,0 +1,1398 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfFunction.hpp                                                    */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFFUNCTION_HPP_
+#define XDMFFUNCTION_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfArrayReference.hpp"
+
+#ifdef __cplusplus
+
+class XdmfArray;
+
+/**
+ * @brief Manipulates arrays based on expressions.
+ *
+ * The function class provides a way to manipulate XdmfArrays via predefined functions.
+ */
+class XDMFCORE_EXPORT XdmfFunction : public XdmfArrayReference {
+
+public:
+
+
+  /**
+   * Function wrapper to allow for more flexibility when wrapping
+   * functions to be used in the dynamic library.
+   *
+   * Not required to use the dynamic library because there are
+   * methods that take function pointers.
+   */
+  class XdmfFunctionInternal {
+    public:
+      virtual ~XdmfFunctionInternal()
+      {
+      }
+
+      virtual shared_ptr<XdmfArray>
+      execute(std::vector<shared_ptr<XdmfArray> > valueVector) = 0;
+  };
+
+  /**
+   * Binary Operator wrapper to allow for more flexibility when wrapping
+   * operations to be used in the dynamic library.
+   *
+   * Not required to use the dynamic library because there are
+   * methods that take function pointers.
+   */
+  class XdmfOperationInternal {
+    public:
+      virtual ~XdmfOperationInternal()
+      {
+      }
+
+      virtual shared_ptr<XdmfArray>
+      execute(shared_ptr<XdmfArray> val1,
+              shared_ptr<XdmfArray> val2) = 0;
+  };
+
+  /**
+   * Create a new XdmfFunction
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfFunction.
+   */
+  static shared_ptr<XdmfFunction> New();
+
+  /**
+   * Create a new XdmfFunction
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   *
+   * @param     newExpression   The expression that the function will evaluate
+   * @param     newVariables    The arrays that the function will use
+   *                            to evalute the expression
+   * @return                    Constructed XdmfFunction.
+   */
+  static shared_ptr<XdmfFunction>
+  New(std::string newExpression,
+      std::map<std::string,
+      shared_ptr<XdmfArray> > newVariables);
+
+  virtual ~XdmfFunction();
+
+  LOKI_DEFINE_VISITABLE(XdmfFunction, XdmfItem)
+
+  static const std::string ItemTag;
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the absolute value equivalent of that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#abs
+   * @until //#abs
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//abs
+   * @until #//abs
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the absolute value
+   *                    equivalent of the first array
+   */
+  static shared_ptr<XdmfArray> abs(std::vector<shared_ptr<XdmfArray> > values);
+
+  /*
+   * Adds a specified function to the list of functions used while
+   * evaluating strings
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declarefunction
+   * @until //#declarefunction
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#addFunction
+   * @until //#addFunction
+   * @skipline //#programend
+   * @until //#programend
+   * @skipline //#definefunction
+   * @until //#definefunction
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//definefunction
+   * @until #//definefunction
+   * @skipline #//programstart
+   * @until #//programstart
+   * @skipline #//addFunction
+   * @until #//addFunction
+   *
+   * @param     name            A string to be associated with the provided
+   *                            function during string evaluation
+   * @param     functionref     A pointer to the function to be associated
+   *                            with the given string
+   * @return                    The total number of functions currently usable
+   */
+  static int
+  addFunction(std::string name,
+              shared_ptr<XdmfArray>(*functionref)(std::vector<shared_ptr<XdmfArray> >));
+
+  /**
+   * Adds a specified function to the list of functions used while
+   * evaluating strings.
+   * This version allows for custom wrapping.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declarefunctionclass
+   * @until //#declarefunctionclass
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#addFunctionclass
+   * @until //#addFunctionclass
+   * @skipline //#programend
+   * @until //#programend
+   *
+   * Python: This version of addFunction is not supported in Python
+   *
+   * @param     name            A string to be associated with the provided
+   *                            function during string evaluation
+   * @param     newFunction     A shared pointer to the function to be
+   *                            associated with the given string
+   * @return                    The total number of functions currently usable
+   */
+  static int
+  addFunction(std::string name,
+              shared_ptr<XdmfFunctionInternal> newFunction);
+
+  /**
+   * Adds an operation to the list of viable binary operators.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declareoperation
+   * @until //#declareoperation
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#addOperation
+   * @until //#addOperation
+   * @skipline //#programend
+   * @until //#programend
+   * @skipline //#defineoperation
+   * @until //#defineoperation
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//defineoperation
+   * @until #//defineoperation
+   * @skipline #//programstart
+   * @until #//programstart
+   * @skipline #//addOperation
+   * @until #//addOperation
+   *
+   * @param     newoperator     The character to be associated with the provided
+   *                            binary operation
+   * @param     functionref     A pointer to the function to be associated with
+   *                            the provided operator
+   * @param     priority        Used to determine order of operations,
+   *                            the higher the value the earlier it is evaluated
+   * @return                    The number of viable operations
+   */
+  static int
+  addOperation(char newoperator,
+               shared_ptr<XdmfArray>(*functionref)(shared_ptr<XdmfArray>,
+                                                   shared_ptr<XdmfArray>),
+               int priority);
+
+  /**
+   * Adds an operation to the list of viable binary operators.
+   * This version allows for custom wrapping.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declareoperationclass
+   * @until //#declareoperationclass
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#addOperationclass
+   * @until //#addOperationclass
+   * @skipline //#programend
+   * @until //#programend
+   *
+   * Python: This version of addOperation is not supported in Python
+   *
+   * @param     newoperator     The character to be associated with the provided
+   *                            binary operation
+   * @param     newOperation    A pointer to the function to be associated
+   *                            with the provided operator
+   * @param     priority        Used to determine order of operations,
+   *                            the higher the value the earlier it is evaluated
+   * @return                    The number of viable operations
+   */
+  static int
+  addOperation(char newoperator,
+               shared_ptr<XdmfOperationInternal> newOperation,
+               int priority);
+
+  /**
+   * Takes the arrays provided adds them together, returning the result.
+   *
+   * If the first array has one value an array is generated adding
+   * it to each value of the second array.
+   *
+   * If the second array has one value. That value is added to
+   * all values in the first array.
+   *
+   * If both arrays have the same number of values, the
+   * value of the first array is added to the value of the second array
+   * with the same index.
+   *
+   * An error is thrown if the array sizes are both large than 1
+   * and do not match.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#addition
+   * @until //#addition
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//addition
+   * @until #//addition
+   *
+   * @param     val1    The first Array to be used
+   * @param     val2    The second Array to be used
+   * @return            An XdmfArray containing the sums
+   *                    of the values of the arrays
+   */
+  static shared_ptr<XdmfArray> addition(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the arcsin of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#arcsin
+   * @until //#arcsin
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//arcsin
+   * @until #//arcsin
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the arcsin of the
+   *                    values of the first array
+   */
+  static shared_ptr<XdmfArray> arcsin(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the arccos of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#arccos
+   * @until //#arccos
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//arccos
+   * @until #//arccos
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the arccos of the
+   *                    values of the first array
+   */
+  static shared_ptr<XdmfArray> arccos(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the arctan of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#arctan
+   * @until //#arctan
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//arctan
+   * @until #//arctan
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the arctan of the
+   *                    values of the first array
+   */
+  static shared_ptr<XdmfArray> arctan(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Averages the values contained in all the provided arrays.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#average
+   * @until //#average
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//average
+   * @until #//average
+   *
+   * @param     values  A vector containing the arrays to be used
+   * @return            An XdmfArray containing one value which is the average
+   *                    of all values contained within the provided arrays
+   */
+  static shared_ptr<XdmfArray>
+  average(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Joins the two provided arrays together end to end.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#chunk
+   * @until //#chunk
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//chunk
+   * @until #//chunk
+   *
+   * @param     val1    The first array being evaluated
+   * @param     val2    The second array being evaluated
+   * @return            The arrays joined end to end
+   */
+  static shared_ptr<XdmfArray>
+  chunk(shared_ptr<XdmfArray> val1,
+        shared_ptr<XdmfArray> val2);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the cos of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#cos
+   * @until //#cos
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//cos
+   * @until #//cos
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the cos of the
+   *                    values of the first array
+   */
+  static shared_ptr<XdmfArray> cos(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the arrays provided and divides the first one by the second,
+   * returning the result.
+   *
+   * If the first array has one value an array is generated
+   * by dividing it by each value of the second array.
+   *
+   * If the second array has one value. Each value in the
+   * first array is divided by that value.
+   *
+   * If both arrays have the same number of values, each value of
+   * the first array is divided by the value of the second array
+   * with the same index.
+   *
+   * An error is thrown if the array sizes are both large than 1
+   * and do not match.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#division
+   * @until //#division
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//division
+   * @until #//division
+   *
+   * @param     val1    The array to be divided
+   * @param     val2    The array to be divided by
+   * @return            An XdmfArray containing the results
+   *                    of the division of the arrays
+   */
+  static shared_ptr<XdmfArray> division(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the values in that array taken to a power relative to the second array.
+   *
+   * If the first array has one value an array is generated by raising that
+   * value to the power of each of the values in the second array
+   *
+   * If the second array has one value. That power is applied to each
+   * value of the first array
+   *
+   * If both arrays have the same number of values, each value of the
+   * first array is raised to the power of the value of the
+   * corresponding index of the second array.
+   *
+   * An error is thrown if the array sizes are both large than 1
+   * and do not match.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#exp
+   * @until //#exp
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//exp
+   * @until #//exp
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the powers
+   *                    of the values of the first array
+   */
+  static shared_ptr<XdmfArray> exponent(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Evaluates an expression based on the list of variables provided.
+   * A list of valid operations is retrievable from the getSupportedOperations
+   * static method.
+   * None of the XdmfArrays provided are modified during the evaluation process.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declarefunction
+   * @until //#declarefunction
+   * @skipline //#declareoperation
+   * @until //#declareoperation
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#addOperation
+   * @until //#addOperation
+   * @skipline //#addFunction
+   * @until //#addFunction
+   * @skipline //#evaluateExpression
+   * @until //#evaluateExpression
+   * @skipline //#programend
+   * @until //#programend
+   * @skipline //#definefunction
+   * @until //#definefunction
+   * @skipline //#defineoperation
+   * @until //#defineoperation
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//definefunction
+   * @until #//definefunction
+   * @skipline #//defineoperation
+   * @until #//defineoperation
+   * @skipline #//programstart
+   * @until #//programstart
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//addOperation
+   * @until #//addOperation
+   * @skipline #//addFunction
+   * @until #//addFunction
+   * @skipline #//evaluateExpression
+   * @until #//evaluateExpression
+   *
+   * @param     expression      A string containing the expresion to be evaluated
+   * @param     variables       A map of strings to their XdmfArray equivalent
+   * @return                    A shared pointer to the XdmfArray resulting
+   *                            from the expression
+   */
+  static shared_ptr<XdmfArray>
+  evaluateExpression(std::string expression,
+                     std::map<std::string, shared_ptr<XdmfArray> > variables);
+
+  /**
+   * Evaluates the operation specified using the two shared pointers to
+   * XdmfArrays provided.
+   * A list of valid operations is retrievable from the getSupportedOperations
+   * static method.
+   * None of the XdmfArrays provided are modified during the evaluation process.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declareoperation
+   * @until //#declareoperation
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#addOperation
+   * @until //#addOperation
+   * @skipline //#evaluateOperation
+   * @until //#evaluateOperation
+   * @skipline //#programend
+   * @until //#programend
+   * @skipline //#defineoperation
+   * @until //#defineoperation
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//defineoperation
+   * @until #//defineoperation
+   * @skipline #//programstart
+   * @until #//programstart
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//addOperation
+   * @until #//addOperation
+   * @skipline #//evaluateOperation
+   * @until #//evaluateOperation
+   *
+   * @param     val1            The first array being evaluated
+   * @param     val2            The second array being evaluated
+   * @param     operation       A character specifying the operation performed
+   * @return                    A shared pointer to the Xdmf Array that results
+   *                            from the calculation
+   */
+  static shared_ptr<XdmfArray>
+  evaluateOperation(shared_ptr<XdmfArray> val1,
+                    shared_ptr<XdmfArray> val2,
+                    char operation);
+
+  /**
+   * Evaluates the function specified using the vector of XdmfArrays provided.
+   * None of the XdmfArrays provided are modified during the evaluation process.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#declarefunction
+   * @until //#declarefunction
+   * @skipline //#programstart
+   * @until //#programstart
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#addFunction
+   * @until //#addFunction
+   * @skipline //#evaluateFunction
+   * @until //#evaluateFunction
+   * @skipline //#programend
+   * @until //#programend
+   * @skipline //#definefunction
+   * @until //#definefunction
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//definefunction
+   * @until #//definefunction
+   * @skipline #//programstart
+   * @until #//programstart
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//addFunction
+   * @until #//addFunction
+   * @skipline #//evaluateFunction
+   * @until #//evaluateFunction
+   *
+   * @param     valueVector     A vector containing the arrays to be used
+   * @param     functionName    The string associated with the function being called
+   * @return                    The result of the function being called,
+   *                            a scalar will be returned as an XdmfArray with one value
+   */
+  static shared_ptr<XdmfArray>
+  evaluateFunction(std::vector<shared_ptr<XdmfArray> > valueVector,
+                   std::string functionName);
+
+  /**
+   * Sets the expression that the function will evaluate.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#setExpression
+   * @until //#setExpression
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//setExpression
+   * @until #//setExpression
+   *
+   * @return    The expression that the function is currently using to evaluate
+   */
+  std::string getExpression() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  /**
+   * Gets the priority of operation whose associated character is provided.
+   * Returns -1 if the operation is not supported.
+   * The higher the value the earlier that operation is evaluated
+   * during evaluateExpression.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#getOperationPriority
+   * @until //#getOperationPriority
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//getOperationPriority
+   * @until #//getOperationPriority
+   *
+   * @param     operation       The character associated with the operation
+   *                            to be checked
+   * @return                    The priority of the operation
+   */
+  static int getOperationPriority(char operation);
+
+  /**
+   * Gets a string that contains all the characters of the supported operations.
+   * Parenthesis are included for grouping purposes in expressions.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#getSupportedOperations
+   * @until //#getSupportedOperations
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//getSupportedOperations
+   * @until #//getSupportedOperations
+   *
+   * @return    A string containing the characters for all supported operations
+   */
+  static const std::string getSupportedOperations();
+
+  /**
+   * Gets a string that contains all the characters of the supported operations.
+   * Parenthesis are included for grouping purposes in expressions.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#getSupportedFunctions
+   * @until //#getSupportedFunctions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//getSupportedFunctions
+   * @until #//getSupportedFunctions
+   *
+   * @return    A vector containing the strings associated with all valid functions
+   */
+  static const std::vector<std::string> getSupportedFunctions();
+
+  /**
+   * Gets a string that contains all strings that are viable for use when mapping
+   * to scalars (which are stored in XdmfArrays of size 1) for the
+   * evaluateExpression function.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#getValidDigitChars
+   * @until //#getValidDigitChars
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//getValidDigitChars
+   * @until #//getValidDigitChars
+   *
+   * @return    A string containing all valid variable characters
+   */
+  static const std::string getValidDigitChars();
+
+  /**
+   * Gets a string that contains all strings that are viable for use when mapping
+   * to shared pointers of XdmfArrays for the evaluateExpression function.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#getValidVariableChars
+   * @until //#getValidVariableChars
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//getValidVariableChars
+   * @until #//getValidVariableChars
+   *
+   * @return    A string containing all valid variable characters
+   */
+  static const std::string getValidVariableChars();
+
+  /**
+   * Gets the array associated with the provided string out of the function's
+   * variable list.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#insertVariable
+   * @until //#insertVariable
+   * @skipline //#getVariable
+   * @until //#getVariable
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//insertVariable
+   * @until #//insertVariable
+   * @skipline #//getVariable
+   * @until #//getVariable
+   *
+   * @param     key     The string that is associated with the array to be retrieved
+   * @return            The array that corresponds with the key provided.
+   */
+  shared_ptr<XdmfArray> getVariable(std::string key);
+
+  /**
+   * Gets a vector containing all the keys accociated with arrays for this function.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#insertVariable
+   * @until //#insertVariable
+   * @skipline //#getVariableList
+   * @until //#getVariableList
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//insertVariable
+   * @until #//insertVariable
+   * @skipline #//getVariableList
+   * @until #//getVariableList
+   *
+   * @return    A vector of all the keys for this function
+   */
+  std::vector<std::string> getVariableList();
+
+  /**
+   * Joins the two provided arrays while interspercing their values evenly.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#interlace
+   * @until //#interlace
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//interlace
+   * @until #//interlace
+   *
+   * @param     val1    The first array being evaluated
+   * @param     val2    The second array being evaluated
+   * @return            The interlaced arrays
+   */
+  static shared_ptr<XdmfArray>
+  interlace(shared_ptr<XdmfArray> val1,
+            shared_ptr<XdmfArray> val2);
+
+  /**
+   * Adds a new variable to the list of variables that the Function will use.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#insertVariable
+   * @until //#insertVariable
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//insertVariable
+   * @until #//insertVariable
+   *
+   * @param     key     The string to be associated with the provided array
+   * @param     value   The value of the variable when evaluated
+   */
+  void insertVariable(std::string key, shared_ptr<XdmfArray> value);
+
+  /**
+   * Concatenates all provided arrays in order provided.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#join
+   * @until //#join
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//join
+   * @until #//join
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the combined values
+   */
+  static shared_ptr<XdmfArray> join(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the log of all the values in that array. If a second array is provided
+   * it specifies the base for the log used. Default is natural log.
+   *
+   * If the first array has one value an array is generated using a log
+   * whose base is specified in the second array.
+   *
+   * If the second array has one value. A log of that base is applied to
+   * all values of the first array.
+   *
+   * If both arrays have the same number of values, the
+   * log of the base specified by the value of the same index
+   * in the second array is used.
+   *
+   * An error is thrown if the array sizes are both large than 1
+   * and do not match.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#log
+   * @until //#log
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//log
+   * @until #//log
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the log
+   *                    of the values of the first array
+   */
+  static shared_ptr<XdmfArray> log(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the arrays provided and multiplies the first one by the second,
+   * returning the result.
+   *
+   * If the first array has one value an array is generated
+   * by multiplying it by each value of the second array.
+   *
+   * If the second array has one value. Each value in the
+   * first array is multiplied by that value.
+   *
+   * If both arrays have the same number of values, each value of
+   * the first array is multiplied by the value of the second array
+   * with the same index.
+   *
+   * An error is thrown if the array sizes are both large than 1
+   * and do not match.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#multiplication
+   * @until //#multiplication
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//multiplication
+   * @until #//multiplication
+   *
+   * @param     val1    The first array to be used
+   * @param     val2    The second array to be used
+   * @return            An XdmfArray containing the products
+   *                    of the multiplication of the arrays
+   */
+  static shared_ptr<XdmfArray> multiplication(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+
+  /**
+   * Parses the expression that the function contains and generates an array
+   * containing the values that the function produces.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//read
+   * @until #//read
+   */
+  virtual shared_ptr<XdmfArray> read() const;
+
+  /**
+   * Removes a variable from the function if it exists.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#insertVariable
+   * @until //#insertVariable
+   * @skipline //#removeVariable
+   * @until //#removeVariable
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//insertVariable
+   * @until #//insertVariable
+   * @skipline #//removeVariable
+   * @until #//removeVariable
+   *
+   * @param     key     The string to be associated with the provided array
+   */
+  void removeVariable(std::string key);
+
+  /**
+   * Sets the expression that the function will evaluate.
+   *
+   * Example of use:
+   *
+   * C++
+   * 
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#initexpression
+   * @until //#initexpression
+   * @skipline //#setExpression
+   * @until //#setExpression
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//initexpression
+   * @until #//initexpression
+   * @skipline #//setExpression
+   * @until #//setExpression
+   *
+   * @param     newExpression   The expression that the function is to evaluate
+   */
+  void setExpression(std::string newExpression);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the sin of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#sin
+   * @until //#sin
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//sin
+   * @until #//sin
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the sin of the
+   *                    values of the first array
+   */
+  static shared_ptr<XdmfArray> sin(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the square root of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#sqrt
+   * @until //#sqrt
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//sqrt
+   * @until #//sqrt
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the square root
+   *                    of the values of the first array
+   */
+  static shared_ptr<XdmfArray> sqrt(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the arrays provided and subtracts the second from the first,
+   * returning the result.
+   *
+   * If the first array has one value an array is generated
+   * by subtracting each value of the second array.
+   *
+   * If the second array has one value. That value is
+   * subtracted from each value of the first array.
+   *
+   * If both arrays have the same number of values, each value of
+   * the second array is subtracted from the value of the first array
+   * with the same index.
+   *
+   * An error is thrown if the array sizes are both large than 1
+   * and do not match.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#subtraction
+   * @until //#subtraction
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//subtraction
+   * @until #//subtraction
+   *
+   * @param     val1    The array to be subtracted from
+   * @param     val2    The array to be subtracted
+   * @return            An XdmfArray containing the difference
+   *                    of the arrays
+   */
+  static shared_ptr<XdmfArray> subtraction(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+
+  /**
+   * Adds together all the values contained in the provided arrays.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#valueinit
+   * @until //#valueinit
+   * @skipline //#sum
+   * @until //#sum
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//valueinit
+   * @until #//valueinit
+   * @skipline #//sum
+   * @until #//sum
+   *
+   * @param     values  A vector containing the arrays to be used
+   * @return            An XdmfArray containing one value which is the total
+   *                    of all the values contained within the provided arrays
+   */
+  static shared_ptr<XdmfArray>
+  sum(std::vector<shared_ptr<XdmfArray> > values);
+
+  /**
+   * Takes the first array provided and returns an array containing
+   * the tan of all the values in that array.
+   *
+   * Example of Use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfFunction.cpp
+   * @skipline //#tan
+   * @until //#tan
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleFunction.py
+   * @skipline #//tan
+   * @until #//tan
+   *
+   * @param     values  A vector containing the array to be used
+   * @return            An XdmfArray containing the tan of the
+   *                    values of the first array
+   */
+  static shared_ptr<XdmfArray> tan(std::vector<shared_ptr<XdmfArray> > values);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfFunction(XdmfFunction &);
+
+protected:
+
+  XdmfFunction();
+  XdmfFunction(std::string newExpression,
+               std::map<std::string,
+               shared_ptr<XdmfArray> > newVariables);
+
+private:
+
+  XdmfFunction(const XdmfFunction &);  // Not implemented.
+  void operator=(const XdmfFunction &);  // Not implemented.
+
+  std::map<std::string, shared_ptr<XdmfArray> > mVariableList;
+  std::string mExpression;
+
+  static std::string mSupportedOperations;
+  static const std::string mValidVariableChars;
+  static const std::string mValidDigitChars;
+  static std::map<char, int> mOperationPriority;
+
+
+  static std::map<std::string, shared_ptr<XdmfFunctionInternal> > arrayFunctions;
+  static std::map<char, shared_ptr<XdmfOperationInternal> > operations;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XDMFFUNCTION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFFUNCTION XDMFFUNCTION;
+
+XDMFCORE_EXPORT XDMFFUNCTION * XdmfFunctionNew();
+
+XDMFCORE_EXPORT XDMFFUNCTION * XdmfFunctionNewInit(char * newExpression,  char ** keys, XDMFARRAY ** values, int numVariables);
+
+XDMFCORE_EXPORT int XdmfFunctionAddFunction(char * name, XDMFARRAY *(*functionref)(XDMFARRAY **, unsigned int), int * status);
+
+XDMFCORE_EXPORT int XdmfFunctionAddOperation(char newoperator, XDMFARRAY *(*operationref)(XDMFARRAY *, XDMFARRAY *), int priority, int * status);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionAverage(XDMFARRAY ** values, int numValues);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionChunk(XDMFARRAY * val1, XDMFARRAY * val2, int * status);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionEvaluateExpression(char * expression, char ** keys, XDMFARRAY ** values, int numVariables, int * status);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionEvaluateOperation(XDMFARRAY * val1, XDMFARRAY * val2, char operation, int * status);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionEvaluateFunction(XDMFARRAY ** valueVector, int numValues, char * functionName, int * status);
+
+XDMFCORE_EXPORT char * XdmfFunctionGetExpression(XDMFFUNCTION * function);
+
+XDMFCORE_EXPORT unsigned int XdmfFunctionGetNumberVariables(XDMFFUNCTION * function);
+
+XDMFCORE_EXPORT int XdmfFunctionGetOperationPriority(char operation);
+
+XDMFCORE_EXPORT char * XdmfFunctionGetSupportedOperations();
+
+XDMFCORE_EXPORT char ** XdmfFunctionGetSupportedFunctions();
+
+XDMFCORE_EXPORT unsigned int XdmfFunctionGetNumberSupportedFunctions();
+
+XDMFCORE_EXPORT char * XdmfFunctionGetValidDigitChars();
+
+XDMFCORE_EXPORT char * XdmfFunctionGetValidVariableChars();
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionGetVariable(XDMFFUNCTION * function, char * key);
+
+XDMFCORE_EXPORT char ** XdmfFunctionGetVariableList(XDMFFUNCTION * function);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionInterlace(XDMFARRAY * val1, XDMFARRAY * val2, int * status);
+
+XDMFCORE_EXPORT void XdmfFunctionInsertVariable(XDMFFUNCTION * function, char * key, XDMFARRAY * value, int passControl);
+
+XDMFCORE_EXPORT void XdmfFunctionRemoveVariable(XDMFFUNCTION * function, char * key);
+
+XDMFCORE_EXPORT void XdmfFunctionSetExpression(XDMFFUNCTION * function, char * newExpression, int * status);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfFunctionSum(XDMFARRAY ** values, int numValues);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfFunction, XDMFFUNCTION, XDMFCORE)
+XDMF_ARRAYREFERENCE_C_CHILD_DECLARE(XdmfFunction, XDMFFUNCTION, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFFUNCTION_HPP_ */
diff --git a/core/XdmfHDF5Controller.cpp b/core/XdmfHDF5Controller.cpp
new file mode 100644
index 0000000..fe7eb60
--- /dev/null
+++ b/core/XdmfHDF5Controller.cpp
@@ -0,0 +1,460 @@
+/*****************************************************************************/
+/*                                    Xdmf                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5Controller.cpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <H5public.h>
+#include <hdf5.h>
+#include <numeric>
+#include <sstream>
+#include "string.h"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfSystemUtils.hpp"
+
+unsigned int XdmfHDF5Controller::mMaxOpenedFiles = 0;
+static std::map<std::string, hid_t> mOpenFiles;
+std::map<std::string, unsigned int> XdmfHDF5Controller::mOpenFileUsage;
+
+shared_ptr<XdmfHDF5Controller>
+XdmfHDF5Controller::New(const std::string & hdf5FilePath,
+                        const std::string & dataSetPath,
+                        const shared_ptr<const XdmfArrayType> & type,
+                        const std::vector<unsigned int> & start,
+                        const std::vector<unsigned int> & stride,
+                        const std::vector<unsigned int> & dimensions,
+                        const std::vector<unsigned int> & dataspaceDimensions)
+{
+  shared_ptr<XdmfHDF5Controller> 
+    p(new XdmfHDF5Controller(hdf5FilePath,
+                             dataSetPath,
+                             type,
+                             start,
+                             stride,
+                             dimensions,
+                             dataspaceDimensions));
+  return p;
+}
+
+XdmfHDF5Controller::XdmfHDF5Controller(const std::string & hdf5FilePath,
+                                       const std::string & dataSetPath,
+                                       const shared_ptr<const XdmfArrayType> & type,
+                                       const std::vector<unsigned int> & start,
+                                       const std::vector<unsigned int> & stride,
+                                       const std::vector<unsigned int> & dimensions,
+                                       const std::vector<unsigned int> & dataspaceDimensions) :
+  XdmfHeavyDataController(hdf5FilePath,
+                          type,
+                          start,
+                          stride, 
+                          dimensions,
+                          dataspaceDimensions),
+  mDataSetPath(dataSetPath),
+  mDataSetPrefix(""),
+  mDataSetId(-1)
+{
+  unsigned int i = 0;
+  for (; i < mDataSetPath.size(); ++i) {
+    if (mDataSetPath[(mDataSetPath.size() - 1) - i] != '0' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '1' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '2' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '3' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '4' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '5' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '6' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '7' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '8' &&
+        mDataSetPath[(mDataSetPath.size() - 1) - i] != '9') {
+      break;
+    }
+  }
+  unsigned int endOfPrefix = (mDataSetPath.size()) - i;
+  mDataSetPrefix = mDataSetPath.substr(0, endOfPrefix);
+  if (mDataSetPrefix.compare(mDataSetPath) != 0) {
+    mDataSetId = atoi(mDataSetPath.substr(endOfPrefix).c_str());
+  }
+}
+
+XdmfHDF5Controller::XdmfHDF5Controller(const XdmfHDF5Controller& refController):
+  XdmfHeavyDataController(refController),
+  mDataSetPath(refController.getDataSetPath()),
+  mDataSetPrefix(refController.mDataSetPrefix),
+  mDataSetId(refController.mDataSetId)
+{
+}
+
+XdmfHDF5Controller::~XdmfHDF5Controller()
+{
+}
+
+void
+XdmfHDF5Controller::closeFiles()
+{
+  for (std::map<std::string, hid_t>::iterator closeIter = mOpenFiles.begin();
+       closeIter != mOpenFiles.end();
+       ++closeIter) {
+    H5Fclose(closeIter->second);
+  }
+  mOpenFiles.clear();
+  mOpenFileUsage.clear();
+}
+
+std::string
+XdmfHDF5Controller::getDataSetPath() const
+{
+  return mDataSetPath;
+}
+
+const std::string
+XdmfHDF5Controller::getDataSetPrefix() const
+{
+  return mDataSetPrefix;
+}
+
+int
+XdmfHDF5Controller::getDataSetId() const
+{
+  return mDataSetId;
+}
+
+std::string
+XdmfHDF5Controller::getDescriptor() const
+{
+  return ":" + mDataSetPath;
+}
+
+std::string
+XdmfHDF5Controller::getName() const
+{
+  return "HDF";
+}
+
+unsigned int
+XdmfHDF5Controller::getMaxOpenedFiles()
+{
+  return XdmfHDF5Controller::mMaxOpenedFiles;
+}
+
+void 
+XdmfHDF5Controller::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties["Format"] = this->getName();
+}
+
+void
+XdmfHDF5Controller::read(XdmfArray * const array)
+{
+  this->read(array, H5P_DEFAULT);
+}
+
+void
+XdmfHDF5Controller::read(XdmfArray * const array, const int fapl)
+{
+  herr_t status;
+  hid_t hdf5Handle;
+  if (XdmfHDF5Controller::mMaxOpenedFiles == 0) {
+    hdf5Handle = H5Fopen(mFilePath.c_str(), H5F_ACC_RDONLY, fapl);
+  }
+  else {
+    std::map<std::string, hid_t>::iterator checkOpen = mOpenFiles.find(mFilePath);
+    if (checkOpen == mOpenFiles.end()) {
+      // If the number of open files would become larger than allowed
+      if (mOpenFiles.size() + 1 > mMaxOpenedFiles) {
+        // Close least used one
+        std::map<std::string, unsigned int>::iterator walker = mOpenFileUsage.begin();
+        std::string oldestFile = walker->first;
+        while (walker != mOpenFileUsage.end()) {
+          // We want the file with the fewest accesses
+          // If two are tied, we use the older one
+          if (mOpenFileUsage[oldestFile] > walker->second) {
+            oldestFile = walker->first;
+          }
+          ++walker;
+        }
+        status = H5Fclose(mOpenFiles[oldestFile]);
+        mOpenFiles.erase(oldestFile);
+        mOpenFileUsage.erase(oldestFile);
+      }
+      hdf5Handle = H5Fopen(mFilePath.c_str(), H5F_ACC_RDONLY, fapl);
+      mOpenFiles[mFilePath] = hdf5Handle;
+      mOpenFileUsage[mFilePath] = 1;
+    }
+    else {
+      hdf5Handle = checkOpen->second;
+      mOpenFileUsage[mFilePath]++;
+    }
+  }
+
+  const hid_t dataset = H5Dopen(hdf5Handle, mDataSetPath.c_str(), H5P_DEFAULT);
+  const hid_t dataspace = H5Dget_space(dataset);
+
+  const unsigned int dataspaceDims = H5Sget_simple_extent_ndims(dataspace);
+  const std::vector<hsize_t> count(mDimensions.begin(), mDimensions.end());
+
+  if(dataspaceDims != mDimensions.size()) {
+    // special case where the number of dimensions of the hdf5 dataset
+    // does not equal the number of dimensions in the light data
+    // description - in this case we cannot properly take a hyperslab
+    // selection, so we assume we are reading the entire dataset and
+    // check whether that is ok to do
+    const int numberValuesHDF5 = H5Sget_select_npoints(dataspace);
+    const int numberValuesXdmf = 
+      std::accumulate(mDimensions.begin(),
+                      mDimensions.end(),
+                      1,
+                      std::multiplies<unsigned int>());
+    if(numberValuesHDF5 != numberValuesXdmf) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Number of dimensions in light data description in "
+                         "Xdmf does not match number of dimensions in hdf5 "
+                         "file.");
+    }
+  }
+  else {
+    const std::vector<hsize_t> start(mStart.begin(), mStart.end());
+    const std::vector<hsize_t> stride(mStride.begin(), mStride.end());
+
+    status = H5Sselect_hyperslab(dataspace,
+                                 H5S_SELECT_SET,
+                                 &start[0],
+                                 &stride[0],
+                                 &count[0],
+                                 NULL);
+  }
+
+  const hssize_t numVals = H5Sget_select_npoints(dataspace);
+  hid_t memspace = H5Screate_simple(mDimensions.size(),
+                                    &count[0],
+                                    NULL);
+
+  /* status = H5Sselect_hyperslab(memspace,
+     H5S_SELECT_SET,
+     &memStart[0],
+     &memStride[0],
+     &memCount[0],
+     NULL);*/
+
+  hid_t datatype = H5T_NO_CLASS;
+  bool closeDatatype = false;
+  if(mType == XdmfArrayType::Int8()) {
+    datatype = H5T_NATIVE_CHAR;
+  }
+  else if(mType == XdmfArrayType::Int16()) {
+    datatype = H5T_NATIVE_SHORT;
+  }
+  else if(mType == XdmfArrayType::Int32()) {
+    datatype = H5T_NATIVE_INT;
+  }
+  else if(mType == XdmfArrayType::Int64()) {
+    datatype = H5T_NATIVE_LONG;
+  }
+  else if(mType == XdmfArrayType::Float32()) {
+    datatype = H5T_NATIVE_FLOAT;
+  }
+  else if(mType == XdmfArrayType::Float64()) {
+    datatype = H5T_NATIVE_DOUBLE;
+  }
+  else if(mType == XdmfArrayType::UInt8()) {
+    datatype = H5T_NATIVE_UCHAR;
+  }
+  else if(mType == XdmfArrayType::UInt16()) {
+    datatype = H5T_NATIVE_USHORT;
+  }
+  else if(mType == XdmfArrayType::UInt32()) {
+    datatype = H5T_NATIVE_UINT;
+  }
+  else if(mType == XdmfArrayType::String()) {
+    datatype = H5Tcopy(H5T_C_S1);
+    H5Tset_size(datatype, H5T_VARIABLE);
+    closeDatatype = true;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Unknown XdmfArrayType encountered in hdf5 "
+                       "controller.");
+  }
+
+  array->initialize(mType, mDimensions);
+
+  if(numVals != array->getSize()) {
+    std::stringstream errOut;
+    errOut << "Number of values in hdf5 dataset (" << numVals;
+    errOut << ")\ndoes not match allocated size in XdmfArray (" << array->getSize() << ").";
+    XdmfError::message(XdmfError::FATAL,
+                       errOut.str());
+  }
+  if(closeDatatype) {
+    char ** data = new char*[numVals];
+    status = H5Dread(dataset,
+                     datatype,
+                     memspace,
+                     dataspace,
+                     H5P_DEFAULT,
+                     data);
+    for(hssize_t i=0; i<numVals; ++i) {
+      array->insert<std::string>(i, data[i]);
+    }
+    status = H5Dvlen_reclaim(datatype,
+                             dataspace,
+                             H5P_DEFAULT,
+                             data);
+    delete [] data;
+  }
+  else {
+    status = H5Dread(dataset,
+                     datatype,
+                     memspace,
+                     dataspace,
+                     H5P_DEFAULT,
+                     array->getValuesInternal());
+  }
+
+  status = H5Sclose(dataspace);
+  status = H5Sclose(memspace);
+  status = H5Dclose(dataset);
+  if(closeDatatype) {
+    status = H5Tclose(datatype);
+  }
+  if (XdmfHDF5Controller::mMaxOpenedFiles == 0) {
+    status = H5Fclose(hdf5Handle);
+  }
+}
+
+void
+XdmfHDF5Controller::setMaxOpenedFiles(unsigned int newMax)
+{
+  XdmfHDF5Controller::mMaxOpenedFiles = newMax;
+}
+
+// C Wrappers
+
+XDMFHDF5CONTROLLER * XdmfHDF5ControllerNew(char * hdf5FilePath,
+                                           char * dataSetPath,
+                                           int type,
+                                           unsigned int * start,
+                                           unsigned int * stride,
+                                           unsigned int * dimensions,
+                                           unsigned int * dataspaceDimensions,
+                                           unsigned int numDims,
+                                           int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfHDF5Controller> generatedController = XdmfHDF5Controller::New(std::string(hdf5FilePath), std::string(dataSetPath), buildType, startVector, strideVector, dimVector, dataspaceVector);
+    return (XDMFHDF5CONTROLLER *)((void *)(new XdmfHDF5Controller(*generatedController.get())));
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfHDF5Controller> generatedController = XdmfHDF5Controller::New(std::string(hdf5FilePath), std::string(dataSetPath), buildType, startVector, strideVector, dimVector, dataspaceVector);
+    return (XDMFHDF5CONTROLLER *)((void *)(new XdmfHDF5Controller(*generatedController.get())));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+char * XdmfHDF5ControllerGetDataSetPath(XDMFHDF5CONTROLLER * controller)
+{
+  char * returnPointer = strdup(((XdmfHDF5Controller *)(controller))->getDataSetPath().c_str());
+  return returnPointer;
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_HEAVYCONTROLLER_C_CHILD_WRAPPER(XdmfHDF5Controller, XDMFHDF5CONTROLLER)
diff --git a/core/XdmfHDF5Controller.hpp b/core/XdmfHDF5Controller.hpp
new file mode 100644
index 0000000..c5c15d0
--- /dev/null
+++ b/core/XdmfHDF5Controller.hpp
@@ -0,0 +1,270 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5Controller.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFHDF5CONTROLLER_HPP_
+#define XDMFHDF5CONTROLLER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataController.hpp"
+
+// So that hdf5 does not need to be included in the header files
+// It would add a dependancy to programs that use Xdmf
+#ifndef _H5Ipublic_H
+  #ifndef XDMF_HID_T
+  #define XDMF_HID_T
+    typedef int hid_t;
+  #endif
+#endif
+
+#ifdef __cplusplus
+
+#include <map>
+
+/**
+ * @brief Couples an XdmfArray with HDF5 data stored on disk.
+ *
+ * Serves as an interface between data stored in XdmfArrays and data
+ * stored in hdf5 files on disk. When an Xdmf file is read from or
+ * written to disk an XdmfHDF5Controller is attached to
+ * XdmfArrays. This allows data to be released from memory but still
+ * be accessible or have its location written to light data.
+ */
+class XDMFCORE_EXPORT XdmfHDF5Controller : public XdmfHeavyDataController {
+
+public:
+
+  friend class XdmfHDF5Writer;
+
+  virtual ~XdmfHDF5Controller();
+
+  /**
+   * Create a new controller for an hdf5 data set on disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param hdf5FilePath the location of the hdf5 file the data set resides in.
+   * @param dataSetPath the location of the dataset within the hdf5 file.
+   * @param type the data type of the dataset to read.
+   * @param start the offset of the starting element in each dimension in
+   * the hdf5 data set.
+   * @param stride the number of elements to move in each dimension from the
+   * hdf5 data set.
+   * @param dimensions the number of elements to select in each
+   * dimension from the hdf5 data set. (size in each dimension)
+   * @param dataspaceDimensions the number of elements in the entire
+   * hdf5 data set (may be larger than dimensions if using
+   * hyperslabs).
+   *
+   * @return    New HDF5 Controller.
+   */
+  static shared_ptr<XdmfHDF5Controller>
+  New(const std::string & hdf5FilePath,
+      const std::string & dataSetPath,
+      const shared_ptr<const XdmfArrayType> & type,
+      const std::vector<unsigned int> & start,
+      const std::vector<unsigned int> & stride,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaceDimensions);
+
+  /**
+   * Closes the files currently open for reading.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#closeFiles
+   * @until //#closeFiles
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//closeFiles
+   * @until #//closeFiles
+   */
+  static void closeFiles();
+
+  /**
+   * Get the path of the data set within the heavy data file owned by
+   * this controller.
+   * For "/home/output.h5:/foo/data" this is "/foo/data"
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDataSetPath
+   * @until //#getDataSetPath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDataSetPath
+   * @until #//getDataSetPath
+   *
+   * @return    A std::string containing the path of the data set.
+   */
+  std::string getDataSetPath() const;
+
+  virtual std::string getDescriptor() const;
+
+  virtual std::string getName() const;
+
+  /**
+   * Gets the maximum number of hdf5 files that are allowed to be open at once.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#getMaxOpenedFiles
+   * @until //#getMaxOpenedFiles
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//getMaxOpenedFiles
+   * @until #//getMaxOpenedFiles
+   *
+   * @return    The maximum number of hdf5 files
+   */
+  static unsigned int getMaxOpenedFiles();
+
+  virtual void 
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+  virtual void read(XdmfArray * const array);
+
+  /**
+   * Sets the maximum number of hdf5 files that are allowed to be open at once.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#setMaxOpenedFiles
+   * @until //#setMaxOpenedFiles
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//setMaxOpenedFiles
+   * @until #//setMaxOpenedFiles
+   *
+   * @param     newMax  The new maximum amount of files to be open
+   */
+  static void setMaxOpenedFiles(unsigned int newMax);
+
+  XdmfHDF5Controller(const XdmfHDF5Controller &);
+
+protected:
+
+  XdmfHDF5Controller(const std::string & hdf5FilePath,
+                     const std::string & dataSetPath,
+                     const shared_ptr<const XdmfArrayType> & type,
+                     const std::vector<unsigned int> & start,
+                     const std::vector<unsigned int> & stride,
+                     const std::vector<unsigned int> & dimensions,
+                     const std::vector<unsigned int> & dataspaceDimensions);
+
+  const std::string getDataSetPrefix() const;
+  int getDataSetId() const;
+
+  void read(XdmfArray * const array, const int fapl);
+
+private:
+
+  void operator=(const XdmfHDF5Controller &);  // Not implemented.
+
+  const std::string mDataSetPath;
+
+  std::string mDataSetPrefix;
+  int mDataSetId;
+
+  static std::map<std::string, unsigned int> mOpenFileUsage;
+  // When set to 0 there will be no files that stay open after a read
+  static unsigned int mMaxOpenedFiles;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XDMFHDF5CONTROLLER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHDF5CONTROLLER XDMFHDF5CONTROLLER;
+
+XDMFCORE_EXPORT XDMFHDF5CONTROLLER * XdmfHDF5ControllerNew(char * hdf5FilePath,
+                                                           char * dataSetPath,
+                                                           int type,
+                                                           unsigned int * start,
+                                                           unsigned int * stride,
+                                                           unsigned int * dimensions,
+                                                           unsigned int * dataspaceDimensions,
+                                                           unsigned int numDims,
+                                                           int * status);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMFCORE_EXPORT char * XdmfHDF5ControllerGetDataSetPath(XDMFHDF5CONTROLLER * controller);
+
+XDMF_HEAVYCONTROLLER_C_CHILD_DECLARE(XdmfHDF5Controller, XDMFHDF5CONTROLLER, XDMFCORE)
+
+#define XDMF_HDF5CONTROLLER_C_CHILD_DECLARE(ClassName, CClassName, Level)              \
+                                                                                       \
+Level##_EXPORT char * ClassName##GetDataSetPath( CClassName * controller);
+
+#define XDMF_HDF5CONTROLLER_C_CHILD_WRAPPER(ClassName, CClassName)                     \
+                                                                                       \
+char * ClassName##GetDataSetPath( CClassName * controller)                             \
+{                                                                                      \
+  return XdmfHDF5ControllerGetDataSetPath((XDMFHDF5CONTROLLER *)((void *)controller)); \
+} 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHDF5CONTROLLER_HPP_ */
diff --git a/core/XdmfHDF5Writer.cpp b/core/XdmfHDF5Writer.cpp
new file mode 100644
index 0000000..4f05cd3
--- /dev/null
+++ b/core/XdmfHDF5Writer.cpp
@@ -0,0 +1,1701 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5Writer.cpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <H5public.h>
+#include <hdf5.h>
+#include <sstream>
+#include <cstdio>
+#include <cmath>
+#include <set>
+#include <list>
+#include <string.h>
+#include "XdmfItem.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfSystemUtils.hpp"
+
+namespace {
+
+  const static unsigned int DEFAULT_CHUNK_SIZE = 1000;
+
+}
+
+XdmfHDF5Writer::XdmfHDF5WriterImpl::XdmfHDF5WriterImpl():
+  mHDF5Handle(-1),
+  mFapl(H5P_DEFAULT),
+  mChunkSize(DEFAULT_CHUNK_SIZE),
+  mOpenFile(""),
+  mDepth(0)
+{
+};
+
+XdmfHDF5Writer::XdmfHDF5WriterImpl::~XdmfHDF5WriterImpl()
+{
+  closeFile();
+};
+
+void
+XdmfHDF5Writer::XdmfHDF5WriterImpl::closeFile()
+{
+  if(mHDF5Handle >= 0) {
+    H5Fclose(mHDF5Handle);
+    mHDF5Handle = -1;
+  }
+  mOpenFile = "";
+};
+
+int
+XdmfHDF5Writer::XdmfHDF5WriterImpl::openFile(const std::string & filePath,
+                                             const int mDataSetId)
+{
+  if(mHDF5Handle >= 0) {
+    // Perhaps we should throw a warning.
+    closeFile();
+  }
+  // Save old error handler and turn off error handling for now
+  H5E_auto_t old_func;
+  void * old_client_data;
+  H5Eget_auto(0, &old_func, &old_client_data);
+  H5Eset_auto2(0, NULL, NULL);
+
+  int toReturn = 0;
+
+  mOpenFile.assign(filePath);
+
+  if(H5Fis_hdf5(filePath.c_str()) > 0) {
+    mHDF5Handle = H5Fopen(filePath.c_str(),
+                          H5F_ACC_RDWR,
+                          mFapl);
+    if(mDataSetId == 0) {
+      hsize_t numObjects;
+      /*herr_t status = */H5Gget_num_objs(mHDF5Handle,
+                                          &numObjects);
+      toReturn = numObjects;
+    }
+    else {
+      toReturn = mDataSetId;
+    }
+  }
+  else {
+    mHDF5Handle = H5Fcreate(filePath.c_str(),
+                            H5F_ACC_TRUNC,
+                            H5P_DEFAULT,
+                            mFapl);
+  }
+
+  // Restore previous error handler
+  H5Eset_auto2(0, old_func, old_client_data);
+
+  return toReturn;
+}
+
+shared_ptr<XdmfHDF5Writer>
+XdmfHDF5Writer::New(const std::string & filePath,
+                    const bool clobberFile)
+{
+  if(clobberFile) {
+    std::remove(filePath.c_str());
+  }
+  shared_ptr<XdmfHDF5Writer> p(new XdmfHDF5Writer(filePath));
+  return p;
+}
+
+XdmfHDF5Writer::XdmfHDF5Writer(const std::string & filePath) :
+  XdmfHeavyDataWriter(filePath, 1, 800),
+  mImpl(new XdmfHDF5WriterImpl()),
+  mUseDeflate(false),
+  mDeflateFactor(0)
+{
+}
+
+XdmfHDF5Writer::XdmfHDF5Writer(const XdmfHDF5Writer & writerRef) :
+  XdmfHeavyDataWriter(writerRef.getFilePath(), 1, 800),
+  mImpl(new XdmfHDF5WriterImpl()),
+  mUseDeflate(false),
+  mDeflateFactor(0)
+{
+}
+
+XdmfHDF5Writer::~XdmfHDF5Writer()
+{
+  delete mImpl;
+}
+
+void
+XdmfHDF5Writer::controllerSplitting(XdmfArray & array,
+                                    int & controllerIndexOffset,
+                                    shared_ptr<XdmfHeavyDataController> heavyDataController,
+                                    const std::string & checkFileName,
+                                    const std::string & checkFileExt,
+                                    const std::string & dataSetPath,
+                                    int dataSetId,
+                                    const std::vector<unsigned int> & dimensions,
+                                    const std::vector<unsigned int> & dataspaceDimensions,
+                                    const std::vector<unsigned int> & start,
+                                    const std::vector<unsigned int> & stride,
+                                    std::list<std::string> & filesWritten,
+                                    std::list<std::string> & datasetsWritten,
+                                    std::list<int> & datasetIdsWritten,
+                                    std::list<void *> & arraysWritten,
+                                    std::list<std::vector<unsigned int> > & startsWritten,
+                                    std::list<std::vector<unsigned int> > & stridesWritten,
+                                    std::list<std::vector<unsigned int> > & dimensionsWritten,
+                                    std::list<std::vector<unsigned int> > & dataSizesWritten,
+                                    std::list<unsigned int> & arrayOffsetsWritten)
+{
+  // This is the file splitting algorithm
+  if (getFileSizeLimit() > 0) {
+    // Only if the file limit is positive, disabled if 0 or negative
+    unsigned int previousDataSize = 0;
+
+    std::vector<unsigned int> previousDimensions;
+    std::vector<unsigned int> previousDataSizes;
+    unsigned int amountAlreadyWritten = 0;
+    // Even though theoretically this could be an infinite loop
+    // if all possible files with the specified name are produced
+    // the chances of that happening are small.
+    // It can handle up to 65535 different files.
+    // This value may vary depending on the compiler and platform.
+    // The variable UINT_MAX holds the value in question.
+    // If all files are take up it will loop until a file opens up
+    // since adding past the max causes overflow.
+
+    unsigned int containedInController = 1;
+    for (unsigned int j = 0; j < dataspaceDimensions.size(); ++j) {
+      containedInController *= dataspaceDimensions[j];
+    }
+    int hyperslabSize = 0;
+    while (amountAlreadyWritten < containedInController) {
+
+      std::vector<unsigned int> partialStarts;
+      std::vector<unsigned int> partialStrides;
+      std::vector<unsigned int> partialDimensions;
+      std::vector<unsigned int> partialDataSizes;
+
+      std::stringstream testFile;
+      if (getFileIndex() == 0) {
+      // If sequentially named files need to be created or referenced
+        testFile << checkFileName << "." << checkFileExt;
+      }
+      else {
+        testFile << checkFileName << getFileIndex() << "." << checkFileExt;
+      }
+      FILE *checkFile = NULL;
+      unsigned int fileSize = 0;
+      // If the file doesn't exist the size is 0 because there's no data
+      // Get the file stream
+      checkFile = fopen(testFile.str().c_str(), "a");
+      if (checkFile != NULL) {
+        // Set the file pointer to end of file
+        fseek(checkFile, 0, SEEK_END);
+        // Get the file size, in bytes
+        fileSize = ftell(checkFile);
+
+        // If overwrite subtract previous data size.
+        if (mMode == Overwrite || mMode == Hyperslab) {
+          // Find previous data size
+          std::stringstream currentDataSetPath;
+          currentDataSetPath << dataSetPath;
+          if (dataSetId >= 0)
+          {
+            currentDataSetPath << dataSetId;
+          }
+          int checkfilesize = getDataSetSize(testFile.str(), currentDataSetPath.str());
+          if (checkfilesize < 0) {
+            checkfilesize = 0;
+          }
+          unsigned int checksize = (unsigned int)checkfilesize;
+          if (mMode == Overwrite) {
+            if (checksize > fileSize) {
+              fileSize = 0;
+            }
+            else {
+              fileSize = fileSize - checksize;
+              // Remove previous set's size, since it's overwritten
+            }
+            if (fileSize == 0) {
+              fileSize += getFileOverhead();
+            }
+          }
+          else if (mMode == Hyperslab) {
+            hyperslabSize = checksize;
+          }
+        }
+        if (fileSize == 0) {
+          fileSize += getFileOverhead();
+        }
+        fclose(checkFile);
+      }
+      else if (previousDataSize == 0) {
+        fileSize += getFileOverhead();
+      }
+      if (fileSize > (unsigned int)getFileSizeLimit()*(1024*1024)) {
+        fileSize = (unsigned int)getFileSizeLimit()*(1024*1024);
+      }
+      //Start of splitting section
+
+      // If needed split the written array
+      // into smaller arrays based on dimension blocks
+      // Working with strings has a more
+      // resource intensive version of this algorithm
+      // Size needed is equal to the dataspaceDimensions if in hyperslab mode
+      // otherwise is equal to the size of the written array
+      unsigned int remainingSize = 0;
+      unsigned int dataItemSize = 1;
+      if (array.getArrayType() == XdmfArrayType::String()) {
+        unsigned int remainingValues = 0;
+        unsigned int sizeArrayIndex = 0;
+        if (mMode == Hyperslab) {
+          remainingValues += 1;
+          sizeArrayIndex += 1;
+          for (unsigned int j = 0; j < dataspaceDimensions[j]; ++j) {
+            remainingValues *= dataspaceDimensions[j];
+            sizeArrayIndex *= dimensions[j];
+          }
+        }
+        else {
+          remainingValues += array.getSize();
+          sizeArrayIndex = amountAlreadyWritten;
+        }
+        remainingValues -= amountAlreadyWritten;
+        // Reduce by number of values already written
+        if (remainingValues == 0) {
+          // End if no remaining values
+          break;
+        }
+        // If remaining size is less than available space, just write all of what's left
+        // Calculate remaining size
+        for (unsigned int j = sizeArrayIndex; j < array.getSize(); ++j) {
+          remainingSize +=
+            (unsigned int)((double)(array.getValue<std::string>(j).size()) *
+                           8.0 * mCompressionRatio);
+        }
+        if (mMode == Hyperslab) {
+          // Size is estimated based on averages
+          remainingSize = (remainingSize /
+                           (array.getSize() - sizeArrayIndex)) *
+                           remainingValues;
+        }
+      }
+      else {
+        unsigned int remainingValues = 0;
+        if (mMode == Hyperslab) {
+          remainingValues += 1;
+          for (unsigned int j = 0; j < dataspaceDimensions.size(); ++j) {
+            remainingValues *= dataspaceDimensions[j];
+          }
+        }
+        else {
+          remainingValues += 1;
+          for (unsigned int j = 0; j < dimensions.size(); ++j) {
+            remainingValues *= dimensions[j];
+          }
+        }
+        if ((int)remainingValues - (int) amountAlreadyWritten < 0) {
+          remainingValues = 0;
+        }
+        else {
+          remainingValues -= amountAlreadyWritten;
+        }
+        // Reduce by number of values already written
+        if (remainingValues == 0) {//end if no remaining values
+          break;
+        }
+        dataItemSize =
+          (unsigned int)((double) (array.getArrayType()->getElementSize()) *
+                         mCompressionRatio);
+        // If remaining size is less than available space, just write all of what's left
+        remainingSize = remainingValues * dataItemSize;
+      }
+      if (remainingSize + previousDataSize + fileSize - (hyperslabSize * dataItemSize)
+          <= (unsigned int)getFileSizeLimit()*(1024*1024)) {
+        // If the array hasn't been split
+        if (amountAlreadyWritten == 0) {
+          // Just pass all data to the partial vectors
+          for (unsigned int j = 0; j < dimensions.size(); ++j) {
+            // Done using a loop so that data is copied, not referenced
+            partialStarts.push_back(start[j]);
+            partialStrides.push_back(stride[j]);
+            partialDimensions.push_back(dimensions[j]);
+            partialDataSizes.push_back(dataspaceDimensions[j]);
+          }
+        }
+        else {
+          // If the array has been split
+          int dimensionIndex = previousDimensions.size() - 1;
+          // Loop previous dimensions in
+          int j = 0;
+          for (j = 0; j < dimensionIndex; ++j) {
+            partialStarts.push_back(start[j]);
+            partialStrides.push_back(stride[j]);
+            partialDimensions.push_back(dimensions[j]);
+            partialDataSizes.push_back(dataspaceDimensions[j]);
+          }
+          if (mMode == Hyperslab) {
+            int newStart = (start[j] +
+                            stride[j] * previousDimensions[j])
+                           - previousDataSizes[j];
+            while (newStart < 0) {
+              newStart += stride[j];
+            }
+            partialStarts.push_back(newStart);
+            // Stride should not change in this algorithm
+            partialStrides.push_back(stride[j]);
+            // Total up number of blocks for
+            // the higher dimesions and subtract the amount already written
+            unsigned int dimensiontotal = dimensions[j];
+            unsigned int dataspacetotal = dataspaceDimensions[j];
+            for (unsigned int k = j + 1; k < dimensions.size(); ++k) {
+              dimensiontotal *= dimensions[k];
+              dataspacetotal *= dataspaceDimensions[k];
+            }
+            if (previousDimensions.size() > 0) {
+              partialDimensions.push_back(dimensiontotal-previousDimensions[j]);
+            }
+            else {
+              partialDimensions.push_back(dimensiontotal);
+            }
+            if (previousDataSizes.size() > 0) {
+              partialDataSizes.push_back(dataspacetotal-previousDataSizes[j]);
+            }
+            else {
+              partialDataSizes.push_back(dataspacetotal);
+            }
+          }
+          else {
+            // Start and stride are not used outside of hyperslab
+            partialStarts.push_back(start[j]);
+            partialStrides.push_back(stride[j]);
+            // Total up number of blocks for
+            // the higher dimesions and subtract the amount already written
+            // since it isn't hyperslab dimensions
+            // and dataspacedimensions should be the same
+            unsigned int dimensiontotal = dimensions[j];
+            for (unsigned int k = j + 1; k < dimensions.size(); ++k) {
+              dimensiontotal *= dimensions[k];
+            }
+            if (previousDimensions.size() > 0) {
+              partialDimensions.push_back(dimensiontotal-previousDimensions[j]);
+            }
+            else {
+              partialDimensions.push_back(dimensiontotal);
+            }
+            if (previousDataSizes.size() > 0) {
+              partialDataSizes.push_back(dimensiontotal-previousDataSizes[j]);
+            }
+            else {
+              partialDataSizes.push_back(dimensiontotal);
+            }
+          }
+        }
+      }
+      else {
+        // Otherwise, take remaining size
+        // and start removing dimensions until the dimension block is less
+        // then take a fraction of the dimension
+        // Calculate the number of values of the data type you're using will fit
+        unsigned int usableSpace = (getFileSizeLimit()*(1024*1024) -
+                                    (fileSize + previousDataSize)) / dataItemSize;
+        if ((unsigned int)getFileSizeLimit()*(1024*1024) < previousDataSize + fileSize) {
+          usableSpace = 0;
+        }
+        usableSpace += hyperslabSize;
+        // If the array hasn't been split
+        if (amountAlreadyWritten == 0) {
+          // See if it will fit in the next file
+          // If it will just go to the next file
+          // Otherwise split it.
+          if (remainingSize + getFileOverhead() >
+              (unsigned int)getFileSizeLimit()*(1024*1024)
+              && usableSpace > 0) {
+            if (getAllowSetSplitting()) {
+              // Figure out the size of the largest block that will fit.
+              unsigned int blockSizeSubtotal = 1;
+              unsigned int dimensionIndex = 0;
+              if (array.getArrayType() == XdmfArrayType::String()) {
+                unsigned int dimensionSizeTotal = 1;
+                unsigned int previousBlockSize = 0;
+                // Find the dimension that was split
+                while (dimensionIndex < dataspaceDimensions.size()
+                       && blockSizeSubtotal <= usableSpace) {
+                  // This is totally different for strings
+                  dimensionSizeTotal *= dimensions[dimensionIndex];
+                  previousBlockSize = blockSizeSubtotal;
+                  blockSizeSubtotal = 0;
+                  for (unsigned int k = 0; k < dimensionSizeTotal; ++k) {
+                    if (amountAlreadyWritten + k > array.getSize()) {
+                      XdmfError::message(XdmfError::FATAL,
+                                         "Error: Invalid Dimension in HDF5 Write.\n");
+                    }
+                    blockSizeSubtotal +=
+                      array.getValue<std::string>(amountAlreadyWritten + k).size();
+                  }
+                  dimensionIndex++;
+                }
+                // It should end on the "blockSizeSubtotal <= usableSpace" statement
+                // the other half is for backup
+                // move back one dimension so we're working
+                // on the dimension that was split, not the one after it
+                dimensionIndex--;
+                blockSizeSubtotal = previousBlockSize;
+              }
+              else {
+                // Find the dimension that was split
+                while (dimensionIndex < dataspaceDimensions.size()
+                       && blockSizeSubtotal <= usableSpace) {
+                  blockSizeSubtotal *= dataspaceDimensions[dimensionIndex];
+                  dimensionIndex++;
+                }
+                // It should end on the "blockSizeSubtotal <= arrayStartIndex" statement
+                // the other half is for backup
+                // Move back one dimension so we're working on the dimension that was split
+                // not the one after it
+                dimensionIndex--;
+                blockSizeSubtotal /= dataspaceDimensions[dimensionIndex];
+              }
+              // Determine how many of those blocks will fit
+              unsigned int numBlocks = usableSpace / blockSizeSubtotal;
+              // This should be less than the current value for the dimension
+              // Add dimensions as required.
+              unsigned int j = 0;
+              for (j = 0; j < dimensionIndex; ++j) {
+                partialStarts.push_back(start[j]);
+                partialStrides.push_back(stride[j]);
+                partialDimensions.push_back(dimensions[j]);
+                partialDataSizes.push_back(dataspaceDimensions[j]);
+              }
+              if (start[j] > numBlocks) {
+                partialStarts.push_back(numBlocks-1);
+              }
+              else {
+                partialStarts.push_back(start[j]);
+              }
+              partialStrides.push_back(stride[j]);
+              partialDataSizes.push_back(numBlocks);
+              if (dimensions[j] == dataspaceDimensions[j]) {
+                // This is for non-hyperslab and specific cases of hyperslab
+                partialDimensions.push_back(numBlocks);
+              }
+              else {
+                // For hyperslab in general
+                // Determine how many values from the array will fit
+                // into the blocks being used with the dimensions specified
+                unsigned int displacement = numBlocks / stride[j];
+                if (((int)displacement * (int)stride[j])
+                      + (start[j] % stride[j])
+                    < numBlocks) {
+                  displacement++;
+                }
+                displacement -= start[j]/stride[j];
+                if (start[j] > numBlocks) {
+                  displacement = 0;
+                }
+                if (dimensions[j] <= displacement) {
+                  // If there are less values than there are space for
+                  // just write all of them.
+                  partialDimensions.push_back(dimensions[j]);
+                }
+                else {
+                  // Otherwise write what space allows for
+                  partialDimensions.push_back(displacement);
+                }
+              }
+            }
+            else {
+              // Just pass all data to the partial vectors
+              for (unsigned int j = 0; j < dimensions.size(); ++j) {
+                // Done using a loop so that data is copied, not referenced
+                partialStarts.push_back(start[j]);
+                partialStrides.push_back(stride[j]);
+                partialDimensions.push_back(dimensions[j]);
+                partialDataSizes.push_back(dataspaceDimensions[j]);
+              }
+            }
+          }
+        }
+        else {
+          // If the array has been split
+          // This case should not come up often
+          // as it requires truly gigantic data sets
+          // See if the remaining data will fit in the next file
+          // If yes, skip to it
+          // If no, split
+          if (remainingSize + getFileOverhead() >
+              (unsigned int)getFileSizeLimit()*(1024*1024)
+              && usableSpace > 0) {
+            // Figure out the size of the largest block that will fit.
+            unsigned int blockSizeSubtotal = 1;
+            unsigned int dimensionIndex = 0;
+            if (array.getArrayType() == XdmfArrayType::String()) {
+              unsigned int dimensionSizeTotal = 1;
+              unsigned int previousBlockSize = 0;
+              // Find the dimension that was split
+              while (dimensionIndex < dataspaceDimensions.size()
+                     && blockSizeSubtotal <= usableSpace) {
+                // This is totally different for strings
+                dimensionSizeTotal *= dimensions[dimensionIndex];
+                previousBlockSize = blockSizeSubtotal;
+                blockSizeSubtotal = 0;
+                for (unsigned int k = 0; k < dimensionSizeTotal; ++k) {
+                  if (amountAlreadyWritten + k > array.getSize()) {
+                    XdmfError::message(XdmfError::FATAL,
+                                       "Error: Invalid Dimension in HDF5 Write.\n");
+                  }
+                  blockSizeSubtotal +=
+                    array.getValue<std::string>(amountAlreadyWritten + k).size();
+                }
+                dimensionIndex++;
+              }
+              // It should end on the "blockSizeSubtotal <= usableSpace" statement
+              // the other half is for backup
+              // move back one dimension so we're working
+              // on the dimension that was split, not the one after it
+              dimensionIndex--;
+              blockSizeSubtotal = previousBlockSize;
+            }
+            else {
+              // Find the dimension that was split
+              while (dimensionIndex < dataspaceDimensions.size()
+                     && blockSizeSubtotal <= usableSpace) {
+                blockSizeSubtotal *= dataspaceDimensions[dimensionIndex];
+                dimensionIndex++;
+              }
+              // It should end on the "blockSizeSubtotal <= arrayStartIndex" statement
+              // the other half is for backup
+              // Move back one dimension so we're working on the dimension that was split
+              // not the one after it
+              dimensionIndex--;
+              blockSizeSubtotal /= dataspaceDimensions[dimensionIndex];
+            }
+            unsigned int j = 0;
+            for (; j < dimensionIndex; ++j) {
+              partialStarts.push_back(start[j]);
+              partialStrides.push_back(stride[j]);
+              partialDimensions.push_back(dimensions[j]);
+              partialDataSizes.push_back(dataspaceDimensions[j]);
+            }
+            // Continue if the block is smaller than the available size
+            if (blockSizeSubtotal <=usableSpace) {
+             // Find number of blocks that will fit
+              // This should be less than the current value for the dimension
+              unsigned int numBlocks = usableSpace / blockSizeSubtotal;
+              // Add dimensions to the partial vectors
+              if (mMode == Hyperslab) {
+                int newStart = (start[j] +
+                                stride[j] * previousDimensions[j]) -
+                               previousDataSizes[j];
+                while (newStart < 0) {
+                  newStart += stride[j];
+                }
+                partialStarts.push_back(newStart);
+                // Stride should not change in this algorithm
+                partialStrides.push_back(stride[j]);
+                partialDataSizes.push_back(numBlocks);
+                // Determine how many values from the array will fit
+                // into the blocks being used
+                // with the dimensions specified
+                unsigned int displacement = (numBlocks - newStart)
+                                            / stride[j];
+                if (((int)displacement * (int)stride[j]) + (newStart % stride[j])
+                    < numBlocks) {
+                  displacement++;
+                }
+                displacement -= newStart/stride[j];
+                if (newStart > (int)numBlocks) {
+                  displacement = 0;
+                }
+                if ((dimensions[j] - previousDimensions[j]) <= displacement) {
+                  // If there are less values than there are space for
+                  // just write all of them.
+                  partialDimensions.push_back(dimensions[j] - previousDimensions[j]);
+                }
+                else {
+                  // Otherwise write what space allows for
+                  partialDimensions.push_back(displacement);
+                }
+              }
+              else {
+                // Start and stride are only specified in hyperslab
+                partialStarts.push_back(start[j]);
+                partialStrides.push_back(stride[j]);
+                partialDataSizes.push_back(numBlocks);
+                partialDimensions.push_back(numBlocks);
+              }
+              // Place dimensions into previous dimensions
+              // for later iterations
+            }
+            else {
+              // If this is larger than usable space, try the next file
+              // If moving to next file
+              // just do nothing and pass out of the if statement
+              // but also check if specified file size is too small
+              if ((unsigned int)getFileSizeLimit()*(1024*1024)
+                  < blockSizeSubtotal) {
+                // This shouldn't ever trigger,
+                // but it's good to cover ourselves
+                // Throw an error if the block size won't work
+                XdmfError::message(XdmfError::FATAL,
+                                   "Error: Dimension Block size"
+                                   " / Maximum File size mismatch.\n");
+              }
+            }
+          }
+        }
+        // Move to next file
+        setFileIndex(getFileIndex()+1);
+      }
+
+      if (partialDimensions.size() > 0) {
+        // Building the array to be written
+        int containedInDimensions = 1;
+        // Count moved
+        for (unsigned int j = 0 ; j < partialDimensions.size(); ++j) {
+          containedInDimensions *= partialDimensions[j];
+        }
+        // Starting index
+        int containedInPriorDimensions = controllerIndexOffset;
+        int startOffset = 1;
+        for (unsigned int j = 0; j < previousDimensions.size(); ++j) {
+          startOffset *= previousDimensions[j];
+        }
+        if (previousDimensions.size() == 0) {
+          startOffset = 0;
+        }
+        containedInPriorDimensions += startOffset;
+        int dimensionTotal = 1;
+        for (unsigned int j = 0; j < dimensions.size(); ++j) {
+          dimensionTotal *= dimensions[j];
+        }
+        if (containedInDimensions > 0) {
+          void * partialArray = NULL;
+          if (array.getArrayType() == XdmfArrayType::Int8()) {
+            partialArray =
+              &(((char *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::Int16()) {
+            partialArray =
+              &(((short *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::Int32()) {
+            partialArray =
+              &(((int *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::Int64()) {
+            partialArray =
+              &(((long *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::Float32()) {
+            partialArray =
+              &(((float *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::Float64()) {
+            partialArray =
+              &(((double *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::UInt8()) {
+            partialArray =
+              &(((unsigned char *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::UInt16()) {
+            partialArray =
+              &(((unsigned short *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::UInt32()) {
+            partialArray =
+              &(((unsigned int *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          else if (array.getArrayType() == XdmfArrayType::String()) {
+            partialArray =
+              &(((std::string *)array.getValuesInternal())[containedInPriorDimensions]);
+          }
+          arraysWritten.push_back(partialArray);
+          filesWritten.push_back(testFile.str());
+          datasetsWritten.push_back(dataSetPath);
+          datasetIdsWritten.push_back(dataSetId);
+          startsWritten.push_back(partialStarts);
+          stridesWritten.push_back(partialStrides);
+          dimensionsWritten.push_back(partialDimensions);
+          dataSizesWritten.push_back(partialDataSizes);
+          arrayOffsetsWritten.push_back(containedInPriorDimensions);
+        }
+        if (mMode == Hyperslab) {
+          containedInPriorDimensions -= controllerIndexOffset;
+        }
+        if (containedInDimensions + containedInPriorDimensions == dimensionTotal) {
+          controllerIndexOffset += dimensionTotal;
+        }
+        // For hyperslab the space is controlled by the dataspace dimensions
+        // So use that since the dimensions should be equal
+        // to the dataspace dimensions in all other variations
+        // Total up written data space
+        unsigned int writtenDataSpace = 1;
+        for (unsigned int j = 0; j < partialDataSizes.size(); ++j) {
+          writtenDataSpace *= partialDataSizes[j];
+        }
+        amountAlreadyWritten += writtenDataSpace;
+        // Generate previous dimensions
+        if (previousDataSizes.size() == 0) {
+          previousDataSizes = partialDataSizes;
+          previousDimensions = partialDimensions;
+        }
+        else {
+          // Determine if the sizes match
+          // If they do, add the top values together
+          // Otherwise, compress the higher dimensions and then add them
+          if (previousDimensions.size() == partialDimensions.size()) {
+            previousDimensions[previousDimensions.size()-1] +=
+              partialDimensions[previousDimensions.size()-1];
+          }
+          else if (previousDimensions.size() < partialDimensions.size()) {
+            unsigned int overflowDimensions = 1;
+            for (unsigned int j = previousDimensions.size() - 1;
+                 j < partialDimensions.size();
+                 ++j) {
+              overflowDimensions *= partialDimensions[j];
+            }
+            previousDimensions[previousDimensions.size()-1] += overflowDimensions;
+          }
+          else if (previousDimensions.size() > partialDimensions.size()) {
+            unsigned int overflowDimensions = 1;
+            for (unsigned int j = partialDimensions.size() - 1;
+                 j < previousDimensions.size();
+                 ++j) {
+              overflowDimensions *= previousDimensions[j];
+            }
+            previousDimensions.resize(partialDimensions.size());
+            previousDimensions[partialDimensions.size()-1] = overflowDimensions;
+            previousDimensions[previousDimensions.size()-1] +=
+              partialDimensions[previousDimensions.size()-1];
+          }
+          if (previousDataSizes.size() == partialDataSizes.size()) {
+            previousDataSizes[previousDataSizes.size()-1] +=
+              partialDataSizes[previousDataSizes.size()-1];
+          }
+          else if (previousDataSizes.size() < partialDataSizes.size()) {
+            unsigned int overflowDataSizes = 1;
+            for (unsigned int j = previousDataSizes.size() - 1;
+                 j < partialDataSizes.size();
+                 ++j) {
+              overflowDataSizes *= partialDataSizes[j];
+            }
+            previousDataSizes[previousDataSizes.size()-1] += overflowDataSizes;
+          }
+          else if (previousDataSizes.size() > partialDataSizes.size()) {
+            unsigned int overflowDataSizes = 1;
+            for (unsigned int j = partialDataSizes.size() - 1;
+                 j < previousDataSizes.size();
+                 ++j) {
+              overflowDataSizes *= previousDataSizes[j];
+            }
+            previousDataSizes.resize(partialDataSizes.size());
+            previousDataSizes[partialDataSizes.size()-1] = overflowDataSizes;
+            previousDataSizes[previousDataSizes.size()-1] +=
+              partialDataSizes[previousDataSizes.size()-1];
+          }
+        }
+      }
+      ++dataSetId;
+    }
+
+    if (mMode == Append) {
+      // If the written filename is different write add the previous controller
+      if (*(filesWritten.rbegin()) != heavyDataController->getFilePath()) {
+        // Should also be different from previous controller
+        if (filesWritten.size() > 1) {
+          if (*(filesWritten.rbegin()) != *((filesWritten.rbegin())++)) {
+            array.insert(heavyDataController);
+          }
+        }
+        else {
+          array.insert(heavyDataController);
+        }
+      }
+    }
+  }
+  else {
+    // Otherwise work with the full array
+    void * partialArray = NULL;
+    // Need to copy by duplicating the contents of the array
+    unsigned int j = controllerIndexOffset;
+    std::string writtenFileName = "";
+    if (mMode == Default) {
+      std::stringstream testFile;
+      if (getFileIndex() == 0) {
+        // If sequentially named files need to be created or referenced
+        testFile << checkFileName << "." << checkFileExt;
+      }
+      else {
+        testFile << checkFileName << getFileIndex() << "." << checkFileExt;
+      }
+      writtenFileName = testFile.str();
+    }
+    else {
+      writtenFileName = heavyDataController->getFilePath();
+    }
+
+    if (array.getArrayType() == XdmfArrayType::Int8()){
+      partialArray =
+        &(((char *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::Int16()){
+      partialArray =
+        &(((short *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::Int32()){
+      partialArray =
+        &(((int *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::Int64()){
+      partialArray =
+        &(((long *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::Float32()){
+      partialArray =
+        &(((float *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::Float64()){
+      partialArray =
+        &(((double *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::UInt8()){
+      partialArray =
+        &(((unsigned char *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::UInt16()){
+      partialArray =
+        &(((unsigned short *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::UInt32()) {
+      partialArray =
+        &(((unsigned int *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    else if (array.getArrayType() == XdmfArrayType::String()) {
+      partialArray =
+        &(((std::string *)array.getValuesInternal())[controllerIndexOffset]);
+    }
+    arrayOffsetsWritten.push_back(controllerIndexOffset);
+    // Set the offset to the point after the end of the current subset
+    controllerIndexOffset = j;
+
+    arraysWritten.push_back(partialArray);
+    filesWritten.push_back(writtenFileName);
+    datasetsWritten.push_back(dataSetPath);
+    datasetIdsWritten.push_back(dataSetId);
+    // Also need to push the starts and strides loaded from the HeavyDataController
+    startsWritten.push_back(start);
+    stridesWritten.push_back(stride);
+    dimensionsWritten.push_back(dimensions);
+    dataSizesWritten.push_back(dataspaceDimensions);
+  }
+}
+
+shared_ptr<XdmfHeavyDataController>
+XdmfHDF5Writer::createController(const std::string & hdf5FilePath,
+                                     const std::string & dataSetPath,
+                                     const shared_ptr<const XdmfArrayType> type,
+                                     const std::vector<unsigned int> & start,
+                                     const std::vector<unsigned int> & stride,
+                                     const std::vector<unsigned int> & dimensions,
+                                     const std::vector<unsigned int> & dataspaceDimensions)
+{
+  return XdmfHDF5Controller::New(hdf5FilePath,
+                                 dataSetPath,
+                                 type,
+                                 start,
+                                 stride,
+                                 dimensions,
+                                 dataspaceDimensions);
+}
+
+unsigned int
+XdmfHDF5Writer::getChunkSize() const
+{
+  return mImpl->mChunkSize;
+}
+
+int
+XdmfHDF5Writer::getDataSetSize(shared_ptr<XdmfHeavyDataController> descriptionController)
+{
+  return getDataSetSize(descriptionController->getFilePath(),
+                        shared_dynamic_cast<XdmfHDF5Controller>(descriptionController)->getDataSetPath());
+}
+
+int
+XdmfHDF5Writer::getDataSetSize(const std::string & fileName, const std::string & dataSetName)
+{
+  hid_t handle = -1;
+  H5E_auto_t old_func;
+  void * old_client_data;
+  H5Eget_auto(0, &old_func, &old_client_data);
+  H5Eset_auto2(0, NULL, NULL);
+  if (XdmfSystemUtils::getRealPath(fileName) !=  mImpl->mOpenFile) {
+    // Save old error handler and turn off error handling for now
+
+    if(H5Fis_hdf5(fileName.c_str()) > 0) {
+      handle = H5Fopen(fileName.c_str(),
+                       H5F_ACC_RDWR,
+                       mImpl->mFapl);
+    }
+    else {
+      // This is where it currently fails
+      handle = H5Fcreate(fileName.c_str(),
+                         H5F_ACC_TRUNC,
+                         H5P_DEFAULT,
+                         mImpl->mFapl);
+    }
+  }
+  else {
+    handle = mImpl->mHDF5Handle;
+  }
+
+  // Restore previous error handler
+  H5Eset_auto2(0, old_func, old_client_data);
+
+  if (!H5Lexists(mImpl->mHDF5Handle,
+                 dataSetName.c_str(),
+                 H5P_DEFAULT))
+  {
+     return 0;
+  }
+
+  hid_t checkset = H5Dopen(handle,
+                           dataSetName.c_str(),
+                           H5P_DEFAULT);
+  hid_t checkspace = H5S_ALL;
+  checkspace = H5Dget_space(checkset);
+  hssize_t checksize = H5Sget_simple_extent_npoints(checkspace);
+  herr_t status = H5Dclose(checkset);
+  if(checkspace != H5S_ALL) {
+    status = H5Sclose(checkspace);
+  }
+  if (handle != mImpl->mHDF5Handle) {
+    H5Fclose(handle);
+  }
+  return checksize;
+}
+
+int
+XdmfHDF5Writer::getDeflateFactor() const
+{
+  return mDeflateFactor;
+}
+
+bool
+XdmfHDF5Writer::getUseDeflate() const
+{
+  return mUseDeflate;
+}
+
+void 
+XdmfHDF5Writer::closeFile()
+{
+  mImpl->closeFile();
+}
+
+void
+XdmfHDF5Writer::openFile()
+{
+  mDataSetId = mImpl->openFile(mFilePath,
+                               mDataSetId);
+}
+
+void
+XdmfHDF5Writer::setChunkSize(const unsigned int chunkSize)
+{
+  mImpl->mChunkSize = chunkSize;
+}
+
+void
+XdmfHDF5Writer::setDeflateFactor(int factor)
+{
+  mDeflateFactor = factor;
+}
+
+void
+XdmfHDF5Writer::setUseDeflate(bool status)
+{
+  mUseDeflate = status;
+}
+
+void
+XdmfHDF5Writer::visit(XdmfArray & array,
+                      const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  mImpl->mDepth++;
+  std::set<const XdmfItem *>::iterator checkWritten = mImpl->mWrittenItems.find(&array);
+  if (checkWritten == mImpl->mWrittenItems.end()) {
+    // If it has children send the writer to them too.
+    array.traverse(visitor);
+    if (array.isInitialized() && array.getSize() > 0) {
+      // Only do this if the object has not already been written
+      this->write(array);
+      mImpl->mWrittenItems.insert(&array);
+    }
+  }
+  // If the object has already been written, just end, it already has the data
+  mImpl->mDepth--;
+  if(mImpl->mDepth <= 0) {
+    mImpl->mWrittenItems.clear();
+  }
+}
+
+
+void
+XdmfHDF5Writer::visit(XdmfItem & item,
+                      const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  mImpl->mDepth++;
+  // This is similar to the algorithm for writing XPaths
+  // shouldn't be a problem if XPaths are turned off because all this does is avoid writing an object twice
+  // if it was written once then all instances of the object should have the controller
+  std::set<const XdmfItem *>::iterator checkWritten = mImpl->mWrittenItems.find(&item);
+  if (checkWritten == mImpl->mWrittenItems.end()) {
+    mImpl->mWrittenItems.insert(&item);
+    item.traverse(visitor);
+  }
+  mImpl->mDepth--;
+  if(mImpl->mDepth <= 0) {
+    mImpl->mWrittenItems.clear();
+  }
+}
+
+
+void
+XdmfHDF5Writer::write(XdmfArray & array)
+{
+  hid_t datatype = -1;
+  bool closeDatatype = false;
+
+  // Determining data type
+  if(array.isInitialized()) {
+    if(array.getArrayType() == XdmfArrayType::Int8()) {
+      datatype = H5T_NATIVE_CHAR;
+    }
+    else if(array.getArrayType() == XdmfArrayType::Int16()) {
+      datatype = H5T_NATIVE_SHORT;
+    }
+    else if(array.getArrayType() == XdmfArrayType::Int32()) {
+      datatype = H5T_NATIVE_INT;
+    }
+    else if(array.getArrayType() == XdmfArrayType::Int64()) {
+      datatype = H5T_NATIVE_LONG;
+    }
+    else if(array.getArrayType() == XdmfArrayType::Float32()) {
+      datatype = H5T_NATIVE_FLOAT;
+    }
+    else if(array.getArrayType() == XdmfArrayType::Float64()) {
+      datatype = H5T_NATIVE_DOUBLE;
+    }
+    else if(array.getArrayType() == XdmfArrayType::UInt8()) {
+      datatype = H5T_NATIVE_UCHAR;
+    }
+    else if(array.getArrayType() == XdmfArrayType::UInt16()) {
+      datatype = H5T_NATIVE_USHORT;
+    }
+    else if(array.getArrayType() == XdmfArrayType::UInt32()) {
+      datatype = H5T_NATIVE_UINT;
+    }
+    else if(array.getArrayType() == XdmfArrayType::String()) {
+      // Strings are a special case as they have mutable size
+      datatype = H5Tcopy(H5T_C_S1);
+      H5Tset_size(datatype, H5T_VARIABLE);
+      closeDatatype = true;
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Array of unsupported type in "
+                         "XdmfHDF5Writer::write");
+    }
+  }
+
+  herr_t status;
+
+  if(datatype != -1) {
+    std::string hdf5FilePath = mFilePath;
+
+    size_t extIndex;
+    std::string checkFileName;
+    std::string checkFileExt;
+    extIndex = hdf5FilePath.find_last_of(".");
+    if (extIndex == std::string::npos) {
+      checkFileName = hdf5FilePath;
+      checkFileExt = "";
+    }
+    else {
+      checkFileName = hdf5FilePath.substr(0, extIndex);
+      checkFileExt = hdf5FilePath.substr(extIndex+1);
+    }
+
+    std::stringstream dataSetPath;
+
+    std::vector<shared_ptr<XdmfHeavyDataController> > previousControllers;
+
+    // Hold the controllers in order to base the new controllers on them
+    for(unsigned int i = 0; i < array.getNumberHeavyDataControllers(); ++i) {
+     // discard controllers of the wrong type
+      if (shared_ptr<XdmfHDF5Controller> controller =
+            shared_dynamic_cast<XdmfHDF5Controller>(array.getHeavyDataController(i)) )
+      {
+        previousControllers.push_back(array.getHeavyDataController(i));
+      }
+    }
+
+    // Remove controllers from the array
+    // they will be replaced by the controllers created by this function.
+    while(array.getNumberHeavyDataControllers() != 0) {
+      array.removeHeavyDataController(array.getNumberHeavyDataControllers() -1);
+    }
+
+    bool hasControllers = true;
+
+    if (previousControllers.size() == 0) {
+      // Create a temporary controller if the array doesn't have one
+      hasControllers = false;
+      shared_ptr<XdmfHeavyDataController> tempDataController =
+        this->createController(hdf5FilePath,
+                               "Data",
+                               array.getArrayType(),
+                               std::vector<unsigned int>(1, 0),
+                               std::vector<unsigned int>(1, 1),
+                               std::vector<unsigned int>(1, array.getSize()),
+                               std::vector<unsigned int>(1, array.getSize()));
+      previousControllers.push_back(tempDataController);
+    }
+
+    int controllerIndexOffset = 0;
+
+    // It is assumed that the array will have at least one controller
+    // if it didn't have one a temporary one was generated
+    for(unsigned int i = 0; i < previousControllers.size(); ++i)
+    {
+      if (mMode == Append) {
+        // Append only cares about the last controller, so add the rest back in
+	for (; i < previousControllers.size() - 1; ++i) {
+          array.insert(previousControllers[i]);
+	}
+      }
+
+      std::list<std::string> filesWritten;
+      std::list<std::string> datasetsWritten;
+      std::list<int> datasetIdsWritten;
+      std::list<void *> arraysWritten;
+      std::list<std::vector<unsigned int> > startsWritten;
+      std::list<std::vector<unsigned int> > stridesWritten;
+      std::list<std::vector<unsigned int> > dimensionsWritten;
+      std::list<std::vector<unsigned int> > dataSizesWritten;
+      std::list<unsigned int> arrayOffsetsWritten;
+
+      // Open a hdf5 dataset and write to it on disk.
+      hsize_t size = array.getSize();
+
+      // Save old error handler and turn off error handling for now
+      H5E_auto_t old_func;
+      void * old_client_data;
+      H5Eget_auto(0, &old_func, &old_client_data);
+      H5Eset_auto2(0, NULL, NULL);
+
+      // If this is in hyperslab mode, this loop will need to execute multiple times
+      // Otherwise the boolean is used simply to start it and one pass is made
+      bool startedloop = false;
+      unsigned int origFileIndex = getFileIndex();
+      while ((mMode == Hyperslab
+              && i < previousControllers.size())
+             || !startedloop) {
+        // Hyperslab mode wants to assign all data using the current location
+        // without writing until all data sets are determined
+
+        startedloop = true;
+
+        shared_ptr<XdmfHDF5Controller> heavyDataController =
+          shared_dynamic_cast<XdmfHDF5Controller>(previousControllers[i]);
+        // Stats for the data currently stored in the array
+    
+        std::vector<unsigned int> dimensions;
+        if (mMode != Hyperslab) {
+          dimensions = array.getDimensions();
+        }
+        else {
+	  dimensions = heavyDataController->getDimensions();
+        }
+        std::vector<unsigned int> dataspaceDimensions = dimensions;
+        std::vector<unsigned int> start(dimensions.size(), 0);
+        std::vector<unsigned int> stride(dimensions.size(), 1);
+
+        if((mMode == Overwrite || mMode == Append || mMode == Hyperslab)
+          && heavyDataController) {
+
+          // Write to the previous dataset
+          dataSetPath.str(std::string());
+          dataSetPath << heavyDataController->getDataSetPath();
+          hdf5FilePath = heavyDataController->getFilePath();
+          if(mMode == Hyperslab) {
+            // Start, stride, and dataspace dimensions only matter for hyperslab mode
+            dataspaceDimensions = heavyDataController->getDataspaceDimensions();
+            start = heavyDataController->getStart();
+            stride = heavyDataController->getStride();
+          }
+        }
+        else {
+          dataSetPath.str(std::string());
+          dataSetPath << "Data" << mDataSetId;
+        }
+
+        // Check here for if the file would become
+        // larger than the limit after the addition.
+        // Then check subsequent files for the same limitation
+        std::string passPath = dataSetPath.str();
+        controllerSplitting(array,
+                            controllerIndexOffset,
+                            heavyDataController,
+                            checkFileName,
+                            checkFileExt,
+                            heavyDataController->getDataSetPrefix(),
+                            heavyDataController->getDataSetId(),
+                            dimensions,
+                            dataspaceDimensions,
+                            start,
+                            stride,
+                            filesWritten,
+                            datasetsWritten,
+                            datasetIdsWritten,
+                            arraysWritten,
+                            startsWritten,
+                            stridesWritten,
+                            dimensionsWritten,
+                            dataSizesWritten,
+                            arrayOffsetsWritten);
+
+        if (mMode == Hyperslab)
+        {
+          // In hyperslab mode, reset the file index and move to next iteration
+          i++;
+          setFileIndex(origFileIndex);
+        }
+
+      }
+
+      std::list<std::string>::iterator fileNameWalker = filesWritten.begin();
+      std::list<std::string>::iterator datasetWalker = datasetsWritten.begin();
+      std::list<int>::iterator datasetIdWalker = datasetIdsWritten.begin();
+      std::list<void *>::iterator arrayWalker = arraysWritten.begin();
+      std::list<std::vector<unsigned int> >::iterator startWalker = startsWritten.begin();
+      std::list<std::vector<unsigned int> >::iterator strideWalker = stridesWritten.begin();
+      std::list<std::vector<unsigned int> >::iterator dimensionWalker = dimensionsWritten.begin();
+      std::list<std::vector<unsigned int> >::iterator dataSizeWalker = dataSizesWritten.begin();
+      std::list<unsigned int>::iterator arrayOffsetWalker = arrayOffsetsWritten.begin();
+
+      // Loop based on the amount of blocks split from the array.
+      for (unsigned int writeIndex = 0; writeIndex < arraysWritten.size(); ++writeIndex) {
+	// This is the section where the data is written to hdf5
+	// If you want to change the writer to write to a different data format, do it here
+
+        std::string curFileName = *fileNameWalker;
+        std::string currDataset = *datasetWalker;
+        int currDatasetId = *datasetIdWalker;
+        void * curArray = *arrayWalker;
+        std::vector<unsigned int> curStart = *startWalker;
+        std::vector<unsigned int> curStride = *strideWalker;
+        std::vector<unsigned int> curDimensions = *dimensionWalker;
+        std::vector<unsigned int> curDataSize = *dataSizeWalker;
+        unsigned int curArrayOffset = *arrayOffsetWalker;
+
+
+	bool closeFile = false;
+        // This is meant to open files if it isn't already opened by the write prior
+        // If it wasn't open prior to writing it will be closed after writing
+        if (mImpl->mOpenFile.compare(curFileName) != 0) {
+          if(mImpl->mHDF5Handle < 0) {
+            closeFile = true;
+          }
+          mImpl->openFile(curFileName,
+                          mDataSetId);
+        }
+
+        if (currDatasetId >= 0)
+        {
+          mDataSetId = currDatasetId;
+          dataSetPath.str(std::string());
+          dataSetPath << currDataset << mDataSetId;
+        }
+
+	htri_t testingSet = H5Lexists(mImpl->mHDF5Handle,
+                                      dataSetPath.str().c_str(),
+                                      H5P_DEFAULT);
+
+        hid_t dataset = 0;
+
+        if (testingSet == 0) {
+          dataset = -1;
+        }
+        else {
+          dataset = H5Dopen(mImpl->mHDF5Handle,
+                            dataSetPath.str().c_str(),
+                            H5P_DEFAULT);
+        }
+
+        // If default mode find a new data set to write to (keep
+        // incrementing dataSetId)
+        if(dataset >=0 &&
+           (mMode == Default ||
+            (mMode == Hyperslab && !hasControllers))) {
+          while(true) {
+            dataSetPath.str(std::string());
+            dataSetPath << currDataset << ++mDataSetId;
+            if(!H5Lexists(mImpl->mHDF5Handle,
+                          dataSetPath.str().c_str(),
+                          H5P_DEFAULT)) {
+              //Close previous dataset
+              status = H5Dclose(dataset);
+              dataset = H5Dopen(mImpl->mHDF5Handle,
+                                dataSetPath.str().c_str(),
+                                H5P_DEFAULT);
+              break;
+            }
+          }
+        }
+
+        // Restore previous error handler
+        H5Eset_auto2(0, old_func, old_client_data);
+
+        hid_t dataspace = H5S_ALL;
+        hid_t memspace = H5S_ALL;
+
+        std::vector<hsize_t> current_dims(curDataSize.begin(),
+                                          curDataSize.end());
+
+        if(dataset < 0) {
+          // If the dataset doesn't contain anything
+
+          std::vector<hsize_t> maximum_dims(curDimensions.size(), H5S_UNLIMITED);
+          // Create a new dataspace
+          dataspace = H5Screate_simple(current_dims.size(),
+                                       &current_dims[0],
+                                       &maximum_dims[0]);
+          hid_t property = H5Pcreate(H5P_DATASET_CREATE);
+
+          const hsize_t totalDimensionsSize =
+            std::accumulate(current_dims.begin(),
+                            current_dims.end(),
+                            1,
+                            std::multiplies<hsize_t>());
+          // The Nth root of the chunk size divided by the dimensions added together
+          const double factor =
+            std::pow(((double)mImpl->mChunkSize / totalDimensionsSize),
+                     1.0 / current_dims.size());
+          // The end result is the amount of slots alloted per unit of dimension
+          std::vector<hsize_t> chunk_size(current_dims.begin(),
+                                          current_dims.end());
+	  if (mImpl->mChunkSize > 0) {
+            // The chunk size won't do anything unless it's positive
+            for(std::vector<hsize_t>::iterator iter = chunk_size.begin();
+                iter != chunk_size.end(); ++iter) {
+              *iter = (hsize_t)(*iter * factor);
+              if(*iter == 0) {
+                *iter = 1;
+              }
+            }
+          }
+
+          // Set ZLIB / DEFLATE Compression
+          if (mUseDeflate)
+          {
+            status = H5Pset_deflate(property, mDeflateFactor);
+          }
+
+          status = H5Pset_chunk(property, current_dims.size(), &chunk_size[0]);
+          // Use that dataspace to create a new dataset
+          dataset = H5Dcreate(mImpl->mHDF5Handle,
+                              dataSetPath.str().c_str(),
+                              datatype,
+                              dataspace,
+                              H5P_DEFAULT,
+                              property,
+                              H5P_DEFAULT);
+          status = H5Pclose(property);
+        }
+
+        if(mMode == Append) {
+          // Need to resize dataset to fit new data
+
+          // Get size of old dataset
+          dataspace = H5Dget_space(dataset);
+          hssize_t datasize = H5Sget_simple_extent_npoints(dataspace);
+          status = H5Sclose(dataspace);
+
+          // Reset the datasize if the file or set is different
+          if (curFileName != previousControllers[i]->getFilePath()) {
+            datasize = 0;
+          }
+          if (shared_ptr<XdmfHDF5Controller> setPathController =
+                shared_dynamic_cast<XdmfHDF5Controller>(previousControllers[i])) {
+            if (dataSetPath.str() != setPathController->getDataSetPath()) {
+              datasize = 0;
+            }
+          }
+          else {
+            datasize = 0;
+          }
+
+          unsigned int sizeTotal = 1;
+
+          for (unsigned int dataSizeIter = 0; dataSizeIter < curDataSize.size(); ++dataSizeIter) {
+            sizeTotal = sizeTotal * curDataSize[dataSizeIter];
+          }
+
+          // Resize to fit size of old and new data.
+          hsize_t newSize = sizeTotal + datasize;
+          status = H5Dset_extent(dataset, &newSize);
+          
+          // Select hyperslab to write to.
+          memspace = H5Screate_simple(1, &size, NULL);
+          dataspace = H5Dget_space(dataset);
+          hsize_t dataStart = datasize;
+          status = H5Sselect_hyperslab(dataspace,
+                                       H5S_SELECT_SET,
+                                       &dataStart,
+                                       NULL,
+                                       &size,
+                                       NULL);
+        }
+        else if(mMode == Overwrite) {
+          // Overwriting - dataset rank must remain the same (hdf5 constraint)
+          dataspace = H5Dget_space(dataset);
+
+          const unsigned int ndims = H5Sget_simple_extent_ndims(dataspace);
+          if(ndims != current_dims.size()) {
+            XdmfError::message(XdmfError::FATAL,                            \
+                               "Data set rank different -- ndims != "
+                               "current_dims.size() -- in "
+                               "XdmfHDF5Writer::write");
+          }
+
+          status = H5Dset_extent(dataset, &current_dims[0]);
+          dataspace = H5Dget_space(dataset);
+        }
+        else if(mMode == Hyperslab) {
+          // Hyperslab - dataset rank must remain the same (hdf5 constraint)
+          dataspace = H5Dget_space(dataset);
+
+          const unsigned int ndims = H5Sget_simple_extent_ndims(dataspace);
+          if(ndims != current_dims.size()) {
+            XdmfError::message(XdmfError::FATAL,                            \
+                               "Data set rank different -- ndims != "
+                               "current_dims.size() -- in "
+                               "XdmfHDF5Writer::write");
+          }
+          status = H5Dset_extent(dataset, &current_dims[0]);
+          dataspace = H5Dget_space(dataset);
+
+
+
+
+          std::vector<hsize_t> count(curDimensions.begin(),
+                                     curDimensions.end());
+          std::vector<hsize_t> currStride(curStride.begin(),
+                                          curStride.end());
+          std::vector<hsize_t> currStart(curStart.begin(),
+                                         curStart.end());
+
+          memspace = H5Screate_simple(count.size(),
+                                      &(count[0]),
+                                      NULL);
+          status = H5Sselect_hyperslab(dataspace,
+                                       H5S_SELECT_SET,
+                                       &currStart[0],
+                                       &currStride[0],
+                                       &count[0],
+                                       NULL) ;
+
+          if(status < 0) {
+            XdmfError::message(XdmfError::FATAL,
+                               "H5Dset_extent returned failure in "
+                               "XdmfHDF5Writer::write -- status: " + status);
+          }
+        }
+
+        status = H5Dwrite(dataset,
+                          datatype,
+                          memspace,
+                          dataspace,
+                          H5P_DEFAULT,
+                          curArray);
+
+        if(status < 0) {
+          XdmfError::message(XdmfError::FATAL,
+                             "H5Dwrite returned failure in XdmfHDF5Writer::write "
+                             "-- status: " + status);
+        }
+
+        if(dataspace != H5S_ALL) {
+          status = H5Sclose(dataspace);
+        }
+
+        if(memspace != H5S_ALL) {
+          status = H5Sclose(memspace);
+        }
+
+        status = H5Dclose(dataset);
+
+        H5Fflush(mImpl->mHDF5Handle, H5F_SCOPE_GLOBAL);
+
+	// This is causing a lot of overhead
+        if(closeFile) {
+          mImpl->closeFile();
+        }
+
+        // Attach a new controller to the array
+        shared_ptr<XdmfHDF5Controller> newDataController =
+          shared_ptr<XdmfHDF5Controller>();
+        //This generates an empty pointer
+
+        unsigned int newSize;
+        if(mMode == Append) {
+          // Find data size
+          mImpl->openFile(curFileName,
+                          mDataSetId);
+          hid_t checkset = H5Dopen(mImpl->mHDF5Handle,
+                                   dataSetPath.str().c_str(),
+                                   H5P_DEFAULT);
+          hid_t checkspace = H5S_ALL;
+          checkspace = H5Dget_space(checkset);
+          newSize = H5Sget_simple_extent_npoints(checkspace);
+          status = H5Dclose(checkset);
+	  if(checkspace != H5S_ALL) {
+	    status = H5Sclose(checkspace);
+          }
+ 
+          std::vector<unsigned int> insertStarts;
+          insertStarts.push_back(0);
+          std::vector<unsigned int> insertStrides;
+          insertStrides.push_back(1);
+          std::vector<unsigned int> insertDimensions;
+          insertDimensions.push_back(newSize);
+          std::vector<unsigned int> insertDataSpaceDimensions;
+          insertDataSpaceDimensions.push_back(newSize);
+
+          newDataController = 
+            shared_dynamic_cast<XdmfHDF5Controller>(this->createController(curFileName,
+                                                    dataSetPath.str(),
+                                                    array.getArrayType(),
+                                                    insertStarts,
+                                                    insertStrides,
+                                                    insertDimensions,
+                                                    insertDataSpaceDimensions));
+        }
+
+        if(!newDataController) {
+          // If the controller wasn't generated by append
+          newDataController =
+            shared_dynamic_cast<XdmfHDF5Controller>(this->createController(curFileName,
+                                                    dataSetPath.str(),
+                                                    array.getArrayType(),
+                                                    curStart,
+                                                    curStride,
+                                                    curDimensions,
+                                                    curDataSize));
+        }
+
+        newDataController->setArrayOffset(curArrayOffset);
+
+        array.insert(newDataController);
+
+        fileNameWalker++;
+        datasetWalker++;
+        datasetIdWalker++;
+        arrayWalker++;
+        startWalker++;
+        strideWalker++;
+        dimensionWalker++;
+        dataSizeWalker++;
+        arrayOffsetWalker++;
+
+        if (mMode == Default) {
+          dataSetPath.str(std::string());
+          dataSetPath << "Data" << ++mDataSetId;
+        }
+
+      }
+
+    }
+
+    if(closeDatatype) {
+      status = H5Tclose(datatype);
+    }
+
+    if(mReleaseData) {
+      array.release();
+    }
+  }
+}
+
+// C Wrappers
+
+XDMFHDF5WRITER * XdmfHDF5WriterNew(char * fileName, int clobberFile)
+{
+  try
+  {
+    shared_ptr<XdmfHDF5Writer> generatedWriter = XdmfHDF5Writer::New(std::string(fileName), clobberFile);
+    return (XDMFHDF5WRITER *)((void *)(new XdmfHDF5Writer(*generatedWriter.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfHDF5Writer> generatedWriter = XdmfHDF5Writer::New(std::string(fileName), clobberFile);
+    return (XDMFHDF5WRITER *)((void *)(new XdmfHDF5Writer(*generatedWriter.get())));
+  }
+}
+
+void XdmfHDF5WriterCloseFile(XDMFHDF5WRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5Writer *)writer)->closeFile();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+unsigned int XdmfHDF5WriterGetChunkSize(XDMFHDF5WRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfHDF5Writer *)writer)->getChunkSize();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+void XdmfHDF5WriterOpenFile(XDMFHDF5WRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5Writer *)writer)->openFile();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHDF5WriterSetChunkSize(XDMFHDF5WRITER * writer, unsigned int chunkSize, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5Writer *)writer)->setChunkSize(chunkSize);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_HEAVYWRITER_C_CHILD_WRAPPER(XdmfHDF5Writer, XDMFHDF5WRITER)
diff --git a/core/XdmfHDF5Writer.hpp b/core/XdmfHDF5Writer.hpp
new file mode 100644
index 0000000..cfbec6f
--- /dev/null
+++ b/core/XdmfHDF5Writer.hpp
@@ -0,0 +1,420 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5Writer.hpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFHDF5WRITER_HPP_
+#define XDMFHDF5WRITER_HPP_
+
+// C Compatible includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfHeavyDataController.hpp"
+
+// So that hdf5 does not need to be included in the header files
+// It would add a dependancy to programs that use Xdmf
+#ifndef _H5Ipublic_H
+  #ifndef XDMF_HID_T
+  #define XDMF_HID_T
+    typedef int hid_t;
+  #endif
+#endif
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+class XdmfArrayType;
+class XdmfHDF5Controller;
+
+// Includes
+#include <list>
+#include <set>
+
+/**
+ * @brief Traverse the Xdmf graph and write heavy data stored in
+ * XdmfArrays to HDF5 on disk.
+ *
+ * XdmfHDF5Writer traverses an Xdmf graph structure and writes data
+ * stored in XdmfArrays to HDF5. Writing begins by calling the
+ * accept() operation on any XdmfItem and supplying this writer as the
+ * parameter. The writer will write all XdmfArrays under the XdmfItem
+ * to an hdf5 file on disk. It will also attach an XdmfHDF5Controller
+ * to all XdmfArrays that it writes to disk.
+ *
+ * This writer supports all heavy data writing modes listed in
+ * XdmfHeavyDataWriter.
+ */
+class XDMFCORE_EXPORT XdmfHDF5Writer : public XdmfHeavyDataWriter {
+
+public:
+
+  /**
+   * Construct XdmfHDF5Writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     filePath        The location of the hdf5 file to output to on disk.
+   * @param     clobberFile     Whether to overwrite the previous file if it exists.
+   *
+   * @return                    New XdmfHDF5Writer.
+   */
+  static shared_ptr<XdmfHDF5Writer> New(const std::string & filePath,
+                                        const bool clobberFile = false);
+
+  virtual ~XdmfHDF5Writer();
+
+
+  virtual void closeFile();
+
+  /**
+   * Get the chunk size used to output datasets to hdf5.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getChunkSize
+   * @until //#getChunkSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getChunkSize
+   * @until #//getChunkSize
+   *
+   * @return    Chunk size used to output datasets to hdf5.
+   */
+  unsigned int getChunkSize() const;
+
+  virtual int getDataSetSize(const std::string & fileName,
+                             const std::string & dataSetName);
+
+  /**
+   * Gets the factor that Deflate uses to compress data.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDeflateFactor
+   * @until //#getDeflateFactor
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDeflateFactor
+   * @until #//getDeflateFactor
+   *
+   * @return    The factor Deflate uses.
+   */
+  int getDeflateFactor() const;
+
+  /**
+   * Gets whether Deflate is enabled.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getUseDeflate
+   * @until //#getUseDeflate
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getUseDeflate
+   * @until #//getUseDeflate
+   *
+   * @return    Whether Deflate is in use.
+   */
+  bool getUseDeflate() const;
+
+  virtual void openFile();
+
+  /**
+   * Set the chunk size used to output datasets to hdf5. For
+   * multidimensional datasets the chunk size is the total number of
+   * elements in the chunk.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setChunkSize
+   * @until //#setChunkSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setChunkSize
+   * @until #//setChunkSize
+   *
+   * @param     chunkSize       The number of elements per chunk.
+   */
+  void setChunkSize(const unsigned int chunkSize);
+
+  /**
+   * Sets the factor that Deflate will use to compress data.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setDeflateFactor
+   * @until //#setDeflateFactor
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setDeflateFactor
+   * @until #//setDeflateFactor
+   *
+   * @param     factor  The factor Deflate will use.
+   */
+  void setDeflateFactor(int factor);
+
+  /**
+   * Sets whether HDF5 will use Deflate compression
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Writer.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setUseDeflate
+   * @until //#setUseDeflate
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Writer.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setUseDeflate
+   * @until #//setUseDeflate
+   *
+   * @param     status  Whether Deflate will be used.
+   */
+  void setUseDeflate(bool status);
+
+  using XdmfHeavyDataWriter::visit;
+  virtual void visit(XdmfArray & array,
+                     const shared_ptr<XdmfBaseVisitor> visitor);
+
+  virtual void visit(XdmfItem & item,
+                     const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfHDF5Writer(const XdmfHDF5Writer &);
+
+protected:
+
+  XdmfHDF5Writer(const std::string & filePath);
+
+  /**
+   * Create a new HDF5 Controller that is able to read in after being
+   * written by this writer.
+   *
+   * @param hdf5FilePath the location of the hdf5 file the data set resides in.
+   * @param dataSetPath the location of the dataset within the hdf5 file.
+   * @param type the data type of the dataset to read.
+   * @param start the offset of the starting element in each dimension in
+   * the hdf5 data set.
+   * @param stride the number of elements to move in each dimension from the
+   * hdf5 data set.
+   * @param dimensions the number of elements to select in each
+   * dimension from the hdf5 data set. (size in each dimension)
+   * @param dataspaceDimensions the number of elements in the entire
+   * hdf5 data set (may be larger that dimensions if using
+   * hyperslabs).
+   *
+   * @return    new HDF5 Controller.
+   */
+  virtual shared_ptr<XdmfHeavyDataController>
+  createController(const std::string & hdf5FilePath,
+                   const std::string & descriptor,
+                   const shared_ptr<const XdmfArrayType> type,
+                   const std::vector<unsigned int> & start,
+                   const std::vector<unsigned int> & stride,
+                   const std::vector<unsigned int> & dimensions,
+                   const std::vector<unsigned int> & dataspaceDimensions);
+
+  virtual int getDataSetSize(shared_ptr<XdmfHeavyDataController> descriptionController);
+
+  /**
+   * Write the XdmfArray to a hdf5 file.
+   *
+   * @param     array   An XdmfArray to write to hdf5.
+   */
+  virtual void write(XdmfArray & array);
+
+  /**
+   * PIMPL
+   */
+  class XdmfHDF5WriterImpl
+  {
+  public:
+
+    XdmfHDF5WriterImpl();
+
+    virtual ~XdmfHDF5WriterImpl();
+
+    virtual void
+    closeFile();
+
+    virtual int
+    openFile(const std::string & filePath,
+             const int mDataSetId);
+
+    hid_t mHDF5Handle;
+    int mFapl;
+    unsigned int mChunkSize;
+    std::string mOpenFile;
+    int mDepth;
+    std::set<const XdmfItem *> mWrittenItems;
+  };
+
+  XdmfHDF5WriterImpl * mImpl;
+
+  bool mUseDeflate;
+  int mDeflateFactor;
+
+private:
+
+  void operator=(const XdmfHDF5Writer &);  // Not implemented.
+
+  virtual void controllerSplitting(XdmfArray & array,
+                                   int & controllerIndexOffset,
+                                   shared_ptr<XdmfHeavyDataController> heavyDataController,
+                                   const std::string & checkFileName,
+                                   const std::string & checkFileExt,
+                                   const std::string & dataSetPath,
+                                   int dataSetId,
+                                   const std::vector<unsigned int> & dimensions,
+                                   const std::vector<unsigned int> & dataspaceDimensions,
+                                   const std::vector<unsigned int> & start,
+                                   const std::vector<unsigned int> & stride,
+                                   std::list<std::string> & filesWritten,
+                                   std::list<std::string> & datasetsWritten,
+                                   std::list<int> & datasetIdsWritten,
+                                   std::list<void *> & arraysWritten,
+                                   std::list<std::vector<unsigned int> > & startsWritten,
+                                   std::list<std::vector<unsigned int> > & stridesWritten,
+                                   std::list<std::vector<unsigned int> > & dimensionsWritten,
+                                   std::list<std::vector<unsigned int> > & dataSizesWritten,
+                                   std::list<unsigned int> & arrayOffsetsWritten);
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFHDF5WRITER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHDF5WRITER XDMFHDF5WRITER;
+
+XDMFCORE_EXPORT XDMFHDF5WRITER * XdmfHDF5WriterNew(char * fileName, int clobberFile);
+
+XDMFCORE_EXPORT void XdmfHDF5WriterCloseFile(XDMFHDF5WRITER * writer, int * status);
+
+XDMFCORE_EXPORT unsigned int XdmfHDF5WriterGetChunkSize(XDMFHDF5WRITER * writer, int * status);
+
+XDMFCORE_EXPORT void XdmfHDF5WriterOpenFile(XDMFHDF5WRITER * writer, int * status);
+
+XDMFCORE_EXPORT void XdmfHDF5WriterSetChunkSize(XDMFHDF5WRITER * writer, unsigned int chunkSize, int * status);
+
+#define XDMF_HDF5WRITER_C_CHILD_DECLARE(ClassName, CClassName, Level)                                    \
+                                                                                                         \
+Level##_EXPORT void ClassName##CloseFile( CClassName * writer, int * status);                            \
+Level##_EXPORT unsigned int ClassName##GetChunkSize( CClassName * writer, int * status);                 \
+Level##_EXPORT void ClassName##OpenFile( CClassName * writer, int * status);                             \
+Level##_EXPORT void ClassName##SetChunkSize( CClassName * writer, unsigned int chunkSize, int * status);
+
+#define XDMF_HDF5WRITER_C_CHILD_WRAPPER(ClassName, CClassName)                                           \
+                                                                                                         \
+void ClassName##CloseFile( CClassName * writer, int * status)                                            \
+{                                                                                                        \
+  XdmfHDF5WriterCloseFile((XDMFHDF5WRITER *)((void *)writer), status);                                   \
+}                                                                                                        \
+                                                                                                         \
+unsigned int ClassName##GetChunkSize( CClassName * writer, int * status)                                 \
+{                                                                                                        \
+  return XdmfHDF5WriterGetChunkSize((XDMFHDF5WRITER *)((void *)writer), status);                         \
+}                                                                                                        \
+                                                                                                         \
+void ClassName##OpenFile( CClassName * writer, int * status)                                             \
+{                                                                                                        \
+  XdmfHDF5WriterOpenFile((XDMFHDF5WRITER *)((void *)writer), status);                                    \
+}                                                                                                        \
+                                                                                                         \
+void ClassName##SetChunkSize( CClassName * writer, unsigned int chunkSize, int * status)                 \
+{                                                                                                        \
+  XdmfHDF5WriterSetChunkSize((XDMFHDF5WRITER *)((void *)writer), chunkSize, status);                     \
+}
+
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_HEAVYWRITER_C_CHILD_DECLARE(XdmfHDF5Writer, XDMFHDF5WRITER, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHDF5WRITER_HPP_ */
diff --git a/core/XdmfHeavyDataController.cpp b/core/XdmfHeavyDataController.cpp
new file mode 100644
index 0000000..0486fcc
--- /dev/null
+++ b/core/XdmfHeavyDataController.cpp
@@ -0,0 +1,398 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHeavyDataController.cpp                                         */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <functional>
+#include <numeric>
+#include "string.h"
+#include "XdmfArrayType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfSystemUtils.hpp"
+
+XdmfHeavyDataController::XdmfHeavyDataController(const std::string & filePath,
+                                                 const shared_ptr<const XdmfArrayType> & type,
+                                                 const std::vector<unsigned int> & starts,
+                                                 const std::vector<unsigned int> & strides,
+                                                 const std::vector<unsigned int> & dimensions,
+                                                 const std::vector<unsigned int> & dataspaces) :
+  mStart(starts),
+  mStride(strides),
+  mDimensions(dimensions),
+  mDataspaceDimensions(dataspaces),
+  mFilePath(filePath),
+  mArrayStartOffset(0),
+  mType(type)
+{
+}
+
+XdmfHeavyDataController::XdmfHeavyDataController(const XdmfHeavyDataController& refController):
+  mStart(refController.getStart()),
+  mStride(refController.getStride()),
+  mDimensions(refController.getDimensions()),
+  mDataspaceDimensions(refController.getDataspaceDimensions()),
+  mFilePath(refController.getFilePath()),
+  mArrayStartOffset(refController.getArrayOffset()),
+  mType(refController.getType())
+{
+}
+
+XdmfHeavyDataController::~XdmfHeavyDataController()
+{
+}
+
+unsigned int
+XdmfHeavyDataController::getArrayOffset() const
+{
+  return mArrayStartOffset;
+}
+
+std::string
+XdmfHeavyDataController::getDataspaceDescription() const
+{
+  std::stringstream dimensionStream;
+
+  for (unsigned int j = 0; j < this->getStart().size(); ++j) {
+    dimensionStream << this->getStart()[j];
+    if (j < this->getStart().size() - 1) {
+      dimensionStream << " ";
+    }
+  }
+  dimensionStream << ":";
+  for (unsigned int j = 0; j < this->getStride().size(); ++j) {
+    dimensionStream << this->getStride()[j];
+    if (j < this->getStride().size() - 1) {
+      dimensionStream << " ";
+    }
+  }
+  dimensionStream << ":";
+  for (unsigned int j = 0; j < this->getDimensions().size(); ++j) {
+    dimensionStream << this->getDimensions()[j];
+    if (j < this->getDimensions().size() - 1) {
+      dimensionStream << " ";
+    }
+  }
+  dimensionStream << ":";
+  for (unsigned int j = 0; j < this->getDataspaceDimensions().size(); ++j) {
+    dimensionStream << this->getDataspaceDimensions()[j];
+    if (j < this->getDataspaceDimensions().size() - 1) {
+      dimensionStream << " ";
+    }
+  }
+  return dimensionStream.str();
+}
+
+std::vector<unsigned int>
+XdmfHeavyDataController::getDataspaceDimensions() const
+{
+  return mDataspaceDimensions;
+}
+
+unsigned int
+XdmfHeavyDataController::getDataspaceSize() const
+{
+  return std::accumulate(mDataspaceDimensions.begin(),
+                         mDataspaceDimensions.end(),
+                         1,
+                         std::multiplies<unsigned int>());
+}
+
+std::string
+XdmfHeavyDataController::getDescriptor() const
+{
+  return "";
+}
+
+std::vector<unsigned int> 
+XdmfHeavyDataController::getDimensions() const
+{
+  return mDimensions;
+}
+
+std::string
+XdmfHeavyDataController::getFilePath() const
+{
+  return mFilePath;
+}
+
+std::vector<unsigned int>
+XdmfHeavyDataController::getStart() const
+{
+  return mStart;
+}
+
+std::vector<unsigned int>
+XdmfHeavyDataController::getStride() const
+{
+  return mStride;
+}
+
+unsigned int
+XdmfHeavyDataController::getSize() const
+{
+  return std::accumulate(mDimensions.begin(),
+                         mDimensions.end(),
+                         1,
+                         std::multiplies<unsigned int>());
+}
+
+shared_ptr<const XdmfArrayType>
+XdmfHeavyDataController::getType() const
+{
+  return mType;
+}
+
+void
+XdmfHeavyDataController::setArrayOffset(unsigned int newOffset)
+{
+  mArrayStartOffset = newOffset;
+}
+
+// C Wrappers
+
+void XdmfHeavyDataControllerFree(XDMFHEAVYDATACONTROLLER * item)
+{
+  if (item != NULL) {
+    delete ((XdmfHeavyDataController *)item);
+    item = NULL;
+  }
+}
+
+unsigned int * XdmfHeavyDataControllerGetDataspaceDimensions(XDMFHEAVYDATACONTROLLER * controller)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getDataspaceDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getDataspaceDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+unsigned int * XdmfHeavyDataControllerGetDimensions(XDMFHEAVYDATACONTROLLER * controller)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+char * XdmfHeavyDataControllerGetFilePath(XDMFHEAVYDATACONTROLLER * controller)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfHeavyDataController *)(controller))->getFilePath().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfHeavyDataController *)(controller))->getFilePath().c_str());
+    return returnPointer;
+  }
+}
+
+char * XdmfHeavyDataControllerGetName(XDMFHEAVYDATACONTROLLER * controller)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfHeavyDataController *)(controller))->getName().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfHeavyDataController *)(controller))->getName().c_str());
+    return returnPointer;
+  }
+}
+
+unsigned int XdmfHeavyDataControllerGetNumberDimensions(XDMFHEAVYDATACONTROLLER * controller)
+{
+  return ((XdmfHeavyDataController *)(controller))->getDimensions().size();
+}
+
+unsigned int XdmfHeavyDataControllerGetSize(XDMFHEAVYDATACONTROLLER * controller)
+{
+  return ((XdmfHeavyDataController *)(controller))->getSize();
+}
+
+unsigned int * XdmfHeavyDataControllerGetStart(XDMFHEAVYDATACONTROLLER * controller)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getStart();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getStart();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+unsigned int * XdmfHeavyDataControllerGetStride(XDMFHEAVYDATACONTROLLER * controller)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getStride();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfHeavyDataController *)(controller))->getStride();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+void XdmfHeavyDataControllerSetArrayOffset(XDMFHEAVYDATACONTROLLER * controller, unsigned int newOffset)
+{
+  ((XdmfHeavyDataController *)(controller))->setArrayOffset(newOffset);
+}
+
+unsigned int XdmfHeavyDataControllerGetArrayOffset(XDMFHEAVYDATACONTROLLER * controller)
+{
+  return ((XdmfHeavyDataController *)(controller))->getArrayOffset();
+}
+
+int XdmfHeavyDataControllerGetType(XDMFHEAVYDATACONTROLLER * controller, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<const XdmfArrayType> compareType = ((XdmfHeavyDataController *)(controller))->getType();
+  std::string typeName = compareType->getName();
+  unsigned int typePrecision = compareType->getElementSize();
+  if (typeName == XdmfArrayType::UInt8()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT8;
+  }
+  else if (typeName == XdmfArrayType::UInt16()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT16;
+  }
+  else if (typeName == XdmfArrayType::UInt32()->getName())
+  {
+      return XDMF_ARRAY_TYPE_UINT32;
+  }
+  else if (typeName == XdmfArrayType::Int8()->getName())
+  {
+      return XDMF_ARRAY_TYPE_INT8;
+  }
+  else if (typeName == XdmfArrayType::Int16()->getName())
+  {
+      return XDMF_ARRAY_TYPE_INT16;
+  }
+  else if (typeName == XdmfArrayType::Int32()->getName() || typeName == XdmfArrayType::Int64()->getName())
+  {
+    if (typePrecision == 4)
+    {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (typePrecision == 8)
+    {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else
+    {
+    }
+  }
+  else if (typeName == XdmfArrayType::Float32()->getName() || typeName == XdmfArrayType::Float64()->getName())
+  {
+    if (typePrecision == 4)
+    {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (typePrecision == 8)
+    {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else
+    {
+    }
+  }
+  else if (typeName == XdmfArrayType::String()->getName())
+  {
+    //This shouldn't be used from C bindings
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: String type not usable from C.");
+  }
+  else
+  {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Invalid ArrayType.");
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+void XdmfHeavyDataControllerRead(XDMFHEAVYDATACONTROLLER * controller, void * array, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHeavyDataController *)(controller))->read((XdmfArray *)array);
+  XDMF_ERROR_WRAP_END(status)
+}
diff --git a/core/XdmfHeavyDataController.hpp b/core/XdmfHeavyDataController.hpp
new file mode 100644
index 0000000..e0622f2
--- /dev/null
+++ b/core/XdmfHeavyDataController.hpp
@@ -0,0 +1,559 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHeavyDataController.hpp                                         */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFHEAVYDATACONTROLLER_HPP_
+#define XDMFHEAVYDATACONTROLLER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfArrayType.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+// Includes
+#include <string>
+#include <vector>
+#include <map>
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Couples an XdmfArray with heavy data stored on disk.
+ *
+ * This is an abstract base class to support the reading of different
+ * heavy data formats.
+ *
+ * Serves as an interface between data stored in XdmfArrays and data
+ * stored on disk. When an Xdmf file is read from or written to disk
+ * an XdmfHeavyController is attached to XdmfArrays. This allows data
+ * to be released from memory but still be accessible or have its
+ * location written to light data.
+ */
+class XDMFCORE_EXPORT XdmfHeavyDataController {
+
+public:
+
+  virtual ~XdmfHeavyDataController() = 0;
+
+  /**
+   * Gets a string containing data on the starts,
+   * strides, dimensions, and dataspaces for this controller.
+   *
+   * @return    The string description
+   */
+  std::string getDataspaceDescription() const;
+
+  /**
+   * Get the dimensions of the dataspace owned by this
+   * controller. This is the dimension of the entire heavy dataset,
+   * which may be larger than the dimensions of the array (if reading
+   * a piece of a larger dataset).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDataspaceDimensions
+   * @until //#getDataspaceDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDataspaceDimensions
+   * @until #//getDataspaceDimensions
+   *
+   * @return    A vector containing the size in each dimension of the dataspace
+   *            owned by this controller.
+   */
+  std::vector<unsigned int> getDataspaceDimensions() const;
+
+  /**
+   * Get the size of dataspace of the heavy data set owned by this controller.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDataspaceSize
+   * @until //#getDataspaceSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDataspaceSize
+   * @until #//getDataspaceSize
+   *
+   * @return    An int containing the size of the heavy data set.
+   */
+  unsigned int getDataspaceSize() const;
+
+  /**
+   * Gets the controller in string form. For writing to file.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDescriptor
+   * @until //#getDescriptor
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDescriptor
+   * @until #//getDescriptor
+   *
+   * @return    A string that contains relevant information for the controller
+   */
+  virtual std::string getDescriptor() const;
+
+  /**
+   * Get the dimensions of the heavy data set owned by this controller.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    A vector containing the size in each dimension of the heavy data
+   *            set owned by this controller.
+   */
+  std::vector<unsigned int> getDimensions() const;
+
+  /**
+   * Get the absolute path to the heavy data file on disk where the
+   * data set owned by this controller resides.
+   * For "/home/output.h5:/foo/data" this is "/home/output.h5"
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getFilePath
+   * @until //#getFilePath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getFilePath
+   * @until #//getFilePath
+   *
+   * @return    A std::string containing the path to the heavy data file.
+   */
+  std::string getFilePath() const;
+
+  /**
+   * Get the name of this heavy data format. E.g. "HDF" for hdf5
+   * format.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    std::string containing the name of this heavy data format
+   */
+  virtual std::string getName() const = 0;
+
+  /**
+   * Get the size of the heavy data set owned by this controller.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getSize
+   * @until //#getSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getSize
+   * @until #//getSize
+   *
+   * @return    An int containing the size of the heavy data set.
+   */
+  unsigned int getSize() const;
+
+  /**
+   * Get the start index of the heavy data set owned by this controller.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getStart
+   * @until //#getStart
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getStart
+   * @until #//getStart
+   *
+   * @return    A vector containing the start index in each dimension of
+   *            the heavy data set owned by this controller.
+   */
+  std::vector<unsigned int> getStart() const;
+
+  /**
+   * Get the stride of the heavy data set owned by this controller.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHDF5Controller.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getStride
+   * @until //#getStride
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHDF5Controller.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getStride
+   * @until #//getStride
+   *
+   * @return    A vector containing the stride in each dimension of the
+   *            heavy data set owned by this controller.
+   */
+  std::vector<unsigned int> getStride() const;
+
+  /**
+   * For use in conjunction with heavy data controllers set to arrays
+   * the offset within the array from which the controller will be inserted
+   * Is also set when created by a writer.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setArrayOffset
+   * @until //#setArrayOffset
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setArrayOffset
+   * @until #//setArrayOffset
+   *
+   * @param     newOffset       The new index at which the controller will be written
+   */
+  void setArrayOffset(unsigned int newOffset);
+
+  /**
+   * Gets the index at which the controller will offset when
+   * an array reads it from its associated controllers.
+   * Set when created by a Writer or set manually.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setArrayOffset
+   * @until //#setArrayOffset
+   * @skipline //#getArrayOffset
+   * @until //#getArrayOffset
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setArrayOffset
+   * @until #//setArrayOffset
+   * @skipline #//getArrayOffset
+   * @until #//getArrayOffset
+   *
+   * @return    The offset that the array will read from
+   */
+  unsigned int getArrayOffset() const;
+
+  virtual void getProperties(std::map<std::string, std::string> & collectedProperties) const = 0;
+
+  /**
+   * Get the array type of the heavy data set owned by this
+   * controller.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getType
+   * @until //#getType
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getType
+   * @until #//getType
+   *
+   * @return    An XdmfArrayType containing the array type of the heavy data set.
+   */
+  shared_ptr<const XdmfArrayType> getType() const;
+
+  /**
+   * Read data owned by this controller on disk into the passed
+   * XdmfArray.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//read
+   * @until #//read
+   *
+   * @param     array   An XdmfArray to read data into.
+   */
+  virtual void read(XdmfArray * const array) = 0;
+
+  XdmfHeavyDataController(const XdmfHeavyDataController&);
+
+protected:
+
+  XdmfHeavyDataController(const std::string & filePath,
+                          const shared_ptr<const XdmfArrayType> & type,
+                          const std::vector<unsigned int> & starts,
+                          const std::vector<unsigned int> & strides,
+                          const std::vector<unsigned int> & dimensions,
+                          const std::vector<unsigned int> & dataspaces);
+
+  const std::vector<unsigned int> mStart;
+  const std::vector<unsigned int> mStride;
+  const std::vector<unsigned int> mDimensions;
+  const std::vector<unsigned int> mDataspaceDimensions;
+  const std::string mFilePath;
+  unsigned int mArrayStartOffset;
+  const shared_ptr<const XdmfArrayType> mType;
+
+private:
+
+  void operator=(const XdmfHeavyDataController &);  // Not implemented.
+
+};
+
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFHEAVYDATACONTROLLER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHEAVYDATACONTROLLER XDMFHEAVYDATACONTROLLER;
+
+XDMFCORE_EXPORT void XdmfHeavyDataControllerFree(XDMFHEAVYDATACONTROLLER * item);
+
+XDMFCORE_EXPORT unsigned int * XdmfHeavyDataControllerGetDataspaceDimensions(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT unsigned int * XdmfHeavyDataControllerGetDimensions(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT char * XdmfHeavyDataControllerGetFilePath(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT char * XdmfHeavyDataControllerGetName(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT unsigned int XdmfHeavyDataControllerGetNumberDimensions(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT unsigned int XdmfHeavyDataControllerGetSize(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT unsigned int * XdmfHeavyDataControllerGetStart(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT unsigned int * XdmfHeavyDataControllerGetStride(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT void XdmfHeavyDataControllerSetArrayOffset(XDMFHEAVYDATACONTROLLER * controller, unsigned int newOffset);
+
+XDMFCORE_EXPORT unsigned int XdmfHeavyDataControllerGetArrayOffset(XDMFHEAVYDATACONTROLLER * controller);
+
+XDMFCORE_EXPORT int XdmfHeavyDataControllerGetType(XDMFHEAVYDATACONTROLLER * controller, int * status);
+
+XDMFCORE_EXPORT void XdmfHeavyDataControllerRead(XDMFHEAVYDATACONTROLLER * controller, void * array, int * status);
+
+#define XDMF_HEAVYCONTROLLER_C_CHILD_DECLARE(ClassName, CClassName, Level)                               \
+                                                                                                         \
+Level##_EXPORT void ClassName##Free( CClassName * item);                                                 \
+Level##_EXPORT unsigned int * ClassName##GetDataspaceDimensions( CClassName * controller);               \
+Level##_EXPORT unsigned int * ClassName##GetDimensions( CClassName * controller);                        \
+Level##_EXPORT char * ClassName##GetFilePath( CClassName * controller);                                  \
+Level##_EXPORT char * ClassName##GetName( CClassName * controller);                                      \
+Level##_EXPORT unsigned int ClassName##GetNumberDimensions( CClassName * controller);                    \
+Level##_EXPORT unsigned int ClassName##GetSize( CClassName * controller);                                \
+Level##_EXPORT unsigned int * ClassName##GetStart( CClassName * controller);                             \
+Level##_EXPORT unsigned int * ClassName##GetStride( CClassName * controller);                            \
+Level##_EXPORT void ClassName##SetArrayOffset( CClassName * controller, unsigned int newOffset);         \
+Level##_EXPORT unsigned int ClassName##GetArrayOffset( CClassName * controller);                         \
+Level##_EXPORT int ClassName##GetType( CClassName * controller, int * status);                           \
+Level##_EXPORT void ClassName##Read( CClassName * controller, void * array, int * status);
+
+
+
+#define XDMF_HEAVYCONTROLLER_C_CHILD_WRAPPER(ClassName, CClassName)                                      \
+                                                                                                         \
+void ClassName##Free( CClassName * item)                                                                 \
+{                                                                                                        \
+  XdmfHeavyDataControllerFree((XDMFHEAVYDATACONTROLLER *)((void *)item));                                \
+}                                                                                                        \
+                                                                                                         \
+unsigned int * ClassName##GetDataspaceDimensions( CClassName * controller)                               \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetDataspaceDimensions((XDMFHEAVYDATACONTROLLER *)((void *)controller)); \
+}                                                                                                        \
+                                                                                                         \
+unsigned int * ClassName##GetDimensions( CClassName * controller)                                        \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetDimensions((XDMFHEAVYDATACONTROLLER *)((void *)controller));          \
+}                                                                                                        \
+                                                                                                         \
+char * ClassName##GetFilePath( CClassName * controller)                                                  \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetFilePath((XDMFHEAVYDATACONTROLLER *)((void *)controller));            \
+}                                                                                                        \
+                                                                                                         \
+char * ClassName##GetName( CClassName * controller)                                                      \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetName((XDMFHEAVYDATACONTROLLER *)((void *)controller));                \
+}                                                                                                        \
+                                                                                                         \
+unsigned int ClassName##GetNumberDimensions( CClassName * controller)                                    \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetNumberDimensions((XDMFHEAVYDATACONTROLLER *)((void *)controller));    \
+}                                                                                                        \
+                                                                                                         \
+unsigned int ClassName##GetSize( CClassName * controller)                                                \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetSize((XDMFHEAVYDATACONTROLLER *)((void *)controller));                \
+}                                                                                                        \
+                                                                                                         \
+unsigned int * ClassName##GetStart( CClassName * controller)                                             \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetStart((XDMFHEAVYDATACONTROLLER *)((void *)controller));               \
+}                                                                                                        \
+                                                                                                         \
+unsigned int * ClassName##GetStride( CClassName * controller)                                            \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetStride((XDMFHEAVYDATACONTROLLER *)((void *)controller));              \
+}                                                                                                        \
+                                                                                                         \
+void ClassName##SetArrayOffset( CClassName * controller, unsigned int newOffset)                         \
+{                                                                                                        \
+  XdmfHeavyDataControllerSetArrayOffset((XDMFHEAVYDATACONTROLLER *)((void *)controller), newOffset);     \
+}                                                                                                        \
+                                                                                                         \
+unsigned int ClassName##GetArrayOffset( CClassName * controller)                                         \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetArrayOffset((XDMFHEAVYDATACONTROLLER *)((void *)controller));         \
+}                                                                                                        \
+                                                                                                         \
+int ClassName##GetType( CClassName * controller, int * status)                                           \
+{                                                                                                        \
+  return XdmfHeavyDataControllerGetType((XDMFHEAVYDATACONTROLLER *)((void *)controller), status);        \
+}                                                                                                        \
+                                                                                                         \
+void ClassName##Read( CClassName * controller, void * array, int * status)                               \
+{                                                                                                        \
+  XdmfHeavyDataControllerRead((XDMFHEAVYDATACONTROLLER *)((void *)controller), array, status);           \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHEAVYDATACONTROLLER_HPP_ */
diff --git a/core/XdmfHeavyDataDescription.cpp b/core/XdmfHeavyDataDescription.cpp
new file mode 100644
index 0000000..37e652f
--- /dev/null
+++ b/core/XdmfHeavyDataDescription.cpp
@@ -0,0 +1,88 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHeavyDataDescription.hpp                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+#include <utility>
+#include "XdmfError.hpp"
+#include "XdmfHeavyDataDescription.hpp"
+#include "XdmfSharedPtr.hpp"
+#include "XdmfVisitor.hpp"
+#include "string.h"
+
+shared_ptr<XdmfHeavyDataDescription>
+XdmfHeavyDataDescription::New()
+{
+  shared_ptr<XdmfHeavyDataDescription> p(new XdmfHeavyDataDescription());
+  return p;
+}
+
+XdmfHeavyDataDescription::XdmfHeavyDataDescription()
+{
+}
+
+XdmfHeavyDataDescription::XdmfHeavyDataDescription(XdmfHeavyDataDescription & refDescription) :
+  XdmfItem(refDescription)
+{
+}
+
+XdmfHeavyDataDescription::~XdmfHeavyDataDescription()
+{
+}
+
+const std::string XdmfHeavyDataDescription::ItemTag = "HeavyData";
+
+std::map<std::string, std::string>
+XdmfHeavyDataDescription::getItemProperties() const
+{
+  std::map<std::string, std::string> descriptionProperties;
+  return descriptionProperties;
+}
+
+std::string
+XdmfHeavyDataDescription::getItemTag() const
+{
+  return ItemTag;
+}
+
+void
+XdmfHeavyDataDescription::populateItem(const std::map<std::string, std::string> & itemProperties,
+                              const std::vector<shared_ptr<XdmfItem> > & childItems,
+                              const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+}
+
+void
+XdmfHeavyDataDescription::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+
+}
+
+XDMFHEAVYDATADESCRIPTION *
+XdmfHeavyDataDescriptionNew(char * key, char * value)
+{
+  std::string createKey(key);
+  std::string createValue(value);
+  shared_ptr<XdmfHeavyDataDescription> generatedDesc = XdmfHeavyDataDescription::New();
+  return (XDMFHEAVYDATADESCRIPTION *)((void *)(new XdmfHeavyDataDescription(*generatedDesc.get())));
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfHeavyDataDescription, XDMFHEAVYDATADESCRIPTION)
diff --git a/core/XdmfHeavyDataDescription.hpp b/core/XdmfHeavyDataDescription.hpp
new file mode 100644
index 0000000..0c46456
--- /dev/null
+++ b/core/XdmfHeavyDataDescription.hpp
@@ -0,0 +1,104 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHeavyDataDescription.hpp                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+#ifndef XDMFHEAVYDATADESCRIPTION_HPP_
+#define XDMFHEAVYDATADESCRIPTION_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Holds information about a dsm buffer so that a process can connect.
+ *
+ * XdmfDescription stores the information required to process
+ * to a data format
+ */
+class XDMFCORE_EXPORT XdmfHeavyDataDescription : public XdmfItem {
+
+public:
+
+  /**
+   * 
+   */
+  static shared_ptr<XdmfHeavyDataDescription> New();
+
+  virtual ~XdmfHeavyDataDescription();
+
+  LOKI_DEFINE_VISITABLE(XdmfHeavyDataDescription, XdmfItem)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  std::string getPortDescription() const;
+
+  using XdmfItem::insert;
+
+  void setPortDescription(std::string portDesc);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfHeavyDataDescription(XdmfHeavyDataDescription &);
+
+protected:
+
+  XdmfHeavyDataDescription();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfHeavyDataDescription(const XdmfHeavyDataDescription &);  // Not implemented.
+  void operator=(const XdmfHeavyDataDescription &);  // Not implemented.
+
+  std::string mPortDescription;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFHEAVYDATADESCRIPTION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHEAVYDATADESCRIPTION XDMFHEAVYDATADESCRIPTION;
+
+XDMFCORE_EXPORT XDMFHEAVYDATADESCRIPTION * XdmfHeavyDataDescriptionNew();
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfHeavyDataDescription, XDMFHEAVYDATADESCRIPTION, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHeavyDataDESCRIPTION_HPP_ */
diff --git a/core/XdmfHeavyDataWriter.cpp b/core/XdmfHeavyDataWriter.cpp
new file mode 100644
index 0000000..09e08a8
--- /dev/null
+++ b/core/XdmfHeavyDataWriter.cpp
@@ -0,0 +1,254 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHeavyDataWriter.cpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfSystemUtils.hpp"
+#include <cstdio>
+#include <list>
+#include <vector>
+#include "string.h"
+
+XdmfHeavyDataWriter::XdmfHeavyDataWriter(const double compression,
+                                         const unsigned int overhead) :
+  mAllowSplitDataSets(false),
+  mDataSetId(0),
+  mFileIndex(0),
+  mFilePath(""),
+  mFileSizeLimit(0),
+  mMode(Default),
+  mCompressionRatio(compression),
+  mFileOverhead(overhead)
+{
+}
+
+XdmfHeavyDataWriter::XdmfHeavyDataWriter(const std::string & filePath,
+                                         const double compression,
+                                         const unsigned int overhead) :
+  mAllowSplitDataSets(false),
+  mDataSetId(0),
+  mFileIndex(0),
+  mFilePath(XdmfSystemUtils::getRealPath(filePath)),
+  mFileSizeLimit(0),
+  mMode(Default),
+  mReleaseData(false),
+  mCompressionRatio(compression),
+  mFileOverhead(overhead)
+{
+}
+
+XdmfHeavyDataWriter::~XdmfHeavyDataWriter()
+{
+}
+
+int
+XdmfHeavyDataWriter::getAllowSetSplitting()
+{
+  return mAllowSplitDataSets;
+}
+
+int
+XdmfHeavyDataWriter::getFileIndex()
+{
+  return mFileIndex;
+}
+
+unsigned int
+XdmfHeavyDataWriter::getFileOverhead()
+{
+  return mFileOverhead;
+}
+
+std::string
+XdmfHeavyDataWriter::getFilePath() const
+{
+  if (mFilePath.c_str() == NULL) {
+    return "";
+  }
+  else {
+    return mFilePath;
+  }
+}
+
+int
+XdmfHeavyDataWriter::getFileSizeLimit()
+{
+  return mFileSizeLimit;
+}
+
+XdmfHeavyDataWriter::Mode
+XdmfHeavyDataWriter::getMode() const
+{
+  return mMode;
+}
+
+bool 
+XdmfHeavyDataWriter::getReleaseData() const
+{
+  return mReleaseData;
+}
+
+void
+XdmfHeavyDataWriter::setAllowSetSplitting(bool newAllow)
+{
+  mAllowSplitDataSets = newAllow;
+}
+
+void
+XdmfHeavyDataWriter::setFileIndex(int newSize)
+{
+  mFileIndex = newSize;
+}
+
+void
+XdmfHeavyDataWriter::setFileSizeLimit(int newSize)
+{
+  mFileSizeLimit = newSize;
+}
+
+void
+XdmfHeavyDataWriter::setMode(const Mode mode)
+{
+  mMode = mode;
+}
+
+void
+XdmfHeavyDataWriter::setReleaseData(const bool releaseData)
+{
+  mReleaseData = releaseData;
+}
+
+// C Wrappers
+
+void XdmfHeavyDataWriterFree(XDMFHEAVYDATAWRITER * item)
+{
+  if (item != NULL) {
+    delete ((XdmfHeavyDataWriter *)item);
+    item = NULL;
+  }
+}
+
+int XdmfHeavyDataWriterGetAllowSetSplitting(XDMFHEAVYDATAWRITER * writer)
+{
+  return ((XdmfHeavyDataWriter *)writer)->getAllowSetSplitting();
+}
+
+int XdmfHeavyDataWriterGetFileIndex(XDMFHEAVYDATAWRITER * writer)
+{
+  return ((XdmfHeavyDataWriter *)writer)->getFileIndex();
+}
+
+unsigned int XdmfHeavyDataWriterGetFileOverhead(XDMFHEAVYDATAWRITER * writer)
+{
+  return ((XdmfHeavyDataWriter *)writer)->getFileOverhead();
+}
+
+char * XdmfHeavyDataWriterGetFilePath(XDMFHEAVYDATAWRITER * writer)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfHeavyDataWriter *)writer)->getFilePath().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfHeavyDataWriter *)writer)->getFilePath().c_str());
+    return returnPointer;
+  }
+}
+
+int XdmfHeavyDataWriterGetFileSizeLimit(XDMFHEAVYDATAWRITER * writer)
+{
+  return ((XdmfHeavyDataWriter *)writer)->getFileSizeLimit();
+}
+
+int XdmfHeavyDataWriterGetMode(XDMFHEAVYDATAWRITER * writer)
+{
+  XdmfHeavyDataWriter::Mode checkMode = ((XdmfHeavyDataWriter *)writer)->getMode();
+  if (checkMode == XdmfHeavyDataWriter::Default) {
+    return XDMF_HEAVY_WRITER_MODE_DEFAULT;
+  }
+  else if (checkMode == XdmfHeavyDataWriter::Overwrite) {
+    return XDMF_HEAVY_WRITER_MODE_OVERWRITE;
+  }
+  else if (checkMode == XdmfHeavyDataWriter::Append) {
+    return XDMF_HEAVY_WRITER_MODE_APPEND;
+  }
+  else if (checkMode == XdmfHeavyDataWriter::Hyperslab) {
+    return XDMF_HEAVY_WRITER_MODE_HYPERSLAB;
+  }
+  return -1;
+}
+
+int XdmfHeavyDataWriterGetReleaseData(XDMFHEAVYDATAWRITER * writer)
+{
+  return ((XdmfHeavyDataWriter *)writer)->getReleaseData();
+}
+
+void XdmfHeavyDataWriterSetAllowSetSplitting(XDMFHEAVYDATAWRITER * writer, int newAllow)
+{
+  ((XdmfHeavyDataWriter *)writer)->setAllowSetSplitting(newAllow);
+}
+
+void XdmfHeavyDataWriterSetFileIndex(XDMFHEAVYDATAWRITER * writer, int newIndex)
+{
+  ((XdmfHeavyDataWriter *)writer)->setFileIndex(newIndex);
+}
+
+void XdmfHeavyDataWriterSetFileSizeLimit(XDMFHEAVYDATAWRITER * writer, int newSize)
+{
+  ((XdmfHeavyDataWriter *)writer)->setFileSizeLimit(newSize);
+}
+
+void XdmfHeavyDataWriterSetMode(XDMFHEAVYDATAWRITER * writer, int mode, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfHeavyDataWriter::Mode newMode;
+  switch (mode) {
+    case XDMF_HEAVY_WRITER_MODE_DEFAULT:
+      newMode = XdmfHeavyDataWriter::Default;
+      break;
+    case XDMF_HEAVY_WRITER_MODE_OVERWRITE:
+      newMode = XdmfHeavyDataWriter::Overwrite;
+      break;
+    case XDMF_HEAVY_WRITER_MODE_APPEND:
+      newMode = XdmfHeavyDataWriter::Append;
+      break;
+    case XDMF_HEAVY_WRITER_MODE_HYPERSLAB:
+      newMode = XdmfHeavyDataWriter::Hyperslab;
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid heavy writer mode.");
+  }
+  ((XdmfHeavyDataWriter *)writer)->setMode(newMode);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHeavyDataWriterSetReleaseData(XDMFHEAVYDATAWRITER * writer, int releaseData)
+{
+  ((XdmfHeavyDataWriter *)writer)->setReleaseData(releaseData);
+}
diff --git a/core/XdmfHeavyDataWriter.hpp b/core/XdmfHeavyDataWriter.hpp
new file mode 100644
index 0000000..389ebd1
--- /dev/null
+++ b/core/XdmfHeavyDataWriter.hpp
@@ -0,0 +1,640 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHeavyDataWriter.hpp                                             */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFHEAVYDATAWRITER_HPP_
+#define XDMFHEAVYDATAWRITER_HPP_
+
+#include "XdmfCore.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHeavyDataController.hpp"
+#include "XdmfVisitor.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+// Includes
+#include <string>
+#include <list>
+
+/**
+ * @brief Traverses the Xdmf graph and writes heavy data stored in
+ * XdmfArrays to heavy data files on disk.
+ *
+ * This is an abstract base class to support the writing of different
+ * heavy data formats.
+ *
+ * XdmfHeavyDataWriter traverses an Xdmf graph structure and writes
+ * data stored in XdmfArrays to heavy data files on disk. Writing
+ * begins by calling the accept() operation on any XdmfItem and
+ * supplying this writer as the parameter. The writer will write all
+ * XdmfArrays under the XdmfItem to a heavy data file on disk. It will
+ * also attach an XdmfHeavyDataController to all XdmfArrays that it
+ * writes to disk.
+ *
+ * There are three modes of operation for this writer:
+ *   Default - All initialized XdmfArrays are written to new heavy datasets
+ *             regardless of whether they are attached to another heavy
+ *             dataset on disk via an XdmfHeavyDataController.
+ *   Overwrite - If an initialized XdmfArray is attached to an heavy dataset
+ *               via an XdmfHeavyDataController the writer will write values
+ *               to that location, overwriting all previous written values.
+ *               The dataset on disk will be resized appropriately.
+ *   Append - If an initialized XdmfArray is attached to an heavy dataset via
+ *            an XdmfHeavyDataController the writer will append the values to
+ *            the end of the dataset on disk.
+ *   Hyperslab - If an initialized XdmfArray is attached to a heavy dataset
+ *               via an XdmfHeavyDataController the writer will write to a
+ *               hyperslab in the dataset based on the start, stride, and
+ *               dimensions of the XdmfHeavyDataController.
+ */
+class XDMFCORE_EXPORT XdmfHeavyDataWriter : public XdmfVisitor,
+                                            public Loki::Visitor<XdmfArray> {
+
+public:
+
+  enum Mode {
+    Default,
+    Overwrite,
+    Append,
+    Hyperslab
+  };
+
+  virtual ~XdmfHeavyDataWriter() = 0;
+
+  /**
+   * Close file. This is only needed when the file is opened manually
+   * through openFile().
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#closeFile
+   * @until //#closeFile
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//closeFile
+   * @until #//closeFile
+   */
+  virtual void closeFile() = 0;
+
+  /**
+   * Gets whether the HDF5 Writer is allowed to split data sets when writing to hdf5.
+   * Splitting should only occur for massive data sets.
+   * Setting to false assures compatibility with previous editions.
+   * Default setting is false.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getAllowSetSplitting
+   * @until //#getAllowSetSplitting
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getAllowSetSplitting
+   * @until #//getAllowSetSplitting
+   *
+   * @return    Whether to allow data sets to be split across hdf5 files
+   */
+  int getAllowSetSplitting();
+
+  /**
+   * Gets the file index. Used when file splitting and incremented whent he current file is full.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getFileIndex
+   * @until //#getFileIndex
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getFileIndex
+   * @until #//getFileIndex
+   *
+   * @return    The current file index.
+   */
+  int getFileIndex();
+
+  /**
+   * Gets the amount of bytes that the heavy data writer uses as overhead for the data type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getFileOverhead
+   * @until //#getFileOverhead
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getFileOverhead
+   * @until #//getFileOverhead
+   *
+   * @return    Amount of bytes used as overhead
+   */
+  unsigned int getFileOverhead();
+
+  /**
+   * Get the path to the heavy data file on disk this writer is writing to.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getFilePath
+   * @until //#getFilePath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getFilePath
+   * @until #//getFilePath
+   *
+   * @return    A std::string containing the path to the heavy file on disk this
+   *            writer is writing to.
+   */
+  std::string getFilePath() const;
+
+  /**
+   * Gets the file size limit of the HDF5 files produced by the writer in MB. Overflow is pushed to a new HDF5 file.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getFileSizeLimit
+   * @until //#getFileSizeLimit
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getFileSizeLimit
+   * @until #//getFileSizeLimit
+   *
+   * @return    The size limit in MB
+   */
+  int getFileSizeLimit();
+
+  /**
+   * Get the Mode of operation for this writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getMode
+   * @until //#getMode
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getMode
+   * @until #//getMode
+   *
+   * @return    The Mode of operation for this writer.
+   */
+  Mode getMode() const;
+
+  /**
+   * Get whether to release data from memory after writing to disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getReleaseData
+   * @until //#getReleaseData
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getReleaseData
+   * @until #//getReleaseData
+   *
+   * @return    True if data is freed after writing
+   */
+  bool getReleaseData() const;
+
+  /**
+   * Open file for writing. This is an optional command that can
+   * improve performance for some writers when writing many datasets
+   * to a single file. User must call closeFile() after completing
+   * output.
+   *
+   * By default, heavy data files are open and closed before and after
+   * writing each dataset to ensure that other writers have access to
+   * the file (we never know whether we will be writing to the file
+   * again). This is expensive in some cases, but is always
+   * safe. Opening the file once and writing many datasets may result
+   * in improved performance, but the user must tell the writer when
+   * to open and close the file.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#openFile
+   * @until //#openFile
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//openFile
+   * @until #//openFile
+   */
+  virtual void openFile() = 0;
+
+  /**
+   * Sets whether to allow the HDF5 writer to split data sets when writing to hdf5.
+   * Splitting should only occur for massive data sets.
+   * Setting to false assures compatibility with previous editions.
+   * Default setting is false
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setAllowSetSplitting
+   * @until //#setAllowSetSplitting
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setAllowSetSplitting
+   * @until #//setAllowSetSplitting
+   *
+   * @param     newAllow        Whether to allow data sets to be split across hdf5 files
+   */
+  void setAllowSetSplitting(bool newAllow);
+
+  /**
+   * Sets the file index. Used when file splitting and incremented when the current file is full. Set to 0 before using hyperslab or overwrite.
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getFileIndex
+   * @until //#getFileIndex
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getFileIndex
+   * @until #//getFileIndex
+   *
+   * @param     newIndex        The index that the writer will append to the file name when incorperating file splitting
+   */
+  void setFileIndex(int newIndex);
+
+  /**
+   * Sets the file size limit of the HDF5 files produced by the writer in MB. Overflow is pushed to a new HDF5 file.
+   * Using with arrays of string type may reduce performance.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setFileSizeLimit
+   * @until //#setFileSizeLimit
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setFileSizeLimit
+   * @until #//setFileSizeLimit
+   *
+   * @param     newSize         The size limit in MB
+   */
+  void setFileSizeLimit(int newSize);
+
+  /**
+   * Set the mode of operation for this writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setMode
+   * @until //#setMode
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setMode
+   * @until #//setMode
+   *
+   * @param     mode    The Mode of operation for this writer.
+   */
+  void setMode(const Mode mode);
+
+  /**
+   * Set whether to release data from memory after writing to disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setReleaseData
+   * @until //#setReleaseData
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setReleaseData
+   * @until #//setReleaseData
+   *
+   * @param     releaseData     True if data should be freed after writing
+   */
+  void setReleaseData(const bool releaseData = true);
+
+  /**
+   * Write an XdmfArray to heavy data file on disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfHeavyDataWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#visit
+   * @until //#visit
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleHeavyDataWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//visit
+   * @until #//visit
+   *
+   * @param     array           An XdmfArray to write to heavy data.
+   * @param     visitor         A smart pointer to this visitor --- aids in grid traversal.
+   */
+  using XdmfVisitor::visit;
+  virtual void visit(XdmfArray & array,
+                     const shared_ptr<XdmfBaseVisitor> visitor) = 0;
+
+protected:
+
+  XdmfHeavyDataWriter(const double compression = 1, const unsigned int overhead = 0);
+  XdmfHeavyDataWriter(const std::string & filePath, const double compression = 1, const unsigned int overhead = 0);
+
+  virtual shared_ptr<XdmfHeavyDataController>
+  createController(const std::string & filePath,
+                   const std::string & descriptor,
+                   const shared_ptr<const XdmfArrayType> type,
+                   const std::vector<unsigned int> & start,
+                   const std::vector<unsigned int> & stride,
+                   const std::vector<unsigned int> & dimensions,
+                   const std::vector<unsigned int> & dataspaceDimensions) = 0;
+
+  virtual int getDataSetSize(shared_ptr<XdmfHeavyDataController> descriptionController) = 0;
+
+  bool mAllowSplitDataSets;
+  int mDataSetId;
+  int mFileIndex;
+  std::string mFilePath;
+  unsigned int mFileSizeLimit;
+  Mode mMode;
+  bool mReleaseData;
+  double  mCompressionRatio;
+  unsigned int mFileOverhead;
+
+private:
+
+  XdmfHeavyDataWriter(const XdmfHeavyDataWriter &); // Not implemented.
+  void operator=(const XdmfHeavyDataWriter &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XDMFHEAVYDATAWRITER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHEAVYDATAWRITER XDMFHEAVYDATAWRITER;
+
+#define XDMF_HEAVY_WRITER_MODE_DEFAULT   20
+#define XDMF_HEAVY_WRITER_MODE_OVERWRITE 21
+#define XDMF_HEAVY_WRITER_MODE_APPEND    22
+#define XDMF_HEAVY_WRITER_MODE_HYPERSLAB 23
+
+// C wrappers go here
+
+XDMFCORE_EXPORT void XdmfHeavyDataWriterFree(XDMFHEAVYDATAWRITER * item);
+
+XDMFCORE_EXPORT int XdmfHeavyDataWriterGetAllowSetSplitting(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT int XdmfHeavyDataWriterGetFileIndex(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT unsigned int XdmfHeavyDataWriterGetFileOverhead(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT char * XdmfHeavyDataWriterGetFilePath(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT int XdmfHeavyDataWriterGetFileSizeLimit(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT int XdmfHeavyDataWriterGetMode(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT int XdmfHeavyDataWriterGetReleaseData(XDMFHEAVYDATAWRITER * writer);
+
+XDMFCORE_EXPORT void XdmfHeavyDataWriterSetAllowSetSplitting(XDMFHEAVYDATAWRITER * writer, int newAllow);
+
+XDMFCORE_EXPORT void XdmfHeavyDataWriterSetFileIndex(XDMFHEAVYDATAWRITER * writer, int newIndex);
+
+XDMFCORE_EXPORT void XdmfHeavyDataWriterSetFileSizeLimit(XDMFHEAVYDATAWRITER * writer, int newSize);
+
+XDMFCORE_EXPORT void XdmfHeavyDataWriterSetMode(XDMFHEAVYDATAWRITER * writer, int mode, int * status);
+
+XDMFCORE_EXPORT void XdmfHeavyDataWriterSetReleaseData(XDMFHEAVYDATAWRITER * writer, int releaseData);
+
+#define XDMF_HEAVYWRITER_C_CHILD_DECLARE(ClassName, CClassName, Level)                        \
+                                                                                              \
+Level##_EXPORT void ClassName##Free( CClassName * item);                                      \
+Level##_EXPORT int ClassName##GetAllowSetSplitting( CClassName * writer);                     \
+Level##_EXPORT int ClassName##GetFileIndex( CClassName * writer);                             \
+Level##_EXPORT unsigned int ClassName##GetFileOverhead( CClassName * writer);                 \
+Level##_EXPORT char * ClassName##GetFilePath( CClassName * writer);                           \
+Level##_EXPORT int ClassName##GetFileSizeLimit( CClassName * writer);                         \
+Level##_EXPORT int ClassName##GetMode( CClassName * writer);                                  \
+Level##_EXPORT int ClassName##GetReleaseData( CClassName * writer);                           \
+Level##_EXPORT void ClassName##SetAllowSetSplitting( CClassName * writer, int newAllow);      \
+Level##_EXPORT void ClassName##SetFileIndex( CClassName * writer, int newIndex);              \
+Level##_EXPORT void ClassName##SetFileSizeLimit( CClassName * writer, int newSize);           \
+Level##_EXPORT void ClassName##SetMode( CClassName * writer, int mode, int * status);         \
+Level##_EXPORT void ClassName##SetReleaseData( CClassName * writer, int releaseData);
+
+
+
+#define XDMF_HEAVYWRITER_C_CHILD_WRAPPER(ClassName, CClassName)                               \
+                                                                                              \
+void  ClassName##Free( CClassName * item)                                                     \
+{                                                                                             \
+  XdmfHeavyDataWriterFree((XDMFHEAVYDATAWRITER *)((void *)item));                             \
+}                                                                                             \
+                                                                                              \
+int ClassName##GetAllowSetSplitting( CClassName * writer)                                     \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetAllowSetSplitting((XDMFHEAVYDATAWRITER *)((void *)writer));    \
+}                                                                                             \
+                                                                                              \
+int ClassName##GetFileIndex( CClassName * writer)                                             \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetFileIndex((XDMFHEAVYDATAWRITER *)((void *)writer));            \
+}                                                                                             \
+                                                                                              \
+unsigned int ClassName##GetFileOverhead( CClassName * writer)                                 \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetFileOverhead((XDMFHEAVYDATAWRITER *)((void *)writer));         \
+}                                                                                             \
+                                                                                              \
+char * ClassName##GetFilePath( CClassName * writer)                                           \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetFilePath((XDMFHEAVYDATAWRITER *)((void *)writer));             \
+}                                                                                             \
+                                                                                              \
+int ClassName##GetFileSizeLimit( CClassName * writer)                                         \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetFileSizeLimit((XDMFHEAVYDATAWRITER *)((void *)writer));        \
+}                                                                                             \
+                                                                                              \
+int ClassName##GetMode( CClassName * writer)                                                  \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetMode((XDMFHEAVYDATAWRITER *)((void *)writer));                 \
+}                                                                                             \
+                                                                                              \
+int ClassName##GetReleaseData( CClassName * writer)                                           \
+{                                                                                             \
+  return XdmfHeavyDataWriterGetReleaseData((XDMFHEAVYDATAWRITER *)((void *)writer));          \
+}                                                                                             \
+                                                                                              \
+void ClassName##SetAllowSetSplitting( CClassName * writer, int newAllow)                      \
+{                                                                                             \
+  XdmfHeavyDataWriterSetAllowSetSplitting((XDMFHEAVYDATAWRITER *)((void *)writer), newAllow); \
+}                                                                                             \
+                                                                                              \
+void ClassName##SetFileIndex( CClassName * writer, int newIndex)                              \
+{                                                                                             \
+  XdmfHeavyDataWriterSetFileIndex((XDMFHEAVYDATAWRITER *)((void *)writer), newIndex);         \
+}                                                                                             \
+                                                                                              \
+void ClassName##SetFileSizeLimit( CClassName * writer, int newSize)                           \
+{                                                                                             \
+  XdmfHeavyDataWriterSetFileSizeLimit((XDMFHEAVYDATAWRITER *)((void *)writer), newSize);      \
+}                                                                                             \
+                                                                                              \
+void ClassName##SetMode( CClassName * writer, int mode, int * status)                         \
+{                                                                                             \
+  XdmfHeavyDataWriterSetMode((XDMFHEAVYDATAWRITER *)((void *)writer), mode, status);          \
+}                                                                                             \
+                                                                                              \
+void ClassName##SetReleaseData( CClassName * writer, int releaseData)                         \
+{                                                                                             \
+  XdmfHeavyDataWriterSetReleaseData((XDMFHEAVYDATAWRITER *)((void *)writer), releaseData);    \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHEAVYDATAWRITER_HPP_ */
diff --git a/core/XdmfInformation.cpp b/core/XdmfInformation.cpp
new file mode 100644
index 0000000..050ac5f
--- /dev/null
+++ b/core/XdmfInformation.cpp
@@ -0,0 +1,277 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfInformation.cpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <utility>
+#include "string.h"
+#include "XdmfArray.hpp"
+#include "XdmfError.hpp"
+#include "XdmfInformation.hpp"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfInformation, XdmfArray, Array, Name)
+
+shared_ptr<XdmfInformation>
+XdmfInformation::New()
+{
+  shared_ptr<XdmfInformation> p(new XdmfInformation());
+  return p;
+}
+
+shared_ptr<XdmfInformation>
+XdmfInformation::New(const std::string & key,
+                     const std::string & value)
+{
+  shared_ptr<XdmfInformation> p(new XdmfInformation(key, value));
+  return p;
+}
+
+XdmfInformation::XdmfInformation(const std::string & key,
+                                 const std::string & value) :
+  mKey(key),
+  mValue(value)
+{
+}
+
+XdmfInformation::XdmfInformation(XdmfInformation & refInfo) :
+  XdmfItem(refInfo),
+  mArrays(refInfo.mArrays)
+{
+  mKey = refInfo.getKey();
+  mValue = refInfo.getValue();
+}
+
+XdmfInformation::~XdmfInformation()
+{
+}
+
+const std::string XdmfInformation::ItemTag = "Information";
+
+std::map<std::string, std::string>
+XdmfInformation::getItemProperties() const
+{
+  std::map<std::string, std::string> informationProperties;
+  informationProperties.insert(std::make_pair("Name", mKey));
+  informationProperties.insert(std::make_pair("Value", mValue));
+  return informationProperties;
+}
+
+std::string
+XdmfInformation::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfInformation::getKey() const
+{
+  return mKey;
+}
+
+std::string
+XdmfInformation::getValue() const
+{
+  return mValue;
+}
+
+void
+XdmfInformation::populateItem(const std::map<std::string, std::string> & itemProperties,
+                              const std::vector<shared_ptr<XdmfItem> > & childItems,
+                              const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+
+  std::map<std::string, std::string>::const_iterator key =
+    itemProperties.find("Name");
+  if(key != itemProperties.end()) {
+    mKey = key->second;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "'Name' not found in itemProperties in "
+                       "XdmfInformation::populateItem");
+  }
+
+  std::map<std::string, std::string>::const_iterator value =
+    itemProperties.find("Value");
+  if(value != itemProperties.end()) {
+    mValue = value->second;
+  }
+  else {
+    value = itemProperties.find("Content");
+    if(value != itemProperties.end()) {
+      mValue = value->second;
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "'Value' not found in itemProperties in "
+                         "XdmfInformation::populateItem");
+    }
+  }
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+      this->insert(array);
+    }
+  }
+}
+
+void
+XdmfInformation::setKey(const std::string & key)
+{
+  mKey = key;
+  this->setIsChanged(true);
+}
+
+void
+XdmfInformation::setValue(const std::string & value)
+{
+  mValue = value;
+  this->setIsChanged(true);
+}
+
+void
+XdmfInformation::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+  for (unsigned int i = 0; i < mArrays.size(); ++i)
+  {
+    mArrays[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+XDMFINFORMATION *
+XdmfInformationNew(char * key, char * value)
+{
+  try
+  {
+    std::string createKey(key);
+    std::string createValue(value);
+    shared_ptr<XdmfInformation> generatedInfo = XdmfInformation::New(createKey, createValue);
+    return (XDMFINFORMATION *)((void *)(new XdmfInformation(*generatedInfo.get())));
+  }
+  catch (...)
+  {
+    std::string createKey(key);
+    std::string createValue(value);
+    shared_ptr<XdmfInformation> generatedInfo = XdmfInformation::New(createKey, createValue);
+    return (XDMFINFORMATION *)((void *)(new XdmfInformation(*generatedInfo.get())));
+  }
+}
+
+XDMFARRAY *
+XdmfInformationGetArray(XDMFINFORMATION * information, unsigned int index)
+{
+  return (XDMFARRAY *)((void *)(((XdmfInformation *)(information))->getArray(index).get()));
+}
+
+XDMFARRAY *
+XdmfInformationGetArrayByName(XDMFINFORMATION * information, char * name)
+{
+  return (XDMFARRAY *)((void *)(((XdmfInformation *)(information))->getArray(name).get()));
+}
+
+char *
+XdmfInformationGetKey(XDMFINFORMATION * information)
+{
+  try
+  {
+    XdmfInformation referenceInfo = *(XdmfInformation *)(information);
+    char * returnPointer = strdup(referenceInfo.getKey().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    XdmfInformation referenceInfo = *(XdmfInformation *)(information);
+    char * returnPointer = strdup(referenceInfo.getKey().c_str());
+    return returnPointer;
+  }
+}
+
+unsigned int
+XdmfInformationGetNumberArrays(XDMFINFORMATION * information)
+{
+  return ((XdmfInformation *)(information))->getNumberArrays();
+}
+
+char *
+XdmfInformationGetValue(XDMFINFORMATION * information)
+{
+  try
+  {
+    XdmfInformation referenceInfo = *(XdmfInformation *)(information);
+    char * returnPointer = strdup(referenceInfo.getValue().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  { 
+    XdmfInformation referenceInfo = *(XdmfInformation *)(information);
+    char * returnPointer = strdup(referenceInfo.getValue().c_str());
+    return returnPointer;
+  }
+}
+
+void
+XdmfInformationInsertArray(XDMFINFORMATION * information, XDMFARRAY * array, int transferOwnership)
+{
+  if (transferOwnership) {
+    ((XdmfInformation *)(information))->insert(shared_ptr<XdmfArray>((XdmfArray *)array));
+  }
+  else {
+    ((XdmfInformation *)(information))->insert(shared_ptr<XdmfArray>((XdmfArray *)array, XdmfNullDeleter()));
+  }
+}
+
+void
+XdmfInformationRemoveArray(XDMFINFORMATION * information, unsigned int index)
+{
+  ((XdmfInformation *)(information))->removeArray(index);
+}
+
+void
+XdmfInformationRemoveArrayByName(XDMFINFORMATION * information, char * name)
+{
+  ((XdmfInformation *)(information))->removeArray(name);
+}
+
+void
+XdmfInformationSetKey(XDMFINFORMATION * information, char * key, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfInformation *)(information))->setKey(key);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfInformationSetValue(XDMFINFORMATION * information, char * value, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfInformation *)(information))->setValue(value);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfInformation, XDMFINFORMATION)
diff --git a/core/XdmfInformation.hpp b/core/XdmfInformation.hpp
new file mode 100644
index 0000000..ac50d96
--- /dev/null
+++ b/core/XdmfInformation.hpp
@@ -0,0 +1,275 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfInformation.hpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFINFORMATION_HPP_
+#define XDMFINFORMATION_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfArray.hpp"
+
+#ifdef __cplusplus
+
+// Forward declarations
+class XdmfArray;
+
+/**
+ * @brief Holds a key/value pair that can be attached to an Xdmf
+ * structure.
+ *
+ * XdmfInformation stores two strings as a key value pair. These can
+ * be used to store input parameters to a code or for simple result
+ * data like wall time.
+ */
+class XDMFCORE_EXPORT XdmfInformation : public XdmfItem {
+
+public:
+
+  /**
+   * Create a new XdmfInformation.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfInformation.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleInformation.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfInformation.
+   */
+  static shared_ptr<XdmfInformation> New();
+
+  /**
+   * Create a new XdmfInformation.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfInformation.cpp
+   * @skipline //#initializationfull
+   * @until //#initializationfull
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleInformation.py
+   * @skipline #//initializationfull
+   * @until #//initializationfull
+   *
+   * @param     key     A string containing the key of the XdmfInformation to create.
+   * @param     value   A string containing the value of the XdmfInformation to
+   * create.
+   *
+   * @return    Constructed XdmfInformation
+   */
+  static shared_ptr<XdmfInformation> New(const std::string & key,
+                                         const std::string & value);
+
+  virtual ~XdmfInformation();
+
+  LOKI_DEFINE_VISITABLE(XdmfInformation, XdmfItem)
+  XDMF_CHILDREN(XdmfInformation, XdmfArray, Array, Name)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  /**
+   * Get the key for this information item.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfInformation.cpp
+   * @skipline //#initializationfull
+   * @until //#initializationfull
+   * @skipline //#getKey
+   * @until //#getKey
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleInformation.py
+   * @skipline #//initializationfull
+   * @until #//initializationfull
+   * @skipline #//getKey
+   * @until #//getKey
+   *
+   * @return    A string containing the key.
+   */
+  std::string getKey() const;
+
+  /**
+   * Get the value for this information item.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfInformation.cpp
+   * @skipline //#initializationfull
+   * @until //#initializationfull
+   * @skipline //#getValue
+   * @until //#getValue
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleInformation.py
+   * @skipline #//initializationfull
+   * @until #//initializationfull
+   * @skipline #//getValue
+   * @until #//getValue
+   *
+   * @return    A string containing the value.
+   */
+  std::string getValue() const;
+
+  using XdmfItem::insert;
+
+  /**
+   * Set the key for this information item.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfInformation.cpp
+   * @skipline //#initializationfull
+   * @until //#initializationfull
+   * @skipline //#setKey
+   * @until //#setKey
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleInformation.py
+   * @skipline #//initializationfull
+   * @until #//initializationfull
+   * @skipline #//setKey
+   * @until #//setKey
+   *
+   * @param     key     A string containing the key to set.
+   */
+  void setKey(const std::string & key);
+
+  /**
+   * Set the value for this information item.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfInformation.cpp
+   * @skipline //#initializationfull
+   * @until //#initializationfull
+   * @skipline //#setValue
+   * @until //#setValue
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleInformation.py
+   * @skipline #//initializationfull
+   * @until #//initializationfull
+   * @skipline #//setValue
+   * @until #//setValue
+   *
+   * @param     value   A string containing the value to set.
+   */
+  void setValue(const std::string & value);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfInformation(XdmfInformation &);
+
+protected:
+
+  XdmfInformation(const std::string & key = "",
+                  const std::string & value = "");
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfInformation(const XdmfInformation &);
+  void operator=(const XdmfInformation &);  // Not implemented.
+
+  std::string mKey;
+  std::string mValue;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+#ifndef XDMFINFORMATIONCDEFINE
+#define XDMFINFORMATIONCDEFINE
+struct XDMFINFORMATION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFINFORMATION XDMFINFORMATION;
+#endif
+
+XDMFCORE_EXPORT XDMFINFORMATION * XdmfInformationNew(char * key, char * value);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfInformationGetArray(XDMFINFORMATION * information, unsigned int index);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfInformationGetArrayByName(XDMFINFORMATION * information, char * name);
+
+XDMFCORE_EXPORT char * XdmfInformationGetKey(XDMFINFORMATION * information);
+
+XDMFCORE_EXPORT unsigned int XdmfInformationGetNumberArrays(XDMFINFORMATION * information);
+
+XDMFCORE_EXPORT char * XdmfInformationGetValue(XDMFINFORMATION * information);
+
+XDMFCORE_EXPORT void XdmfInformationInsertArray(XDMFINFORMATION * information, XDMFARRAY * array, int transferOwnership);
+
+XDMFCORE_EXPORT void XdmfInformationRemoveArray(XDMFINFORMATION * information, unsigned int index);
+
+XDMFCORE_EXPORT void XdmfInformationRemoveArrayByName(XDMFINFORMATION * information, char * name);
+
+XDMFCORE_EXPORT void XdmfInformationSetKey(XDMFINFORMATION * information, char * key, int * status);
+
+XDMFCORE_EXPORT void XdmfInformationSetValue(XDMFINFORMATION * information, char * value, int * status);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfInformation, XDMFINFORMATION, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFINFORMATION_HPP_ */
diff --git a/core/XdmfItem.cpp b/core/XdmfItem.cpp
new file mode 100644
index 0000000..38c0dfd
--- /dev/null
+++ b/core/XdmfItem.cpp
@@ -0,0 +1,155 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfItem.cpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfInformation.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfVisitor.hpp"
+#include "XdmfError.hpp"
+#include "string.h"
+
+XDMF_CHILDREN_IMPLEMENTATION(XdmfItem, XdmfInformation, Information, Key)
+
+XdmfItem::XdmfItem() :
+  mIsChanged(true)
+{
+}
+
+XdmfItem::XdmfItem(XdmfItem &refItem) :
+  mInformations(refItem.mInformations),
+  mIsChanged(true)
+{
+}
+
+XdmfItem::~XdmfItem()
+{
+}
+
+bool
+XdmfItem::getIsChanged()
+{
+  return mIsChanged;
+}
+
+void
+XdmfItem::setIsChanged(bool status)
+{
+  // No change if status is the same
+  if (mIsChanged != status)
+  {
+    mIsChanged = status;
+    // If it was changed all parents should be alerted
+    if (status)
+    {
+      for (std::set<XdmfItem *>::iterator iter = mParents.begin();
+           iter != mParents.end();
+           ++iter)
+      {
+        (*iter)->setIsChanged(status);
+      }
+    }
+  }
+}
+
+void
+XdmfItem::populateItem(const std::map<std::string, std::string> &,
+                       const std::vector<shared_ptr<XdmfItem > > & childItems,
+                       const XdmfCoreReader * const)
+{
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfInformation> information = 
+       shared_dynamic_cast<XdmfInformation>(*iter)) {
+      this->insert(information);
+    }
+  }
+}
+
+void
+XdmfItem::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  for (unsigned int i = 0; i < mInformations.size(); ++i)
+  {
+    mInformations[i]->accept(visitor);
+  }
+}
+
+// C Wrappers
+
+void XdmfItemAccept(XDMFITEM * item, XDMFVISITOR * visitor, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfVisitor> visitPointer((XdmfVisitor *)visitor, XdmfNullDeleter());
+  ((XdmfItem *)(item))->accept(visitPointer);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfItemFree(void * item)
+{
+  if (item != NULL) {
+    delete ((XdmfItem *)item);
+    item = NULL;
+  }
+}
+
+XDMFINFORMATION * XdmfItemGetInformation(XDMFITEM * item, unsigned int index)
+{
+  return (XDMFINFORMATION *)((void *)(((XdmfItem *)(item))->getInformation(index).get()));
+}
+
+XDMFINFORMATION * XdmfItemGetInformationByKey(XDMFITEM * item, char * key)
+{
+  return (XDMFINFORMATION *)((void *)(((XdmfItem *)(item))->getInformation(key).get()));
+}
+
+unsigned int XdmfItemGetNumberInformations(XDMFITEM * item)
+{
+  return ((XdmfItem *)(item))->getNumberInformations();
+}
+
+void XdmfItemInsertInformation(XDMFITEM * item, XDMFINFORMATION * information, int passControl)
+{
+  if (passControl == 0) {
+    ((XdmfItem *)(item))->insert(shared_ptr<XdmfInformation>((XdmfInformation *)information, XdmfNullDeleter()));
+  }
+  else {
+    ((XdmfItem *)(item))->insert(shared_ptr<XdmfInformation>((XdmfInformation *)information));
+  }
+}
+
+void XdmfItemRemoveInformation(XDMFITEM * item, unsigned int index)
+{
+  ((XdmfItem *)(item))->removeInformation(index);
+}
+
+void XdmfItemRemoveInformationByKey(XDMFITEM * item, char * key)
+{
+  ((XdmfItem *)(item))->removeInformation(std::string(key));
+}
+
+char * XdmfItemGetItemTag(XDMFITEM * item)
+{
+  char * returnPointer = strdup(((XdmfItem *)(item))->getItemTag().c_str());
+  return returnPointer;
+}
diff --git a/core/XdmfItem.hpp b/core/XdmfItem.hpp
new file mode 100644
index 0000000..ebdb728
--- /dev/null
+++ b/core/XdmfItem.hpp
@@ -0,0 +1,515 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfItem.hpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFITEM_HPP_
+#define XDMFITEM_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfVisitor.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfCoreReader;
+class XdmfInformation;
+class XdmfVisitor;
+
+// Includes
+#include <loki/Visitor.h>
+#include <libxml/xmlexports.h>
+#include <libxml/tree.h>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+#include "XdmfSharedPtr.hpp"
+
+// Macro that allows children XdmfItems to be attached to a parent XdmfItem.
+// -- For Header File
+#define XDMF_CHILDREN(ParentClass, ChildClass, ChildName, SearchName)         \
+                                                                              \
+public:                                                                       \
+                                                                              \
+  /** Get a ChildClass attached to this item by index.<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      unsigned int getIndex = 0;<br>
+      shared_ptr<XdmfInformation> exampleChild = exampleItem->getInformation(getIndex);<br>
+      Python<br>
+      '''<br>
+      Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      '''<br>
+      getIndex = 0<br>
+      exampleChild = exampleItem.getInformation(getIndex)<br>
+      @return requested ChildClass. If no ChildClass##s exist at the index,
+      a NULL pointer is returned.
+  */                                                                          \
+  virtual shared_ptr<ChildClass>                                              \
+  get##ChildName(const unsigned int index);                                   \
+                                                                              \
+  /** Get a ChildClass attached to this item by index (const version).<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      unsigned int getIndex = 0;<br>
+      shared_ptr<const XdmfInformation> exampleChildConst = exampleItem->getInformation(getIndex);<br>
+      Python: does not support a constant version of this function
+      @param index of the ChildClass to retrieve.
+      @return requested ChildClass. If no ChildClass##s exist at the index, a
+      NULL pointer is returned.
+  */                                                                          \
+  virtual shared_ptr<const ChildClass>                                        \
+  get##ChildName(const unsigned int index) const;                             \
+                                                                              \
+  /** Get a ChildClass attached to this item by SearchName.<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      std::string findingInfo = "Find this";<br>
+      shared_ptr<XdmfInformation> exampleStringChild = exampleItem->getInformation(findingInfo);<br>
+      Python<br>
+      '''<br>
+      Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      '''<br>
+      findingInfo = "Find this"<br>
+      exampleStringChild = exampleItem.getInformation(findingInfo)<br>
+      @param SearchName of the ChildClass to retrieve.
+      @return requested ChildClass. If no ChildClass##s are found with the
+      correct SearchName, a NULL pointer is returned.
+  */                                                                          \
+  virtual shared_ptr<ChildClass>                                              \
+  get##ChildName(const std::string & SearchName);                             \
+                                                                              \
+  /** Get a ChildClass attached to this item by SearchName (const version).<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      std::string findingInfo = "Find this";<br>
+      shared_ptr<const XdmfInformation> exampleStringChildConst = exampleItem->getInformation(findingInfo);<br>
+      Python: does not support a constant version of this function
+      @param SearchName of the ChildClass to retrieve.
+      @return requested ChildClass  If no ChildClass##s are found with the
+      correct SearchName, a NULL pointer is returned.
+  */                                                                          \
+  virtual shared_ptr<const ChildClass>                                        \
+  get##ChildName(const std::string & SearchName) const;                       \
+                                                                              \
+  /** Get the number of ChildClass##s attached to this item.<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      unsigned int exampleSize = exampleItem->getNumberInformations();<br>
+      Python<br>
+      '''<br>
+      Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      '''<br>
+      exampleSize = exampleItem.getNumberInformations()<br>
+      @return number of ChildClass##s attached to this item.
+  */                                                                          \
+  virtual unsigned int getNumber##ChildName##s() const;                       \
+                                                                              \
+  /** Insert a ChildClass into to this item.<br>
+      Example of use:<br>
+      C++<br>
+      shared_ptr<XdmfInformation> exampleItem = XdmfInformation::New("Parent", "This is a parent information");<br>
+      shared_ptr<XdmfInformation> addChild = XdmfInformation::New("Child", "This is a child information");<br>
+      exampleItem->insert(addChild);<br>
+      Python<br>
+      exampleItem = XdmfInformation.New("Parent", "This is a parent information")<br>
+      addChild = XdmfInformation.New("Child", "This is a child information")<br>
+      exampleItem.insert(addChild)<br>
+      @param ChildName to attach to this item.
+  */                                                                          \
+  virtual void insert(const shared_ptr<ChildClass> ChildName);                \
+                                                                              \
+  /** Remove a ChildClass from this item by index. If no object exists
+      at the index, nothing is removed.<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      unsigned int removeIndex = 0;<br>
+      exampleItem->removeInformation(removeIndex);<br>
+      Python<br>
+      '''<br>
+      Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      '''<br>
+      removeIndex = 0<br>
+      exampleItem.removeInformation(removeIndex)
+      @param index of the ChildClass to remove.
+  */                                                                          \
+  virtual void remove##ChildName(const unsigned int index);                   \
+                                                                              \
+  /** Remove a ChildClass from this item by SearchName. If no ChildClass##s
+      have the correct SearchName, nothing is removed.<br>
+      Example of use:<br>
+      C++<br>
+      //Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      std::string removeInfo = "Remove this";<br>
+      exampleItem->removeInformation(removeInfo);<br>
+      Python<br>
+      '''<br>
+      Assume that exampleItem is a shared pointer to the ParentClass object<br>
+      Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class<br>
+      '''<br>
+      removeInfo = "Remove this"<br>
+      exampleItem.removeInformation(removeInfo)<br>
+      @param SearchName of the ChildClass to remove.
+  */                                                                          \
+  virtual void remove##ChildName(const std::string & SearchName);             \
+                                                                              \
+protected :                                                                   \
+                                                                              \
+  std::vector<shared_ptr<ChildClass> > m##ChildName##s;                       \
+                                                                              \
+public :
+
+// Macro that allows children XdmfItems to be attached to a parent XdmfItem.
+// -- For Implementation File
+#define XDMF_CHILDREN_IMPLEMENTATION(ParentClass,                             \
+                                     ChildClass,                              \
+                                     ChildName,                               \
+                                     SearchName)                              \
+                                                                              \
+  shared_ptr<ChildClass>                                                      \
+  ParentClass::get##ChildName(const unsigned int index)                       \
+  {                                                                           \
+    return boost::const_pointer_cast<ChildClass>                              \
+      (static_cast<const ParentClass &>(*this).get##ChildName(index));        \
+  }                                                                           \
+                                                                              \
+  shared_ptr<const ChildClass>                                                \
+  ParentClass::get##ChildName(const unsigned int index) const                 \
+  {                                                                           \
+    if(index < m##ChildName##s.size()) {                                      \
+      return m##ChildName##s[index];                                          \
+    }                                                                         \
+    return shared_ptr<ChildClass>();                                          \
+  }                                                                           \
+                                                                              \
+  shared_ptr<ChildClass>                                                      \
+  ParentClass::get##ChildName(const std::string & SearchName)                 \
+  {                                                                           \
+    return boost::const_pointer_cast<ChildClass>                              \
+      (static_cast<const ParentClass &>(*this).get##ChildName(SearchName));   \
+  }                                                                           \
+                                                                              \
+  shared_ptr<const ChildClass>                                                \
+  ParentClass::get##ChildName(const std::string & SearchName) const           \
+  {                                                                           \
+    for(std::vector<shared_ptr<ChildClass> >::const_iterator iter =           \
+          m##ChildName##s.begin();                                            \
+        iter != m##ChildName##s.end();                                        \
+        ++iter) {                                                             \
+      if((*iter)->get##SearchName().compare(SearchName) == 0) {               \
+        return *iter;                                                         \
+      }                                                                       \
+    }                                                                         \
+    return shared_ptr<ChildClass>();                                          \
+  }                                                                           \
+                                                                              \
+  unsigned int                                                                \
+  ParentClass::getNumber##ChildName##s() const                                \
+  {                                                                           \
+    return m##ChildName##s.size();                                            \
+  }                                                                           \
+                                                                              \
+  void                                                                        \
+  ParentClass::insert(const shared_ptr<ChildClass> ChildName)                 \
+  {                                                                           \
+    m##ChildName##s.push_back(ChildName);                                     \
+    this->setIsChanged(true);                                                 \
+  }                                                                           \
+                                                                              \
+  void                                                                        \
+  ParentClass::remove##ChildName(const unsigned int index)                    \
+  {                                                                           \
+    if(index < m##ChildName##s.size()) {                                      \
+      m##ChildName##s.erase(m##ChildName##s.begin() + index);                 \
+    }                                                                         \
+    this->setIsChanged(true);                                                 \
+  }                                                                           \
+                                                                              \
+  void                                                                        \
+  ParentClass::remove##ChildName(const std::string & SearchName)              \
+  {                                                                           \
+    for(std::vector<shared_ptr<ChildClass> >::iterator iter =                 \
+          m##ChildName##s.begin();                                            \
+        iter != m##ChildName##s.end();                                        \
+        ++iter) {                                                             \
+        if((*iter)->get##SearchName().compare(SearchName) == 0) {             \
+          m##ChildName##s.erase(iter);                                        \
+          return;                                                             \
+        }                                                                     \
+    }                                                                         \
+    this->setIsChanged(true);                                                 \
+  }
+
+/**
+ * @brief Base class of any object that is able to be added to an Xdmf
+ * structure.
+ *
+ * XdmfItem is an abstract base class. An XdmfItem is a structure that
+ * can be visited and traversed by an XdmfVisitor and have its
+ * contents written to an Xdmf file.
+ */
+class XDMFCORE_EXPORT XdmfItem : public Loki::BaseVisitable<void> {
+
+public:
+
+  virtual ~XdmfItem() = 0;
+
+  LOKI_DEFINE_VISITABLE_BASE()
+  XDMF_CHILDREN(XdmfItem, XdmfInformation, Information, Key)
+  friend class XdmfCoreReader;
+  friend class XdmfWriter;
+  friend class XdmfHeavyDataWriter;
+  friend class XdmfHDF5Writer;
+
+  /**
+   * Get the tag for this item.  This is equivalent to tags in XML
+   * parlance.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfItem.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getItemTag
+   * @until //#getItemTag
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleItem.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getItemTag
+   * @until #//getItemTag
+   *
+   * @return    The tag for this XdmfItem.
+   */
+  virtual std::string getItemTag() const = 0;
+
+  /**
+   * Get the key/value property pairs for this item. These are
+   * equivalent to attributes in XML parlance.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfItem.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getItemProperties
+   * @until //#getItemProperties
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleItem.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getItemProperties
+   * @until #//getItemProperties
+   *
+   * @return    A map of key/value properties associated with this XdmfItem.
+   */
+  virtual std::map<std::string, std::string> getItemProperties() const = 0;
+
+  /**
+   * Traverse this item by passing the visitor to child items.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfItem.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#traverse
+   * @until //#traverse
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleItem.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//traverse
+   * @until #//traverse
+   *
+   * @param     visitor         The visitor to pass to child items.
+   */
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfItem(XdmfItem &);
+
+protected:
+
+  XdmfItem();
+
+  /**
+   * Populates an item using a map of key/value property pairs and a
+   * vector of its child items. This is used to support generic
+   * reading of XdmfItems from disk.
+   *
+   * @param itemProperties a map of key/value properties associated with
+   * this item.
+   * @param childItems a vector of child items to be added to this item.
+   * @param reader the current XdmfCoreReader being used to populate Xdmf
+   * structures.
+   */
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem > > & childItems,
+               const XdmfCoreReader * const reader);
+
+  bool
+  getIsChanged();
+
+  void
+  setIsChanged(bool status);
+
+  std::set<XdmfItem *> mParents;
+
+  bool mIsChanged;
+
+private:
+
+  XdmfItem(const XdmfItem &);  // Not implemented.
+  void operator=(const XdmfItem &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFITEM; // Simply as a typedef to ensure correct typing
+typedef struct XDMFITEM XDMFITEM;
+
+#ifndef XDMFINFORMATIONCDEFINE
+#define XDMFINFORMATIONCDEFINE
+struct XDMFINFORMATION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFINFORMATION XDMFINFORMATION;
+#endif
+
+XDMFCORE_EXPORT void XdmfItemAccept(XDMFITEM * item, XDMFVISITOR * visitor, int * status);
+
+XDMFCORE_EXPORT void XdmfItemFree(void * item);
+
+XDMFCORE_EXPORT XDMFINFORMATION * XdmfItemGetInformation(XDMFITEM * item, unsigned int index);
+
+XDMFCORE_EXPORT XDMFINFORMATION * XdmfItemGetInformationByKey(XDMFITEM * item, char * key);
+
+XDMFCORE_EXPORT unsigned int XdmfItemGetNumberInformations(XDMFITEM * item);
+
+XDMFCORE_EXPORT void XdmfItemInsertInformation(XDMFITEM * item, XDMFINFORMATION * information, int passControl);
+
+XDMFCORE_EXPORT void XdmfItemRemoveInformation(XDMFITEM * item, unsigned int index);
+
+XDMFCORE_EXPORT void XdmfItemRemoveInformationByKey(XDMFITEM * item, char * key);
+
+XDMFCORE_EXPORT char * XdmfItemGetItemTag(XDMFITEM * item);
+
+#define XDMF_ITEM_C_CHILD_DECLARE(ClassName, CClassName, Level)                                                       \
+                                                                                                                      \
+Level##_EXPORT void ClassName##Accept ( CClassName * item, XDMFVISITOR * visitor, int * status);                      \
+XDMFCORE_EXPORT void ClassName##Free(void * item);                                                                    \
+Level##_EXPORT XDMFINFORMATION * ClassName##GetInformation( CClassName * item, unsigned int index);                   \
+Level##_EXPORT XDMFINFORMATION * ClassName##GetInformationByKey( CClassName * item, char * key);                      \
+Level##_EXPORT unsigned int ClassName##GetNumberInformations( CClassName * item);                                     \
+Level##_EXPORT void ClassName##InsertInformation( CClassName * item, XDMFINFORMATION * information, int passControl); \
+Level##_EXPORT void ClassName##RemoveInformation( CClassName * item, unsigned int index);                             \
+Level##_EXPORT void ClassName##RemoveInformationByKey( CClassName * item, char * key);                                \
+Level##_EXPORT char * ClassName##GetItemTag( CClassName * item);
+
+
+#define XDMF_ITEM_C_CHILD_WRAPPER(ClassName, CClassName)                                                    \
+void ClassName##Accept( CClassName * item, XDMFVISITOR * visitor, int * status)                             \
+{                                                                                                           \
+  XdmfItemAccept(((XDMFITEM *)item), visitor, status);                                                      \
+}                                                                                                           \
+                                                                                                            \
+void ClassName##Free(void * item)                                                                           \
+{                                                                                                           \
+  XdmfItemFree(item);                                                                                       \
+}                                                                                                           \
+                                                                                                            \
+XDMFINFORMATION * ClassName##GetInformation( CClassName * item, unsigned int index)                         \
+{                                                                                                           \
+  return XdmfItemGetInformation(((XDMFITEM *)item), index);                                                 \
+}                                                                                                           \
+                                                                                                            \
+XDMFINFORMATION * ClassName##GetInformationByKey( CClassName * item, char * key)                            \
+{                                                                                                           \
+  return XdmfItemGetInformationByKey(((XDMFITEM *)item), key);                                              \
+}                                                                                                           \
+                                                                                                            \
+unsigned int ClassName##GetNumberInformations( CClassName * item)                                           \
+{                                                                                                           \
+  return XdmfItemGetNumberInformations(((XDMFITEM *)item));                                                 \
+}                                                                                                           \
+                                                                                                            \
+void ClassName##InsertInformation( CClassName * item, XDMFINFORMATION * information, int passControl)       \
+{                                                                                                           \
+  XdmfItemInsertInformation(((XDMFITEM *)item), information, passControl);                                  \
+}                                                                                                           \
+                                                                                                            \
+void ClassName##RemoveInformation( CClassName * item, unsigned int index)                                   \
+{                                                                                                           \
+  XdmfItemRemoveInformation(((XDMFITEM *)item), index);                                                     \
+}                                                                                                           \
+                                                                                                            \
+void ClassName##RemoveInformationByKey( CClassName * item, char * key)                                      \
+{                                                                                                           \
+  XdmfItemRemoveInformationByKey(((XDMFITEM *)item), key);                                                  \
+}                                                                                                           \
+                                                                                                            \
+char * ClassName##GetItemTag( CClassName * item)                                                            \
+{                                                                                                           \
+  return XdmfItemGetItemTag(((XDMFITEM *)item));                                                            \
+} 
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFITEM_HPP_ */
diff --git a/core/XdmfItemProperty.cpp b/core/XdmfItemProperty.cpp
new file mode 100644
index 0000000..d3d46bd
--- /dev/null
+++ b/core/XdmfItemProperty.cpp
@@ -0,0 +1,83 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfItemProperty.cpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfItemProperty.hpp"
+#include <boost/assign.hpp>
+
+const std::map<const char, const char> XdmfItemProperty::UpperConversionMap =
+        boost::assign::map_list_of ('a', 'A')
+                                   ('b', 'B')
+                                   ('c', 'C')
+                                   ('d', 'D')
+                                   ('e', 'E')
+                                   ('f', 'F')
+                                   ('g', 'G')
+                                   ('h', 'H')
+                                   ('i', 'I')
+                                   ('j', 'J')
+                                   ('k', 'K')
+                                   ('l', 'L')
+                                   ('m', 'M')
+                                   ('n', 'N')
+                                   ('o', 'O')
+                                   ('p', 'P')
+                                   ('q', 'Q')
+                                   ('r', 'R')
+                                   ('s', 'S')
+                                   ('t', 'T')
+                                   ('u', 'U')
+                                   ('v', 'V')
+                                   ('w', 'W')
+                                   ('x', 'X')
+                                   ('y', 'Y')
+                                   ('z', 'Z');
+
+// Using this method because ANSI and std transform aren't guarenteed
+std::string
+XdmfItemProperty::ConvertToUpper(const std::string & converted)
+{
+  std::string returnstring;
+  returnstring.resize(converted.size());
+  std::map<const char, const char>::const_iterator characterConversion;
+  for (unsigned int i = 0; i < converted.size(); ++i)
+  {
+    characterConversion = UpperConversionMap.find(converted[i]);
+    if (characterConversion != UpperConversionMap.end())
+    {
+      returnstring[i] = characterConversion->second;
+    }
+    else
+    {
+      returnstring[i] = converted[i];
+    }
+  }
+  return returnstring;
+}
+
+XdmfItemProperty::XdmfItemProperty()
+{
+}
+
+XdmfItemProperty::~XdmfItemProperty()
+{
+}
diff --git a/core/XdmfItemProperty.hpp b/core/XdmfItemProperty.hpp
new file mode 100644
index 0000000..9a1bd86
--- /dev/null
+++ b/core/XdmfItemProperty.hpp
@@ -0,0 +1,92 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfItemProperty.hpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFITEMPROPERTY_HPP_
+#define XDMFITEMPROPERTY_HPP_
+
+#ifdef __cplusplus
+
+// Includes
+#include <map>
+#include <string>
+#include "XdmfCore.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief A property attached to an XdmfItem.
+ *
+ * XdmfItems can have zero or more properties attached to them that
+ * describe a specific characteristic of that item. For instance,
+ * XdmfAttributes have both center and type properties.
+ *
+ * This is an abstract base class to facilitate reading and writing of
+ * properties in a generic way.
+ */
+
+class XDMFCORE_EXPORT XdmfItemProperty {
+
+public:
+
+  virtual ~XdmfItemProperty() = 0;
+
+  /**
+   * Retrieve the key/value pairs that this XdmfItemProperty contains by
+   * inserting into the passed map.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfItemProperty.cpp
+   * @skipline //#getProperties
+   * @until //#getProperties
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleItemProperty.py
+   * @skipline #//getProperties
+   * @until #//getProperties
+   *
+   * @param     collectedProperties     A map to insert name / value pairs into.
+   */
+  virtual void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const = 0;
+
+protected:
+
+  XdmfItemProperty();
+
+  static std::string ConvertToUpper(const std::string & converted);
+
+  static const std::map<const char, const char> UpperConversionMap;
+
+private:
+
+  XdmfItemProperty(const XdmfItemProperty &);  // Not implemented.
+  void operator=(const XdmfItemProperty &);  // Not implemented.
+
+};
+
+#endif
+
+#endif /* XDMFITEMPROPERTY_HPP_ */
diff --git a/core/XdmfPlaceholder.cpp b/core/XdmfPlaceholder.cpp
new file mode 100644
index 0000000..0ee885a
--- /dev/null
+++ b/core/XdmfPlaceholder.cpp
@@ -0,0 +1,224 @@
+/*****************************************************************************/
+/*                                    Xdmf                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfPlaceholder.cpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2014 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <hdf5.h>
+#include <sstream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfHeavyDataDescription.hpp"
+#include "XdmfPlaceholder.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "string.h"
+
+shared_ptr<XdmfPlaceholder>
+XdmfPlaceholder::New(const std::string & filePath,
+                     const shared_ptr<const XdmfArrayType> type,
+                     const std::vector<unsigned int> & start,
+                     const std::vector<unsigned int> & stride,
+                     const std::vector<unsigned int> & dimensions,
+                     const std::vector<unsigned int> & dataspaceDimensions)
+{
+  shared_ptr<XdmfPlaceholder> 
+    p(new XdmfPlaceholder(filePath,
+                          type,
+                          start,
+                          stride,
+                          dimensions,
+                          dataspaceDimensions));
+  return p;
+}
+
+XdmfPlaceholder::XdmfPlaceholder(const std::string & filePath,
+                                 const shared_ptr<const XdmfArrayType> type,
+                                 const std::vector<unsigned int> & start,
+                                 const std::vector<unsigned int> & stride,
+                                 const std::vector<unsigned int> & dimensions,
+                                 const std::vector<unsigned int> & dataspaceDimensions) :
+  XdmfHeavyDataController(filePath,
+                          type,
+                          start,
+                          stride,
+                          dimensions,
+                          dataspaceDimensions)
+{
+}
+
+XdmfPlaceholder::XdmfPlaceholder(const XdmfPlaceholder & refController):
+  XdmfHeavyDataController(refController)
+{
+}
+
+XdmfPlaceholder::~XdmfPlaceholder()
+{
+}
+
+shared_ptr<XdmfHeavyDataController>
+XdmfPlaceholder::createSubController(const std::vector<unsigned int> & starts,
+                                     const std::vector<unsigned int> & strides,
+                                     const std::vector<unsigned int> & dimensions)
+{
+  return XdmfPlaceholder::New(mFilePath,
+                              mType,
+                              starts,
+                              strides,
+                              dimensions,
+                              mDataspaceDimensions);
+}
+
+std::string
+XdmfPlaceholder::getDescriptor() const
+{
+  return "";
+}
+
+shared_ptr<XdmfHeavyDataDescription>
+XdmfPlaceholder::getHeavyDataDescription()
+{
+  static shared_ptr<XdmfHeavyDataDescription> p = shared_ptr<XdmfHeavyDataDescription>();
+  return p;
+}
+
+std::string
+XdmfPlaceholder::getName() const
+{
+  return "Placeholder";
+}
+
+void
+XdmfPlaceholder::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties["Format"] = this->getName();
+}
+
+void
+XdmfPlaceholder::read(XdmfArray * const array)
+{
+  array->initialize(this->getType(), this->getDimensions());
+}
+
+// C Wrappers
+
+XDMFPLACEHOLDER * XdmfPlaceholderNew(char * hdf5FilePath,
+                                     int type,
+                                     unsigned int * start,
+                                     unsigned int * stride,
+                                     unsigned int * dimensions,
+                                     unsigned int * dataspaceDimensions,
+                                     unsigned int numDims,
+                                     int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfPlaceholder> generatedController = XdmfPlaceholder::New(std::string(hdf5FilePath), buildType, startVector, strideVector, dimVector, dataspaceVector);
+    return (XDMFPLACEHOLDER *)((void *)(new XdmfPlaceholder(*generatedController.get())));
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfPlaceholder> generatedController = XdmfPlaceholder::New(std::string(hdf5FilePath), buildType, startVector, strideVector, dimVector, dataspaceVector);
+    return (XDMFPLACEHOLDER *)((void *)(new XdmfPlaceholder(*generatedController.get())));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_HEAVYCONTROLLER_C_CHILD_WRAPPER(XdmfPlaceholder, XDMFPLACEHOLDER)
diff --git a/core/XdmfPlaceholder.hpp b/core/XdmfPlaceholder.hpp
new file mode 100644
index 0000000..4988dca
--- /dev/null
+++ b/core/XdmfPlaceholder.hpp
@@ -0,0 +1,156 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfPlaceholder.hpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFPLACEHOLDER_HPP_
+#define XDMFPLACEHOLDER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataController.hpp"
+
+#ifdef __cplusplus
+
+#include <map>
+
+/**
+ * @brief Couples an XdmfArray with an array structure.
+ *
+ * Takes the place of a heavy data set. Allows an array to define
+ * its structure without having to have an associated dataset.
+ */
+class XDMFCORE_EXPORT XdmfPlaceholder : public XdmfHeavyDataController {
+
+public:
+
+  virtual ~XdmfPlaceholder();
+
+  /**
+   * Create a new placeholder to define array structure.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfPlaceholder.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExamplePlaceholder.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     filePath                The location of the file the data set resides in.
+   * @param     type                    The data type of the dataset to read.
+   * @param     start                   The offset of the starting element in each
+   *                                    dimension in the data set.
+   * @param     stride                  The number of elements to move in each
+   *                                    dimension from the data set.
+   * @param     dimensions              The number of elements to select in each
+   *                                    dimension from the data set.
+   *                                    (size in each dimension)
+   * @param     dataspaceDimensions     The number of elements in the entire
+   *                                    data set (may be larger than
+   *                                    dimensions if using hyperslabs).
+   *
+   * @return    New Placeholder.
+   */
+  static shared_ptr<XdmfPlaceholder>
+  New(const std::string & FilePath,
+      const shared_ptr<const XdmfArrayType> type,
+      const std::vector<unsigned int> & start,
+      const std::vector<unsigned int> & stride,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaceDimensions);
+
+  virtual std::string getDescriptor() const;
+
+  virtual std::string getName() const;
+
+  virtual void
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+  virtual void read(XdmfArray * const array);
+
+  XdmfPlaceholder(const XdmfPlaceholder &);
+
+protected:
+
+  XdmfPlaceholder(const std::string & filePath,
+                  const shared_ptr<const XdmfArrayType> type,
+                  const std::vector<unsigned int> & start,
+                  const std::vector<unsigned int> & stride,
+                  const std::vector<unsigned int> & dimensions,
+                  const std::vector<unsigned int> & dataspaceDimensions);
+
+  shared_ptr<XdmfHeavyDataController>
+  createSubController(const std::vector<unsigned int> & starts,
+                      const std::vector<unsigned int> & strides,
+                      const std::vector<unsigned int> & dimensions);
+
+  virtual shared_ptr<XdmfHeavyDataDescription>
+  getHeavyDataDescription();
+
+  void read(XdmfArray * const array, const int fapl);
+
+private:
+
+  void operator=(const XdmfPlaceholder &);  // Not implemented.
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XDMFPLACEHOLDER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFPLACEHOLDER XDMFPLACEHOLDER;
+
+XDMFCORE_EXPORT XDMFPLACEHOLDER * XdmfPlaceholderNew(char * hdf5FilePath,
+                                                     int type,
+                                                     unsigned int * start,
+                                                     unsigned int * stride,
+                                                     unsigned int * dimensions,
+                                                     unsigned int * dataspaceDimensions,
+                                                     unsigned int numDims,
+                                                     int * status);
+
+// C Wrappers for parent classes are generated by macros
+
+/*
+XDMFCORE_EXPORT unsigned int * XdmfPlaceholderGetDataspaceDimensions(XDMFPLACEHOLDER * controller);
+
+XDMFCORE_EXPORT unsigned int * XdmfPlaceholderGetStart(XDMFPLACEHOLDER * controller);
+
+XDMFCORE_EXPORT unsigned int * XdmfPlaceholderGetStride(XDMFPLACEHOLDER * controller); 
+*/
+
+XDMF_HEAVYCONTROLLER_C_CHILD_DECLARE(XdmfPlaceholder, XDMFPLACEHOLDER, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFPLACEHOLDER_HPP_ */
diff --git a/core/XdmfSharedPtr.hpp b/core/XdmfSharedPtr.hpp
new file mode 100644
index 0000000..cfa7b91
--- /dev/null
+++ b/core/XdmfSharedPtr.hpp
@@ -0,0 +1,61 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSharedPtr.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFSHAREDPTR_HPP_
+#define XDMFSHAREDPTR_HPP_
+
+#ifdef __cplusplus
+
+#include "XdmfCoreConfig.hpp"
+#include <boost/shared_ptr.hpp>
+
+using boost::shared_ptr;
+
+#ifdef HAVE_BOOST_SHARED_DYNAMIC_CAST
+
+using boost::shared_dynamic_cast;
+
+#else
+
+template <typename T, typename U>
+shared_ptr<T> shared_dynamic_cast(shared_ptr<U> const & r) 
+{
+  typedef typename shared_ptr<T>::element_type E;
+  E * p = dynamic_cast< E* >( r.get() );
+  return p? shared_ptr<T>( r, p ): shared_ptr<T>();
+}
+
+#endif /* HAVE_BOOST_SHARED_DYNAMIC_CAST */
+
+// Used by C wrappers to prevent shared pointers from prematurely deleting objects
+// Normally this would be completely against the point of shared pointers,
+// but the  C wrapping requires that objects be seperated from the shared pointers.
+struct XdmfNullDeleter
+{
+template<typename T>
+void operator()(T*) {}
+};
+
+#endif
+
+#endif /* XDMFSHAREDPTR_HPP_ */
diff --git a/core/XdmfSparseMatrix.cpp b/core/XdmfSparseMatrix.cpp
new file mode 100644
index 0000000..8276cc6
--- /dev/null
+++ b/core/XdmfSparseMatrix.cpp
@@ -0,0 +1,387 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSparseMatrix.cpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <iostream>
+#include <sstream>
+#include "string.h"
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfError.hpp"
+
+shared_ptr<XdmfSparseMatrix>
+XdmfSparseMatrix::New(const unsigned int numberRows,
+                      const unsigned int numberColumns)
+{
+  shared_ptr<XdmfSparseMatrix> p(new XdmfSparseMatrix(numberRows,
+                                                      numberColumns));
+  return p;
+}
+
+XdmfSparseMatrix::XdmfSparseMatrix(const unsigned int numberRows,
+                                   const unsigned int numberColumns) :
+  mColumnIndex(XdmfArray::New()),
+  mName(""),
+  mNumberColumns(numberColumns),
+  mNumberRows(numberRows),
+  mRowPointer(XdmfArray::New()),
+  mValues(XdmfArray::New())
+{
+  mRowPointer->resize<unsigned int>(mNumberRows + 1, 0);
+}
+
+XdmfSparseMatrix::XdmfSparseMatrix(XdmfSparseMatrix & matrixRef) :
+  XdmfItem(matrixRef),
+  mColumnIndex(matrixRef.getColumnIndex()),
+  mName(matrixRef.getName()),
+  mNumberColumns(matrixRef.getNumberColumns()),
+  mNumberRows(matrixRef.getNumberRows()),
+  mRowPointer(matrixRef.getRowPointer()),
+  mValues(matrixRef.getValues())
+{
+}
+
+XdmfSparseMatrix::~XdmfSparseMatrix()
+{
+}
+
+const std::string XdmfSparseMatrix::ItemTag = "SparseMatrix";
+
+shared_ptr<XdmfArray>
+XdmfSparseMatrix::getColumnIndex()
+{
+  return mColumnIndex;
+}
+
+std::map<std::string, std::string>
+XdmfSparseMatrix::getItemProperties() const
+{
+  std::map<std::string, std::string> sparseMatrixProperties;
+  sparseMatrixProperties.insert(std::make_pair("Name", mName));
+  std::stringstream numberRowsString;
+  numberRowsString << mNumberRows;
+  sparseMatrixProperties.insert(std::make_pair("NumberRows",
+                                               numberRowsString.str()));
+  std::stringstream numberColumnsString;
+  numberColumnsString << mNumberColumns;
+  sparseMatrixProperties.insert(std::make_pair("NumberColumns",
+                                               numberColumnsString.str()));
+  return sparseMatrixProperties;
+}
+
+std::string
+XdmfSparseMatrix::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfSparseMatrix::getName() const
+{
+  if (mName.c_str() == NULL) {
+    return "";
+  }
+  else {
+    return mName;
+  }
+}
+
+unsigned int
+XdmfSparseMatrix::getNumberColumns() const
+{
+  return mNumberColumns;
+}
+
+unsigned int
+XdmfSparseMatrix::getNumberRows() const
+{
+  return mNumberRows;
+}
+
+shared_ptr<XdmfArray>
+XdmfSparseMatrix::getRowPointer()
+{
+  return mRowPointer;
+}
+
+shared_ptr<XdmfArray>
+XdmfSparseMatrix::getValues()
+{
+  return mValues;
+}
+
+std::string
+XdmfSparseMatrix::getValuesString() const
+{
+
+  std::stringstream toReturn;
+  for(unsigned int i=0; i<mNumberRows; ++i) {
+    if (i + 1 < mNumberRows) {
+      if (mRowPointer->getValue<unsigned int>(i) > mRowPointer->getValue<unsigned int>(i+1)) {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: getValuesString(), Sparse Matrix Row Pointer is not sorted.");
+      }
+    }
+    unsigned int index = 0;
+    for(unsigned int j=mRowPointer->getValue<unsigned int>(i);
+        j<mRowPointer->getValue<unsigned int>(i+1);
+        ++j) {
+      const unsigned int k = mColumnIndex->getValue<unsigned int>(j);
+      while(index++ < k) {
+        toReturn << "0.0, ";
+      }
+      toReturn << mValues->getValue<double>(j) << ", ";
+    }
+    while(index++ < mNumberColumns) {
+      toReturn << "0.0, ";
+    }
+    toReturn << std::endl;
+  }
+
+  return toReturn.str();
+
+}
+
+void
+XdmfSparseMatrix::populateItem(const std::map<std::string, std::string> & itemProperties,
+                               const std::vector<shared_ptr<XdmfItem> > & childItems,
+                               const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+  std::map<std::string, std::string>::const_iterator name =
+    itemProperties.find("Name");
+  if(name != itemProperties.end()) {
+    mName = name->second;
+  }
+  else  {
+    XdmfError::message(XdmfError::FATAL,
+                       "'Name' not found in itemProperties in "
+                       "XdmfSparseMatrix::populateItem");
+  }
+  std::map<std::string, std::string>::const_iterator numberRows =
+    itemProperties.find("NumberRows");
+  if(numberRows != itemProperties.end()) {
+    mNumberRows = std::atoi(numberRows->second.c_str());
+  }
+  else  {
+    XdmfError::message(XdmfError::FATAL,
+                       "'NumberRows' not found in itemProperties in "
+                       "XdmfSparseMatrix::populateItem");
+  }
+  std::map<std::string, std::string>::const_iterator numberColumns =
+    itemProperties.find("NumberColumns");
+  if(numberColumns != itemProperties.end()) {
+    mNumberColumns = std::atoi(numberColumns->second.c_str());
+  }
+  else  {
+    XdmfError::message(XdmfError::FATAL,
+                       "'NumberColumns' not found in itemProperties in "
+                       "XdmfSparseMatrix::populateItem");
+  }
+
+  std::vector<shared_ptr<XdmfArray> > arrayVector;
+  arrayVector.reserve(3);
+  for(std::vector<shared_ptr<XdmfItem> >::const_iterator iter =
+        childItems.begin();
+      iter != childItems.end();
+      ++iter) {
+    if(shared_ptr<XdmfArray> array = shared_dynamic_cast<XdmfArray>(*iter)) {
+      arrayVector.push_back(array);
+    }
+  }
+
+  if(arrayVector.size() < 3) {
+    // The three required arrays are for
+    // the row pointer, column index, and the contained values.
+    // Without these arrays the object can't be properly built.
+    XdmfError::message(XdmfError::FATAL,
+                       "Expected 3 arrays attached to "
+                       "XdmfSparseMatrix::populateItem");
+  }
+  mRowPointer = arrayVector[0];
+  mColumnIndex = arrayVector[1];
+  mValues = arrayVector[2];
+}
+
+void
+XdmfSparseMatrix::setColumnIndex(const shared_ptr<XdmfArray> columnIndex)
+{
+  mColumnIndex = columnIndex;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSparseMatrix::setName(const std::string & name)
+{
+  mName = name;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSparseMatrix::setRowPointer(const shared_ptr<XdmfArray> rowPointer)
+{
+  mRowPointer = rowPointer;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSparseMatrix::setValues(const shared_ptr<XdmfArray> values)
+{
+  mValues = values;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSparseMatrix::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+  mRowPointer->accept(visitor);
+  mColumnIndex->accept(visitor);
+  mValues->accept(visitor);
+}
+
+// C Wrappers
+
+XDMFSPARSEMATRIX * XdmfSparseMatrixNew(unsigned int numberRows, unsigned int numberColumns)
+{
+  try
+  {
+    shared_ptr<XdmfSparseMatrix> generatedMatrix = XdmfSparseMatrix::New(numberRows, numberColumns);
+    return (XDMFSPARSEMATRIX *)((void *)(new XdmfSparseMatrix(*generatedMatrix.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfSparseMatrix> generatedMatrix = XdmfSparseMatrix::New(numberRows, numberColumns);
+    return (XDMFSPARSEMATRIX *)((void *)(new XdmfSparseMatrix(*generatedMatrix.get())));
+  }
+}
+
+XDMFARRAY * XdmfSparseMatrixGetColumnIndex(XDMFSPARSEMATRIX * matrix, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return (XDMFARRAY *)((void *)(((XdmfSparseMatrix *)(matrix))->getColumnIndex().get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+char * XdmfSparseMatrixGetName(XDMFSPARSEMATRIX * matrix)
+{
+  try
+  {
+    char * returnPointer= strdup(((XdmfSparseMatrix *)(matrix))->getName().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer= strdup(((XdmfSparseMatrix *)(matrix))->getName().c_str());
+    return returnPointer;
+  }
+}
+
+unsigned int XdmfSparseMatrixGetNumberColumns(XDMFSPARSEMATRIX * matrix)
+{
+  return ((XdmfSparseMatrix *)matrix)->getNumberColumns();
+}
+
+unsigned int XdmfSparseMatrixGetNumberRows(XDMFSPARSEMATRIX * matrix)
+{
+  return ((XdmfSparseMatrix *)matrix)->getNumberRows();
+}
+
+XDMFARRAY * XdmfSparseMatrixGetRowPointer(XDMFSPARSEMATRIX * matrix, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return (XDMFARRAY *)((void *)(((XdmfSparseMatrix *)(matrix))->getRowPointer().get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFARRAY * XdmfSparseMatrixGetValues(XDMFSPARSEMATRIX * matrix, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return (XDMFARRAY *)((void *)(((XdmfSparseMatrix *)(matrix))->getValues().get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+char * XdmfSparseMatrixGetValuesString(XDMFSPARSEMATRIX * matrix, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    char * returnPointer = strdup(((XdmfSparseMatrix *)(matrix))->getValuesString().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfSparseMatrix *)(matrix))->getValuesString().c_str());
+    return returnPointer;
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+void XdmfSparseMatrixSetColumnIndex(XDMFSPARSEMATRIX * matrix, XDMFARRAY * columnIndex, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  if (passControl) {
+    ((XdmfSparseMatrix *)(matrix))->setColumnIndex(shared_ptr<XdmfArray>((XdmfArray *)columnIndex));
+  }
+  else {
+    ((XdmfSparseMatrix *)(matrix))->setColumnIndex(shared_ptr<XdmfArray>((XdmfArray *)columnIndex, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfSparseMatrixSetName(XDMFSPARSEMATRIX * matrix, char * name, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfSparseMatrix *)matrix)->setName(std::string(name));
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfSparseMatrixSetRowPointer(XDMFSPARSEMATRIX * matrix, XDMFARRAY * rowPointer, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  if (passControl) {
+    ((XdmfSparseMatrix *)(matrix))->setRowPointer(shared_ptr<XdmfArray>((XdmfArray *)rowPointer));
+  }
+  else {
+    ((XdmfSparseMatrix *)(matrix))->setRowPointer(shared_ptr<XdmfArray>((XdmfArray *)rowPointer, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfSparseMatrixSetValues(XDMFSPARSEMATRIX * matrix, XDMFARRAY * values, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  if (passControl) {
+    ((XdmfSparseMatrix *)(matrix))->setValues(shared_ptr<XdmfArray>((XdmfArray *)values));
+  }
+  else {
+    ((XdmfSparseMatrix *)(matrix))->setValues(shared_ptr<XdmfArray>((XdmfArray *)values, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfSparseMatrix, XDMFSPARSEMATRIX)
diff --git a/core/XdmfSparseMatrix.hpp b/core/XdmfSparseMatrix.hpp
new file mode 100644
index 0000000..496f13a
--- /dev/null
+++ b/core/XdmfSparseMatrix.hpp
@@ -0,0 +1,555 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSparseMatrix.hpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFSPARSEMATRIX_HPP_
+#define XDMFSPARSEMATRIX_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfArray.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Sparse matrix implemented as compressed row storage.
+ *
+ * An XdmfSparseMatrix provides routines for interacting with a sparse
+ * matrix.  It is stored internally in compressed row storage.
+ */
+class XDMFCORE_EXPORT XdmfSparseMatrix : public XdmfItem {
+
+public:
+
+  /**
+   * Create a new XdmfSparseMatrix.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     numberRows      Number of rows in matrix.
+   * @param     numberColumns   Number of columns in matrix.
+   *
+   * @return                    Constructed XdmfSparseMatrix.
+   */
+  static shared_ptr<XdmfSparseMatrix> New(const unsigned int numberRows,
+                                          const unsigned int numberColumns);
+
+  virtual ~XdmfSparseMatrix();
+
+  LOKI_DEFINE_VISITABLE(XdmfSparseMatrix, XdmfItem)
+  static const std::string ItemTag;
+
+  /**
+   * Get the column index array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setColumnIndex
+   * @until //#setColumnIndex
+   * @skipline //#getColumnIndex
+   * @until //#getColumnIndex
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setColumnIndex
+   * @until #//setColumnIndex
+   * @skipline #//getColumnIndex
+   * @until #//getColumnIndex
+   *
+   * @return    Array containing column indices for nonzero entries of
+   *            matrix. This is the same size as values.
+   */
+  shared_ptr<XdmfArray> getColumnIndex();
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Get the name of the sparse matrix.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   * @skipline //#getName
+   * @until //#getName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   * @skipline #//getName
+   * @until #//getName
+   *
+   * @return    A string containing the name of the sparse matrix.
+   */
+  std::string getName() const;
+
+  /**
+   * Get the number of columns in the sparse matrix.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setColumnIndex
+   * @until //#setColumnIndex
+   * @skipline //#getNumberColumns
+   * @until //#getNumberColumns
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setColumnIndex
+   * @until #//setColumnIndex
+   * @skipline #//getNumberColumns
+   * @until #//getNumberColumns
+   *
+   * @return    The number of columns in the sparse matrix.
+   */
+  unsigned int getNumberColumns() const;
+
+  /**
+   * Get the number of rows in the sparse matrix.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setRowPointer
+   * @until //#setRowPointer
+   * @skipline //#getNumberRows
+   * @until //#getNumberRows
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setRowPointer
+   * @until #//setRowPointer
+   * @skipline #//getNumberRows
+   * @until #//getNumberRows
+   *
+   * @return    The number of rows in the sparse matrix.
+   */
+  unsigned int getNumberRows() const;
+
+  /**
+   * Get the row pointer array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setRowPointer
+   * @until //#setRowPointer
+   * @skipline //#getRowPointer
+   * @until //#getRowPointer
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setRowPointer
+   * @until #//setRowPointer
+   * @skipline #//getRowPointer
+   * @until #//getRowPointer
+   *
+   * @return    Array containing indices into column array for each
+   *            row. This is the size of the number of rows in the matrix +
+   *            1. The last value is the number of nonzero entries in the matrix
+   */
+  shared_ptr<XdmfArray> getRowPointer();
+
+  /**
+   * Get the values array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setRowPointer
+   * @until //#setRowPointer
+   * @skipline //#setColumnIndex
+   * @until //#setColumnIndex
+   * @skipline //#setValues
+   * @until //#setValues
+   * @skipline //#getValues
+   * @until //#getValues
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setRowPointer
+   * @until #//setRowPointer
+   * @skipline #//setColumnIndex
+   * @until #//setColumnIndex
+   * @skipline #//setValues
+   * @until #//setValues
+   * @skipline #//getValues
+   * @until #//getValues
+   *
+   * @return    Array containing values of nonzero entries of matrix.
+   */
+  shared_ptr<XdmfArray> getValues();
+
+  /**
+   * Get values as a string in two dimensional format.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setRowPointer
+   * @until //#setRowPointer
+   * @skipline //#setColumnIndex
+   * @until //#setColumnIndex
+   * @skipline //#setValues
+   * @until //#setValues
+   * @skipline //#getValuesString
+   * @until //#getValuesString
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setRowPointer
+   * @until #//setRowPointer
+   * @skipline #//setColumnIndex
+   * @until #//setColumnIndex
+   * @skipline #//setValues
+   * @until #//setValues
+   * @skipline #//getValuesString
+   * @until #//getValuesString
+   *
+   * @return    Atring representation of matrix.
+   */
+  std::string getValuesString() const;
+
+  /**
+   * Set the column index array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setColumnIndex
+   * @until //#setColumnIndex
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setColumnIndex
+   * @until #//setColumnIndex
+   *
+   * @param     columnIndex     Array containing column indices for nonzero
+   *                            entries of matrix. This is the same size as values.
+   */
+  void setColumnIndex(const shared_ptr<XdmfArray> columnIndex);
+
+  /**
+   * Set the name of the sparse matrix.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setName
+   * @until //#setName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setName
+   * @until #//setName
+   *
+   * @param     name    A string containing the name to set.
+   */
+  void setName(const std::string & name);
+
+  /**
+   * Set the row pointer array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setRowPointer
+   * @until //#setRowPointer
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setRowPointer
+   * @until #//setRowPointer
+   *
+   * @param     rowPointer      Array containing indices into column array for
+   *                            each row. This is the size of the number of rows in the matrix +
+   *                            1. The last value is the number of nonzero entries in the matrix
+   */
+  void setRowPointer(const shared_ptr<XdmfArray> rowPointer);
+
+  /**
+   * Set the values array.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSparseMatrix.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#setRowPointer
+   * @until //#setRowPointer
+   * @skipline //#setColumnIndex
+   * @until //#setColumnIndex
+   * @skipline //#setValues
+   * @until //#setValues
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSparseMatrix.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//setRowPointer
+   * @until #//setRowPointer
+   * @skipline #//setColumnIndex
+   * @until #//setColumnIndex
+   * @skipline #//setValues
+   * @until #//setValues
+   *
+   * @param     values  Array containing values of nonzero entries of
+   *                    matrix.
+   */
+  void setValues(const shared_ptr<XdmfArray> values);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfSparseMatrix(XdmfSparseMatrix &);
+
+protected:
+
+  XdmfSparseMatrix(const unsigned int numberRows,
+                   const unsigned int numberColumns);
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfSparseMatrix(const XdmfSparseMatrix &);  // Not implemented.
+  void operator=(const XdmfSparseMatrix &);  // Not implemented.
+
+  shared_ptr<XdmfArray> mColumnIndex;
+  std::string mName;
+  unsigned int mNumberColumns;
+  unsigned int mNumberRows;
+  shared_ptr<XdmfArray> mRowPointer;
+  shared_ptr<XdmfArray> mValues;
+};
+
+#ifdef _WIN32
+#endif
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFSPARSEMATRIX; // Simply as a typedef to ensure correct typing
+typedef struct XDMFSPARSEMATRIX XDMFSPARSEMATRIX;
+
+XDMFCORE_EXPORT XDMFSPARSEMATRIX * XdmfSparseMatrixNew(unsigned int numberRows, unsigned int numberColumns);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfSparseMatrixGetColumnIndex(XDMFSPARSEMATRIX * matrix, int * status);
+
+XDMFCORE_EXPORT char * XdmfSparseMatrixGetName(XDMFSPARSEMATRIX * matrix);
+
+XDMFCORE_EXPORT unsigned int XdmfSparseMatrixGetNumberColumns(XDMFSPARSEMATRIX * matrix);
+
+XDMFCORE_EXPORT unsigned int XdmfSparseMatrixGetNumberRows(XDMFSPARSEMATRIX * matrix);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfSparseMatrixGetRowPointer(XDMFSPARSEMATRIX * matrix, int * status);
+
+XDMFCORE_EXPORT XDMFARRAY * XdmfSparseMatrixGetValues(XDMFSPARSEMATRIX * matrix, int * status);
+
+XDMFCORE_EXPORT char * XdmfSparseMatrixGetValuesString(XDMFSPARSEMATRIX * matrix, int * status);
+
+XDMFCORE_EXPORT void XdmfSparseMatrixSetColumnIndex(XDMFSPARSEMATRIX * matrix, XDMFARRAY * columnIndex, int passControl, int * status);
+
+XDMFCORE_EXPORT void XdmfSparseMatrixSetName(XDMFSPARSEMATRIX * matrix, char * name, int * status);
+
+XDMFCORE_EXPORT void XdmfSparseMatrixSetRowPointer(XDMFSPARSEMATRIX * matrix, XDMFARRAY * rowPointer, int passControl, int * status);
+
+XDMFCORE_EXPORT void XdmfSparseMatrixSetValues(XDMFSPARSEMATRIX * matrix, XDMFARRAY * values, int passControl, int * status);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfSparseMatrix, XDMFSPARSEMATRIX, XDMFCORE)
+
+#define XDMF_SPARSEMATRIX_C_CHILD_DECLARE(ClassName, CClassName, Level)                                                      \
+                                                                                                                             \
+Level##_EXPORT XDMFARRAY * ClassName##GetColumnIndex( CClassName * matrix, int * status);                                    \
+Level##_EXPORT char * ClassName##GetName( CClassName * matrix);                                                              \
+Level##_EXPORT unsigned int ClassName##GetNumberColumns( CClassName * matrix);                                               \
+Level##_EXPORT unsigned int ClassName##GetNumberRows( CClassName * matrix);                                                  \
+Level##_EXPORT XDMFARRAY * ClassName##GetRowPointer( CClassName * matrix, int * status);                                     \
+Level##_EXPORT XDMFARRAY * ClassName##GetValues( CClassName * matrix, int * status);                                         \
+Level##_EXPORT char * ClassName##GetValuesString( CClassName * matrix, int * status);                                        \
+Level##_EXPORT void ClassName##SetColumnIndex( CClassName * matrix, XDMFARRAY * columnIndex, int passControl, int * status); \
+Level##_EXPORT void ClassName##SetName( CClassName * matrix, char * name, int * status);                                     \
+Level##_EXPORT void ClassName##SetRowPointer( CClassName * matrix, XDMFARRAY * rowPointer, int passControl, int * status);   \
+Level##_EXPORT void ClassName##SetValues( CClassName * matrix, XDMFARRAY * values, int passControl, int * status);
+
+#define XDMF_SPARSEMATRIX_C_CHILD_WRAPPER(ClassName, CClassName)                                                             \
+                                                                                                                             \
+XDMFARRAY * ClassName##GetColumnIndex( CClassName * matrix, int * status)                                                    \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetColumnIndex((XDMFSPARSEMATRIX *)((void *)matrix), status);                                       \
+}                                                                                                                            \
+                                                                                                                             \
+char * ClassName##GetName( CClassName * matrix)                                                                              \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetName((XDMFSPARSEMATRIX *)((void *)matrix));                                                      \
+}                                                                                                                            \
+                                                                                                                             \
+unsigned int ClassName##GetNumberColumns( CClassName * matrix)                                                               \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetNumberColumns((XDMFSPARSEMATRIX *)((void *)matrix));                                             \
+}                                                                                                                            \
+                                                                                                                             \
+unsigned int ClassName##GetNumberRows( CClassName * matrix)                                                                  \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetNumberRows((XDMFSPARSEMATRIX *)((void *)matrix));                                                \
+}                                                                                                                            \
+                                                                                                                             \
+XDMFARRAY * ClassName##GetRowPointer( CClassName * matrix, int * status)                                                     \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetRowPointer((XDMFSPARSEMATRIX *)((void *)matrix), status);                                        \
+}                                                                                                                            \
+                                                                                                                             \
+XDMFARRAY * ClassName##GetValues( CClassName * matrix, int * status)                                                         \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetValues((XDMFSPARSEMATRIX *)((void *)matrix), status);                                            \
+}                                                                                                                            \
+                                                                                                                             \
+char * ClassName##GetValuesString( CClassName * matrix, int * status)                                                        \
+{                                                                                                                            \
+  return XdmfSparseMatrixGetValuesString((XDMFSPARSEMATRIX *)((void *)matrix), status);                                      \
+}                                                                                                                            \
+                                                                                                                             \
+void ClassName##SetColumnIndex( CClassName * matrix, XDMFARRAY * columnIndex, int passControl, int * status)                 \
+{                                                                                                                            \
+  XdmfSparseMatrixSetColumnIndex((XDMFSPARSEMATRIX *)((void *)matrix), columnIndex, passControl, status);                    \
+}                                                                                                                            \
+                                                                                                                             \
+void ClassName##SetName( CClassName * matrix, char * name, int * status)                                                     \
+{                                                                                                                            \
+  XdmfSparseMatrixSetName((XDMFSPARSEMATRIX *)((void *)matrix), name, status);                                               \
+}                                                                                                                            \
+                                                                                                                             \
+void ClassName##SetRowPointer( CClassName * matrix, XDMFARRAY * rowPointer, int passControl, int * status)                   \
+{                                                                                                                            \
+  XdmfSparseMatrixSetRowPointer((XDMFSPARSEMATRIX *)((void *)matrix), rowPointer, passControl, status);                      \
+}                                                                                                                            \
+                                                                                                                             \
+void ClassName##SetValues( CClassName * matrix, XDMFARRAY * values, int passControl, int * status)                           \
+{                                                                                                                            \
+  XdmfSparseMatrixSetValues((XDMFSPARSEMATRIX *)((void *)matrix), values, passControl, status);                              \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFSPARSEMATRIX_HPP_ */
diff --git a/core/XdmfSubset.cpp b/core/XdmfSubset.cpp
new file mode 100644
index 0000000..04236a9
--- /dev/null
+++ b/core/XdmfSubset.cpp
@@ -0,0 +1,489 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSubset.cpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <numeric>
+#include <functional>
+#include <boost/tokenizer.hpp>
+#include "string.h"
+#include "XdmfArray.hpp"
+#include "XdmfError.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfWriter.hpp"
+
+XdmfSubset::XdmfSubset(shared_ptr<XdmfArray> referenceArray,
+                       std::vector<unsigned int> & start,
+                       std::vector<unsigned int> & stride,
+                       std::vector<unsigned int> & dimensions) :
+  mParent(referenceArray),
+  mDimensions(dimensions),
+  mStart(start),
+  mStride(stride)
+{
+  if(!(mStart.size() == mStride.size() &&
+       mStride.size() == mDimensions.size())) {
+    XdmfError::message(XdmfError::FATAL,
+                       "mStart, mStride, mDimensions must all be of equal "
+                       "length in XdmfSubset constructor");
+  }
+}
+
+XdmfSubset::XdmfSubset(XdmfSubset & refSubset) :
+  XdmfArrayReference(refSubset),
+  mParent(refSubset.getReferenceArray()),
+  mDimensions(refSubset.getDimensions()),
+  mStart(refSubset.getStart()),
+  mStride(refSubset.getStride())
+{
+}
+
+XdmfSubset::~XdmfSubset()
+{
+}
+
+const std::string XdmfSubset::ItemTag = "Subset";
+
+shared_ptr<XdmfSubset>
+XdmfSubset::New(shared_ptr<XdmfArray> referenceArray,
+                std::vector<unsigned int> & start,
+                std::vector<unsigned int> & stride,
+                std::vector<unsigned int> & dimensions)
+{
+  shared_ptr<XdmfSubset> p(new XdmfSubset(referenceArray, start, stride, dimensions));
+  return p;
+}
+
+std::vector<unsigned int> XdmfSubset::getDimensions() const
+{
+  return mDimensions;
+}
+
+std::map<std::string, std::string>
+XdmfSubset::getItemProperties() const
+{
+  // Check to make sure the subset is valid
+  // before generating the properties.
+  if(!(mStart.size() == mStride.size() &&
+       mStride.size() == mDimensions.size())) {
+    XdmfError::message(XdmfError::FATAL,
+                       "mStart, mStride, mDimensions must all be of equal "
+                       "length in XdmfSubset getItemProperties");
+  }
+
+  if (mStart.size() < 1 ||
+      mStride.size() < 1 ||
+      mDimensions.size() < 1) {
+    XdmfError::message(XdmfError::WARNING,
+                       "mStart, mStride, mDimensions must have at least "
+                       "one value contained within");
+  }
+
+  std::map<std::string, std::string> subsetMap = XdmfArrayReference::getItemProperties();
+
+  std::stringstream vectorStream;
+
+  vectorStream << mStart[0];
+
+  for (unsigned int i = 1; i < mStart.size(); ++i) {
+    vectorStream << " " << mStart[i];
+  }
+
+  subsetMap["SubsetStarts"] = vectorStream.str();
+
+  vectorStream.str(std::string());
+
+  vectorStream << mStride[0];
+
+  for (unsigned int i = 1; i < mStride.size(); ++i) {
+    vectorStream << " " << mStride[i];
+  }
+
+  subsetMap["SubsetStrides"] = vectorStream.str();
+
+  vectorStream.str(std::string());
+
+  vectorStream << mDimensions[0];
+
+  for (unsigned int i = 1; i < mDimensions.size(); ++i) {
+    vectorStream << " " << mDimensions[i];
+  }
+
+  subsetMap["SubsetDimensions"] = vectorStream.str();
+
+  return subsetMap;
+}
+
+std::string
+XdmfSubset::getItemTag() const
+{
+  return ItemTag;
+}
+
+shared_ptr<XdmfArray>
+XdmfSubset::getReferenceArray()
+{
+  if (mParent) {
+    return mParent;
+  }
+  else {
+    return shared_ptr<XdmfArray>();
+  }
+}
+
+unsigned int
+XdmfSubset::getSize() const
+{
+  return std::accumulate(mDimensions.begin(),
+                         mDimensions.end(),
+                         1,
+                         std::multiplies<unsigned int>());
+}
+
+std::vector<unsigned int>
+XdmfSubset::getStart() const
+{
+  return mStart;
+}
+
+std::vector<unsigned int>
+XdmfSubset::getStride() const
+{
+  return mStride;
+}
+
+void
+XdmfSubset::populateItem(const std::map<std::string, std::string> & itemProperties,
+             const std::vector<shared_ptr<XdmfItem> > & childItems,
+             const XdmfCoreReader * const reader)
+{
+  std::map<std::string, std::string>::const_iterator starts =
+    itemProperties.find("SubsetStarts");
+
+  boost::tokenizer<> tokens(starts->second);
+  for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+      iter != tokens.end();
+      ++iter) {
+    mStart.push_back(atoi((*iter).c_str()));
+  }
+
+  std::map<std::string, std::string>::const_iterator strides =
+    itemProperties.find("SubsetStrides");
+
+  boost::tokenizer<> stridetokens(strides->second);
+  for(boost::tokenizer<>::const_iterator iter = stridetokens.begin();
+      iter != stridetokens.end();
+      ++iter) {
+    mStride.push_back(atoi((*iter).c_str()));
+  }
+
+  std::map<std::string, std::string>::const_iterator dimensions =
+    itemProperties.find("SubsetDimensions");
+
+  boost::tokenizer<> dimtokens(dimensions->second);
+  for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+      iter != dimtokens.end();
+      ++iter) {
+    mDimensions.push_back(atoi((*iter).c_str()));
+  }
+
+  mParent = shared_dynamic_cast<XdmfArray>(childItems[0]);
+}
+
+shared_ptr<XdmfArray>
+XdmfSubset::read() const
+{
+  if (mStart.size() < 1 ||
+      mStride.size() < 1 ||
+      mDimensions.size() < 1) {
+    XdmfError::message(XdmfError::WARNING,
+                       "mStart, mStride, mDimensions must have at least "
+                       "one value contained within");
+  }
+
+  if (!mParent->isInitialized()) {
+    mParent->read();
+  }
+
+  shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+  tempArray->initialize(mParent->getArrayType());
+  tempArray->resize(this->getSize(), 0);
+  std::vector<unsigned int> writeStarts;
+  writeStarts.push_back(0);
+  std::vector<unsigned int> writeStrides;
+  writeStrides.push_back(1);
+  std::vector<unsigned int> writeDimensions;
+  writeDimensions.push_back(this->getSize());
+
+  tempArray->insert(writeStarts,
+                    mParent,
+                    mStart,
+                    mDimensions,
+                    writeDimensions,
+                    writeStrides,
+                    mStride);
+  return tempArray;
+}
+
+void
+XdmfSubset::setDimensions(std::vector<unsigned int> newDimensions)
+{
+  mDimensions = newDimensions;
+  // Give the user a warning so they know they might have messed something up.
+  // If they don't want the warning they can suppress it.
+  if(!(mStart.size() == mStride.size() &&
+       mStride.size() == mDimensions.size())) {
+    XdmfError::message(XdmfError::WARNING,
+                       "mStart, mStride, mDimensions now have different sizes."
+                       "The sizes should be equal before use.");
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfSubset::setReferenceArray(shared_ptr<XdmfArray> newReference)
+{
+  mParent = newReference;
+  this->setIsChanged(true);
+}
+
+void
+XdmfSubset::setStart(std::vector<unsigned int> newStarts)
+{
+  mStart = newStarts;
+  // Give the user a warning so they know they might have messed something up.
+  // If they don't want the warning they can suppress it.
+  if(!(mStart.size() == mStride.size() &&
+       mStride.size() == mDimensions.size())) {
+    XdmfError::message(XdmfError::WARNING,
+                       "mStart, mStride, mDimensions now have different sizes."
+                       "The sizes should be equal before use.");
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfSubset::setStride(std::vector<unsigned int> newStrides)
+{
+  mStride = newStrides;
+  // Give the user a warning so they know they might have messed something up.
+  // If they don't want the warning they can suppress it.
+  if(!(mStart.size() == mStride.size() &&
+       mStride.size() == mDimensions.size())) {
+    XdmfError::message(XdmfError::WARNING,
+                       "mStart, mStride, mDimensions now have different sizes."
+                       "The sizes should be equal before use.");
+  }
+  this->setIsChanged(true);
+}
+
+void
+XdmfSubset::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  XdmfItem::traverse(visitor);
+
+  bool originalXPath;
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    originalXPath = writer->getWriteXPaths();
+    writer->setWriteXPaths(false);
+  }
+
+  shared_ptr<XdmfArray> spacerarray = XdmfArray::New();
+  spacerarray->pushBack((int)0);
+  spacerarray->accept(visitor);
+
+  if (shared_ptr<XdmfWriter> writer =
+        shared_dynamic_cast<XdmfWriter>(visitor)) {
+    writer->setWriteXPaths(originalXPath);
+  }
+
+  mParent->accept(visitor);
+}
+
+// C Wrappers
+
+XDMFSUBSET * XdmfSubsetNew(void * referenceArray, unsigned int * start, unsigned int * stride, unsigned int * dimensions, unsigned int numDims, int passControl, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    shared_ptr<XdmfArray> referencePointer;
+    if (passControl) {
+      referencePointer = shared_ptr<XdmfArray>((XdmfArray *)referenceArray);
+    }
+    else {
+      referencePointer = shared_ptr<XdmfArray>((XdmfArray *)referenceArray, XdmfNullDeleter());
+    }
+    shared_ptr<XdmfSubset> generatedSubset = XdmfSubset::New(referencePointer, startVector, strideVector, dimVector);
+    return (XDMFSUBSET *)((void *)(new XdmfSubset(*generatedSubset.get())));
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    shared_ptr<XdmfArray> referencePointer;
+    if (passControl) {
+      referencePointer = shared_ptr<XdmfArray>((XdmfArray *)referenceArray);
+    }
+    else {
+      referencePointer = shared_ptr<XdmfArray>((XdmfArray *)referenceArray, XdmfNullDeleter());
+    }
+    shared_ptr<XdmfSubset> generatedSubset = XdmfSubset::New(referencePointer, startVector, strideVector, dimVector);
+    return (XDMFSUBSET *)((void *)(new XdmfSubset(*generatedSubset.get())));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+unsigned int * XdmfSubsetGetDimensions(XDMFSUBSET * subset)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfSubset *)(subset))->getDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfSubset *)(subset))->getDimensions();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+unsigned int XdmfSubsetGetNumberDimensions(XDMFSUBSET * subset)
+{
+  return ((XdmfSubset *)(subset))->getDimensions().size();
+}
+
+void * XdmfSubsetGetReferenceArray(XDMFSUBSET * subset)
+{
+  shared_ptr<XdmfArray> returnItem = ((XdmfSubset *)subset)->getReferenceArray();
+  return returnItem.get();
+}
+
+unsigned int XdmfSubsetGetSize(XDMFSUBSET * subset)
+{
+  return ((XdmfSubset *)(subset))->getSize();
+}
+
+unsigned int * XdmfSubsetGetStart(XDMFSUBSET * subset)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfSubset *)(subset))->getStart();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfSubset *)(subset))->getStart();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+unsigned int * XdmfSubsetGetStride(XDMFSUBSET * subset)
+{
+  try
+  {
+    std::vector<unsigned int> tempVector = ((XdmfSubset *)(subset))->getStride();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> tempVector = ((XdmfSubset *)(subset))->getStride();
+    unsigned int returnSize = tempVector.size();
+    unsigned int * returnArray = new unsigned int[returnSize]();
+    for (unsigned int i = 0; i < returnSize; ++i) {
+      returnArray[i] = tempVector[i];
+    }
+    return returnArray;
+  }
+}
+
+void XdmfSubsetSetDimensions(XDMFSUBSET * subset, unsigned int * newDimensions, unsigned int numDims, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> dimVector(newDimensions, newDimensions + numDims);
+  ((XdmfSubset *)(subset))->setDimensions(dimVector);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfSubsetSetReferenceArray(XDMFSUBSET * subset, XDMFARRAY * referenceArray, int passControl)
+{
+  shared_ptr<XdmfArray> referencePointer;
+  if (passControl) {
+    referencePointer = shared_ptr<XdmfArray>((XdmfArray *)referenceArray);
+  }
+  else {
+    referencePointer = shared_ptr<XdmfArray>((XdmfArray *)referenceArray, XdmfNullDeleter());
+  }
+  ((XdmfSubset *)subset)->setReferenceArray(referencePointer);
+}
+
+void XdmfSubsetSetStart(XDMFSUBSET * subset, unsigned int * newStarts, unsigned int numDims, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> startVector(newStarts, newStarts + numDims);
+  ((XdmfSubset *)(subset))->setStart(startVector);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfSubsetSetStride(XDMFSUBSET * subset, unsigned int * newStrides, unsigned int numDims, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> strideVector(newStrides, newStrides + numDims);
+  ((XdmfSubset *)(subset))->setStride(strideVector);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfSubset, XDMFSUBSET)
+XDMF_ARRAYREFERENCE_C_CHILD_WRAPPER(XdmfSubset, XDMFSUBSET)
diff --git a/core/XdmfSubset.hpp b/core/XdmfSubset.hpp
new file mode 100644
index 0000000..b4b0657
--- /dev/null
+++ b/core/XdmfSubset.hpp
@@ -0,0 +1,437 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSubset.hpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFSUBSET_HPP_
+#define XDMFSUBSET_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfArrayReference.hpp"
+#include "XdmfItem.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+
+// Includes
+#include <vector>
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Couples an XdmfArray with heavy data stored in another XdmfArray.
+ *
+ * This class serves to allow an array to retrieve data that is a subsection
+ * of an already existing array.
+ */
+class XDMFCORE_EXPORT XdmfSubset: public XdmfArrayReference {
+
+public:
+
+  /**
+   * Generates an XdmfSubset object based on the parameters provided
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization 
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     referenceArray  The array that the subset is generated from.
+   * @param     start           A vector of the starting points for each
+   *                            dimension.
+   * @param     stride          A vector of the strides for each dimension.
+   * @param     dimensions      A vector of the amount of values read from each
+   *                            dimension.
+   * @return                    A constructed XdmfSubset
+   */
+  static shared_ptr<XdmfSubset>
+  New(shared_ptr<XdmfArray> referenceArray,
+      std::vector<unsigned int> & start,
+      std::vector<unsigned int> & stride,
+      std::vector<unsigned int> & dimensions);
+
+  virtual ~XdmfSubset();
+
+  LOKI_DEFINE_VISITABLE(XdmfSubset, XdmfItem)
+  static const std::string ItemTag;
+
+  /**
+   * Get the dimensions of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   *
+   * @return    A vector containing the size in each dimension of the
+   *            set referenced by this subset.
+   */
+  std::vector<unsigned int> getDimensions() const;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  std::string getItemTag() const;
+
+  /**
+   * Gets the array that the subset pulls data from.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getReferenceArray
+   * @until //#getReferenceArray
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getReferenceArray
+   * @until #//getReferenceArray
+   *
+   * @return    The array that the subset pulls data from
+   */
+  shared_ptr<XdmfArray> getReferenceArray();
+
+  /**
+   * Get the size of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getSize
+   * @until //#getSize
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getSize
+   * @until #//getSize
+   *
+   * @return    An int containing the size of the subset.
+   */
+  unsigned int getSize() const;
+
+  /**
+   * Get the start index of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getStart
+   * @until //#getStart
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getStart
+   * @until #//getStart
+   *
+   * @return    A vector containing the start index in each dimension of
+   *            the set referenced by this subset.
+   */
+  std::vector<unsigned int> getStart() const;
+
+  /**
+   * Get the stride of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getStride
+   * @until //#getStride
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getStride
+   * @until #//getStride
+   *
+   * @return    A vector containing the stride in each dimension of the
+   *            heavy data set owned by this controller.
+   */
+  std::vector<unsigned int> getStride() const;
+
+  /**
+   * Read data reference by this subset and return as an XdmfArray.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#read
+   * @until //#read
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//read
+   * @until #//read
+   *
+   * @return    An array filled with data based on the subset's parameters.
+   */
+  virtual shared_ptr<XdmfArray> read() const;
+
+  /**
+   * Set the dimensions of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getDimensions
+   * @until //#getDimensions
+   * @skipline //#setDimensions
+   * @until //#setDimensions
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getDimensions
+   * @until #//getDimensions
+   * @skipline #//setDimensions
+   * @until #//setDimensions
+   *
+   * @param     newDimensions   A vector containing the size in each dimension
+   *                            of the set to be referenced by this subset.
+   */
+  void setDimensions(std::vector<unsigned int> newDimensions);
+
+  /**
+   * Set the Array that the subset is generated from.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getReferenceArray
+   * @until //#getReferenceArray
+   * @skipline //#setReferenceArray
+   * @until //#setReferenceArray
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getReferenceArray
+   * @until #//getReferenceArray
+   * @skipline #//setReferenceArray
+   * @until #//setReferenceArray
+   *
+   * @param     newReference    A shared pointer to the array that the subset
+   *                            will be generated from
+   */
+  void setReferenceArray(shared_ptr<XdmfArray> newReference);
+
+  /**
+   * Set the start index of the set referenced by this subset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getStart
+   * @until //#getStart
+   * @skipline //#setStart
+   * @until //#setStart
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getStart
+   * @until #//getStart
+   * @skipline #//setStart
+   * @until #//setStart
+   *
+   * @param     newStarts       A vector containing the start index in each
+   *                            dimension of the set to be referenced by this
+   *                            subset.
+   */
+  void setStart(std::vector<unsigned int> newStarts);
+
+  /**
+   * Set the stride of the heavy data set owned by this controller.
+   *
+   * Example of use:
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSubset.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   * @skipline //#getStride
+   * @until //#getStride
+   * @skipline //#setStride
+   * @until //#setStride
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSubset.py
+   * @skipline #//initialization
+   * @until #//initialization
+   * @skipline #//getStride
+   * @until #//getStride
+   * @skipline #//setStride
+   * @until #//setStride
+   *
+   * @param     newStrides      A vector containing the stride in each
+   *                            dimension of the set referenced by this subset.
+   */
+  void setStride(std::vector<unsigned int> newStrides);
+
+  void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfSubset(XdmfSubset&);
+
+protected:
+
+  XdmfSubset(shared_ptr<XdmfArray> referenceArray,
+             std::vector<unsigned int> & start,
+             std::vector<unsigned int> & stride,
+             std::vector<unsigned int> & dimensions);
+
+  void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+  shared_ptr<XdmfArray> mParent;
+  std::vector<unsigned int> mDimensions;
+  std::vector<unsigned int> mStart;
+  std::vector<unsigned int> mStride;
+
+private:
+
+  XdmfSubset(const XdmfSubset&);  // Not implemented.
+  void operator=(const XdmfSubset &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFSUBSET; // Simply as a typedef to ensure correct typing
+typedef struct XDMFSUBSET XDMFSUBSET;
+
+XDMFCORE_EXPORT XDMFSUBSET * XdmfSubsetNew(void * referenceArray, unsigned int * start, unsigned int * stride, unsigned int * dimensions, unsigned int numDims, int passControl, int * status);
+
+XDMFCORE_EXPORT unsigned int * XdmfSubsetGetDimensions(XDMFSUBSET * subset);
+
+XDMFCORE_EXPORT unsigned int XdmfSubsetGetNumberDimensions(XDMFSUBSET * subset);
+
+XDMFCORE_EXPORT void * XdmfSubsetGetReferenceArray(XDMFSUBSET * subset);
+
+XDMFCORE_EXPORT unsigned int XdmfSubsetGetSize(XDMFSUBSET * subset);
+
+XDMFCORE_EXPORT unsigned int * XdmfSubsetGetStart(XDMFSUBSET * subset);
+
+XDMFCORE_EXPORT unsigned int * XdmfSubsetGetStride(XDMFSUBSET * subset);
+
+XDMFCORE_EXPORT void XdmfSubsetSetDimensions(XDMFSUBSET * subset, unsigned int * newDimensions, unsigned int numDims, int * status);
+
+XDMFCORE_EXPORT void XdmfSubsetSetReferenceArray(XDMFSUBSET * subset, XDMFARRAY * referenceArray, int passControl);
+
+XDMFCORE_EXPORT void XdmfSubsetSetStart(XDMFSUBSET * subset, unsigned int * newStarts, unsigned int numDims, int * status);
+
+XDMFCORE_EXPORT void XdmfSubsetSetStride(XDMFSUBSET * subset, unsigned int * newStrides, unsigned int numDims, int * status);
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfSubset, XDMFSUBSET, XDMFCORE)
+XDMF_ARRAYREFERENCE_C_CHILD_DECLARE(XdmfSubset, XDMFSUBSET, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFSUBSET_HPP_ */
diff --git a/core/XdmfSystemUtils.cpp b/core/XdmfSystemUtils.cpp
new file mode 100644
index 0000000..3fe54b2
--- /dev/null
+++ b/core/XdmfSystemUtils.cpp
@@ -0,0 +1,80 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSystemUtils.cpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <libxml/uri.h>
+#include <limits.h>
+#include <stdlib.h>
+#include "XdmfSystemUtils.hpp"
+#include "XdmfCoreConfig.hpp"
+#include <iostream>
+#include "string.h"
+
+XdmfSystemUtils::XdmfSystemUtils()
+{
+}
+
+XdmfSystemUtils::~XdmfSystemUtils()
+{
+}
+
+#ifdef XDMF_NO_REALPATH
+//allows symbolic links
+std::string
+XdmfSystemUtils::getRealPath(const std::string & path)
+{
+  return path;
+}
+#else
+std::string
+XdmfSystemUtils::getRealPath(const std::string & path)
+{
+  xmlURIPtr ref = NULL;
+  ref = xmlCreateURI();
+  xmlParseURIReference(ref, path.c_str());
+#ifdef WIN32
+  char realPath[_MAX_PATH];
+  _fullpath(realPath, path.c_str(), _MAX_PATH);
+  xmlFreeURI(ref);
+  return realPath;
+#else
+  char realPath[PATH_MAX];
+  char *rp = realpath(ref->path, realPath);
+  if (rp == 0)
+  {
+     //indicates a failure that we are silently ignoring
+     //TODO: realPath is now undefined but in practice
+     //ends up path.c_str()
+     rp = realPath;
+  }
+  xmlFreeURI(ref);
+  return std::string(rp);
+#endif
+}
+#endif
+
+char * XdmfSystemUtilsGetRealPath(char * path)
+{
+  std::string returnstring = XdmfSystemUtils::getRealPath(std::string(path));
+  char * returnPointer = strdup(returnstring.c_str());
+  return returnPointer;
+}
diff --git a/core/XdmfSystemUtils.hpp b/core/XdmfSystemUtils.hpp
new file mode 100644
index 0000000..d8e5329
--- /dev/null
+++ b/core/XdmfSystemUtils.hpp
@@ -0,0 +1,93 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfSystemUtils.hpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFSYSTEMUTILS_HPP_
+#define XDMFSYSTEMUTILS_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+
+#ifdef __cplusplus
+
+// Includes
+#include <string>
+
+/**
+ * @brief System specific functions.
+ *
+ * Collects all system specific functions needed by Xdmf.
+ */
+class XDMFCORE_EXPORT XdmfSystemUtils {
+
+ public:
+
+  /**
+   * Converts a filesystem path to an absolute real path (absolute
+   * path with no symlinks)
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfSystemUtils.cpp
+   * @skipline //#getRealPath
+   * @until //#getRealPath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleSystemUtils.py
+   * @skipline #//getRealPath
+   * @until #//getRealPath
+   *
+   * @param path a string containing the path to convert.
+   *
+   * @return the equivalent real path.
+   */
+  static std::string getRealPath(const std::string & path);
+
+ protected:
+
+  XdmfSystemUtils();
+  ~XdmfSystemUtils();
+
+ private:
+
+  XdmfSystemUtils(const XdmfSystemUtils &);  // Not implemented.
+  void operator=(const XdmfSystemUtils &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XDMFCORE_EXPORT char * XdmfSystemUtilsGetRealPath(char * path);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* XDMFSYSTEMUTILS_HPP_ */
diff --git a/core/XdmfTIFFController.cpp b/core/XdmfTIFFController.cpp
new file mode 100644
index 0000000..08411b6
--- /dev/null
+++ b/core/XdmfTIFFController.cpp
@@ -0,0 +1,617 @@
+/*****************************************************************************/
+/*                                    Xdmf                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTIFFController.cpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <fstream>
+#include <sstream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfTIFFController.hpp"
+#include "XdmfError.hpp"
+
+#include "tiff.h"
+#include "tiffio.h"
+
+shared_ptr<XdmfTIFFController>
+XdmfTIFFController::New(const std::string & filePath,
+                        const shared_ptr<const XdmfArrayType> & type,
+                        const std::vector<unsigned int> & dimensions)
+{
+  shared_ptr<XdmfTIFFController> p(new XdmfTIFFController(filePath,
+                                                          type,
+                                                          std::vector<unsigned int>(dimensions.size(), 0),
+                                                          std::vector<unsigned int>(dimensions.size(), 1),
+                                                          dimensions,
+                                                          dimensions));
+  return p;
+}
+
+shared_ptr<XdmfTIFFController>
+XdmfTIFFController::New(const std::string & filePath,
+                        const shared_ptr<const XdmfArrayType> & type,
+                        const std::vector<unsigned int> & starts,
+                        const std::vector<unsigned int> & strides,
+                        const std::vector<unsigned int> & dimensions,
+                        const std::vector<unsigned int> & dataspaces)
+{
+  shared_ptr<XdmfTIFFController> p(new XdmfTIFFController(filePath,
+                                                          type,
+                                                          starts,
+                                                          strides,
+                                                          dimensions,
+                                                          dataspaces));
+  return p;
+}
+
+XdmfTIFFController::XdmfTIFFController(const std::string & filePath,
+                                       const shared_ptr<const XdmfArrayType> & type,
+                                       const std::vector<unsigned int> & starts,
+                                       const std::vector<unsigned int> & strides,
+                                       const std::vector<unsigned int> & dimensions,
+                                       const std::vector<unsigned int> & dataspaces) :
+  XdmfHeavyDataController(filePath,
+                          type,
+                          starts,
+                          strides,
+                          dimensions,
+                          dataspaces)
+{
+}
+
+XdmfTIFFController::XdmfTIFFController(const XdmfTIFFController& refController):
+  XdmfHeavyDataController(refController)
+{
+}
+
+XdmfTIFFController::~XdmfTIFFController()
+{
+}
+
+shared_ptr<XdmfHeavyDataController>
+XdmfTIFFController::createSubController(const std::vector<unsigned int> & starts,
+                                        const std::vector<unsigned int> & strides,
+                                        const std::vector<unsigned int> & dimensions)
+{
+  return XdmfTIFFController::New(mFilePath,
+                                 mType,
+                                 starts,
+                                 strides,
+                                 dimensions,
+                                 mDataspaceDimensions);
+}
+
+void
+XdmfTIFFController::readToArray(XdmfArray * const array,
+                                void * pointer,
+                                unsigned int offset,
+                                unsigned int start,
+                                unsigned int stride,
+                                unsigned int amount,
+                                shared_ptr<const XdmfArrayType> type)
+{
+  if (type == XdmfArrayType::UInt32())
+  {
+    unsigned int * offsetpointer = &(((unsigned int *)pointer)[start]);
+    array->insert(offset,
+                  offsetpointer,
+                  amount,
+                  1,
+                  stride);
+  }
+  else if (type == XdmfArrayType::UInt16())
+  {
+    unsigned short * offsetpointer = &(((unsigned short *)pointer)[start]);
+    array->insert(offset,
+                  offsetpointer,
+                  amount,
+                  1,
+                  stride);
+  }
+  else if (type == XdmfArrayType::UInt8())
+  {
+    unsigned char * offsetpointer = &(((unsigned char *)pointer)[start]);
+    array->insert(offset,
+                  offsetpointer,
+                  amount,
+                  1,
+                  stride);
+  }
+}
+
+std::string
+XdmfTIFFController::getName() const
+{
+  return "TIFF";
+}
+
+unsigned int
+XdmfTIFFController::getNumberDirectories() const
+{
+  TIFF* tif = TIFFOpen(mFilePath.c_str(), "r");
+  unsigned int count = 0;
+  if (tif) {
+    do {
+      count++;
+    } while (TIFFReadDirectory(tif));
+    TIFFClose(tif);
+  }
+  return count;
+}
+
+void
+XdmfTIFFController::getProperties(std::map<std::string, std::string> & collectedProperties) const
+{
+  collectedProperties["Format"] = this->getName();
+  std::stringstream seekStream;
+}
+
+void
+XdmfTIFFController::read(XdmfArray * const array)
+{
+  TIFF* tif = TIFFOpen(mFilePath.c_str(), "r");
+
+  unsigned int compression = 0;
+
+  TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression);
+
+  unsigned int currentDirectory = 0;
+
+  if (tif && mStart.size() >= 3) {
+    // setting the start for the first directory
+    TIFFSetDirectory(tif, mStart[2]);
+    currentDirectory = mStart[2];
+  }
+
+  unsigned int amountWritten = 0;
+  // Only used for 1d controllers
+  unsigned int sizeLeft = this->getSize();
+  if (!array->isInitialized()) {
+    array->initialize(this->getType());
+  }
+  if (array->getSize() != this->getSize()) {
+    array->resize(mDimensions, 0);
+  }
+
+  // For single dimension version only
+  unsigned int currentRowStart = mStart[0];
+  unsigned int scanlineIndex = 0;
+
+  if (mDimensions.size() > 1)
+  {
+    scanlineIndex = mStart[1];
+  }
+
+  if (tif) {
+    bool validDir = true;
+    while (validDir) {
+      // Directories are handled by the third dimension
+      // If no directories are specified, progress as far
+      // as needed to fill the dimensions provided.
+      unsigned int imagelength, bitsPerSample;
+      tdata_t buf;
+      unsigned int row;
+      unsigned int scanlinesize = TIFFScanlineSize(tif);
+
+      shared_ptr<const XdmfArrayType> tiffDataType = array->getArrayType();
+
+      TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
+
+      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imagelength);
+
+      if (compression == 1) {
+        // Specific to non-compressed read
+
+        if (bitsPerSample / 8 == 1) {
+          tiffDataType = XdmfArrayType::UInt8();
+        }
+        else if (bitsPerSample / 8 == 2) {
+          tiffDataType = XdmfArrayType::UInt16();
+        }
+        else if (bitsPerSample / 8 == 4) {
+          tiffDataType = XdmfArrayType::UInt32();
+        }
+
+        // the buffer is a number of bytes equal to the scan line size
+        buf = _TIFFmalloc(scanlinesize );
+
+        scanlinesize /= array->getArrayType()->getElementSize();
+
+        if (mDimensions.size() == 1)
+        {
+          if (sizeLeft == 0) {
+            break;
+          }
+          // If there is one dimensions then we treat the entire entry as a single dataset.
+          // We need to adjust the starting point accordingly.
+          for (row = 0; row < imagelength; ++row)
+          {
+            TIFFReadScanline(tif, buf, row);
+            unsigned int amountRead = sizeLeft;
+            if ((scanlinesize - currentRowStart) / mStride[0] <= sizeLeft) {
+              amountRead = (scanlinesize - currentRowStart) / mStride[0];
+              if (scanlinesize % mStride[0] != 0 &&
+                  currentRowStart % mStride[0] <= scanlinesize - (amountRead * mStride[0] + currentRowStart))
+              {
+                 amountRead++;
+              }
+            }
+            readToArray(array,
+                        buf,
+                        amountWritten,
+                        currentRowStart,
+                        mStride[0],
+                        amountRead,
+                        tiffDataType);
+            // check to see how the start matches up with the scanline size
+            amountWritten += amountRead;
+            if (sizeLeft == 0) {
+              break;
+            }
+
+            if (amountRead < sizeLeft) {
+              sizeLeft = sizeLeft - amountRead;
+            }
+            else {
+              sizeLeft = 0;
+            }
+            if (((int)((amountRead * mStride[0]) + currentRowStart)) - scanlinesize >= 0)
+            {
+              currentRowStart = ((amountRead * mStride[0]) + currentRowStart) - scanlinesize;
+            }
+            else
+            {
+              currentRowStart = ((amountRead * (mStride[0] + 1)) + currentRowStart) - scanlinesize;
+            }
+          }
+        }
+        else {
+        // Dimensions correspond to scanline size and number of scanlines
+          unsigned int rowstride = mStride[1];
+          unsigned int currentRowStart = mStart[0];
+          for (row = mStart[1]; row < imagelength && row < mDataspaceDimensions[1]; row+=rowstride)
+          {
+            TIFFReadScanline(tif, buf, row);
+            readToArray(array,
+                        buf,
+                        amountWritten,
+                        currentRowStart,
+                        mStride[0],
+                        mDimensions[0],
+                        tiffDataType);
+            amountWritten += mDimensions[0];
+          }
+        }
+        _TIFFfree(buf);
+
+      }
+      else if (compression == 5)
+      {
+        // In this case we need to use strips instead of scanlines
+        // scanline size is in bytes when dealing with compression
+        if (bitsPerSample == 1) {
+          tiffDataType = XdmfArrayType::UInt8();
+        }
+        else if (bitsPerSample == 2) {
+          tiffDataType = XdmfArrayType::UInt16();
+        }
+        else if (bitsPerSample == 4) {
+          tiffDataType = XdmfArrayType::UInt32();
+        }
+
+        // the buffer is a number of bytes equal to the scan line size
+        buf = _TIFFmalloc(TIFFStripSize(tif));
+
+        scanlinesize /= array->getArrayType()->getElementSize();
+
+        // For each strip in the directory
+        for (unsigned int strip = 0; strip < TIFFNumberOfStrips(tif); strip++)
+        {
+          if (sizeLeft == 0) {
+            break;
+          }
+
+          unsigned int currentStripSize = TIFFReadEncodedStrip(tif, strip, buf, -1);
+          currentStripSize = currentStripSize / array->getArrayType()->getElementSize();
+          // Size is in bits, and is not necessarily the same per strip
+          unsigned int numberScanlines = currentStripSize / scanlinesize;
+          // For the case of a partial scanline
+          if (currentStripSize % scanlinesize != 0) {
+            ++numberScanlines;
+          }
+          // If singledimensional
+          // then write out the strip as if it was a scanline
+
+          if (mDimensions.size() == 1)
+          {
+            unsigned int amountRead = sizeLeft;
+            if ((currentStripSize - currentRowStart) / mStride[0] <= sizeLeft) {
+              amountRead = (currentStripSize - currentRowStart) / mStride[0];
+              if (currentStripSize % mStride[0] != 0 &&
+                  currentRowStart % mStride[0] <= currentStripSize - (amountRead * mStride[0] + currentRowStart))
+              {
+                 amountRead++;
+              }
+            }
+            readToArray(array,
+                        buf,
+                        amountWritten,
+                        currentRowStart,
+                        mStride[0],
+                        amountRead,
+                        tiffDataType);
+            amountWritten += amountRead;
+            if (sizeLeft == 0) {
+              break;
+            }
+
+            if (amountRead < sizeLeft) {
+              sizeLeft = sizeLeft - amountRead;
+            }
+            else {
+              sizeLeft = 0;
+            }
+            if (((int)((amountRead * mStride[0]) + currentRowStart)) - currentStripSize >= 0)
+            {
+              currentRowStart = ((amountRead * mStride[0]) + currentRowStart) - currentStripSize;
+            }
+            else
+            {
+              currentRowStart = ((amountRead * (mStride[0] + 1)) + currentRowStart) - currentStripSize;
+            }
+          }
+          else
+          {
+            currentRowStart = scanlineIndex;
+            // If multidimensional
+            // Loop through the scanlines in the strip
+            for (; scanlineIndex < numberScanlines; scanlineIndex += mStride[1])
+            {
+              readToArray(array,
+                          buf,
+                          amountWritten,
+                          currentRowStart,
+                          mStride[0],
+                          mDimensions[0],
+                          tiffDataType);
+              amountWritten += mDimensions[0];
+              currentRowStart = currentRowStart + scanlinesize * mStride[1];
+            }
+            scanlineIndex = scanlineIndex % mStride[1];
+          }
+        }
+      }
+
+      if (mStride.size() >= 3)
+      {
+        currentDirectory += mStride[2];
+      }
+      else
+      {
+        ++currentDirectory;
+      }
+
+      validDir = TIFFSetDirectory(tif, currentDirectory);
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL, "Error: Invalid TIFF file");
+  }
+
+  TIFFClose(tif);
+}
+
+// C Wrappers
+
+XDMFTIFFCONTROLLER * XdmfTIFFControllerNew(char * filePath,
+                                           int type,
+                                           unsigned int * dimensions,
+                                           unsigned int numDims,
+                                           int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfTIFFController> generatedController = XdmfTIFFController::New(std::string(filePath), buildType, dimVector);
+    return (XDMFTIFFCONTROLLER *)((void *)(new XdmfTIFFController(*generatedController.get())));
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+      case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfTIFFController> generatedController = XdmfTIFFController::New(std::string(filePath), buildType, dimVector);
+    return (XDMFTIFFCONTROLLER *)((void *)(new XdmfTIFFController(*generatedController.get())));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFTIFFCONTROLLER * XdmfTIFFControllerNewHyperslab(char * filePath,
+                                                    int type,
+                                                    unsigned int * start,
+                                                    unsigned int * stride,
+                                                    unsigned int * dimensions,
+                                                    unsigned int * dataspaceDimensions,
+                                                    unsigned int numDims,
+                                                    int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  try
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+     case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfTIFFController> generatedController = XdmfTIFFController::New(std::string(filePath), buildType, startVector, strideVector, dimVector, dataspaceVector);
+    return (XDMFTIFFCONTROLLER *)((void *)(new XdmfTIFFController(*generatedController.get())));
+  }
+  catch (...)
+  {
+    std::vector<unsigned int> startVector(start, start + numDims);
+    std::vector<unsigned int> strideVector(stride, stride + numDims);
+    std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+    std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+    shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+    switch (type) {
+      case XDMF_ARRAY_TYPE_UINT8:
+        buildType = XdmfArrayType::UInt8();
+        break;
+      case XDMF_ARRAY_TYPE_UINT16:
+        buildType = XdmfArrayType::UInt16();
+        break;
+      case XDMF_ARRAY_TYPE_UINT32:
+        buildType = XdmfArrayType::UInt32();
+        break;
+     case XDMF_ARRAY_TYPE_INT8:
+        buildType = XdmfArrayType::Int8();
+        break;
+      case XDMF_ARRAY_TYPE_INT16:
+        buildType = XdmfArrayType::Int16();
+        break;
+      case XDMF_ARRAY_TYPE_INT32:
+        buildType = XdmfArrayType::Int32();
+        break;
+      case XDMF_ARRAY_TYPE_INT64:
+        buildType = XdmfArrayType::Int64();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT32:
+        buildType = XdmfArrayType::Float32();
+        break;
+      case XDMF_ARRAY_TYPE_FLOAT64:
+        buildType = XdmfArrayType::Float64();
+        break;
+      default:
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+        break;
+    }
+    shared_ptr<XdmfTIFFController> generatedController = XdmfTIFFController::New(std::string(filePath), buildType, startVector, strideVector, dimVector, dataspaceVector);
+    return (XDMFTIFFCONTROLLER *)((void *)(new XdmfTIFFController(*generatedController.get())));
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_HEAVYCONTROLLER_C_CHILD_WRAPPER(XdmfTIFFController, XDMFTIFFCONTROLLER)
diff --git a/core/XdmfTIFFController.hpp b/core/XdmfTIFFController.hpp
new file mode 100644
index 0000000..94daf5b
--- /dev/null
+++ b/core/XdmfTIFFController.hpp
@@ -0,0 +1,187 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTIFFController.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFTIFFCONTROLLER_HPP_
+#define XDMFTIFFCONTROLLER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataController.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Couples an XdmfArray with TIFF data stored on disk.
+ *
+ * Serves as an interface between data stored in XdmfArrays and data
+ * stored in tiff files on disk. When an Xdmf file is read from or
+ * written to disk an XdmfTIFFController is attached to
+ * XdmfArrays. This allows data to be released from memory but still
+ * be accessible or have its location written to light data.
+ */
+class XDMFCORE_EXPORT XdmfTIFFController : public XdmfHeavyDataController {
+
+public:
+
+  virtual ~XdmfTIFFController();
+
+  /**
+   * Create a new controller for an TIFF file on disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTIFFController.cpp
+   * @skipline //#initializationsimplified
+   * @until //#initializationsimplified
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTIFFController.py
+   * @skipline #//initializationsimplified
+   * @until #//initializationsimplified
+   *
+   * @param     filePath                The location of the tiff file the data
+   *                                    set resides in.
+   * @param     type                    The data type of the dataset to read.
+   * @param     dimensions              The number of elements to select in each
+   *                                    dimension from the data set.
+   *                                    (size in each dimension)
+   *
+   * @return    New TIFF Controller.
+   */
+  static shared_ptr<XdmfTIFFController>
+  New(const std::string & filePath,
+      const shared_ptr<const XdmfArrayType> & type,
+      const std::vector<unsigned int> & dimensions);
+
+  /**
+   * Create a new controller for an TIFF file on disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfTIFFController.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleTIFFController.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     filePath                The location of the tiff file the data set resides in.
+   * @param     type                    The data type of the dataset to read.
+   * @param     starts                  The offset of the starting element in each
+   *                                    dimension in the data set.
+   * @param     strides                 The number of elements to move in each
+   *                                    dimension from the data set.
+   * @param     dimensions              The number of elements to select in each
+   *                                    dimension from the data set.
+   *                                    (size in each dimension)
+   * @param     dataspaces              The number of elements in the entire
+   *                                    data set (may be larger than
+   *                                    dimensions if using hyperslabs).
+   *
+   * @return    New TIFF Controller.
+   */
+  static shared_ptr<XdmfTIFFController>
+  New(const std::string & filePath,
+      const shared_ptr<const XdmfArrayType> & type,
+      const std::vector<unsigned int> & starts,
+      const std::vector<unsigned int> & strides,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaces);
+
+  virtual std::string getName() const;
+
+  virtual void 
+  getProperties(std::map<std::string, std::string> & collectedProperties) const;
+
+  virtual void read(XdmfArray * const array);
+
+  XdmfTIFFController(const XdmfTIFFController &);
+
+protected:
+
+  XdmfTIFFController(const std::string & filePath,
+                     const shared_ptr<const XdmfArrayType> & type,
+                     const std::vector<unsigned int> & starts,
+                     const std::vector<unsigned int> & strides,
+                     const std::vector<unsigned int> & dimensions,
+                     const std::vector<unsigned int> & dataspaces);
+
+  virtual shared_ptr<XdmfHeavyDataController>
+  createSubController(const std::vector<unsigned int> & starts,
+                      const std::vector<unsigned int> & strides,
+                      const std::vector<unsigned int> & dimensions);
+
+  unsigned int getNumberDirectories() const;
+
+  void readToArray(XdmfArray * const array,
+                   void * pointer,
+                   unsigned int offset,
+                   unsigned int start,
+                   unsigned int stride,
+                   unsigned int amount,
+                   shared_ptr<const XdmfArrayType> type);
+
+private:
+
+  void operator=(const XdmfTIFFController &);  // Not implemented.
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct XDMFTIFFCONTROLLER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFTIFFCONTROLLER XDMFTIFFCONTROLLER;
+
+XDMFCORE_EXPORT XDMFTIFFCONTROLLER * XdmfTIFFControllerNew(char * filePath,
+                                                           int type,
+                                                           unsigned int * dimensions,
+                                                           unsigned int numDims,
+                                                           int * status);
+
+XDMFCORE_EXPORT XDMFTIFFCONTROLLER * XdmfTIFFControllerNewHyperslab(char * filePath,
+                                                                    int type,
+                                                                    unsigned int * starts,
+                                                                    unsigned int * strides,
+                                                                    unsigned int * dimensions,
+                                                                    unsigned int * dataspaces,
+                                                                    unsigned int numDims,
+                                                                    int * status);
+
+XDMF_HEAVYCONTROLLER_C_CHILD_DECLARE(XdmfTIFFController, XDMFTIFFCONTROLLER, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFTIFFCONTROLLER_HPP_ */
diff --git a/core/XdmfVisitor.cpp b/core/XdmfVisitor.cpp
new file mode 100644
index 0000000..51f9c71
--- /dev/null
+++ b/core/XdmfVisitor.cpp
@@ -0,0 +1,40 @@
+/*****************************************************************************/
+/*                                    Xdmf                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfVisitor.cpp                                                     */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include "XdmfItem.hpp"
+#include "XdmfVisitor.hpp"
+
+XdmfVisitor::XdmfVisitor()
+{
+}
+
+XdmfVisitor::~XdmfVisitor()
+{
+}
+
+void
+XdmfVisitor::visit(XdmfItem & item,
+                   const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  item.traverse(visitor);
+}
diff --git a/core/XdmfVisitor.hpp b/core/XdmfVisitor.hpp
new file mode 100644
index 0000000..86bb40d
--- /dev/null
+++ b/core/XdmfVisitor.hpp
@@ -0,0 +1,81 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfVisitor.hpp                                                     */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFVISITOR_HPP_
+#define XDMFVISITOR_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfItem;
+
+// Includes
+#include <loki/Visitor.h>
+
+/**
+ * @brief Perform an operation on an Xdmf tree structure.
+ *
+ * XdmfVisitor is an abstract base class for any operation that
+ * operates on an Xdmf tree structure. These operations could involve
+ * writing to disk or modifying the structure in some way.
+ */
+class XDMFCORE_EXPORT XdmfVisitor : public XdmfBaseVisitor,
+                                    public Loki::Visitor<XdmfItem> {
+
+public:
+
+  virtual ~XdmfVisitor() = 0;
+
+  virtual void visit(XdmfItem & item,
+                     const shared_ptr<XdmfBaseVisitor> visitor);
+
+protected:
+
+  XdmfVisitor();
+
+private:
+
+  XdmfVisitor(const XdmfVisitor & visitor);  // Not implemented.
+  void operator=(const XdmfVisitor & visitor);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFVISITOR; // Simply as a typedef to ensure correct typing
+typedef struct XDMFVISITOR XDMFVISITOR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFVISITOR_HPP_ */
diff --git a/core/XdmfWriter.cpp b/core/XdmfWriter.cpp
new file mode 100644
index 0000000..227c6ce
--- /dev/null
+++ b/core/XdmfWriter.cpp
@@ -0,0 +1,842 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfWriter.cpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <fstream>
+#include <libxml/tree.h>
+#include <sstream>
+#include <utility>
+#include "XdmfArray.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfVersion.hpp"
+#include "XdmfError.hpp"
+#include "string.h"
+
+/**
+ * PIMPL
+ */
+class XdmfWriter::XdmfWriterImpl {
+
+public:
+
+  XdmfWriterImpl(const std::string & xmlFilePath,
+                 const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter,
+                 std::ostream * stream) :
+    mDepth(0),
+    mDocumentTitle("Xdmf"),
+    mHeavyDataWriter(heavyDataWriter),
+    mHeavyWriterIsOpen(false),
+    mLastXPathed(false),
+    mLightDataLimit(100),
+    mMode(Default),
+    mStream(stream),
+    mWriteXPaths(true),
+    mXPathParse(true),
+    mXMLCurrentNode(NULL),
+    mXMLDocument(NULL),
+    mXMLFilePath(XdmfSystemUtils::getRealPath(xmlFilePath)),
+    mXPathCount(0),
+    mXPathString(""),
+    mVersionString(XdmfVersion.getShort())
+  {
+  };
+
+  ~XdmfWriterImpl()
+  {
+  };
+
+  void
+  closeFile()
+  {
+    mXPath.clear();
+    mXPathCount = 0;
+
+    // This section writes to file
+    std::ofstream fileStream;
+    if(!mStream) {
+      fileStream.open(mXMLFilePath.c_str());
+      mStream = &fileStream;
+    }
+
+    xmlBufferPtr buffer = xmlBufferCreate();
+    xmlOutputBuffer * outputBuffer = xmlOutputBufferCreateBuffer(buffer,
+                                                                 NULL);
+    xmlSaveFormatFileTo(outputBuffer,
+                        mXMLDocument,
+                        "utf-8",
+                        1);
+    *mStream << buffer->content;
+    xmlBufferFree(buffer);
+    
+    if(fileStream.is_open()) {
+      fileStream.close();
+      mStream = NULL;
+    }
+    
+//    xmlFreeDoc(mXMLDocument);
+    xmlCleanupParser();
+
+    if(mHeavyDataWriter->getMode() == XdmfHeavyDataWriter::Default) {
+      if (mHeavyWriterIsOpen) {
+        mHeavyDataWriter->closeFile();
+      }
+    }
+  };
+
+  void
+  openFile()
+  {
+    mXMLDocument = xmlNewDoc((xmlChar*)"1.0");
+    mXMLCurrentNode = xmlNewNode(NULL, (xmlChar*)mDocumentTitle.c_str());
+    xmlNewProp(mXMLCurrentNode,
+               (xmlChar*)"xmlns:xi",
+               (xmlChar*)"http://www.w3.org/2001/XInclude");
+    xmlNewProp(mXMLCurrentNode,
+               (xmlChar*)"Version",
+               (xmlChar*)mVersionString.c_str());
+    xmlDocSetRootElement(mXMLDocument, mXMLCurrentNode);
+  }
+
+  int mDepth;
+  std::string mDocumentTitle;
+  shared_ptr<XdmfHeavyDataWriter> mHeavyDataWriter;
+  bool mHeavyWriterIsOpen;
+  bool mLastXPathed;
+  unsigned int mLightDataLimit;
+  Mode mMode;
+  std::ostream * mStream;
+  bool mWriteXPaths;
+  bool mXPathParse;
+  xmlNodePtr mXMLCurrentNode;
+  xmlDocPtr mXMLDocument;
+  std::string mXMLFilePath;
+  std::map<const XdmfItem * const, std::string> mXPath;
+  unsigned int mXPathCount;
+  std::string mXPathString;
+  std::string mVersionString;
+
+};
+
+shared_ptr<XdmfWriter>
+XdmfWriter::New(const std::string & xmlFilePath)
+{
+  std::stringstream heavyFileName;
+  size_t extension = xmlFilePath.rfind(".");
+  if(extension != std::string::npos) {
+    heavyFileName << xmlFilePath.substr(0, extension) << ".h5";
+  }
+  else {
+    heavyFileName << xmlFilePath << ".h5";
+  }
+  shared_ptr<XdmfHDF5Writer> hdf5Writer = 
+    XdmfHDF5Writer::New(heavyFileName.str());
+  shared_ptr<XdmfWriter> p(new XdmfWriter(xmlFilePath, hdf5Writer));
+  return p;
+}
+
+shared_ptr<XdmfWriter>
+XdmfWriter::New(const std::string & xmlFilePath,
+                const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter)
+{
+  shared_ptr<XdmfWriter> p(new XdmfWriter(xmlFilePath,
+                                          heavyDataWriter));
+  return p;
+}
+
+shared_ptr<XdmfWriter> 
+XdmfWriter::New(std::ostream & stream,
+                const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter)
+{
+  shared_ptr<XdmfWriter> p(new XdmfWriter("",
+                                          heavyDataWriter,
+                                          &stream));
+  return p;
+}
+
+XdmfWriter::XdmfWriter(const std::string & xmlFilePath,
+                       shared_ptr<XdmfHeavyDataWriter> heavyDataWriter,
+                       std::ostream * stream) :
+  mRebuildAlreadyVisited(true),
+  mImpl(new XdmfWriterImpl(xmlFilePath, 
+                           heavyDataWriter,
+                           stream))
+{
+}
+
+XdmfWriter::XdmfWriter(const XdmfWriter & writerRef) :
+  mRebuildAlreadyVisited(writerRef.mRebuildAlreadyVisited)
+{
+  char * transferPath = strdup(writerRef.getFilePath().c_str());
+  char * heavyTransferPath = strdup(writerRef.getHeavyDataWriter()->getFilePath().c_str());
+  mImpl = new XdmfWriterImpl(transferPath, XdmfHDF5Writer::New(heavyTransferPath), NULL);
+}
+
+XdmfWriter::~XdmfWriter()
+{
+  mXMLArchive.clear();
+  xmlFreeDoc(mImpl->mXMLDocument);
+  delete mImpl;
+}
+
+shared_ptr<XdmfHeavyDataWriter>
+XdmfWriter::getHeavyDataWriter()
+{
+  return boost::const_pointer_cast<XdmfHeavyDataWriter>
+    (static_cast<const XdmfWriter &>(*this).getHeavyDataWriter());
+}
+
+shared_ptr<const XdmfHeavyDataWriter>
+XdmfWriter::getHeavyDataWriter() const
+{
+  return mImpl->mHeavyDataWriter;
+}
+
+std::string
+XdmfWriter::getFilePath() const
+{
+  return mImpl->mXMLFilePath;
+}
+
+unsigned int
+XdmfWriter::getLightDataLimit() const
+{
+  return mImpl->mLightDataLimit;
+}
+
+XdmfWriter::Mode
+XdmfWriter::getMode() const
+{
+  return mImpl->mMode;
+}
+
+bool
+XdmfWriter::getRebuildXML()
+{
+  return mRebuildAlreadyVisited;
+}
+
+xmlNodePtr
+XdmfWriter::getXMLNode(XdmfItem * item, xmlDocPtr parentDoc, xmlNodePtr parentNode)
+{
+  std::map<XdmfItem *, xmlNodePtr>::iterator node =
+    mXMLArchive.find(item);
+  if (node != mXMLArchive.end())
+  {
+    xmlAddChild(parentNode, mXMLArchive[item]);
+    return mXMLArchive[item];
+  }
+  else
+  {
+    return xmlNewNode(NULL, (xmlChar*)"NULL");
+  }
+}
+
+bool
+XdmfWriter::getHasXMLArchive(XdmfItem * item)
+{
+  std::map<XdmfItem *, xmlNodePtr>::iterator node =
+    mXMLArchive.find(item);
+  if (node != mXMLArchive.end())
+  {
+    return true;
+  }
+  else
+  {
+    return false;
+  }
+}
+
+bool
+XdmfWriter::getWriteXPaths() const
+{
+  return mImpl->mWriteXPaths;
+}
+
+bool
+XdmfWriter::getXPathParse() const
+{
+  return mImpl->mXPathParse;
+}
+
+void
+XdmfWriter::setDocumentTitle(std::string title)
+{
+  mImpl->mDocumentTitle = title;
+}
+
+void
+XdmfWriter::setHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter> heavyDataWriter)
+{
+  mImpl->mHeavyDataWriter = heavyDataWriter;
+}
+
+void
+XdmfWriter::setLightDataLimit(const unsigned int numValues)
+{
+  mImpl->mLightDataLimit = numValues;
+}
+
+void
+XdmfWriter::setMode(const Mode mode)
+{
+  mImpl->mMode = mode;
+}
+
+void
+XdmfWriter::setRebuildXML(bool newStatus)
+{
+  mRebuildAlreadyVisited = newStatus;
+}
+
+void
+XdmfWriter::setVersionString(std::string version)
+{
+  mImpl->mVersionString = version;
+}
+
+void
+XdmfWriter::setXMLNode(XdmfItem * item, xmlNodePtr & newNode)
+{
+    mXMLArchive[item] = xmlCopyNode(newNode, 1);
+}
+
+void
+XdmfWriter::setWriteXPaths(const bool writeXPaths)
+{
+  mImpl->mWriteXPaths = writeXPaths;
+}
+
+void
+XdmfWriter::setXPathParse(const bool xPathParse)
+{
+  mImpl->mXPathParse = xPathParse;
+}
+
+void
+XdmfWriter::visit(XdmfArray & array,
+                  const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  if (mImpl->mDepth == 0) {
+    mImpl->openFile();
+  }
+  mImpl->mDepth++;
+
+  // Pull the Function and Subset accociated with the array
+  shared_ptr<XdmfArrayReference> internalReference = array.getReference();
+
+  // If in the correct read mode process the function or subset
+  // if it exists
+  if (internalReference && array.getReadMode() == XdmfArray::Reference) {
+    // Pass information about the array to the function
+    // so it can properly recreate it when read
+    internalReference->setConstructedType(array.getItemTag());
+    internalReference->setConstructedProperties(array.getItemProperties());
+    internalReference->accept(visitor);
+    // This does not write the data contained within the array to file
+    // The data is regenerated upon read
+  }
+  else if (array.getReadMode() == XdmfArray::Controller) {
+    // Controller mode is the default mode
+    const bool isSubclassed = 
+      array.getItemTag().compare(XdmfArray::ItemTag) != 0;
+
+    if(isSubclassed) {
+      this->visit(dynamic_cast<XdmfItem &>(array), visitor);
+    }
+
+    if(array.getSize() > 0 && !(mImpl->mLastXPathed && isSubclassed)) {
+      std::vector<std::string> xmlTextValues;
+
+      // Take care of writing to single heavy data file (Default behavior)
+      if(!array.isInitialized() && array.getHeavyDataController(0) &&
+         array.getHeavyDataController(0)->getFilePath().compare(mImpl->mHeavyDataWriter->getFilePath()) != 0 &&
+         mImpl->mMode == Default) {
+        array.read();
+      }
+
+      if(array.getHeavyDataController(0) ||
+         array.getSize() > mImpl->mLightDataLimit) {
+        // Write values to heavy data
+
+        // This takes about half the time needed
+        if ((!mImpl->mHeavyWriterIsOpen) &&
+            mImpl->mHeavyDataWriter->getMode() == XdmfHeavyDataWriter::Default) {
+          mImpl->mHeavyDataWriter->openFile();
+          mImpl->mHeavyWriterIsOpen = true;
+        }
+        mImpl->mHeavyDataWriter->visit(array, mImpl->mHeavyDataWriter);
+
+        std::stringstream valuesStream;
+        for(unsigned int i = 0; i < array.getNumberHeavyDataControllers(); ++i) {
+
+          std::string heavyDataPath =
+            array.getHeavyDataController(i)->getFilePath();
+          size_t index = heavyDataPath.find_last_of("/\\");
+          if(index != std::string::npos) {
+            // If path is not a folder
+            // put the directory path into this variable
+            const std::string heavyDataDir = heavyDataPath.substr(0, index + 1);
+            // If the directory is in the XML File Path
+            if(mImpl->mXMLFilePath.find(heavyDataDir) == 0) {
+              heavyDataPath =
+                heavyDataPath.substr(heavyDataDir.size(),
+                                     heavyDataPath.size() - heavyDataDir.size());
+              // Pull the file off of the end and place it in the DataPath
+            }
+            // Otherwise the full path is required
+          }
+          // Clear the stream
+          valuesStream.str(std::string());
+          valuesStream << heavyDataPath << array.getHeavyDataController(i)->getDescriptor();
+          if (array.getNumberHeavyDataControllers() > 1 ||
+              (array.getHeavyDataController(i)->getSize() !=
+               array.getHeavyDataController(i)->getDataspaceSize())) {
+            valuesStream << "|" << array.getHeavyDataController(i)->getDataspaceDescription();
+            if (i + 1 < array.getNumberHeavyDataControllers()) {
+              valuesStream << "|";
+            }
+          }
+          xmlTextValues.push_back(valuesStream.str());
+        }
+      }
+      else {
+        // Write values to XML
+        xmlTextValues.push_back(array.getValuesString());
+      }
+
+      bool oldWriteXPaths = mImpl->mWriteXPaths;
+
+      // Write XML (metadata) description
+      if(isSubclassed) {
+        // We don't want temporary items to be on the XPath List
+        // This is a one-of anyway, so it shouldn't be equivalent
+        // to anything written before now or after.
+        mImpl->mWriteXPaths = false;
+        const unsigned int parentCount = mImpl->mXPathCount;
+        mImpl->mXPathCount = 0;
+        shared_ptr<XdmfArray> arrayToWrite = XdmfArray::New();
+        array.swap(arrayToWrite);
+        mImpl->mXMLCurrentNode = mImpl->mXMLCurrentNode->last;
+        this->visit(dynamic_cast<XdmfItem &>(*arrayToWrite.get()), visitor);
+        for(unsigned int i = 0; i<xmlTextValues.size(); ++i) {
+          xmlAddChild(mImpl->mXMLCurrentNode->last,
+                      xmlNewText((xmlChar*)xmlTextValues[i].c_str()));
+        }
+        mImpl->mXMLCurrentNode = mImpl->mXMLCurrentNode->parent;
+        array.swap(arrayToWrite);
+        mImpl->mXPathCount = parentCount;
+        mImpl->mLastXPathed = false;
+      }
+      else {
+        std::map<const XdmfItem * const, std::string>::const_iterator iter =
+          mImpl->mXPath.find(&array);
+        this->visit(dynamic_cast<XdmfItem &>(array), visitor);
+        if(iter == mImpl->mXPath.end()) {
+          for(unsigned int i = 0; i<xmlTextValues.size(); ++i) {
+            xmlAddChild(mImpl->mXMLCurrentNode->last,
+                        xmlNewText((xmlChar*)xmlTextValues[i].c_str()));
+          }
+        }
+      }
+      mImpl->mWriteXPaths = oldWriteXPaths;
+    }
+  }
+  else {
+    // These statements are reached when an unsupported read mode is used
+    // or when a read mode is not properly set up
+    if (array.getReadMode() == XdmfArray::Reference) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Array to be output as an array reference"
+                         " does not have an associated reference.");
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid output type.");
+    }
+  }
+
+  mImpl->mDepth--;
+  if(mImpl->mDepth <= 0) {
+    mImpl->closeFile();
+  }
+}
+
+void
+XdmfWriter::visit(XdmfItem & item,
+                  const shared_ptr<XdmfBaseVisitor> visitor)
+{
+  if (mImpl->mDepth == 0) {
+    mImpl->openFile();
+  }
+  mImpl->mDepth++;
+
+  if ((item.getItemTag().compare("Grid") != 0) || // If not a grid
+      (item.getItemTag().compare("Grid") == 0 && item.getIsChanged()) || // If a Grid that is changed
+      (item.getItemTag().compare("Grid") == 0 && !getHasXMLArchive(&item)) || // If the grid doesn't have an XML Archive
+      mRebuildAlreadyVisited) // If Rebuild
+  {
+    std::string tag = item.getItemTag();
+    if (tag.length() == 0) {
+      item.traverse(visitor);
+    }
+    else {
+      if(mImpl->mWriteXPaths) {
+        if (tag == "Information" && mImpl->mXPathParse) {
+          XdmfInformation & xpathinfo = dynamic_cast<XdmfInformation &>(item);
+          if (xpathinfo.getKey() == "XIncludes") {
+            shared_ptr<XdmfInformation> outputinfo;
+            for (unsigned int i = 0; i < xpathinfo.getNumberInformations(); ++i) {
+              mImpl->mXPathCount++;
+              outputinfo = xpathinfo.getInformation(i);
+              mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                                   NULL,
+                                                   (xmlChar*)"xi:include",
+                                                   NULL);
+              xmlNewProp(mImpl->mXMLCurrentNode,
+                         (xmlChar*)"href",
+                         (xmlChar*)(outputinfo->getKey().c_str()));
+              xmlNewProp(mImpl->mXMLCurrentNode,
+                         (xmlChar*)"xpointer",
+                         (xmlChar*)(outputinfo->getValue().c_str()));
+              if (i < xpathinfo.getNumberInformations()-1) {
+                mImpl->mXMLCurrentNode = mImpl->mXMLCurrentNode->parent;
+              }
+            }
+          }
+          else {
+            mImpl->mXPathCount++;
+
+            const std::string parentXPathString = mImpl->mXPathString;
+
+            std::stringstream newXPathString;
+            newXPathString << mImpl->mXPathString << "/" << mImpl->mXPathCount;
+            mImpl->mXPathString = newXPathString.str();
+
+            std::map<const XdmfItem * const, std::string>::const_iterator iter =
+              mImpl->mXPath.find(&item);
+            if(iter != mImpl->mXPath.end()) {
+              // Inserted before --- just xpath location of previously written node
+              mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                                   NULL,
+                                                   (xmlChar*)"xi:include",
+                                                   NULL);
+              xmlNewProp(mImpl->mXMLCurrentNode,
+                         (xmlChar*)"xpointer",
+                         (xmlChar*)iter->second.c_str());
+              mImpl->mLastXPathed = true;
+            }
+            else {
+              // Not inserted before --- need to write all data and traverse.
+              mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                                   NULL,
+                                                   (xmlChar *)tag.c_str(),
+                                                   NULL);
+              std::stringstream xPathProp;
+              xPathProp << "element(/1" << mImpl->mXPathString << ")";
+              mImpl->mXPath.insert(std::make_pair(&item, xPathProp.str()));
+              const std::map<std::string, std::string> & itemProperties =
+                item.getItemProperties();
+              for(std::map<std::string, std::string>::const_iterator iter =
+                  itemProperties.begin();
+                  iter != itemProperties.end();
+                  ++iter) {
+                xmlNewProp(mImpl->mXMLCurrentNode,
+                           (xmlChar*)iter->first.c_str(),
+                           (xmlChar*)iter->second.c_str());
+              }
+              const unsigned int parentCount = mImpl->mXPathCount;
+              mImpl->mXPathCount = 0;
+              item.traverse(visitor);
+              mImpl->mXPathCount = parentCount;
+              mImpl->mLastXPathed = false;
+            }
+
+            mImpl->mXPathString = parentXPathString;
+
+          }
+        }
+        else {
+          mImpl->mXPathCount++;
+
+          const std::string parentXPathString = mImpl->mXPathString;
+
+          std::stringstream newXPathString;
+          newXPathString << mImpl->mXPathString << "/" << mImpl->mXPathCount;
+          mImpl->mXPathString = newXPathString.str();
+
+          std::map<const XdmfItem * const, std::string>::const_iterator iter =
+          mImpl->mXPath.find(&item);
+          if(iter != mImpl->mXPath.end()) {
+            // Inserted before --- just xpath location of previously written node
+            mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                                 NULL,
+                                                 (xmlChar*)"xi:include",
+                                                 NULL);
+           xmlNewProp(mImpl->mXMLCurrentNode,
+                      (xmlChar*)"xpointer",
+                      (xmlChar*)iter->second.c_str());
+           mImpl->mLastXPathed = true;
+          }
+          else {
+            // Not inserted before --- need to write all data and traverse.
+
+            mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                                 NULL,
+                                                 (xmlChar *)tag.c_str(),
+                                                 NULL);
+            std::stringstream xPathProp;
+            xPathProp << "element(/1" << mImpl->mXPathString << ")";
+            mImpl->mXPath.insert(std::make_pair(&item, xPathProp.str()));
+            const std::map<std::string, std::string> & itemProperties =
+            item.getItemProperties();
+            for(std::map<std::string, std::string>::const_iterator iter =
+                itemProperties.begin();
+                iter != itemProperties.end();
+                ++iter) {
+              xmlNewProp(mImpl->mXMLCurrentNode,
+                         (xmlChar*)iter->first.c_str(),
+                         (xmlChar*)iter->second.c_str());
+            }
+            const unsigned int parentCount = mImpl->mXPathCount;
+            mImpl->mXPathCount = 0;
+            item.traverse(visitor);
+            mImpl->mXPathCount = parentCount;
+            mImpl->mLastXPathed = false;
+          }
+          mImpl->mXPathString = parentXPathString;
+        }
+      }
+      else
+      {
+        // Increment XPathCount, handling temporary arrays not written to XPath
+        mImpl->mXPathCount++;
+        // Not inserted before --- need to write all data and traverse.
+        mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                             NULL,
+                                             (xmlChar*)tag.c_str(),
+                                             NULL);
+        const std::map<std::string, std::string> itemProperties =
+          item.getItemProperties();
+        for(std::map<std::string, std::string>::const_iterator iter =
+              itemProperties.begin();
+            iter != itemProperties.end();
+            ++iter) {
+          xmlNewProp(mImpl->mXMLCurrentNode,
+                     (xmlChar*)iter->first.c_str(),
+                     (xmlChar*)iter->second.c_str());
+        }
+        const unsigned int parentCount = mImpl->mXPathCount;
+        mImpl->mXPathCount = 0;
+        item.traverse(visitor);
+        mImpl->mXPathCount = parentCount;
+        mImpl->mLastXPathed = false;
+      }
+
+      if (!mRebuildAlreadyVisited)
+      {
+        if (item.getItemTag().compare("Grid") == 0)
+        {
+          setXMLNode(&item, mImpl->mXMLCurrentNode);
+        }
+        item.setIsChanged(false);
+      }
+
+      mImpl->mXMLCurrentNode = mImpl->mXMLCurrentNode->parent;
+    }
+  }
+  else
+  {
+    std::map<const XdmfItem * const, std::string>::const_iterator iter =
+      mImpl->mXPath.find(&item);
+    if(iter != mImpl->mXPath.end()) {
+      // Inserted before --- just xpath location of previously written node
+      mImpl->mXMLCurrentNode = xmlNewChild(mImpl->mXMLCurrentNode,
+                                           NULL,
+                                           (xmlChar*)"xi:include",
+                                           NULL);
+      xmlNewProp(mImpl->mXMLCurrentNode,
+                 (xmlChar*)"xpointer",
+                 (xmlChar*)iter->second.c_str());
+      mImpl->mXMLCurrentNode = mImpl->mXMLCurrentNode->parent;
+    }
+    else {
+      this->getXMLNode(&item, mImpl->mXMLDocument, mImpl->mXMLCurrentNode);
+    }
+  }
+
+  mImpl->mDepth--;
+  if(mImpl->mDepth <= 0) {
+    mImpl->closeFile();
+  }
+}
+
+// C Wrappers
+
+XDMFWRITER * XdmfWriterNew(char * fileName)
+{
+  try
+  {
+    shared_ptr<XdmfWriter> generatedWriter = XdmfWriter::New(std::string(fileName));
+    return (XDMFWRITER *)((void *)(new XdmfWriter(*generatedWriter.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfWriter> generatedWriter = XdmfWriter::New(std::string(fileName));
+    return (XDMFWRITER *)((void *)(new XdmfWriter(*generatedWriter.get())));
+  }
+}
+
+XDMFWRITER * XdmfWriterNewSpecifyHeavyDataWriter(char * fileName, XDMFHEAVYDATAWRITER * heavyDataWriter)
+{
+  try
+  {
+    shared_ptr<XdmfWriter> generatedWriter = XdmfWriter::New(std::string(fileName), shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *) heavyDataWriter));
+    return (XDMFWRITER *)((void *)(new XdmfWriter(*generatedWriter.get())));
+  }
+  catch (...)
+  {
+    shared_ptr<XdmfWriter> generatedWriter = XdmfWriter::New(std::string(fileName), shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *) heavyDataWriter));
+    return (XDMFWRITER *)((void *)(new XdmfWriter(*generatedWriter.get())));
+  }
+}
+
+void XdmfWriterFree(XDMFWRITER * item)
+{
+  if (item != NULL) {
+    delete ((XdmfWriter *)item);
+    item = NULL;
+  }
+}
+
+char * XdmfWriterGetFilePath(XDMFWRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  char * returnPointer = strdup(((XdmfWriter *)writer)->getFilePath().c_str());
+  return returnPointer;
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFHEAVYDATAWRITER * XdmfWriterGetHeavyDataWriter(XDMFWRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return (XDMFHEAVYDATAWRITER *)((void *)(((XdmfWriter *)writer)->getHeavyDataWriter().get()));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+unsigned int XdmfWriterGetLightDataLimit(XDMFWRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfWriter *)writer)->getLightDataLimit();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+int XdmfWriterGetMode(XDMFWRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  XdmfWriter::Mode testMode = ((XdmfWriter *)writer)->getMode();
+  if (testMode == XdmfWriter::Default) {
+    return XDMF_WRITER_MODE_DEFAULT;
+  }
+  else if (testMode == XdmfWriter::DistributedHeavyData) {
+    return XDMF_WRITER_MODE_DISTRIBUTED_HEAVY_DATA;
+  }
+  else {
+    return -1;
+  }
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+int XdmfWriterGetWriteXPaths(XDMFWRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfWriter *)writer)->getWriteXPaths();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+int XdmfWriterGetXPathParse(XDMFWRITER * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfWriter *)writer)->getXPathParse();
+  XDMF_ERROR_WRAP_END(status)
+  return 0;
+}
+
+void XdmfWriterSetHeavyDataWriter(XDMFWRITER * writer, XDMFHEAVYDATAWRITER * heavyDataWriter, int transferOwnership, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  if (transferOwnership) {
+    ((XdmfWriter *)writer)->setHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *) heavyDataWriter));
+  }
+  else {
+    ((XdmfWriter *)writer)->setHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *) heavyDataWriter, XdmfNullDeleter()));
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfWriterSetLightDataLimit(XDMFWRITER * writer, unsigned int numValues, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfWriter *)writer)->setLightDataLimit(numValues);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfWriterSetMode(XDMFWRITER * writer, int mode, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  switch (mode) {
+    case XDMF_WRITER_MODE_DEFAULT:
+      ((XdmfWriter *)writer)->setMode(XdmfWriter::Default);
+      break;
+    case XDMF_WRITER_MODE_DISTRIBUTED_HEAVY_DATA:
+      ((XdmfWriter *)writer)->setMode(XdmfWriter::DistributedHeavyData);
+      break;
+    default:
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid writer mode.");
+  }
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfWriterSetWriteXPaths(XDMFWRITER * writer, int writeXPaths, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfWriter *)writer)->setWriteXPaths(writeXPaths);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfWriterSetXPathParse(XDMFWRITER * writer, int xPathParse, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfWriter *)writer)->setXPathParse(xPathParse);
+  XDMF_ERROR_WRAP_END(status)
+}
diff --git a/core/XdmfWriter.hpp b/core/XdmfWriter.hpp
new file mode 100644
index 0000000..8f9f365
--- /dev/null
+++ b/core/XdmfWriter.hpp
@@ -0,0 +1,629 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfWriter.hpp                                                      */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFWRITER_HPP_
+#define XDMFWRITER_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfVisitor.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfArray;
+class XdmfInformation;
+class XdmfHeavyDataWriter;
+
+/**
+ * @brief Traverse the Xdmf graph and write light and heavy data
+ * stored to disk.
+ *
+ * XdmfWriter visits each node of an Xdmf graph structure and writes
+ * data to disk. Writing begins by calling the accept() operation on
+ * any XdmfItem and supplying this writer as the parameter. The
+ * XdmfItem as well as all children attached to the XdmfItem are
+ * written to disk. Heavy data is written to a heavy data format using
+ * an XdmfHeavyDataWriter and light data is written to XML.
+ *
+ * An infinite loop is possible if an XdmfItem somehow ends up as its own child,
+ * either directly or by way of another Xdmf Item.
+ *
+ * By default, the XdmfWriter writes all heavy data to a single heavy
+ * data file specified by the XdmfHeavyDataWriter. If a dataset is
+ * encountered that resides in a different heavy data file on disk,
+ * the dataset is read from disk and written to the new heavy data
+ * file. If this is undesired, the XdmfWriter can be set to
+ * DistributedHeavyData mode in which the writer will automatically
+ * reference any heavy dataset even if it resides in a different file
+ * than the one currently being written to.
+ */
+class XDMFCORE_EXPORT XdmfWriter : public XdmfVisitor,
+                                   public Loki::Visitor<XdmfArray> {
+
+public:
+
+  enum Mode {
+    Default,
+    DistributedHeavyData
+  };
+
+  /**
+   * Create a new XdmfWriter to write Xdmf data to disk. This will
+   * create its own hdf5 writer based on the xmlFileName. For example,
+   * if supplied "output.xmf" the created hdf5 writer would write to
+   * file "output.h5".
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @param     xmlFilePath     The path to the xml file to write to.
+   *
+   * @return                    The new XdmfWriter.
+   */
+  static shared_ptr<XdmfWriter> New(const std::string & xmlFilePath);
+
+  /**
+   * Create a new XdmfWriter to write Xdmf data to disk. This will
+   * utilize the passed heavy data writer to write any heavy data to
+   * disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   *
+   * @param     xmlFilePath             The path to the xml file to write to.
+   * @param     heavyDataWriter         The heavy data writer to use when writing.
+   *
+   * @return                            The new XdmfWriter.
+   */
+  static shared_ptr<XdmfWriter> New(const std::string & xmlFilePath, 
+                                    const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter);
+
+  /**
+   * Create a new XdmfWriter to write Xdmf data to disk. This will
+   * write heavy data to disk using the passed heavy data writer and
+   * will add xml output to the stream.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline #//bufferinitialization
+   * @until #//bufferinitialization
+   *
+   * Python: does not curretnly support this version of New
+   *
+   * @param     stream                  The output stream to write light data to.
+   * @param     heavyDataWriter         The heavy data writer to use when writing.
+   *
+   * @return                            The new XdmfWriter.
+   */
+  static shared_ptr<XdmfWriter> New(std::ostream & stream,
+                                    const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter);
+
+  virtual ~XdmfWriter();
+
+  /**
+   * Get the absolute path to the XML file on disk this writer is
+   * writing to.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getFilePath
+   * @until //#getFilePath
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getFilePath
+   * @until //#getFilePath
+   *
+   * @return    A std::string containing the path to the XML file on disk this
+   *            writer is writing to.
+   */
+  std::string getFilePath() const;
+
+  /**
+   * Get the heavy data writer that this XdmfWriter uses to write
+   * heavy data to disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getHeavyDataWriter
+   * @until //#getHeavyDataWriter
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getHeavyDataWriter
+   * @until #//getHeavyDataWriter
+   *
+   * @return    The requested heavy data writer.
+   */
+  shared_ptr<XdmfHeavyDataWriter> getHeavyDataWriter();
+
+  /**
+   * Get the heavy data writer that this XdmfWriter uses to write
+   * heavy data to disk (const version).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getHeavyDataWriterconst
+   * @until //#getHeavyDataWriterconst
+   *
+   * Python: Does not support a contant version of this function
+   *
+   * @return    The requested heavy data writer.
+   */
+  shared_ptr<const XdmfHeavyDataWriter> getHeavyDataWriter() const;
+
+  /**
+   * Get the number of values that this writer writes to light data
+   * (XML) before switching to a heavy data format.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getLightDataLimit
+   * @until //#getLightDataLimit
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getLightDataLimit
+   * @until #//getLightDataLimit
+   *
+   * @return    An unsigned int containing the number of values.
+   */
+  unsigned int getLightDataLimit() const;
+
+  /**
+   * Get the Mode of operation for this writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getMode
+   * @until //#getMode
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getMode
+   * @until #//getMode
+   *
+   * @return    The Mode of operation for this writer.
+   */
+  Mode getMode() const;
+
+  /**
+   * Gets whether XML is rebuilt with each write.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getRebuildXML
+   * @until //#getRebuildXML
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getRebuildXML
+   * @until #//getRebuildXML
+   *
+   * @return    Whether XML will be rebuilt.
+   */
+  bool getRebuildXML();
+
+  /**
+   * Get whether this writer is set to write xpaths.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getWriteXPaths
+   * @until //#getWriteXPaths
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getWriteXPaths
+   * @until #//getWriteXPaths
+   *
+   * @return    bool whether this writer is set to write xpaths.
+   */
+  bool getWriteXPaths() const;
+
+  /**
+   * Get whether this writer is set to parse xpaths from information.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getXPathParse
+   * @until //#getXPathParse
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getXPathParse
+   * @until #//getXPathParse
+   *
+   * @return    bool whether this writer is set to write xpaths.
+   */
+  bool getXPathParse() const;
+
+  /**
+   * Set the heavy data writer that this XdmfWriter uses to write
+   * heavy data to disk.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#getHeavyDataWriter
+   * @until //#getHeavyDataWriter
+   * @skipline //#setHeavyDataWriter
+   * @until //#setHeavyDataWriter
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//getHeavyDataWriter
+   * @until #//getHeavyDataWriter
+   * @skipline #//setHeavyDataWriter
+   * @until #//setHeavyDataWriter
+   *
+   * @param     heavyDataWriter         The heavy data writer to set.
+   */
+  void setHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter> heavyDataWriter);
+
+  /**
+   * Set the number of values that this writer writes to light data
+   * (XML) before switching to a heavy data format.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#setLightDataLimit
+   * @until //#setLightDataLimit
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//setLightDataLimit
+   * @until #//setLightDataLimit
+   *
+   * @param     numValues       An unsigned int containing the number of values.
+   */
+  void setLightDataLimit(const unsigned int numValues);
+
+  /**
+   * Set the mode of operation for this writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#setMode
+   * @until //#setMode
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//setMode
+   * @until #//setMode
+   *
+   * @param     mode    The Mode of operation for this writer.
+   */
+  void setMode(const Mode mode);
+
+  /**
+   * Sets whether XML will be rebuilt with each write.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#setRebuildXML
+   * @until //#setRebuildXML
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//setRebuildXML
+   * @until #//setRebuildXML
+   *
+   * @param     newStatus       Whether to rebuild XML.
+   */
+  void setRebuildXML(bool newStatus);
+
+  /**
+   * Set whether to write xpaths for this writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#setWriteXPaths
+   * @until //#setWriteXPaths
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//setWriteXPaths
+   * @until #//setWriteXPaths
+   *
+   * @param     writeXPaths     Whether to write xpaths for this writer.
+   */
+  void setWriteXPaths(const bool writeXPaths = true);
+
+  /**
+   * Set whether to parse xpaths from infomation for this writer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#heavyinitialization
+   * @until //#heavyinitialization
+   * @skipline //#setXPathParse
+   * @until //#setXPathParse
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//heavyinitialization
+   * @until #//heavyinitialization
+   * @skipline #//setXPathParse
+   * @until #//setXPathParse
+   *
+   * @param     xPathParse      Whether to write xpaths for this writer.
+   */
+  void setXPathParse(const bool xPathParse = true);
+
+  /**
+   * Write an XdmfArray to disk
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#visitarray
+   * @until //#visitarray
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//visitarray
+   * @until #//visitarray
+   *
+   * @param     array           An XdmfArray to write to disk.
+   * @param     visitor         A smart pointer to this visitor --- aids in grid traversal.
+   */
+  virtual void visit(XdmfArray & array,
+                     const shared_ptr<XdmfBaseVisitor> visitor);
+
+  /**
+   * Write an XdmfItem to disk
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfWriter.cpp
+   * @skipline //#visititem
+   * @until //#visititem
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleWriter.py
+   * @skipline #//visititem
+   * @until #//visititem
+   *
+   * @param     item            An XdmfItem to write to disk.
+   * @param     visitor         A smart pointer to this visitor --- aids in grid traversal.
+   */
+  virtual void visit(XdmfItem & item,
+                     const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfWriter(const XdmfWriter &);
+
+protected:
+
+  XdmfWriter(const std::string & xmlFilePath,
+             shared_ptr<XdmfHeavyDataWriter> heavyDataWriter,
+             std::ostream * stream = NULL);
+
+  xmlNodePtr getXMLNode(XdmfItem * item, xmlDocPtr parentDoc, xmlNodePtr parentNode);
+  bool getHasXMLArchive(XdmfItem * item);
+  void setXMLNode(XdmfItem * item, xmlNodePtr & newNode);
+
+  void setDocumentTitle(std::string title);
+  void setVersionString(std::string version);
+
+  bool mRebuildAlreadyVisited;
+
+  std::map<XdmfItem *, xmlNodePtr> mXMLArchive;
+
+private:
+
+  /**
+   * PIMPL
+   */
+  class XdmfWriterImpl;
+
+  void operator=(const XdmfWriter &);  // Not implemented.
+
+  XdmfWriterImpl * mImpl;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XDMF_WRITER_MODE_DEFAULT                30
+#define XDMF_WRITER_MODE_DISTRIBUTED_HEAVY_DATA 31
+
+// C wrappers go here
+
+struct XDMFWRITER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFWRITER XDMFWRITER;
+
+XDMFCORE_EXPORT XDMFWRITER * XdmfWriterNew(char * fileName);
+
+XDMFCORE_EXPORT XDMFWRITER * XdmfWriterNewSpecifyHeavyDataWriter(char * fileName, XDMFHEAVYDATAWRITER * heavyDataWriter);
+
+XDMFCORE_EXPORT void XdmfWriterFree(XDMFWRITER * item);
+
+XDMFCORE_EXPORT char * XdmfWriterGetFilePath(XDMFWRITER * writer, int * status);
+
+XDMFCORE_EXPORT XDMFHEAVYDATAWRITER * XdmfWriterGetHeavyDataWriter(XDMFWRITER * writer, int * status);
+
+XDMFCORE_EXPORT unsigned int XdmfWriterGetLightDataLimit(XDMFWRITER * writer, int * status);
+
+XDMFCORE_EXPORT int XdmfWriterGetMode(XDMFWRITER * writer, int * status);
+
+XDMFCORE_EXPORT int XdmfWriterGetWriteXPaths(XDMFWRITER * writer, int * status);
+
+XDMFCORE_EXPORT int XdmfWriterGetXPathParse(XDMFWRITER * writer, int * status);
+
+XDMFCORE_EXPORT void XdmfWriterSetHeavyDataWriter(XDMFWRITER * writer, XDMFHEAVYDATAWRITER * heavyDataWriter, int transferOwnership, int * status);
+
+XDMFCORE_EXPORT void XdmfWriterSetLightDataLimit(XDMFWRITER * writer, unsigned int numValues, int * status);
+
+XDMFCORE_EXPORT void XdmfWriterSetMode(XDMFWRITER * writer, int mode, int * status);
+
+XDMFCORE_EXPORT void XdmfWriterSetWriteXPaths(XDMFWRITER * writer, int writeXPaths, int * status);
+
+XDMFCORE_EXPORT void XdmfWriterSetXPathParse(XDMFWRITER * writer, int xPathParse, int * status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFWRITER_HPP_ */
diff --git a/core/dsm/CMakeLists.txt b/core/dsm/CMakeLists.txt
new file mode 100644
index 0000000..36d0ed6
--- /dev/null
+++ b/core/dsm/CMakeLists.txt
@@ -0,0 +1,216 @@
+project(XdmfDSM)
+cmake_minimum_required(VERSION 2.6)
+if (POLICY CMP0015)
+  cmake_policy(SET CMP0015 NEW)
+endif ()
+
+set(XdmfDSMLinkLibraries XdmfCore)
+set(XdmfDSMLinkLibraryDir )
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+option(XDMF_BUILD_DSM_THREADS ON)
+
+mark_as_advanced(Boost_INCLUDE_DIR)
+include_directories(${Boost_INCLUDE_DIRS})
+mark_as_advanced(FORCE Boost_INCLUDE_DIR)
+
+#mark_as_advanced(CLEAR HDF5_C_INCLUDE_DIR)
+#mark_as_advanced(CLEAR HDF5_hdf5_LIBRARY_DEBUG)
+#mark_as_advanced(CLEAR HDF5_hdf5_LIBRARY_RELEASE)
+#find_package(HDF5 REQUIRED)
+if(HDF5_FOUND)
+  mark_as_advanced(FORCE HDF5_C_INCLUDE_DIR)
+  mark_as_advanced(FORCE HDF5_hdf5_LIBRARY_DEBUG)
+  mark_as_advanced(FORCE HDF5_hdf5_LIBRARY_RELEASE)
+  include_directories(${HDF5_INCLUDE_DIRS})
+  include_directories(${HDF5_C_INCLUDE_DIR})
+  set(HDF5_LIBRARIES ${HDF5_hdf5_LIBRARY_RELEASE})
+  get_filename_component(HDF5_LIBRARY_DIR "${HDF5_hdf5_LIBRARY_RELEASE}" PATH)
+  set(XdmfDSMLinkLibraryDir ${XdmfDSMLinkLibraryDir} ${HDF5_LIBRARY_DIR})
+  # FIXME: Would like to get this info from HDF5 so we don't have conflicting
+  # MPI versions
+  if(HDF5_IS_PARALLEL)
+    # If MPI variables are already populated don't search again
+    if (NOT MPI_FOUND)
+    find_package(MPI REQUIRED)
+    endif (NOT MPI_FOUND)
+    if(MPI_FOUND)
+      include_directories(${MPI_INCLUDE_PATH})
+      set(XdmfDSMLinkLibraries ${XdmfDSMLinkLibraries} ${MPI_LIBRARY} ${MPI_EXTRA_LIBRARY})
+    endif()
+  else()
+    message(SEND_ERROR
+      "Error: XdmfDSM requires a parallel enabled build of HDF5.")
+  endif()
+  set(XdmfDSMLinkLibraries ${XdmfDSMLinkLibraries} ${HDF5_LIBRARIES})
+endif()
+
+
+find_package(LibXml2 REQUIRED)
+if(LIBXML2_FOUND)
+  include_directories(${LIBXML2_INCLUDE_DIR})
+  set(XdmfDSMLinkLibraries ${XdmfDSMLinkLibraries} ${LIBXML2_LIBRARIES})
+endif()
+
+set(XdmfDSMSources
+  XdmfHDF5ControllerDSM
+  XdmfHDF5WriterDSM
+  XdmfDSMCommMPI
+  XdmfDSMBuffer
+  XdmfDSMDescription
+  XdmfDSMItemFactory
+  XdmfDSMDriver)
+
+if (XDMF_BUILD_DSM_THREADS)
+  add_definitions(-DXDMF_BUILD_DSM_THREADS)
+endif ()
+
+if (XDMF_BUILD_DSM_THREADS)
+  find_package(H5FDdsm REQUIRED NO_MODULE)
+  if(H5FDdsm_FOUND)
+    include_directories(${H5FDdsm_INCLUDE_DIR})
+    get_property(h5fddsm_lib_location TARGET H5FDdsm PROPERTY LOCATION)
+    set(H5FDdsm_LIBRARIES ${h5fddsm_lib_location})
+    set(XdmfDSMLinkLibraries ${XdmfDSMLinkLibraries} ${H5FDdsm_LIBRARIES})
+  else()
+    message(SEND_ERROR
+      "Cannot find HDF5 DSM!  Please set H5FDdsm_DIR or disable XDMF_BUILD_DSM_THREADS and configure again.")
+  endif()
+endif ()
+
+# Set a variable if cray is being used
+STRING(REGEX MATCH "aprun" IS_CRAY "${MPIEXEC}")
+
+set(XDMF_DSM_IS_CRAY "${IS_CRAY}")
+set(XDMF_DSM_IS_CRAY "${XDMF_DSM_IS_CRAY}" PARENT_SCOPE)
+
+if (XDMF_DSM_IS_CRAY)
+  add_definitions(-DXDMF_DSM_IS_CRAY)
+endif (XDMF_DSM_IS_CRAY)
+
+add_library(XdmfDSMObjects OBJECT ${XdmfDSMSources})
+set_target_properties(XdmfDSMObjects PROPERTIES
+  POSITION_INDEPENDENT_CODE True)
+add_library(XdmfDSM $<TARGET_OBJECTS:XdmfDSMObjects>)
+if (BUILD_SHARED_LIBS)
+  add_library(XdmfDSM_Static STATIC $<TARGET_OBJECTS:XdmfDSMObjects>)
+  if (UNIX)
+    set_target_properties(XdmfDSM_Static PROPERTIES
+      OUTPUT_NAME "XdmfDSM")
+  endif (UNIX)
+endif (BUILD_SHARED_LIBS)
+#add_library(XdmfDSM ${XdmfDSMSources})
+#if (BUILD_SHARED_LIBS)
+#  add_library(XdmfDSM_Static STATIC ${XdmfDSMSources})
+#  if (UNIX)
+#    set_target_properties(XdmfDSM_Static PROPERTIES
+#      OUTPUT_NAME "XdmfDSM")
+#  endif (UNIX)
+#endif (BUILD_SHARED_LIBS)
+link_directories(${XDMF_LIBRARY_DIRS} ${XdmfDSMLinkLibraryDir})
+target_link_libraries(XdmfDSM ${XdmfDSMLinkLibraries})
+if (BUILD_SHARED_LIBS)
+  target_link_libraries(XdmfDSM_Static ${XdmfDSMLinkLibraries})
+endif (BUILD_SHARED_LIBS)
+
+if(WIN32)
+  add_definitions(-D_HDF5USEDLL_ -D_HDF5USEHLDLL_)
+  set_target_properties(XdmfDSM PROPERTIES
+      DEFINE_SYMBOL XdmfDSM_EXPORTS)
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(XdmfDSM_Static PROPERTIES
+        DEFINE_SYMBOL XdmfDSM_EXPORTS)
+  endif (BUILD_SHARED_LIBS)
+  if(NOT MSVC10)
+    set_target_properties(XdmfDSM PROPERTIES
+      PREFIX ../
+      IMPORT_PREFIX ../
+      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+      ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+    if (BUILD_SHARED_LIBS)
+      set_target_properties(XdmfDSM_Static PROPERTIES
+        PREFIX ../
+        IMPORT_PREFIX ../
+        RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+        LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+        ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+    endif()
+  endif()
+endif()
+
+if(XDMF_WRAP_JAVA)
+  XDMF_SWIG_JAVA(XdmfDSM Compiled_XdmfCore_Jar)
+endif()
+
+if(XDMF_WRAP_PYTHON)
+  if (NOT BUILD_SHARED_LIBS)
+    message(FATAL_ERROR "Python Wrappers do not function"
+                        " properly without shared libraries")
+  endif (NOT BUILD_SHARED_LIBS)
+  XDMF_SWIG_PYTHON(XdmfDSM XdmfCore)
+endif()
+
+
+set(XDMF_LIBRARY_DIRS ${XDMF_LIBRARY_DIRS} PARENT_SCOPE)
+
+if(WIN32)
+  set(XDMFDSM_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/XdmfDSM.lib PARENT_SCOPE)
+endif()
+
+if(UNIX)
+  if (BUILD_SHARED_LIBS)
+    set(XDMFDSM_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/libXdmfDSM.so
+      PARENT_SCOPE)
+  else (BUILD_SHARED_LIBS)
+    set(XDMFDSM_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/libXdmfDSM.a
+      PARENT_SCOPE)
+  endif (BUILD_SHARED_LIBS)
+endif()
+
+if(APPLE)
+    set(XDMFDSM_LIBRARY ${CMAKE_INSTALL_PREFIX}/lib/libXdmfDSM.dylib
+        PARENT_SCOPE)
+endif()
+
+file(GLOB_RECURSE
+  XdmfDSMHeaders
+  "*.hpp" "*.tpp" "*.i"
+  "../../CMake/VersionSuite/*.hpp")
+install(FILES ${XdmfDSMHeaders} DESTINATION include)
+install(TARGETS XdmfDSM
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib)
+if (BUILD_SHARED_LIBS)
+  install(TARGETS XdmfDSM_Static
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib)
+endif (BUILD_SHARED_LIBS)
+
+if(XDMF_BUILD_DSM_THREADS)
+set(XdmfDSM_INCLUDE_DIRS
+  ${Boost_INCLUDE_DIRS}
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${HDF5_INCLUDE_DIR}
+  ${H5FDdsm_INCLUDE_DIR}
+  ${LIBXML2_INCLUDE_DIR}
+  ${PYTHON_INCLUDE_DIRS}
+  CACHE INTERNAL "")
+else()
+set(XdmfDSM_INCLUDE_DIRS
+  ${Boost_INCLUDE_DIRS}
+  ${CMAKE_CURRENT_SOURCE_DIR}
+  ${HDF5_INCLUDE_DIR}
+  ${LIBXML2_INCLUDE_DIR}
+  ${PYTHON_INCLUDE_DIRS}
+  CACHE INTERNAL "")
+endif()
+
+include_directories(${XdmfCore_INCLUDE_DIRS} ${XdmfDSM_INCLUDE_DIRS})
+
+if(XDMF_BUILD_TESTING)
+  add_subdirectory(tests)
+endif()
diff --git a/core/dsm/XdmfDSM.hpp b/core/dsm/XdmfDSM.hpp
new file mode 100644
index 0000000..ee12cdf
--- /dev/null
+++ b/core/dsm/XdmfDSM.hpp
@@ -0,0 +1,66 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfCore.hpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef _XDMF_HPP
+#ifndef _XDMFDSM_HPP
+#define _XDMFDSM_HPP
+/* Keep all our Win32 Conversions here */
+#ifdef _WIN32
+/* Used to export/import from the dlls */
+#undef XDMFCORE_EXPORT
+#define XDMFCORE_EXPORT __declspec(dllimport)
+#undef XDMFCORE_TEMPLATE
+#define XDMFCORE_TEMPLATE extern
+
+#ifdef XdmfDSM_EXPORTS
+#define XDMFDSM_EXPORT __declspec(dllexport)
+#define XDMFDSM_TEMPLATE
+#else /* Xdmf_EXPORTS */
+#define XDMFDSM_EXPORT __declspec(dllimport)
+#define XDMFDSM_TEMPLATE extern
+#endif /* Xdmf_EXPORTS */
+
+/* Compiler Warnings */
+#ifndef XDMF_DEBUG
+#pragma warning( disable : 4231 ) /* nonstandard extension used : 'extern' before template explicit instantiation */
+#pragma warning( disable : 4251 ) /* needs to have dll-interface to be used by clients (Most of these guys are in private */
+#pragma warning( disable : 4275 ) /* non dll-interface class 'std::_Container_base_aux' used as base for dll-interface class */
+#pragma warning( disable : 4373 ) /* virtual function overrides,  parameters only differed by const/volatile qualifiers */
+#pragma warning( disable : 4101 ) /* 'exception' : unreferenced local variable */
+#pragma warning( disable : 4355 ) /* 'this' : used in base member initializer list */
+#pragma warning( disable : 4748 ) /* /GS can not protect parameters and local variables from local buffer overrun (turned off op)*/
+#endif /* XDMF_DEBUG */
+
+/* Compiler Optimizations will result in an 'internal compiler error', so turn them off */
+#pragma optimize("g", off)
+
+#else /* _WIN32 */
+/* We don't need to export/import since there are no dlls */
+#define XDMFCORE_EXPORT
+#define XDMFDSM_EXPORT
+#define XDMFCORE_TEMPLATE
+#define XDMFDSM_TEMPLATE
+#endif /* _WIN32 */
+#endif /* _XDMFCORE_HPP */
+#endif /*_XDMF_HPP */
+
diff --git a/core/dsm/XdmfDSM.i b/core/dsm/XdmfDSM.i
new file mode 100644
index 0000000..cf1b0c1
--- /dev/null
+++ b/core/dsm/XdmfDSM.i
@@ -0,0 +1,374 @@
+/*
+XdmfDSMPython.cpp:
+swig -v -c++ -python -o XdmfDSMPython.cpp XdmfDSM.i
+*/
+
+
+%module XdmfDSM
+%{
+
+    #include <mpi.h>
+
+    #include <XdmfArray.hpp>
+    #include <XdmfArrayReference.hpp>
+    #include <XdmfArrayType.hpp>
+    #include <XdmfCore.hpp>
+    #include <XdmfCoreItemFactory.hpp>
+    #include <XdmfCoreReader.hpp>
+    #include <XdmfDSM.hpp>
+    #include <XdmfDSMBuffer.hpp>
+    #include <XdmfDSMCommMPI.hpp>
+    #include <XdmfDSMItemFactory.hpp>
+    #include <XdmfError.hpp>
+    #include <XdmfFunction.hpp>
+    #include <XdmfHeavyDataController.hpp>
+    #include <XdmfHeavyDataWriter.hpp>
+    #include <XdmfHDF5Controller.hpp>
+    #include <XdmfHDF5Writer.hpp>
+    #include <XdmfHDF5ControllerDSM.hpp>
+    #include <XdmfHDF5WriterDSM.hpp>
+    #include <XdmfInformation.hpp>
+    #include <XdmfItem.hpp>
+    #include <XdmfItemProperty.hpp>
+    #include <XdmfSharedPtr.hpp>
+    #include <XdmfSparseMatrix.hpp>
+    #include <XdmfSubset.hpp>
+    #include <XdmfTIFFController.hpp>
+    #include <XdmfSystemUtils.hpp>
+    #include <XdmfVersion.hpp>
+    #include <XdmfVisitor.hpp>
+    #include <XdmfWriter.hpp>
+
+    #include <ProjectVersion.hpp>
+%}
+
+%import XdmfCore.i
+
+// Ignore C Wrappers
+
+// XdmfHDF5ControllerDSM
+
+%ignore XdmfHDF5ControllerDSMNewFromServerBuffer(char * hdf5FilePath,
+                                                 char * dataSetPath,
+                                                 int type,
+                                                 unsigned int * start,
+                                                 unsigned int * stride,
+                                                 unsigned int * dimensions,
+                                                 unsigned int * dataspaceDimensions,
+                                                 unsigned int numDims,
+                                                 void * dsmBuffer,
+                                                 int * status);
+%ignore XdmfHDF5ControllerDSMNew(char * hdf5FilePath,
+                                 char * dataSetPath,
+                                 int type,
+                                 unsigned int * start,
+                                 unsigned int * stride,
+                                 unsigned int * dimensions,
+                                 unsigned int * dataspaceDimensions,
+                                 unsigned int numDims,
+                                 MPI_Comm comm,
+                                 unsigned int bufferSize,
+                                 int startCoreIndex,
+                                 int endCoreIndex,
+                                 char * applicationName,
+                                 int * status);
+%ignore XdmfHDF5ControllerDSMNewPaged(char * hdf5FilePath,
+                                      char * dataSetPath,
+                                      int type,
+                                      unsigned int * start,
+                                      unsigned int * stride,
+                                      unsigned int * dimensions,
+                                      unsigned int * dataspaceDimensions,
+                                      unsigned int numDims,
+                                      MPI_Comm comm,
+                                      unsigned int bufferSize,
+                                      unsigned int blockSize,
+                                      int startCoreIndex,
+                                      int endCoreIndex,
+                                      char * applicationName,
+                                      int * status);
+%ignore XdmfHDF5ControllerDSMGetServerBuffer(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControllerDSMGetServerMode(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControllerDSMGetWorkerComm(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControllerDSMSetServerBuffer(XDMFHDF5CONTROLLERDSM * controller, XDMFDSMBUFFER * newBuffer);
+%ignore XdmfHDF5ControllerDSMSetServerMode(XDMFHDF5CONTROLLERDSM * controller, int newMode);
+%ignore XdmfHDF5ControllerDSMSetWorkerComm(XDMFHDF5CONTROLLERDSM * controller, MPI_Comm comm, int * status);
+%ignore XdmfHDF5ControllerDSMStopDSM(XDMFHDF5CONTROLLERDSM * controller, int * status);
+%ignore XdmfHDF5ControllerDSMRestartDSM(XDMFHDF5CONTROLLERDSM * controller, int * status);
+// XdmfHDF5ControlerDSM inherited from XdmfHDF5Controler
+%ignore XdmfHDF5ControlerDSMGetDataSetPath(XDMFHDF5CONTROLLERDSM * controller);
+// XdmfHDF5ControlerDSM inherited from XdmfHeavyDataController
+%ignore XdmfHDF5ControlerDSMFree(XDMFHDF5CONTROLLERDSM * item);
+%ignore XdmfHDF5ControlerDSMGetDataspaceDimensions(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetDimensions(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetFilePath(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetName(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetNumberDimensions(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetSize(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetStart(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetStride(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMSetArrayOffset(XDMFHDF5CONTROLLERDSM * controller, unsigned int newOffset);
+%ignore XdmfHDF5ControlerDSMGetArrayOffset(XDMFHDF5CONTROLLERDSM * controller);
+%ignore XdmfHDF5ControlerDSMGetType(XDMFHDF5CONTROLLERDSM * controller, int * status);
+%ignore XdmfHDF5ControlerDSMRead(XDMFHDF5CONTROLLERDSM * controller, void * array, int * status);
+
+// XdmfHDF5WriterDSM
+
+%ignore XdmfHDF5WriterDSMNewFromServerBuffer(char * filePath,
+                                             void * dsmBuffer,
+                                             int * status);
+%ignore XdmfHDF5WriterDSMNew(char * filePath,
+                             MPI_Comm comm,
+                             unsigned int bufferSize,
+                             int startCoreIndex,
+                             int endCoreIndex,
+                             int * status);
+%ignore XdmfHDF5WriterDSMNewPaged(char * filePath,
+                                  MPI_Comm comm,
+                                  unsigned int bufferSize,
+                                  unsigned int blockSize,
+                                  int startCoreIndex,
+                                  int endCoreIndex,
+                                  int * status);
+%ignore XdmfHDF5WriterDSMNewConnectRequired(char * filePath,
+                                            MPI_Comm comm,
+                                            char * applicationName,
+                                            int * status);
+%ignore XdmfHDF5WriterDSMGetDataSetSize(XDMFHDF5WRITERDSM * writer, char * fileName, char * dataSetName);
+%ignore XdmfHDF5WriterDSMGetServerBuffer(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetServerMode(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetWorkerComm(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMSetServerBuffer(XDMFHDF5WRITERDSM * writer, XDMFDSMBUFFER * newBuffer);
+%ignore XdmfHDF5WriterDSMSetServerMode(XDMFHDF5WRITERDSM * writer, int newMode);
+%ignore XdmfHDF5WriterDSMSetWorkerComm(XDMFHDF5WRITERDSM * writer, MPI_Comm comm, int * status);
+%ignore XdmfHDF5WriterDSMStopDSM(XDMFHDF5WRITERDSM * writer, int * status);
+%ignore XdmfHDF5WriterDSMRestartDSM(XDMFHDF5WRITERDSM * writer, int * status);
+%ignore XdmfHDF5WriterDSMWaitRelease(XDMFHDF5WRITERDSM * writer, char * fileName, char * datasetName, int code);
+%ignore XdmfHDF5WriterDSMWaitOn(XDMFHDF5WRITERDSM * writer, char * fileName, char * datasetName);
+// XdmfHDF5WriterDSM inherited from XdmfHDF5Writer
+%ignore XdmfHDF5WriterCloseFile(XDMFHDF5WRITER * writer, int * status);
+%ignore XdmfHDF5WriterGetChunkSize(XDMFHDF5WRITER * writer, int * status);
+%ignore XdmfHDF5WriterOpenFile(XDMFHDF5WRITER * writer, int * status);
+%ignore XdmfHDF5WriterSetChunkSize(XDMFHDF5WRITER * writer, unsigned int chunkSize, int * status);
+// XdmfHDF5WriterDSM inherited from XdmfHeavyDataWriter
+%ignore XdmfHDF5WriterDSMFree(XDMFHDF5WRITERDSM * item);
+%ignore XdmfHDF5WriterDSMGetAllowSetSplitting(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetFileIndex(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetFileOverhead(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetFilePath(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetFileSizeLimit(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetMode(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMGetReleaseData(XDMFHDF5WRITERDSM * writer);
+%ignore XdmfHDF5WriterDSMSetAllowSetSplitting(XDMFHDF5WRITERDSM * writer, int newAllow);
+%ignore XdmfHDF5WriterDSMSetFileIndex(XDMFHDF5WRITERDSM * writer, int newIndex);
+%ignore XdmfHDF5WriterDSMSetFileSizeLimit(XDMFHDF5WRITERDSM * writer, int newSize);
+%ignore XdmfHDF5WriterDSMSetMode(XDMFHDF5WRITERDSM * writer, int mode, int * status);
+%ignore XdmfHDF5WriterDSMSetReleaseData(XDMFHDF5WRITERDSM * writer, int releaseData);
+
+// XdmfDSMCommMPI
+
+%ignore XdmfDSMCommMPINew();
+%ignore XdmfDSMCommMPIFree(XDMFDSMCOMMMPI * item);
+%ignore XdmfDSMCommMPIAccept(XDMFDSMCOMMMPI * dsmComm, unsigned int numConnections, int * status);
+%ignore XdmfDSMCommMPIClosePort(XDMFDSMCOMMMPI * dsmComm, int * status);
+%ignore XdmfDSMCommMPIConnect(XDMFDSMCOMMMPI * dsmComm, int * status);
+%ignore XdmfDSMCommMPIDisconnect(XDMFDSMCOMMMPI * dsmComm, int * status);
+%ignore XdmfDSMCommMPIDupComm(XDMFDSMCOMMMPI * dsmComm, MPI_Comm comm, int * status);
+%ignore XdmfDSMCommMPIDupInterComm(XDMFDSMCOMMMPI * dsmComm, MPI_Comm comm, int * status);
+%ignore XdmfDSMCommMPIGetApplicationName(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetDsmFileName(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetDsmPortName(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetDsmProcessStructure(XDMFDSMCOMMMPI * dsmComm,
+                                             char ** names,
+                                             unsigned int * coreCount,
+                                             int * numApplications);
+%ignore XdmfDSMCommMPIGetId(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetInterComm(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetInterCommType(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetInterId(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetInterSize(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetIntraComm(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetIntraSize(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIGetUseEnvFileName(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPIInit(XDMFDSMCOMMMPI * dsmComm, int * status);
+%ignore XdmfDSMCommMPIOpenPort(XDMFDSMCOMMMPI * dsmComm, int * status);
+%ignore XdmfDSMCommMPIReadDsmPortName(XDMFDSMCOMMMPI * dsmComm);
+%ignore XdmfDSMCommMPISetApplicationName(XDMFDSMCOMMMPI * dsmComm, char * newName);
+%ignore XdmfDSMCommMPISetDsmFileName(XDMFDSMCOMMMPI * dsmComm, char * filename);
+%ignore XdmfDSMCommMPISetDsmPortName(XDMFDSMCOMMMPI * dsmComm, char * hostName);
+%ignore XdmfDSMCommMPISetUseEnvFileName(XDMFDSMCOMMMPI * dsmComm, int status);
+
+// XdmfDSMBuffer
+
+%ignore XdmfDSMBufferNew();
+%ignore XdmfDSMBufferFree(XDMFDSMBUFFER * item);
+%ignore XdmfDSMBufferAddressToId(XDMFDSMBUFFER * buffer, int Address, int * status);
+%ignore XdmfDSMBufferBroadcastComm(XDMFDSMBUFFER * buffer, int *comm, int root, int * status);
+%ignore XdmfDSMBufferBufferService(XDMFDSMBUFFER * buffer, int *returnOpcode, int * status);
+%ignore XdmfDSMBufferBufferServiceLoop(XDMFDSMBUFFER * buffer, int *returnOpcode, int * status);
+%ignore XdmfDSMBufferConfigureUniform(XDMFDSMBUFFER * buffer,
+                                      XDMFDSMCOMMMPI * Comm,
+                                      long Length,
+                                      int StartId,
+                                      int EndId,
+                                      long aBlockLength,
+                                      int random,
+                                      int * status);
+%ignore XdmfDSMBufferConnect(XDMFDSMBUFFER * buffer, int persist, int * status);
+%ignore XdmfDSMBufferCreate(XDMFDSMBUFFER * buffer, int comm, int startId, int endId, int * status);
+%ignore XdmfDSMBufferDisconnect(XDMFDSMBUFFER * buffer, int * status);
+%ignore XdmfDSMBufferGet(XDMFDSMBUFFER * buffer, long Address, long aLength, void * Data, int * status);
+%ignore XdmfDSMBufferGetAddressRangeForId(XDMFDSMBUFFER * buffer, int Id, int * Start, int * End, int * status);
+%ignore XdmfDSMBufferGetBlockLength(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetComm(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetDataPointer(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetDsmType(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetEndAddress(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetEndServerId(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetInterCommType(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetIsConnected(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetIsServer(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetLength(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetLocalBufferSizeMBytes(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetResizeFactor(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetStartAddress(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetStartServerId(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferGetTotalLength(XDMFDSMBUFFER * buffer);
+%ignore XdmfDSMBufferProbeCommandHeader(XDMFDSMBUFFER * buffer, int * comm, int * status);
+%ignore XdmfDSMBufferPut(XDMFDSMBUFFER * buffer, long Address, long aLength, void * Data, int * status);
+%ignore XdmfDSMBufferReceiveAcknowledgment(XDMFDSMBUFFER * buffer,
+                                           int source,
+                                           int * data,
+                                           int tag,
+                                           int comm,
+                                           int * status);
+%ignore XdmfDSMBufferReceiveCommandHeader(XDMFDSMBUFFER * buffer,
+                                          int * opcode,
+                                          int * source,
+                                          int * address,
+                                          int * aLength,
+                                          int comm,
+                                          int remoteSource,
+                                          int * status);
+%ignore XdmfDSMBufferReceiveData(XDMFDSMBUFFER * buffer,
+                                 int source,
+                                 char * data,
+                                 int aLength,
+                                 int tag,
+                                 int aAddress,
+                                 int comm,
+                                 int * status);
+%ignore XdmfDSMBufferReceiveInfo(XDMFDSMBUFFER * buffer,
+                                 int * status);
+%ignore XdmfDSMBufferSendAccept(XDMFDSMBUFFER * buffer, unsigned int numConnects);
+%ignore XdmfDSMBufferSendAcknowledgment(XDMFDSMBUFFER * buffer,
+                                        int dest,
+                                        int data,
+                                        int tag,
+                                        int comm,
+                                        int * status);
+%ignore XdmfDSMBufferSendCommandHeader(XDMFDSMBUFFER * buffer,
+                                       int opcode,
+                                       int dest,
+                                       int address,
+                                       int aLength,
+                                       int comm,
+                                       int * status);
+%ignore XdmfDSMBufferSendData(XDMFDSMBUFFER * buffer,
+                              int dest,
+                              char * data,
+                              int aLength,
+                              int tag,
+                              int aAddress,
+                              int comm,
+                              int * status);
+%ignore XdmfDSMBufferSendDone(XDMFDSMBUFFER * buffer, int * status);
+%ignore XdmfDSMBufferSendInfo(XDMFDSMBUFFER * buffer, int * status);
+%ignore XdmfDSMBufferSetBlockLength(XDMFDSMBUFFER * buffer, long newBlock);
+%ignore XdmfDSMBufferSetComm(XDMFDSMBUFFER * buffer, XDMFDSMCOMMMPI * newComm);
+%ignore XdmfDSMBufferSetDsmType(XDMFDSMBUFFER * buffer, int newDsmType);
+%ignore XdmfDSMBufferSetInterCommType(XDMFDSMBUFFER * buffer, int newType);
+%ignore XdmfDSMBufferSetIsConnected(XDMFDSMBUFFER * buffer, int newStatus);
+%ignore XdmfDSMBufferSetIsServer(XDMFDSMBUFFER * buffer, int newIsServer);
+%ignore XdmfDSMBufferSetLocalBufferSizeMBytes(XDMFDSMBUFFER * buffer, unsigned int newSize);
+%ignore XdmfDSMBufferSetResizeFactor(XDMFDSMBUFFER * buffer, double newFactor);
+%ignore XdmfDSMBufferWaitRelease(XDMFDSMBUFFER * buffer, char * filename, char * datasetname, int code);
+%ignore XdmfDSMBufferWaitOn(XDMFDSMBUFFER * buffer, char * filename, char * datasetname);
+
+#ifdef SWIGJAVA
+
+%pragma(java) jniclasscode=%{
+    static {
+        try {
+            System.loadLibrary("XdmfDSMJava");
+        }
+        catch (UnsatisfiedLinkError e) {
+            System.err.println("Native code library failed to load for" +
+                               "XdmfDSMJava\n" + e);
+            System.exit(1);
+        }
+    }
+%}
+
+
+#endif /* SWIGJAVA */
+
+#ifdef SWIGPYTHON
+
+%pythoncode {
+    from XdmfCore import *
+}
+
+%include mpi4py/mpi4py.i
+
+%mpi4py_typemap(Comm, MPI_Comm);
+
+%include <typemaps.i>
+%apply int & INOUT {int & data };
+
+%extend XdmfDSMBuffer {
+    bool __eq__(const XdmfDSMBuffer * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfDSMCommMPI {
+    bool __eq__(const XdmfDSMCommMPI * item) {
+        return $self == item;
+    }
+};
+
+%extend XdmfHeavyDataController {
+    static shared_ptr<XdmfHDF5ControllerDSM> XdmfHDF5ControllerDSMCast(PyObject * obj)
+    {
+      void * resultPointer = 0;
+      swig_type_info * returnType = SWIG_TypeQuery("_p_boost__shared_ptrT_XdmfHeavyDataController_t");
+      SWIG_ConvertPtr(obj, &resultPointer, returnType, 0);
+      shared_ptr<XdmfHeavyDataController> * returnControllerPointer =
+        reinterpret_cast<shared_ptr<XdmfHeavyDataController> *>(resultPointer);
+      shared_ptr<XdmfHeavyDataController> returnController = returnControllerPointer[0];
+      if (shared_ptr<XdmfHDF5ControllerDSM> returnHDF5Controller = shared_dynamic_cast<XdmfHDF5ControllerDSM>(returnController)) {
+        return returnHDF5Controller;
+      }
+      else {
+        XdmfError::message(XdmfError::FATAL, "Error: Attempting to cast a non HDF5 Controller to HDF5");
+        return shared_ptr<XdmfHDF5ControllerDSM>();
+      }
+    }
+};
+
+#endif /* SWIGPYTHON */
+
+
+
+// Shared Pointer Templates
+%shared_ptr(XdmfHDF5ControllerDSM)
+%shared_ptr(XdmfHDF5WriterDSM)
+%shared_ptr(XdmfDSMItemFactory)
+
+%include XdmfDSM.hpp
+%include XdmfHDF5ControllerDSM.hpp
+%include XdmfHDF5WriterDSM.hpp
+%include XdmfDSMBuffer.hpp
+%include XdmfDSMCommMPI.hpp
+%include XdmfDSMItemFactory.hpp
diff --git a/core/dsm/XdmfDSMBuffer.cpp b/core/dsm/XdmfDSMBuffer.cpp
new file mode 100644
index 0000000..e02ea7b
--- /dev/null
+++ b/core/dsm/XdmfDSMBuffer.cpp
@@ -0,0 +1,3030 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMBuffer.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+/*=========================================================================
+  This code is derived from an earlier work and is distributed
+  with permission from, and thanks to ...
+=========================================================================*/
+
+/*============================================================================
+
+  Project                 : H5FDdsm
+  Module                  : H5FDdsmBufferService.cxx H5FDdsmBuffer.cxx
+
+  Authors:
+     John Biddiscombe     Jerome Soumagne
+     biddisco at cscs.ch     soumagne at cscs.ch
+
+  Copyright (C) CSCS - Swiss National Supercomputing Centre.
+  You may use modify and and distribute this code freely providing
+  1) This copyright notice appears on all copies of source code
+  2) An acknowledgment appears with any substantial usage of the code
+  3) If this code is contributed to any other open source project, it
+  must not be reformatted such that the indentation, bracketing or
+  overall style is modified significantly.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  This work has received funding from the European Community's Seventh
+  Framework Programme (FP7/2007-2013) under grant agreement 225967 âxtMuSEâOC
+
+============================================================================*/
+
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+#include <XdmfError.hpp>
+#include <mpi.h>
+#include <string.h>
+#include <stdlib.h>
+#include <algorithm>
+
+#ifndef _WIN32
+  #include <unistd.h>
+#endif
+
+XdmfDSMBuffer::XdmfDSMBuffer()
+{
+  this->CommChannel = XDMF_DSM_INTER_COMM;
+  this->DsmType = XDMF_DSM_TYPE_UNIFORM;
+  this->IsServer = true;
+  this->StartAddress = this->EndAddress = 0;
+  this->StartServerId = this->EndServerId = -1;
+  this->LocalBufferSizeMBytes = 128;
+  this->Length = 0;
+  this->TotalLength = 0;
+  this->BlockLength = XDMF_DSM_DEFAULT_BLOCK_LENGTH;
+  this->NumPages = 0;
+  this->PagesAssigned = 0;
+  this->Comm = NULL;
+  this->DataPointer = NULL;
+  this->InterCommType = XDMF_DSM_COMM_MPI;
+  this->IsConnected = false;
+  this->ResizeFactor = 1;
+}
+
+XdmfDSMBuffer::~XdmfDSMBuffer()
+{
+  if (this->DataPointer) {
+    free(this->DataPointer);
+  }
+  this->DataPointer = NULL;
+}
+
+class XdmfDSMBuffer::CommandMsg
+{
+  public:
+    int Opcode;
+    int Source;
+    int  Target;
+    int Address;
+    int Length;
+};
+
+class XdmfDSMBuffer::InfoMsg
+{
+  public:
+    int type;
+    unsigned int length;
+    unsigned int total_length;
+    unsigned int block_length;
+    int start_server_id;
+    int end_server_id;
+};
+
+int
+XdmfDSMBuffer::AddressToId(int Address)
+{
+  int   ServerId = XDMF_DSM_FAIL;
+
+  switch(this->DsmType) {
+    case XDMF_DSM_TYPE_UNIFORM :
+    case XDMF_DSM_TYPE_UNIFORM_RANGE :
+      // Block based allocation should use PageToId
+      // All Servers have same length
+      // This finds out which server the address provided starts on
+      ServerId = this->StartServerId + (Address / this->Length);
+      if(ServerId > this->EndServerId ){
+        try {
+          std::stringstream message;
+          message << "ServerId " << ServerId << " for Address "
+                  << Address << " is larger than EndServerId "
+                  << this->EndServerId;
+          XdmfError::message(XdmfError::FATAL, message.str());
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      break;
+    default :
+      // Not Implemented
+      try {
+        std::stringstream message;
+        message << "DsmType " << this->DsmType << " not yet implemented or not uniform";
+        XdmfError::message(XdmfError::FATAL, message.str());
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+    }
+    return(ServerId);
+}
+
+void
+XdmfDSMBuffer::BroadcastComm(int *comm, int root)
+{
+  int status;
+
+  this->Comm->Broadcast(comm,
+                        sizeof(int),
+                        root,
+                        XDMF_DSM_INTRA_COMM);
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError(XdmfError::FATAL, "Broadcast of Comm failed");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfDSMBuffer::BufferService(int *returnOpcode)
+{
+  int        opcode, who;
+  int        aLength;
+  int          address;
+  char        *datap;
+  static int syncId      = -1;
+
+  if (this->CommChannel == XDMF_DSM_ANY_COMM) {
+    if (this->Comm->GetId() == 0) {
+      try {
+        this->Comm->Probe(&this->CommChannel);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    try {
+      this->BroadcastComm(&this->CommChannel, 0);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  try {
+    this->ReceiveCommandHeader(&opcode,
+                               &who,
+                               &address,
+                               &aLength,
+                               this->CommChannel,
+                               syncId);
+  }
+  catch (XdmfError & e) {
+    throw e;
+  }
+
+  // Connection is an ID for client or server,
+//  int communicatorId = this->CommChannel;
+
+  switch(opcode) {
+
+  // H5FD_DSM_OPCODE_PUT
+  case XDMF_DSM_OPCODE_PUT:
+    if (((unsigned int) aLength + address) > this->Length) {
+      try {
+        std::stringstream message;
+        message << "Length " << aLength << " too long for Address " << address 
+                << "\n" << "Server Start = " << this->StartAddress << " End = "
+                << this->EndAddress;
+        XdmfError::message(XdmfError::FATAL, message.str());
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    if ((datap = this->DataPointer) == NULL) {
+       try {
+         XdmfError::message(XdmfError::FATAL,
+                            "Null Data Pointer when trying to put data");
+       }
+       catch (XdmfError & e) {
+         throw e;
+       }
+    }
+    datap += address;
+    try {
+      this->ReceiveData(who,
+                        datap,
+                        aLength,
+                        XDMF_DSM_PUT_DATA_TAG,
+                        0,
+                        this->CommChannel);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    break;
+
+  // H5FD_DSM_OPCODE_GET
+  case XDMF_DSM_OPCODE_GET:
+    if (((unsigned int) aLength + address) > this->Length) {
+      try {
+        std::stringstream message;
+        message << "Length " << aLength << " too long for Address " << address
+                << "\n" << "Server Start = " << this->StartAddress << " End = "
+                << this->EndAddress;
+        XdmfError::message(XdmfError::FATAL, message.str());
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    if ((datap = this->DataPointer) == NULL) {
+      try {
+         XdmfError::message(XdmfError::FATAL,
+                            "Null Data Pointer when trying to put data");
+       }
+       catch (XdmfError & e) {
+         throw e;
+       }
+    }
+    datap += address;
+    try {
+      this->SendData(who,
+                     datap,
+                     aLength,
+                     XDMF_DSM_GET_DATA_TAG,
+                     0,
+                     this->CommChannel);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    break;
+
+  // H5FD_DSM_ACCEPT
+  // Comes from client
+  case XDMF_DSM_ACCEPT:
+  {
+    int numConnections;	
+    this->ReceiveAcknowledgment(who,
+                                numConnections,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                XDMF_DSM_INTER_COMM);
+    this->Comm->Accept(numConnections);
+    this->SendInfo();
+    break;
+  }
+  // Comes from client, requests a notifcation when a file is touched.
+  // The notification is sent out when clear is called.
+  case XDMF_DSM_SET_NOTIFY:
+  {
+    // Send the notify info to all cores.
+    int strlength = 0;
+    char * notifystring;
+    int waitingCore = 0;
+    if (this->Comm->GetId() == 0)
+    {
+      waitingCore = who;
+      this->ReceiveAcknowledgment(who,
+                                  strlength,
+                                  XDMF_DSM_EXCHANGE_TAG,
+                                  this->CommChannel);
+      notifystring = new char[strlength+1]();
+      this->ReceiveData(who,
+                        notifystring,
+                        strlength,
+                        XDMF_DSM_EXCHANGE_TAG,
+                        0,
+                        this->CommChannel);
+      notifystring[strlength] = 0;
+      WaitingMap[std::string(notifystring)].push_back(who);
+      // Send XDMF_DSM_SET_NOTIFY to all server cores in order of increasing id
+      for (int i = this->GetStartServerId() + 1; // Since this is core 0 sending it
+           i <= this->GetEndServerId();
+           ++i) {
+        if (i != this->Comm->GetInterId())
+        {
+          this->SendCommandHeader(XDMF_DSM_SET_NOTIFY, i, 0, 0, XDMF_DSM_INTER_COMM);
+        }
+      }
+    }
+    // broadcast to the other server cores
+    // BCAST strlen
+    this->Comm->Broadcast(&strlength,
+                          sizeof(int),
+                          0,
+                          XDMF_DSM_INTRA_COMM);
+    // BCAST notifystring
+    if  (this->Comm->GetId() != 0)
+    {
+      notifystring = new char[strlength + 1]();
+    }
+    this->Comm->Broadcast(&notifystring,
+                          strlength,
+                          0,
+                          XDMF_DSM_INTRA_COMM);
+    notifystring[strlength] = 0;
+    // BCAST locked core
+    this->Comm->Broadcast(&waitingCore,
+                          sizeof(int),
+                          0,
+                          XDMF_DSM_INTRA_COMM);
+
+    if (this->Comm->GetId() != 0)
+    {
+      WaitingMap[std::string(notifystring)].push_back(waitingCore);
+    }
+
+    break;
+  }
+  // sends out and clears the notifcations that are stored for a specific file.
+  case XDMF_DSM_CLEAR_NOTIFY:
+  {
+    // send a command to other cores to clear this notification
+    int strlength = 0;
+    char * notifystring;
+    int clearCode = 0;
+    if (this->Comm->GetId() == 0)
+    {
+      this->ReceiveAcknowledgment(who,
+                                  strlength,
+                                  XDMF_DSM_EXCHANGE_TAG,
+                                  this->CommChannel);
+      notifystring = new char[strlength+1]();
+      this->ReceiveData(who,
+                        notifystring,
+                        strlength,
+                        XDMF_DSM_EXCHANGE_TAG,
+                        0,
+                        this->CommChannel);
+      notifystring[strlength] = 0;
+      this->ReceiveAcknowledgment(who,
+                                  clearCode,
+                                  XDMF_DSM_EXCHANGE_TAG,
+                                  this->CommChannel);
+    }
+    // broad cast string to be notified
+    if (WaitingMap[std::string(notifystring)].size() > 0)
+    {
+      // Request the help of the rest of the server
+      // Send XDMF_DSM_SET_NOTIFY to all server cores in order of increasing id
+      for (int i = this->GetStartServerId() + 1; // Since this is core 0 sending it
+           i <= this->GetEndServerId();
+           ++i) {
+        if (i != this->Comm->GetInterId())
+        {
+          this->SendCommandHeader(XDMF_DSM_CLEAR_NOTIFY, i, 0, 0, XDMF_DSM_INTER_COMM);
+        }
+      }
+
+      // BCAST strlen and code
+      this->Comm->Broadcast(&strlength,
+                            sizeof(int),
+                            0,
+                            XDMF_DSM_INTRA_COMM);
+      this->Comm->Broadcast(&clearCode,
+                            sizeof(int),
+                            0,
+                            XDMF_DSM_INTRA_COMM);
+      // BCAST notifystring
+      if  (this->Comm->GetId() != 0)
+      {
+        notifystring = new char[strlength+1]();
+      }
+      this->Comm->Broadcast(&notifystring,
+                            strlength,
+                            0,
+                            XDMF_DSM_INTRA_COMM);
+      notifystring[strlength] = 0;
+      // cores notify based on their index, in order to split up the work
+      std::vector<unsigned int> notifiedCores = WaitingMap[std::string(notifystring)];
+      for (unsigned int i = this->Comm->GetId(); i < notifiedCores.size(); i+=this->Comm->GetIntraSize())
+      {
+        unsigned int recvCore = notifiedCores[i];
+        this->SendAcknowledgment(recvCore,
+                                 clearCode,
+                                 XDMF_DSM_EXCHANGE_TAG,
+                                 this->CommChannel);
+      }
+      // Then all cores remove the string from the map of notifications
+      WaitingMap.erase(std::string(notifystring));
+    }
+    break;
+  }
+  case XDMF_DSM_REGISTER_FILE:
+  {
+    // save file description
+    XdmfDSMBuffer::XDMF_file_desc * newfile = new XdmfDSMBuffer::XDMF_file_desc();
+
+    int strlength = 0;
+
+    this->ReceiveAcknowledgment(who,
+                                strlength,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    newfile->name = new char[strlength + 1];
+
+    this->ReceiveData(who,
+                      newfile->name,
+                      strlength,
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    newfile->name[strlength] = 0;
+
+    this->ReceiveData(who,
+                      (char *)&newfile->start,
+                      sizeof(haddr_t),
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    this->ReceiveData(who,
+                      (char *)&newfile->end,
+                      sizeof(haddr_t),
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    int recvNumPages = 0;
+
+    this->ReceiveAcknowledgment(who,
+                                recvNumPages,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    newfile->numPages = recvNumPages;
+
+    if (newfile->numPages > 0)
+    {
+      newfile->pages = new unsigned int[newfile->numPages]();
+
+      this->ReceiveData(who,
+                        (char *)newfile->pages,
+                        newfile->numPages * sizeof(unsigned int),
+                        XDMF_DSM_EXCHANGE_TAG,
+                        0,
+                        this->CommChannel);
+    }
+    else
+    {
+      newfile->pages = NULL;
+    }
+
+    // If old description exists, overwrite it.
+
+    FileDefinitions[std::string(newfile->name)] = newfile;
+
+    break;
+  }
+  case XDMF_DSM_REQUEST_PAGES:
+  {
+    // set aside pages to a file
+    char * requestfile;
+    int strlength = 0;
+
+    this->ReceiveAcknowledgment(who,
+                                strlength,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    requestfile = new char[strlength + 1];
+
+    this->ReceiveData(who,
+                      requestfile,
+                      strlength,
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    requestfile[strlength] = 0;
+
+    // This file will have its pages appended to.
+    XdmfDSMBuffer::XDMF_file_desc * filedesc;
+
+    if (FileDefinitions.count(std::string(requestfile)) > 0)
+    {
+      filedesc = FileDefinitions[std::string(requestfile)];
+    }
+    else
+    {
+      filedesc = new XDMF_file_desc();
+      filedesc->start = 0;
+      filedesc->end = 0;
+      filedesc->numPages = 0;
+      filedesc->pages = NULL;
+    }
+
+    int datasize = 0;
+
+    // Request size required for the file
+    this->ReceiveAcknowledgment(who,
+                                datasize,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    // TODO Error handling block length must be greater than 0
+    // If Block size = 0 then do nothing?
+    // Then return blank data?
+
+    int requestedblocks = ((double)datasize) / this->BlockLength;
+
+    // Round up
+    if (requestedblocks * this->BlockLength != datasize)
+    {
+      ++requestedblocks;
+    }
+
+    while (requestedblocks + PagesAssigned >= this->NumPages * this->Comm->GetIntraSize())
+    {
+      // If requested blocks are out of range, resize
+      for (int i = this->GetStartServerId() + 1; // Since this is core 0 sending it
+           i <= this->GetEndServerId();
+           ++i) {
+        if (i != this->Comm->GetInterId())
+        {
+          this->SendCommandHeader(XDMF_DSM_OPCODE_RESIZE, i, 0, 0, XDMF_DSM_INTER_COMM);
+        }
+      }
+      this->SetLength(this->Length + (this->Length * this->ResizeFactor));
+    }
+
+    unsigned int * newpagelist = new unsigned int[filedesc->numPages + requestedblocks]();
+
+    unsigned int index = 0;
+
+    for (unsigned int i = 0; i < filedesc->numPages; ++i)
+    {
+      newpagelist[index] = filedesc->pages[index];
+      ++index;
+    }
+
+    for (;index < filedesc->numPages + requestedblocks; ++index)
+    {
+      // The number of pages assigned is incremented after the page is added.
+      // The value added is simply an index
+      newpagelist[index] = PagesAssigned++;
+    }
+
+    filedesc->numPages = filedesc->numPages + requestedblocks;
+    unsigned int * oldpointer = filedesc->pages;
+    filedesc->pages = newpagelist;
+
+    if (oldpointer != NULL)
+    {
+      delete oldpointer;
+    }
+
+    // Send back new page allocation pointer
+
+    this->SendAcknowledgment(who,
+                             filedesc->numPages,
+                             XDMF_DSM_EXCHANGE_TAG,
+                             this->CommChannel);
+
+    this->SendData(who,
+                   (char *)filedesc->pages,
+                   filedesc->numPages * sizeof(unsigned int),
+                   XDMF_DSM_EXCHANGE_TAG,
+                   0,
+                   this->CommChannel);
+
+    this->SendData(who,
+                   (char*)&filedesc->start,
+                   sizeof(haddr_t),
+                   XDMF_DSM_EXCHANGE_TAG,
+                   0,
+                   this->CommChannel);
+
+    filedesc->end = filedesc->start + (filedesc->numPages * this->BlockLength);
+
+    this->SendData(who,
+                   (char*)&(filedesc->end),
+                   sizeof(haddr_t),
+                   XDMF_DSM_EXCHANGE_TAG,
+                   0,
+                   this->CommChannel);
+
+    // Notify the current size of the buffer
+    int currentLength = this->Length;
+    this->SendAcknowledgment(who,
+                             currentLength,
+                             XDMF_DSM_EXCHANGE_TAG,
+                             this->CommChannel);
+
+    break;
+  }
+  case XDMF_DSM_REQUEST_FILE:
+  {
+    char * requestfile;
+    int strlength = 0;
+
+    this->ReceiveAcknowledgment(who,
+                                strlength,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    requestfile = new char[strlength + 1];
+
+    this->ReceiveData(who,
+                      requestfile,
+                      strlength,
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    requestfile[strlength] = 0;
+
+    // This file will be returned.
+    XdmfDSMBuffer::XDMF_file_desc * filedesc;
+
+    if (FileDefinitions.count(std::string(requestfile)) > 0)
+    {
+      this->SendAcknowledgment(who,
+                               XDMF_DSM_SUCCESS,
+                               XDMF_DSM_EXCHANGE_TAG,
+                               this->CommChannel);
+
+      filedesc = FileDefinitions[std::string(requestfile)];
+
+      this->SendData(who,
+                     (char*)&filedesc->start,
+                     sizeof(haddr_t),
+                     XDMF_DSM_EXCHANGE_TAG,
+                     0,
+                     this->CommChannel);
+
+      this->SendData(who,
+                     (char*)&filedesc->end,
+                     sizeof(haddr_t),
+                     XDMF_DSM_EXCHANGE_TAG,
+                     0,
+                     this->CommChannel);
+
+      int sendNumPages = filedesc->numPages;
+
+      this->SendAcknowledgment(who,
+                               sendNumPages,
+                               XDMF_DSM_EXCHANGE_TAG,
+                               this->CommChannel);
+
+      this->SendData(who,
+                     (char *)filedesc->pages,
+                     filedesc->numPages * sizeof(unsigned int),
+                     XDMF_DSM_EXCHANGE_TAG,
+                     0,
+                     this->CommChannel);
+    }
+    else
+    {
+      this->SendAcknowledgment(who,
+                               XDMF_DSM_FAIL,
+                               XDMF_DSM_EXCHANGE_TAG,
+                               this->CommChannel);
+    }
+
+    break;
+  }
+  case XDMF_DSM_OPCODE_RESIZE:
+    this->SetLength(this->Length + (this->Length * this->ResizeFactor));
+    break;
+  case XDMF_DSM_REQUEST_ACCESS:
+  {
+    int isLocked = 0;
+
+    char * requestfile;
+    int strlength = 0;
+
+    this->ReceiveAcknowledgment(who,
+                                strlength,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    requestfile = new char[strlength + 1];
+
+    this->ReceiveData(who,
+                      requestfile,
+                      strlength,
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    requestfile[strlength] = 0;
+
+    // If the requesting core is the one who
+    // already locked the file then tell it that there is not lock.
+    std::map<std::string, int>::iterator isOwner = FileOwners.find(std::string(requestfile));
+
+    if (LockedMap.count(std::string(requestfile)) > 0)
+    {
+      if (isOwner->second != who)
+      {
+        // If the file is locked notify the requesting core and add it to the queue.
+        isLocked = 1;
+        LockedMap[std::string(requestfile)].push(who);
+      }
+    }
+    else
+    {
+      LockedMap[std::string(requestfile)] = std::queue<unsigned int>();
+      FileOwners[std::string(requestfile)] = who;
+    }
+
+    this->SendAcknowledgment(who,
+                             isLocked,
+                             XDMF_DSM_EXCHANGE_TAG,
+                             this->CommChannel);
+
+    break;
+  }
+  case XDMF_DSM_UNLOCK_FILE:
+  {
+    char * requestfile;
+    int strlength = 0;
+
+    this->ReceiveAcknowledgment(who,
+                                strlength,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                this->CommChannel);
+
+    requestfile = new char[strlength + 1];
+
+    this->ReceiveData(who,
+                      requestfile,
+                      strlength,
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      this->CommChannel);
+
+    requestfile[strlength] = 0;
+
+    // If file isn't locked do nothing
+    if (LockedMap.count(std::string(requestfile)) > 0)
+    {
+      // Remove the queue if there are no more waiting
+      if (LockedMap[std::string(requestfile)].size() > 0)
+      {
+        // Pop the next process waiting off the queue
+        unsigned int nextCore = LockedMap[std::string(requestfile)].front();
+        LockedMap[std::string(requestfile)].pop();
+        FileOwners[std::string(requestfile)] = nextCore;
+        this->SendAcknowledgment(nextCore,
+                                 1,
+                                 XDMF_DSM_EXCHANGE_TAG,
+                                 this->CommChannel);
+      }
+      if(LockedMap[std::string(requestfile)].size() == 0)
+      {
+        LockedMap.erase(std::string(requestfile));
+        FileOwners.erase(std::string(requestfile));
+      }
+    }
+
+    break;
+  }
+  case XDMF_DSM_LOCK_ACQUIRE:
+    // Currently unsupported
+    break;
+
+  // H5FD_DSM_LOCK_RELEASE
+  // Comes from client or server depending on communicator
+  case XDMF_DSM_LOCK_RELEASE:
+    // Currently unsupported
+    break;
+
+  // H5FD_DSM_OPCODE_DONE
+  // Always received on server
+  case XDMF_DSM_OPCODE_DONE:
+    break;
+
+  // DEFAULT
+  default :
+    try {
+      std::stringstream message;
+      message << "Error: Unknown Opcode " << opcode;
+      XdmfError::message(XdmfError::FATAL, message.str());
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  if (returnOpcode) *returnOpcode = opcode;
+  return(XDMF_DSM_SUCCESS);
+}
+
+void
+XdmfDSMBuffer::BufferServiceLoop(int *returnOpcode)
+{
+  int op, status = XDMF_DSM_SUCCESS;
+  while (status == XDMF_DSM_SUCCESS) {
+    try {
+      status = this->BufferService(&op);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    if (returnOpcode) *returnOpcode = op;
+    if (op == XDMF_DSM_OPCODE_DONE) {
+      break;
+    }
+  }
+}
+
+void
+XdmfDSMBuffer::Create(MPI_Comm newComm, int startId, int endId)
+{
+  //
+  // Create DSM communicator
+  //
+  switch (this->InterCommType) {
+    case XDMF_DSM_COMM_MPI:
+      this->Comm = new XdmfDSMCommMPI();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL, "DSM communication type not supported");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+  }
+
+  this->Comm->DupComm(newComm);
+  this->Comm->Init();
+
+  // Uniform Dsm : every node has a buffer the same size. (Addresses are sequential)
+  // Block DSM : nodes are set up using paging
+  long length = (long) (this->LocalBufferSizeMBytes)*1024LU*1024LU;
+  switch (this->DsmType) {
+    case XDMF_DSM_TYPE_UNIFORM:
+    case XDMF_DSM_TYPE_UNIFORM_RANGE:
+      this->ConfigureUniform(this->Comm, length, startId, endId);
+      break;
+    case XDMF_DSM_TYPE_BLOCK_CYCLIC:
+      this->ConfigureUniform(this->Comm, length, startId, endId, this->BlockLength, false);
+      break;
+    case XDMF_DSM_TYPE_BLOCK_RANDOM:
+      this->ConfigureUniform(this->Comm, length, startId, endId, this->BlockLength, true);
+      break;
+    default:
+      try {
+        XdmfError(XdmfError::FATAL, "DSM configuration type not supported");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+  }
+}
+
+void
+XdmfDSMBuffer::ConfigureUniform(XdmfDSMCommMPI *aComm, long aLength,
+                                int startId, int endId, long aBlockLength,
+                                bool random)
+{
+  if (startId < 0) {
+    startId = 0;
+  }
+  if (endId < 0) {
+    endId = aComm->GetIntraSize() - 1;
+  }
+  this->SetDsmType(XDMF_DSM_TYPE_UNIFORM_RANGE);
+  if ((startId == 0) && (endId == aComm->GetIntraSize() - 1)) {
+    this->SetDsmType(XDMF_DSM_TYPE_UNIFORM);
+  }
+  if (aBlockLength) {
+    if (!random) {
+      this->SetDsmType(XDMF_DSM_TYPE_BLOCK_CYCLIC);
+    }
+    else {
+      this->SetDsmType(XDMF_DSM_TYPE_BLOCK_RANDOM);
+    }
+    this->SetBlockLength(aBlockLength);
+  }
+  this->StartServerId = startId;
+  this->EndServerId = endId;
+  this->SetComm(aComm);
+  if ((aComm->GetId() >= startId) &&
+      (aComm->GetId() <= endId) &&
+      this->IsServer) {
+    try {
+      if (aBlockLength) {
+        // For optimization we make the DSM length fit to a multiple of block size
+        this->SetLength(((long)(aLength / aBlockLength)) * aBlockLength);
+        this->NumPages = ((long)(aLength / aBlockLength));
+      }
+      else {
+        this->SetLength(aLength);
+      }
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    this->StartAddress = (aComm->GetId() - startId) * aLength;
+    this->EndAddress = this->StartAddress + aLength - 1;
+  }
+  else {
+    if (aBlockLength) {
+      this->Length = ((long)(aLength / aBlockLength)) * aBlockLength;
+    }
+    else {
+      this->Length = aLength;
+    }
+  }
+  this->TotalLength = this->GetLength() * (endId - startId + 1);
+  // Set DSM structure
+  std::vector<std::pair<std::string, unsigned int> > newStructure;
+  // determine size of application before the server
+  if (startId > 0)
+  {
+    newStructure.push_back(std::pair<std::string, unsigned int>(aComm->GetApplicationName(), startId));
+  }
+  newStructure.push_back(std::pair<std::string, unsigned int>("Server", (endId + 1) - startId));
+  if(aComm->GetInterSize() - (startId +((endId + 1) - startId)) > 0)
+  {
+    newStructure.push_back(std::pair<std::string, unsigned int>(aComm->GetApplicationName(), aComm->GetInterSize() - (startId +((endId + 1) - startId))));
+  }
+  aComm->SetDsmProcessStructure(newStructure);
+}
+
+void
+XdmfDSMBuffer::Connect(bool persist)
+{
+  int status;
+
+  do {
+    try {
+      status = this->GetComm()->Connect();
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    if (status == MPI_SUCCESS) {
+      this->SetIsConnected(true);
+      try {
+        this->ReceiveInfo();
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    else {
+#ifdef _WIN32
+  Sleep(1000);
+  // Since windows has a different sleep command
+#else
+  sleep(1);
+#endif
+    }
+  } while (persist && (status != MPI_SUCCESS));
+}
+
+void
+XdmfDSMBuffer::Disconnect()
+{
+  // Disconnecting is done manually
+  try {
+    this->GetComm()->Disconnect();
+  }
+  catch (XdmfError & e) {
+    throw e;
+  }
+  this->SetIsConnected(false);
+}
+
+void
+XdmfDSMBuffer::Get(long Address, long aLength, void *Data)
+{
+  int   who, MyId = this->Comm->GetInterId();
+  int   astart, aend, len;
+  char   *datap = (char *)Data;
+
+  // While there is length left
+  while(aLength) {
+    // Figure out what server core the address is located on
+    who = this->AddressToId(Address);
+    if(who == XDMF_DSM_FAIL){
+      try {
+        XdmfError::message(XdmfError::FATAL, "Address Error");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    // Get the start and end of the block listed
+    this->GetAddressRangeForId(who, &astart, &aend);
+    // Determine the amount of data to be written to that core
+    // Basically, it's how much data will fit from
+    // the starting point of the address to the end
+    len = std::min(aLength, aend - Address + 1);
+    // If the data is on the core running this code, then the put is simple
+    if(who == MyId){
+      char *dp;
+      dp = this->DataPointer;
+      dp += Address - this->StartAddress;
+      memcpy(datap, dp, len);
+    }
+    else{
+      // Otherwise send it to the appropriate core to deal with
+      int   dataComm = XDMF_DSM_INTRA_COMM;
+      if (this->Comm->GetInterComm() != MPI_COMM_NULL) {
+        dataComm = XDMF_DSM_INTER_COMM;
+      }
+      try {
+        this->SendCommandHeader(XDMF_DSM_OPCODE_GET, who, Address - astart, len, dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      try {
+        this->ReceiveData(who, datap, len, XDMF_DSM_GET_DATA_TAG, Address - astart, dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    // Shift all the numbers by the length of the data written
+    // Until aLength = 0
+    aLength -= len;
+    Address += len;
+    datap += len;
+  }
+}
+
+void
+XdmfDSMBuffer::Get(unsigned int * pages, unsigned int numPages, long Address, long aLength, void *Data)
+{
+  char * currentStart;
+  unsigned int currentPageId = Address / this->BlockLength;
+  unsigned int dsmPage;
+  long startingAddress = Address % this->BlockLength;
+  unsigned int tranferedLength;
+  unsigned int dataPage = 0;
+
+  long pointeroffset = 0;
+
+  int serverCore;
+  int writeAddress;
+
+  while (aLength) {
+    if (dataPage == 0) {
+      tranferedLength = this->BlockLength - startingAddress;
+    }
+    else {
+      tranferedLength = this->BlockLength;
+    }
+    if (tranferedLength > aLength) {
+      tranferedLength = aLength;
+    }
+
+    dsmPage = pages[currentPageId];
+
+    currentStart = (char *)Data + pointeroffset;;
+
+    // Write page to DSM
+    // page to DSM server Id
+    // page to address
+    // write to location
+
+    serverCore = PageToId(dsmPage);
+    writeAddress = PageToAddress(dsmPage);
+
+    if (serverCore == XDMF_DSM_FAIL) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Unable to determine server core.");
+    }
+
+    if (writeAddress == XDMF_DSM_FAIL) {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Unable to determine write address.");
+    }
+
+    if (dataPage == 0)
+    {
+      writeAddress += startingAddress;
+    }
+
+    // If the data is on the core running this code, then the put is simple
+    if(serverCore == this->Comm->GetInterId()){
+      char *dp;
+      dp = this->DataPointer;
+      dp += writeAddress;
+      memcpy(currentStart, dp, tranferedLength);
+    }
+    else{
+      // Otherwise send it to the appropriate core to deal with
+      int dataComm = XDMF_DSM_INTRA_COMM;
+      if (this->Comm->GetInterComm() != MPI_COMM_NULL) {
+        dataComm = XDMF_DSM_INTER_COMM;
+      }
+      try {
+        this->SendCommandHeader(XDMF_DSM_OPCODE_GET,
+                                serverCore,
+                                writeAddress,
+                                tranferedLength,
+                                dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      try {
+        this->ReceiveData(serverCore,
+                          currentStart,
+                          tranferedLength,
+                          XDMF_DSM_GET_DATA_TAG,
+                          writeAddress,
+                          dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+
+    aLength -= tranferedLength;
+    pointeroffset += tranferedLength;
+    // move to the next page
+    ++currentPageId;
+    ++dataPage;
+  }
+}
+
+void
+XdmfDSMBuffer::GetAddressRangeForId(int Id, int *Start, int *End){
+    switch(this->DsmType) {
+      case XDMF_DSM_TYPE_UNIFORM :
+      case XDMF_DSM_TYPE_UNIFORM_RANGE :
+        // All Servers have same length
+        // Start index is equal to the id inside the servers times
+        // the length of the block per server
+        // It is the starting index of the server's data block relative
+        // to the entire block
+        *Start = (Id - this->StartServerId) * this->Length;
+        // End index is simply the start index + the length of the
+        // server's data block.
+        // The range produced is the start of the server's data block to its end.
+        *End = *Start + Length - 1;
+        break;
+      default :
+        // Not Implemented
+        try {
+          std::stringstream message;
+          message << "DsmType " << this->DsmType << " not yet implemented";
+          XdmfError::message(XdmfError::FATAL, message.str());
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        break;
+    }
+}
+
+long
+XdmfDSMBuffer::GetBlockLength()
+{
+  return this->BlockLength;
+}
+
+XdmfDSMCommMPI *
+XdmfDSMBuffer::GetComm()
+{
+  return this->Comm;
+}
+
+char *
+XdmfDSMBuffer::GetDataPointer()
+{
+  return this->DataPointer;
+}
+
+int
+XdmfDSMBuffer::GetDsmType()
+{
+  return this->DsmType;
+}
+
+int
+XdmfDSMBuffer::GetEndAddress()
+{
+  return this->EndAddress;
+}
+
+int
+XdmfDSMBuffer::GetEndServerId()
+{
+  return this->EndServerId;
+}
+
+int
+XdmfDSMBuffer::GetInterCommType()
+{
+  return this->InterCommType;
+}
+
+bool
+XdmfDSMBuffer::GetIsConnected()
+{
+  return IsConnected;
+}
+
+bool
+XdmfDSMBuffer::GetIsServer()
+{
+  return this->IsServer;
+}
+
+long
+XdmfDSMBuffer::GetLength()
+{
+  // This is the length of the pointer on the current core.
+  // Different from local buffer size as that value is
+  // the starting size.
+  return this->Length;
+}
+
+unsigned int
+XdmfDSMBuffer::GetLocalBufferSizeMBytes()
+{
+  // This is the starting value, so it is not updated as the pointer is expanded.
+  return this->LocalBufferSizeMBytes;
+}
+
+double
+XdmfDSMBuffer::GetResizeFactor()
+{
+  return this->ResizeFactor;
+}
+
+int
+XdmfDSMBuffer::GetStartAddress()
+{
+  return this->StartAddress;
+}
+
+int
+XdmfDSMBuffer::GetStartServerId()
+{
+  return this->StartServerId;
+}
+
+long
+XdmfDSMBuffer::GetTotalLength()
+{
+  return this->TotalLength;
+}
+
+void
+XdmfDSMBuffer::Lock(char * filename)
+{
+  int strlength = std::string(filename).size();
+  // Request access to the file
+  this->SendCommandHeader(XDMF_DSM_REQUEST_ACCESS,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           strlength,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 filename,
+                 strlength,
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  int isLocked = 0;
+
+  this->ReceiveAcknowledgment(this->GetStartServerId(),
+                              isLocked,
+                              XDMF_DSM_EXCHANGE_TAG,
+                              XDMF_DSM_INTER_COMM);
+
+  if (isLocked == 1)
+  {
+    // If locked wait for notification that the file is available.
+    this->ReceiveAcknowledgment(this->GetStartServerId(),
+                            isLocked,
+                            XDMF_DSM_EXCHANGE_TAG,
+                            XDMF_DSM_INTER_COMM);
+  }
+}
+
+int
+XdmfDSMBuffer::PageToId(int pageId)
+{
+  int   ServerId = XDMF_DSM_FAIL;
+
+  switch(this->DsmType) {
+    case XDMF_DSM_TYPE_BLOCK_CYCLIC :
+    case XDMF_DSM_TYPE_BLOCK_RANDOM :
+    {
+      // Block based allocation should use PageToId
+      // All Servers have same length
+      // This finds out which server the address provided starts on
+      int serversize = (this->EndServerId - this->StartServerId);
+      if (serversize < 1)
+      {
+        serversize = 1;
+      }
+      ServerId = pageId % serversize;// This should only be called by the server
+      ServerId += this->StartServerId; // Apply the offset of the server if required.
+      break;
+    }
+    default :
+      // Not Implemented
+      try {
+        std::stringstream message;
+        message << "DsmType " << this->DsmType << " not yet implemented or not paged";
+        XdmfError::message(XdmfError::FATAL, message.str());
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+    }
+    return(ServerId);
+}
+
+int
+XdmfDSMBuffer::PageToAddress(int pageId)
+{
+  int   resultAddress = XDMF_DSM_FAIL;
+
+  switch(this->DsmType) {
+    case XDMF_DSM_TYPE_BLOCK_CYCLIC :
+    case XDMF_DSM_TYPE_BLOCK_RANDOM :
+    {
+      // Block based allocation should use PageToId
+      // All Servers have same length
+      // This finds out which server the address provided starts on
+      // Since this is integers being divided the result is truncated.
+      int serversize = (this->EndServerId - this->StartServerId);
+      if (serversize < 1)
+      {
+        serversize = 1;
+      }
+      resultAddress = this->BlockLength * (pageId / serversize);
+      break;
+    }
+    default :
+      // Not Implemented
+      try {
+        std::stringstream message;
+        message << "DsmType " << this->DsmType << " not yet implemented or not paged";
+        XdmfError::message(XdmfError::FATAL, message.str());
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+    }
+    return(resultAddress);
+}
+
+void
+XdmfDSMBuffer::ProbeCommandHeader(int *comm)
+{
+  // Used for finding a comm that has a waiting command, then sets the comm
+  int status = XDMF_DSM_FAIL;
+  MPI_Status signalStatus;
+
+  int flag;
+  MPI_Comm probeComm =
+    static_cast<XdmfDSMCommMPI *>(this->Comm)->GetIntraComm();
+
+  // Spin until a message is found on one of the communicators
+  while (status != XDMF_DSM_SUCCESS) {
+    status = MPI_Iprobe(XDMF_DSM_ANY_SOURCE,
+                        XDMF_DSM_ANY_TAG,
+                        probeComm,
+                        &flag,
+                        &signalStatus);
+    if (status != MPI_SUCCESS)
+    {
+       try {
+         XdmfError::message(XdmfError::FATAL,
+                            "Error: Failed to probe for command header");
+       }
+       catch (XdmfError & e) {
+         throw e;
+       }
+    }
+    if (flag) {
+      status = XDMF_DSM_SUCCESS;
+    }
+    else {
+      if (static_cast<XdmfDSMCommMPI *>(this->Comm)->GetInterComm() != MPI_COMM_NULL) {
+        if (probeComm == static_cast<XdmfDSMCommMPI *>(this->Comm)->GetIntraComm()) {
+          probeComm = static_cast<XdmfDSMCommMPI *>(this->Comm)->GetInterComm();
+        }
+        else {
+          probeComm = static_cast<XdmfDSMCommMPI *>(this->Comm)->GetIntraComm();
+        }
+      }
+    }
+  }
+  if (probeComm == static_cast<XdmfDSMCommMPI *>(this->Comm)->GetInterComm()) {
+    *comm = XDMF_DSM_INTER_COMM;
+  }
+  else
+  {
+    *comm = XDMF_DSM_INTRA_COMM;
+  }
+
+  probeComm = MPI_COMM_NULL;
+}
+
+void
+XdmfDSMBuffer::Put(long Address, long aLength, const void *Data)
+{
+  int   who, MyId = this->Comm->GetInterId();
+  int   astart, aend, len;
+  char    *datap = (char *)Data;
+
+  // While there is length left
+  while(aLength){
+    // Figure out what server core the address is located on
+    who = this->AddressToId(Address);
+    if(who == XDMF_DSM_FAIL){
+      try {
+        XdmfError::message(XdmfError::FATAL, "Address Error");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    // Get the start and end of the block listed
+    this->GetAddressRangeForId(who, &astart, &aend);
+    // Determine the amount of data to be written to that core
+    // Basically, it's how much data will fit from the starting point of
+    // the address to the end
+    len = std::min(aLength, aend - Address + 1);
+    // If the data is on the core running this code, then the put is simple
+    if(who == MyId){
+      char *dp;
+      dp = this->DataPointer;
+      dp += Address - this->StartAddress;
+      memcpy(dp, datap, len);
+    }
+    else{
+      // Otherwise send it to the appropriate core to deal with
+      int   dataComm = XDMF_DSM_INTRA_COMM;
+      if (this->Comm->GetInterComm() != MPI_COMM_NULL) {
+        dataComm = XDMF_DSM_INTER_COMM;
+      }
+      try {
+        this->SendCommandHeader(XDMF_DSM_OPCODE_PUT,
+                                who,
+                                Address - astart,
+                                len,
+                                dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      try {
+        this->SendData(who,
+                       datap, 
+                       len,
+                       XDMF_DSM_PUT_DATA_TAG,
+                       Address - astart,
+                       dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    // Shift all the numbers by the length of the data written
+    // Until aLength = 0
+    aLength -= len;
+    Address += len;
+    datap += len;
+  }
+}
+
+void
+XdmfDSMBuffer::Put(unsigned int * pages, unsigned int numPages, haddr_t Address, haddr_t aLength, const void *Data)
+{
+
+  char * currentStart;
+  unsigned int currentPageId = Address / this->BlockLength;
+  unsigned int dsmPage = 0;
+  long startingAddress = Address % this->BlockLength;
+  unsigned int tranferedLength;
+
+  long pointeroffset = 0;
+
+  unsigned int dataPage = 0;
+
+  int serverCore = 0;
+  int writeAddress = 0;
+
+  while (aLength) {
+    if (dataPage == 0) {
+      tranferedLength = this->BlockLength - startingAddress;
+    }
+    else {
+      tranferedLength = this->BlockLength;
+    }
+    if (tranferedLength > aLength) {
+      tranferedLength = aLength;
+    }
+
+    dsmPage = pages[currentPageId];
+
+    currentStart = (char *)Data + pointeroffset;
+
+    // Write page to DSM
+    // page to DSM server Id
+    // page to address
+    // write to location
+    serverCore = PageToId(dsmPage);
+
+    writeAddress = PageToAddress(dsmPage);
+
+    if (serverCore == XDMF_DSM_FAIL) {
+      XdmfError::message(XdmfError::FATAL, "Error: Unable to determine page server core.");
+    }
+    if (writeAddress == XDMF_DSM_FAIL) {
+      XdmfError::message(XdmfError::FATAL, "Error: Unable to determine page address.");
+    }
+
+    if (dataPage == 0)
+    {
+      writeAddress += startingAddress;
+    }
+
+    // If the data is on the core running this code, then the put is simple
+    if(serverCore == this->Comm->GetInterId()) {
+      char *dp;
+      dp = this->DataPointer;
+      dp += writeAddress;
+      memcpy(dp, currentStart, tranferedLength);
+    }
+    else{
+      // Otherwise send it to the appropriate core to deal with
+      int dataComm = XDMF_DSM_INTRA_COMM;
+      if (this->Comm->GetInterComm() != MPI_COMM_NULL) {
+        dataComm = XDMF_DSM_INTER_COMM;
+      }
+      try {
+        this->SendCommandHeader(XDMF_DSM_OPCODE_PUT,
+                                serverCore,
+                                writeAddress,
+                                tranferedLength,
+                                dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      try {
+        this->SendData(serverCore,
+                       currentStart,
+                       tranferedLength,
+                       XDMF_DSM_PUT_DATA_TAG,
+                       writeAddress,
+                       dataComm);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+
+    aLength -= tranferedLength;
+    pointeroffset += tranferedLength;
+    // move to the next page
+    ++currentPageId;
+    ++dataPage;
+  }
+}
+
+void
+XdmfDSMBuffer::ReceiveAcknowledgment(int source, int &data, int tag, int comm)
+{
+  int status;
+  MPI_Status signalStatus;
+
+  this->Comm->Receive(&data,
+                      sizeof(int),
+                      source,
+                      comm,
+                      tag);
+  status = MPI_SUCCESS;
+
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to receive data");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfDSMBuffer::ReceiveCommandHeader(int *opcode, int *source, int *address, int *aLength, int comm, int remoteSource)
+{
+  CommandMsg cmd;
+  memset(&cmd, 0, sizeof(CommandMsg));
+  int status = MPI_ERR_OTHER;
+  MPI_Status signalStatus;
+
+  if (remoteSource < 0) {
+    remoteSource = MPI_ANY_SOURCE;
+  }
+
+  this->Comm->Receive(&cmd,
+                      sizeof(CommandMsg),
+                      remoteSource,
+                      comm,
+                      XDMF_DSM_COMMAND_TAG);
+
+  status = MPI_SUCCESS;
+
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to receive command header");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    *opcode  = cmd.Opcode;
+    *source  = cmd.Source;
+    *address = cmd.Address;
+    *aLength = cmd.Length;
+  }
+}
+
+void
+XdmfDSMBuffer::ReceiveData(int source, char * data, int aLength, int tag, int aAddress, int comm)
+{
+  int status;
+  MPI_Status signalStatus;
+  this->Comm->Receive(data,
+                      aLength,
+                      source,
+                      comm,
+                      tag);
+  status = MPI_SUCCESS;
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to receive data");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfDSMBuffer::ReceiveInfo()
+{
+  InfoMsg  dsmInfo;
+  int status;
+
+  memset(&dsmInfo, 0, sizeof(InfoMsg));
+
+  int infoStatus = 0;
+
+  if (this->Comm->GetId() == 0) {
+    infoStatus = 1;
+  }
+
+  int * groupInfoStatus = new int[this->Comm->GetInterSize()]();
+
+  this->Comm->AllGather(&infoStatus,
+                        sizeof(int),
+                        &(groupInfoStatus[0]),
+                        sizeof(int),
+                        XDMF_DSM_INTER_COMM);
+
+  int sendCore = 0;
+
+  for (int i = 0; i < this->Comm->GetInterSize(); ++i) {
+    if (groupInfoStatus[i] == 2) {
+      sendCore = i;
+    }
+  }
+
+  status = MPI_SUCCESS;
+
+  this->Comm->Broadcast(&dsmInfo,
+                        sizeof(InfoMsg),
+                        sendCore,
+                        XDMF_DSM_INTER_COMM);
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to broadcast info");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  this->SetDsmType(dsmInfo.type);
+  // We are a client so don't allocate anything but only set a virtual remote length
+  this->SetLength(dsmInfo.length);
+  this->TotalLength = dsmInfo.total_length;
+  this->SetBlockLength(dsmInfo.block_length);
+  this->StartServerId = dsmInfo.start_server_id;
+  this->EndServerId = dsmInfo.end_server_id;
+
+  MPI_Comm comm = this->Comm->GetInterComm();
+
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  int rank = this->Comm->GetInterId();
+  int size = this->Comm->GetInterSize();
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+  std::string applicationName = this->Comm->GetApplicationName();
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  std::vector<std::pair<std::string, unsigned int> > newStructure;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    newStructure.push_back(std::pair<std::string, unsigned int>(std::string(coreTag), coreSplit.size()));
+    coreSplit.clear();
+    ++splitid;
+  }
+  this->Comm->SetDsmProcessStructure(newStructure);
+}
+
+int
+XdmfDSMBuffer::RegisterFile(char * name, unsigned int * pages, unsigned int numPages, haddr_t start, haddr_t end)
+{
+  this->SendCommandHeader(XDMF_DSM_REGISTER_FILE,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+
+  int strlength = std::string(name).size();
+
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           strlength,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 name,
+                 strlength,
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 (char *)&start,
+                 sizeof(haddr_t),
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 (char *)&end,
+                 sizeof(haddr_t),
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           numPages,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  if (numPages > 0)
+  {
+    this->SendData(this->GetStartServerId(),
+                   (char *)pages,
+                   numPages * sizeof(unsigned int),
+                   XDMF_DSM_EXCHANGE_TAG,
+                   0,
+                   XDMF_DSM_INTER_COMM);
+  }
+
+  return XDMF_DSM_SUCCESS;
+}
+
+int
+XdmfDSMBuffer::RequestFileDescription(char * name, std::vector<unsigned int> & pages, unsigned int & numPages, haddr_t & start, haddr_t & end)
+{
+  this->SendCommandHeader(XDMF_DSM_REQUEST_FILE,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+
+  int strlength = std::string(name).size();
+
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           strlength,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 name,
+                 strlength,
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  int fileExists = XDMF_DSM_SUCCESS;
+
+  this->ReceiveAcknowledgment(this->GetStartServerId(),
+                              fileExists,
+                              XDMF_DSM_EXCHANGE_TAG,
+                              XDMF_DSM_INTER_COMM);
+
+  if (fileExists == XDMF_DSM_SUCCESS)
+  {
+    this->ReceiveData(this->GetStartServerId(),
+                      (char*)&start,
+                      sizeof(haddr_t),
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      XDMF_DSM_INTER_COMM);
+
+    this->ReceiveData(this->GetStartServerId(),
+                      (char*)&end,
+                      sizeof(haddr_t),
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      XDMF_DSM_INTER_COMM);
+
+    int recvNumPages = 0;
+
+    this->ReceiveAcknowledgment(this->GetStartServerId(),
+                                recvNumPages,
+                                XDMF_DSM_EXCHANGE_TAG,
+                                XDMF_DSM_INTER_COMM);
+
+    numPages = recvNumPages;
+
+    // Reallocate pointer
+    pages.clear();
+
+    unsigned int * pagelist = new unsigned int[numPages];
+
+    this->ReceiveData(this->GetStartServerId(),
+                      (char *)pagelist,
+                      numPages * sizeof(unsigned int),
+                      XDMF_DSM_EXCHANGE_TAG,
+                      0,
+                      XDMF_DSM_INTER_COMM);
+
+    for (unsigned int i = 0; i < numPages; ++i)
+    {
+      pages.push_back(pagelist[i]);
+    }
+
+    return XDMF_DSM_SUCCESS;
+  }
+  else
+  {
+    return XDMF_DSM_FAIL;
+  }
+}
+
+
+void
+XdmfDSMBuffer::RequestPages(char * name,
+                            haddr_t spaceRequired,
+                            std::vector<unsigned int> & pages,
+                            unsigned int & numPages,
+                            haddr_t & start,
+                            haddr_t & end)
+{
+  this->SendCommandHeader(XDMF_DSM_REQUEST_PAGES,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+
+  // set aside pages to a file
+  int strlength = std::string(name).size();
+
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           strlength,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 name,
+                 strlength,
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  // Request size required for the file
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           spaceRequired,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  // Send back new page allocation pointer
+
+  int newPageCount = 0;
+
+  this->ReceiveAcknowledgment(this->GetStartServerId(),
+                              newPageCount,
+                              XDMF_DSM_EXCHANGE_TAG,
+                              XDMF_DSM_INTER_COMM);
+
+  numPages = newPageCount;
+
+  unsigned int * pagelist = new unsigned int[numPages]();
+  pages.clear();
+
+  this->ReceiveData(this->GetStartServerId(),
+                    (char *) pagelist,
+                    numPages * sizeof(unsigned int),
+                    XDMF_DSM_EXCHANGE_TAG,
+                    0,
+                    XDMF_DSM_INTER_COMM);
+
+  for (unsigned int i = 0; i < numPages; ++i)
+  {
+    pages.push_back(pagelist[i]);
+  }
+
+  // Recieve the new start and end addresses
+  this->ReceiveData(this->GetStartServerId(),
+                    (char*)&start,
+                    sizeof(haddr_t),
+                    XDMF_DSM_EXCHANGE_TAG,
+                    0,
+                    XDMF_DSM_INTER_COMM);
+
+  this->ReceiveData(this->GetStartServerId(),
+                    (char*)&end,
+                    sizeof(haddr_t),
+                    XDMF_DSM_EXCHANGE_TAG,
+                    0,
+                    XDMF_DSM_INTER_COMM);
+
+  // If resized, set up the reset the total length.
+  int currentLength = 0;
+  this->ReceiveAcknowledgment(this->GetStartServerId(),
+                              currentLength,
+                              XDMF_DSM_EXCHANGE_TAG,
+                              XDMF_DSM_INTER_COMM);
+
+  this->UpdateLength(currentLength);
+}
+
+void
+XdmfDSMBuffer::SendAccept(unsigned int numConnections)
+{
+#ifndef XDMF_DSM_IS_CRAY
+  for (int i = this->StartServerId; i <= this->EndServerId; ++i) {
+    if (i != this->Comm->GetInterId()){
+      this->SendCommandHeader(XDMF_DSM_ACCEPT, i, 0, 0, XDMF_DSM_INTER_COMM);
+      this->SendAcknowledgment(i, numConnections, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+    }
+  }
+  this->Comm->Accept(numConnections);
+  this->SendInfo();
+#endif
+}
+
+void
+XdmfDSMBuffer::SendAcknowledgment(int dest, int data, int tag, int comm)
+{
+  int status;
+  this->Comm->Send(&data,
+                   sizeof(int),
+                   dest,
+                   comm,
+                   tag);
+  status = MPI_SUCCESS;
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to receive data");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfDSMBuffer::SendCommandHeader(int opcode, int dest, int address, int aLength, int comm)
+{
+  int status;
+  CommandMsg cmd;
+  memset(&cmd, 0, sizeof(CommandMsg));
+  cmd.Opcode = opcode;
+  if (comm == XDMF_DSM_INTRA_COMM) {
+    cmd.Source = this->Comm->GetId();
+  }
+  else if (comm == XDMF_DSM_INTER_COMM) {
+    cmd.Source = this->Comm->GetInterId();
+  }
+  cmd.Target = dest;
+  cmd.Address = address;
+  cmd.Length = aLength;
+
+  this->Comm->Send(&cmd,
+                   sizeof(CommandMsg),
+                   dest,
+                   comm,
+                   XDMF_DSM_COMMAND_TAG);
+  status = MPI_SUCCESS;
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to send command header");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfDSMBuffer::SendData(int dest, char * data, int aLength, int tag, int aAddress, int comm)
+{
+  int status;
+
+  this->Comm->Send(data,
+                   aLength,
+                   dest,
+                   comm,
+                   tag);
+  status = MPI_SUCCESS;
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to send data");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfDSMBuffer::SendDone()
+{
+  try {
+    if (static_cast<XdmfDSMCommMPI *>(this->Comm)->GetInterComm() == MPI_COMM_NULL)
+    {
+      for (int i = this->StartServerId; i <= this->EndServerId; ++i) {
+        if (i != this->Comm->GetId()){
+          this->SendCommandHeader(XDMF_DSM_OPCODE_DONE, i, 0, 0, XDMF_DSM_INTRA_COMM);
+        }
+      }
+    }
+    else
+    {
+      for (int i = this->StartServerId; i <= this->EndServerId; ++i) {
+        if (i != this->Comm->GetId()){
+          this->SendCommandHeader(XDMF_DSM_OPCODE_DONE, i, 0, 0, XDMF_DSM_INTER_COMM);
+        }
+      }
+    }
+  }
+  catch (XdmfError & e) {
+    throw e;
+  }
+}
+
+void
+XdmfDSMBuffer::SendInfo()
+{
+  InfoMsg  dsmInfo;
+  int status;
+
+  memset(&dsmInfo, 0, sizeof(InfoMsg));
+  dsmInfo.type = this->GetDsmType();
+  dsmInfo.length = this->GetLength();
+  dsmInfo.total_length = this->GetTotalLength();
+  dsmInfo.block_length = this->GetBlockLength();
+  dsmInfo.start_server_id = this->GetStartServerId();
+  dsmInfo.end_server_id = this->GetEndServerId();
+
+  int infoStatus = 3;
+  if (this->Comm->GetId() == 0) {
+    infoStatus = 2;
+  }
+
+  int * groupInfoStatus = new int[this->Comm->GetInterSize()]();
+
+  this->Comm->AllGather(&infoStatus,
+                        sizeof(int),
+                        &(groupInfoStatus[0]),
+                        sizeof(int),
+                        XDMF_DSM_INTER_COMM);
+
+  int sendCore = 0;
+
+  for (int i = 0; i < this->Comm->GetInterSize(); ++i) {
+    if (groupInfoStatus[i] == 2) {
+      sendCore = i;
+    }
+  }
+
+  status = MPI_SUCCESS;
+
+  this->Comm->Broadcast(&dsmInfo,
+                        sizeof(InfoMsg),
+                        sendCore,
+                        XDMF_DSM_INTER_COMM);
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Failed to send info");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  MPI_Comm comm = this->Comm->GetInterComm();
+
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  int rank = this->Comm->GetInterId();
+  int size = this->Comm->GetInterSize();
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+  std::string applicationName = this->Comm->GetApplicationName();
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  std::vector<std::pair<std::string, unsigned int> > newStructure;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    newStructure.push_back(std::pair<std::string, unsigned int>(std::string(coreTag), coreSplit.size()));
+    coreSplit.clear();
+    ++splitid;
+  }
+  this->Comm->SetDsmProcessStructure(newStructure);
+}
+
+void
+XdmfDSMBuffer::SetBlockLength(long newBlock)
+{
+  this->BlockLength = newBlock;
+}
+
+void
+XdmfDSMBuffer::SetComm(XdmfDSMCommMPI * newComm)
+{
+  this->Comm = newComm;
+}
+
+void
+XdmfDSMBuffer::SetDsmType(int newDsmType)
+{
+  this->DsmType = newDsmType;
+}
+
+void
+XdmfDSMBuffer::SetInterCommType(int newType)
+{
+  this->InterCommType = newType;
+}
+
+void
+XdmfDSMBuffer::SetIsConnected(bool newStatus)
+{
+  IsConnected =  newStatus;
+}
+
+void
+XdmfDSMBuffer::SetIsServer(bool newIsServer)
+{
+  this->IsServer = newIsServer;
+}
+
+void
+XdmfDSMBuffer::SetResizeFactor(double newFactor)
+{
+  if (newFactor >= 0)
+  {
+    this->ResizeFactor = newFactor;
+  }
+  else
+  {
+    this->ResizeFactor = newFactor * -1;
+  }
+}
+
+void
+XdmfDSMBuffer::SetLength(long aLength)
+{
+  this->Length = aLength;
+  if (this->DataPointer) {
+    // Try to reallocate
+    // This should not be called in most cases
+    this->DataPointer =
+      static_cast<char *>(realloc(this->DataPointer, this->Length*sizeof(char)));
+  }
+  else {
+#ifdef _WIN32
+    this->DataPointer = calloc(this->Length, sizeof(char));
+#else
+  #ifdef _SC_PAGESIZE
+    posix_memalign((void **)(&this->DataPointer), sysconf(_SC_PAGESIZE), this->Length);
+    memset(this->DataPointer, 0, this->Length);
+  #else
+    // Older linux variation, for backwards compatibility
+    posix_memalign((void **)(&this->DataPointer), getpagesize(), this->Length);
+    memset(this->DataPointer, 0, this->Length);
+  #endif
+#endif
+  }
+
+  if (this->DataPointer == NULL) {
+    std::stringstream message;
+    message << "Allocation Failed, unable to allocate " << this->Length;
+    XdmfError::message(XdmfError::FATAL, message.str());
+  }
+
+  if (this->BlockLength > 0)
+  {
+    this->NumPages = this->Length / this->BlockLength;
+  }
+}
+
+void
+XdmfDSMBuffer::SetLocalBufferSizeMBytes(unsigned int newSize)
+{
+  this->LocalBufferSizeMBytes = newSize;
+}
+
+void
+XdmfDSMBuffer::Unlock(char * filename)
+{
+  int strlength = std::string(filename).size();
+  this->SendCommandHeader(XDMF_DSM_UNLOCK_FILE,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           strlength,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+
+  this->SendData(this->GetStartServerId(),
+                 filename,
+                 strlength,
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+}
+
+void
+XdmfDSMBuffer::UpdateLength(unsigned int newLength)
+{
+  this->Length = newLength;
+  this->TotalLength = this->Length * (this->EndServerId - this->StartServerId);
+}
+
+void
+XdmfDSMBuffer::WaitRelease(std::string filename, std::string datasetname, int code)
+{
+  // Send Command Header
+  this->SendCommandHeader(XDMF_DSM_CLEAR_NOTIFY,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+  // Send string size
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           filename.size() + datasetname.size(),
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+  // Send string
+  char * sendPointer = new char[filename.size() + datasetname.size()]();
+  unsigned int placementIndex = 0;
+  for (unsigned int i = 0; i < filename.size(); ++i)
+  {
+    sendPointer[placementIndex++] = filename[i];
+  }
+  for (unsigned int i = 0; i < datasetname.size(); ++i)
+  {
+    sendPointer[placementIndex++] = datasetname[i];
+  }
+  this->SendData(this->GetStartServerId(),
+                 sendPointer,
+                 filename.size() + datasetname.size(),
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+  delete sendPointer;
+  // Send Release Code
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           code,
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+}
+
+int
+XdmfDSMBuffer::WaitOn(std::string filename, std::string datasetname)
+{
+  // Send Command Header
+  this->SendCommandHeader(XDMF_DSM_SET_NOTIFY,
+                          this->GetStartServerId(),
+                          0,
+                          0,
+                          XDMF_DSM_INTER_COMM);
+  // Send string size
+  this->SendAcknowledgment(this->GetStartServerId(),
+                           filename.size() + datasetname.size(),
+                           XDMF_DSM_EXCHANGE_TAG,
+                           XDMF_DSM_INTER_COMM);
+  // Send string
+  char * sendPointer = new char[filename.size() + datasetname.size()]();
+  unsigned int placementIndex = 0;
+  for (unsigned int i = 0; i < filename.size(); ++i)
+  {
+    sendPointer[placementIndex++] = filename[i];
+  }
+  for (unsigned int i = 0; i < datasetname.size(); ++i)
+  {
+    sendPointer[placementIndex++] = datasetname[i];
+  }  
+  this->SendData(this->GetStartServerId(),
+                 sendPointer,
+                 filename.size() + datasetname.size(),
+                 XDMF_DSM_EXCHANGE_TAG,
+                 0,
+                 XDMF_DSM_INTER_COMM);
+
+  // Wait for Release
+  int code = 0;
+  this->ReceiveAcknowledgment(MPI_ANY_SOURCE,
+                              code,
+                              XDMF_DSM_EXCHANGE_TAG,
+                              this->CommChannel);
+  delete sendPointer;
+  // Return Code from Notification
+  return code;
+}
+
+// C Wrappers
+
+XDMFDSMBUFFER * XdmfDSMBufferNew()
+{
+  try
+  {
+    return (XDMFDSMBUFFER *)((void *)(new XdmfDSMBuffer()));
+  }
+  catch (...)
+  {
+    return (XDMFDSMBUFFER *)((void *)(new XdmfDSMBuffer()));
+  }
+}
+
+void XdmfDSMBufferFree(XDMFDSMBUFFER * item)
+{
+  if (item != NULL) {
+    delete ((XdmfDSMBuffer *)item);
+  }
+  item = NULL;
+}
+
+void XdmfDSMBufferBroadcastComm(XDMFDSMBUFFER * buffer, int *comm, int root, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->BroadcastComm(comm, root);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+int XdmfDSMBufferBufferService(XDMFDSMBUFFER * buffer, int *returnOpcode, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfDSMBuffer *)buffer)->BufferService(returnOpcode);
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+void XdmfDSMBufferBufferServiceLoop(XDMFDSMBUFFER * buffer, int *returnOpcode, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->BufferServiceLoop(returnOpcode);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferConfigureUniform(XDMFDSMBUFFER * buffer,
+                                   XDMFDSMCOMMMPI * Comm,
+                                   long Length,
+                                   int StartId,
+                                   int EndId,
+                                   long aBlockLength,
+                                   int random,
+                                   int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->ConfigureUniform((XdmfDSMCommMPI *)Comm, Length, StartId, EndId, aBlockLength, random);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferConnect(XDMFDSMBUFFER * buffer, int persist, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->Connect(persist);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferCreate(XDMFDSMBUFFER * buffer, MPI_Comm comm, int startId, int endId, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->Create(comm, startId, endId);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferDisconnect(XDMFDSMBUFFER * buffer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->Disconnect();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferGet(XDMFDSMBUFFER * buffer, long Address, long aLength, void * Data, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->Get(Address, aLength, Data);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferGetAddressRangeForId(XDMFDSMBUFFER * buffer, int Id, int * Start, int * End, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->GetAddressRangeForId(Id, Start, End);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+long XdmfDSMBufferGetBlockLength(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetBlockLength();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetBlockLength();
+  }
+}
+
+XDMFDSMCOMMMPI * XdmfDSMBufferGetComm(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return (XDMFDSMCOMMMPI *)((void *)(((XdmfDSMBuffer *)buffer)->GetComm()));
+  }
+  catch (...)
+  {
+    return (XDMFDSMCOMMMPI *)((void *)(((XdmfDSMBuffer *)buffer)->GetComm()));
+  }
+}
+
+char * XdmfDSMBufferGetDataPointer(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetDataPointer();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetDataPointer();
+  }
+}
+
+int XdmfDSMBufferGetDsmType(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetDsmType();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetDsmType();
+  }
+}
+
+int XdmfDSMBufferGetEndAddress(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetEndAddress();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetEndAddress();
+  }
+}
+
+int XdmfDSMBufferGetEndServerId(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetEndServerId();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetEndServerId();
+  }
+}
+
+int XdmfDSMBufferGetInterCommType(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetInterCommType();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetInterCommType();
+  }
+}
+
+int XdmfDSMBufferGetIsConnected(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetIsConnected();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetIsConnected();
+  }
+}
+
+int XdmfDSMBufferGetIsServer(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetIsServer();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetIsServer();
+  }
+}
+
+long XdmfDSMBufferGetLength(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetLength();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetLength();
+  }
+}
+
+unsigned int XdmfDSMBufferGetLocalBufferSizeMBytes(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetLocalBufferSizeMBytes();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetLocalBufferSizeMBytes();
+  }
+}
+
+double XdmfDSMBufferGetResizeFactor(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetResizeFactor();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetResizeFactor();
+  }
+}
+
+int XdmfDSMBufferGetStartAddress(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetStartAddress();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetStartAddress();
+  }
+}
+
+int XdmfDSMBufferGetStartServerId(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetStartServerId();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetStartServerId();
+  }
+}
+
+long XdmfDSMBufferGetTotalLength(XDMFDSMBUFFER * buffer)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetTotalLength();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->GetTotalLength();
+  }
+}
+
+void XdmfDSMBufferProbeCommandHeader(XDMFDSMBUFFER * buffer, int * comm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->ProbeCommandHeader(comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferPut(XDMFDSMBUFFER * buffer, long Address, long aLength, void * Data, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->Put(Address, aLength, Data);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferReceiveAcknowledgment(XDMFDSMBUFFER * buffer,
+                                        int source,
+                                        int * data,
+                                        int tag,
+                                        int comm,
+                                        int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->ReceiveAcknowledgment(source, *data, tag, comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferReceiveCommandHeader(XDMFDSMBUFFER * buffer,
+                                       int * opcode,
+                                       int * source,
+                                       int * address,
+                                       int * aLength,
+                                       int comm,
+                                       int remoteSource,
+                                       int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->ReceiveCommandHeader(opcode, source, address, aLength, comm, remoteSource);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferReceiveData(XDMFDSMBUFFER * buffer,
+                              int source,
+                              char * data,
+                              int aLength,
+                              int tag,
+                              int aAddress,
+                              int comm,
+                              int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->ReceiveData(source, data, aLength, tag, aAddress, comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferReceiveInfo(XDMFDSMBUFFER * buffer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->ReceiveInfo();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferSendAccept(XDMFDSMBUFFER * buffer, unsigned int numConnects)
+{
+  ((XdmfDSMBuffer *)buffer)->SendAccept(numConnects);
+}
+
+void XdmfDSMBufferSendAcknowledgment(XDMFDSMBUFFER * buffer,
+                                     int dest,
+                                     int data,
+                                     int tag,
+                                     int comm,
+                                     int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->SendAcknowledgment(dest, data, tag, comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferSendCommandHeader(XDMFDSMBUFFER * buffer,
+                                    int opcode,
+                                    int dest,
+                                    int address,
+                                    int aLength,
+                                    int comm,
+                                    int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->SendCommandHeader(opcode, dest, address, aLength, comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferSendData(XDMFDSMBUFFER * buffer,
+                           int dest,
+                           char * data,
+                           int aLength,
+                           int tag,
+                           int aAddress,
+                           int comm,
+                           int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->SendData(dest, data, aLength, tag, aAddress, comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferSendDone(XDMFDSMBUFFER * buffer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->SendDone();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferSendInfo(XDMFDSMBUFFER * buffer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMBuffer *)buffer)->SendInfo();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMBufferSetBlockLength(XDMFDSMBUFFER * buffer, long newBlock)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetBlockLength(newBlock);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetBlockLength(newBlock);
+  }
+}
+
+void XdmfDSMBufferSetComm(XDMFDSMBUFFER * buffer, XDMFDSMCOMMMPI * newComm)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetComm((XdmfDSMCommMPI *)newComm);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetComm((XdmfDSMCommMPI *)newComm);
+  }
+}
+
+void XdmfDSMBufferSetDsmType(XDMFDSMBUFFER * buffer, int newDsmType)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetDsmType(newDsmType);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetDsmType(newDsmType);
+  }
+}
+
+void XdmfDSMBufferSetInterCommType(XDMFDSMBUFFER * buffer, int newType)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetInterCommType(newType);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetInterCommType(newType);
+  }
+}
+
+void XdmfDSMBufferSetIsConnected(XDMFDSMBUFFER * buffer, int newStatus)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetIsConnected(newStatus);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetIsConnected(newStatus);
+  }
+}
+
+void XdmfDSMBufferSetIsServer(XDMFDSMBUFFER * buffer, int newIsServer)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetIsServer(newIsServer);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetIsServer(newIsServer);
+  }
+}
+
+void XdmfDSMBufferSetLocalBufferSizeMBytes(XDMFDSMBUFFER * buffer, unsigned int newSize)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetLocalBufferSizeMBytes(newSize);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetLocalBufferSizeMBytes(newSize);
+  }
+}
+
+void XdmfDSMBufferSetResizeFactor(XDMFDSMBUFFER * buffer, double newFactor)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->SetResizeFactor(newFactor);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->SetResizeFactor(newFactor);
+  }
+}
+
+void XdmfDSMBufferWaitRelease(XDMFDSMBUFFER * buffer, char * filename, char * datasetname, int code)
+{
+  try
+  {
+    ((XdmfDSMBuffer *)buffer)->WaitRelease(std::string(filename), std::string(datasetname), code);
+  }
+  catch (...)
+  {
+    ((XdmfDSMBuffer *)buffer)->WaitRelease(std::string(filename), std::string(datasetname), code);
+  }
+}
+
+int XdmfDSMBufferWaitOn(XDMFDSMBUFFER * buffer, char * filename, char * datasetname)
+{
+  try
+  {
+    return ((XdmfDSMBuffer *)buffer)->WaitOn(std::string(filename), std::string(datasetname));
+  }
+  catch (...)
+  {
+    return ((XdmfDSMBuffer *)buffer)->WaitOn(std::string(filename), std::string(datasetname));
+  }
+}
diff --git a/core/dsm/XdmfDSMBuffer.hpp b/core/dsm/XdmfDSMBuffer.hpp
new file mode 100644
index 0000000..ec2d4cb
--- /dev/null
+++ b/core/dsm/XdmfDSMBuffer.hpp
@@ -0,0 +1,2949 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMBuffer.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+/*=========================================================================
+  This code is derived from an earlier work and is distributed
+  with permission from, and thanks to ...
+=========================================================================*/
+
+/*=========================================================================
+
+  Project                 : H5FDdsm
+  Module                  : H5FDdsmBufferService.h, H5FDdsmBuffer.h
+
+  Authors:
+     John Biddiscombe     Jerome Soumagne
+     biddisco at cscs.ch     soumagne at cscs.ch
+
+  Copyright (C) CSCS - Swiss National Supercomputing Centre.
+  You may use modify and and distribute this code freely providing
+  1) This copyright notice appears on all copies of source code
+  2) An acknowledgment appears with any substantial usage of the code
+  3) If this code is contributed to any other open source project, it
+  must not be reformatted such that the indentation, bracketing or
+  overall style is modified significantly.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  This work has received funding from the European Community's Seventh
+  Framework Programme (FP7/2007-2013) under grant agreement 225967 âxtMuSEâOB
+=========================================================================*/
+
+#ifndef XDMFDSMBUFFER_HPP_
+#define XDMFDSMBUFFER_HPP_
+
+// C Compatible Includes
+#include <XdmfDSM.hpp>
+#include <mpi.h>
+#include <XdmfDSMCommMPI.hpp>
+
+#ifndef _H5public_H
+  #ifndef XDMF_HADDR_T
+  #define XDMF_HADDR_T
+    typedef unsigned long haddr_t;
+  #endif
+#endif
+
+// Definitions
+
+/*
+#define XDMF_DSM_DEFAULT_TAG    0x80
+#define XDMF_DSM_COMMAND_TAG    0x81
+#define XDMF_DSM_SERVER_ACK_TAG 0x82
+#define XDMF_DSM_CLIENT_ACK_TAG 0x83
+#define XDMF_DSM_PUT_DATA_TAG   0x84
+#define XDMF_DSM_GET_DATA_TAG   0x85
+#define XDMF_DSM_EXCHANGE_TAG   0x86
+
+#define XDMF_DSM_ANY_TAG        -1
+#define XDMF_DSM_ANY_SOURCE     -2
+*/
+
+#define XDMF_DSM_TYPE_UNIFORM       0
+#define XDMF_DSM_TYPE_UNIFORM_RANGE 1
+#define XDMF_DSM_TYPE_MIXED         2
+#define XDMF_DSM_TYPE_BLOCK_CYCLIC  3
+#define XDMF_DSM_TYPE_BLOCK_RANDOM  4
+
+#define XDMF_DSM_DEFAULT_LENGTH 10000
+#define XDMF_DSM_DEFAULT_BLOCK_LENGTH 1024
+#define XDMF_DSM_ALIGNMENT 4096
+
+#define XDMF_DSM_OPCODE_PUT          0x01
+#define XDMF_DSM_OPCODE_GET          0x02
+
+#define XDMF_DSM_LOCK_ACQUIRE        0x03
+#define XDMF_DSM_LOCK_RELEASE        0x05
+
+#define XDMF_DSM_SET_NOTIFY          0x06
+#define XDMF_DSM_CLEAR_NOTIFY        0x07
+
+#define XDMF_DSM_ACCEPT              0x10
+#define XDMF_DSM_DISCONNECT          0x11
+
+#define XDMF_DSM_REGISTER_FILE       0x12
+#define XDMF_DSM_REQUEST_PAGES       0x13
+#define XDMF_DSM_REQUEST_FILE        0x14
+
+#define XDMF_DSM_OPCODE_RESIZE       0x15
+
+#define XDMF_DSM_REQUEST_ACCESS      0x16
+#define XDMF_DSM_UNLOCK_FILE         0x17
+
+#define XDMF_DSM_OPCODE_DONE         0xFF
+
+#define XDMF_DSM_SUCCESS  1
+#define XDMF_DSM_FAIL    -1
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfHDF5WriterDSM;
+
+// Includes
+#include <map>
+#include <queue>
+
+/**
+ * @brief Controls the data buffer for DSM.
+ *
+ * XdmfDSMBuffer takes the place of the H5FDdsmBuffer defined in H5FD.
+ * It is primarily for allowing the XdmfDSM to interact with HDF5 dsm
+ * without threads.
+ */
+class XDMFDSM_EXPORT XdmfDSMBuffer {
+
+public:
+
+  friend class XdmfHDF5WriterDSM;
+
+  XdmfDSMBuffer();
+  ~XdmfDSMBuffer();
+
+  /**
+   * Broadcasts the provided comm from the specified core to all other cores. 
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#BroadcastComm
+   * @until //#BroadcastComm
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is
+   * passed via wrapped code
+   *
+   *
+   *
+   * @param     comm    The communicator to be transmitted
+   * @param     root    The core that the broadcast is originating from
+   */
+  void BroadcastComm(int *comm, int root);
+
+  /**
+   * One iteration of the service loop.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#BufferService
+   * @until //#BufferService
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//BufferService
+   * @until #//BufferService
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     returnOpcode    A variable that will hold the code at the
+   *                            end of the loop
+   * @return                    If the iteration executed without problem
+   *                            returns XDMF_DSM_SUCCESS
+   */
+  int BufferService(int *returnOpcode = 0);
+
+  /**
+   * Starts up the service loop.
+   * The loop then executes until the op code "Done" is sent to this core.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#BufferServiceLoop
+   * @until //#BufferServiceLoop
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//BufferServiceLoop
+   * @until #//BufferServiceLoop
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     returnOpcode    A variable that will hold the code at the
+   *                            end of the loop
+   */
+  void BufferServiceLoop(int *returnOpcode = 0);
+
+  /**
+   * Creates an internal buffer based on the information provided.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#Create
+   * @until //#Create
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//Create
+   * @until #//Create
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newComm         The communicator that will be used.
+   * @param     startId         The index of the first server node
+   * @param     endId           The index of the last server node
+   */
+  void Create(MPI_Comm newComm, int startId = -1, int endId = -1);
+
+  /**
+   * Configures the Buffer to match the configuration details provided.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferrwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#ConfigureUniform
+   * @until //#ConfigureUniform
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//ConfigureUniform
+   * @until #//ConfigureUniform
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     Comm            The communicator that will be handling the
+   *                            communications for the DSM
+   * @param     Length          The length of the data buffer on server cores
+   * @param     StartId         The id that the server cores will start on,
+   *                            if set to -1 then it will default to 0
+   * @param     EndId           The id that the server cores will end on,
+   *                            if set to -1 then it will be the last core
+   *                            in the communicator
+   * @param     aBlockLength    The block size of the data buffer, 0 is
+   *                            no blocking
+   * @param     random          Whether the assignment is random or cyclic.
+   *                            Default is cyclic
+   */
+  void ConfigureUniform(XdmfDSMCommMPI *Comm, long Length,
+                        int StartId = -1, int EndId = -1,
+                        long aBlockLength = 0, bool random = false);
+
+  /**
+   * Attempts to connect the buffer to the port that is currently set.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#Connect
+   * @until //#Connect
+   * @skipline //#Disconnectmanager
+   * @until //#Disconnectmanager
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//Connect
+   * @until #//Connect
+   * @skipline #//Disconnectmanager
+   * 
+   * @param     persist         Whether to try to connect repeatedly
+   */
+  void Connect(bool persist = false);
+
+  /**
+   * Disconnects the buffer from the port it was connected to.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#Connect
+   * @until //#Connect
+   * @skipline //#Disconnectmanager
+   * @until //#Disconnectmanager
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//Connect
+   * @until #//Connect
+   * @skipline #//Disconnectmanager
+   * @until #//Disconnectmanager
+   */
+  void Disconnect();
+
+  /**
+   * Gets data from the server cores.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PutGet
+   * @until //#PutGet
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed via
+   *  wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   *
+   *
+   * @param     Address         The starting address of the data retrieved
+   * @param     aLength         The length of the data to be retrieved
+   * @param     Data            A pointer in which the data is to be stored
+   *                            after retieval
+   */
+  void Get(long Address, long aLength, void *Data);
+
+  /**
+   * Gets data from the server cores. This version is for paged allocation.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PutGetPaged
+   * @until //#PutGetPaged
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed via
+   *  wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   * @param     pages           A pointer to the list of pages to be written to
+   * @param     numPages        The number of pages in the provided pointer
+   * @param     Address         The starting address of the data retrieved
+   * @param     aLength         The length of the data to be retrieved
+   * @param     Data            A pointer in which the data is to be stored
+   *                            after retieval
+   */
+  void Get(unsigned int * pages, unsigned int numPages, long Address, long aLength, void *Data);
+
+  /**
+   * Gets the starting address and ending address for the core of the provided Id.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declaremanager
+   * @until //#declaremanager
+   * @skipline //#getServerManagerwriter
+   * @until //#getServerManagerwriter
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#GetDsmBuffer
+   * @until //#GetDsmBuffer
+   * @skipline //#GetAddressRangeForId
+   * @until //#GetAddressRangeForId
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed via
+   * wrapped code
+   *
+   *
+   *
+   * @param     Id      The core for which the start and end address are
+   *                    to be found
+   * @param     Start   A pointer in which the start address is to be placed
+   * @param     End     A pointer in which the end address is to be placed
+   */
+  void GetAddressRangeForId(int Id, int *Start, int *End);
+
+  /**
+   * Gets the size of the blocks for the data buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetBlockLengthbuffer
+   * @until //#GetBlockLengthbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetBlockLength
+   * @until #//GetBlockLength
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return      The size of the blocks in the DSM buffer
+   */
+  long GetBlockLength();
+
+  /**
+   * Gets the Comm being used to facilitate the communications for the DSM
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return      The Comm controlling the communications for the DSM
+   */
+  XdmfDSMCommMPI * GetComm();
+
+  /**
+   * Gets the data pointer that the buffer controls.
+   * Should be NULL on non-server cores.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetDataPointer
+   * @until //#GetDataPointer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetDataPointer
+   * @until #//GetDataPointer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The buffer's internal data pointer.
+   */
+  char * GetDataPointer();
+
+  /**
+   * Gets the DSM type currently being used.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebufferr
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetDsmTypebuffer
+   * @until //#GetDsmTypebuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetDsmTypebuffer
+   * @until #//GetDsmTypebuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The integer representation of the DSM type
+   */
+  int GetDsmType();
+
+  /**
+   * Gets the address at the end of DSM buffer for this buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetEndAddress
+   * @until //#GetEndAddress
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetEndAddress
+   * @until #//GetEndAddress
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The end address of the DSM buffer
+   */
+  int GetEndAddress();
+
+  /**
+   * Gets the id of the last of the server cores that handle the DSM buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetEndServerId
+   * @until //#GetEndServerId
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetEndServerId
+   * @until #//GetEndServerId
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The id of the last core that serves as a DSM server
+   */
+  int GetEndServerId();
+
+  /**
+   * Gets the type of intercomm that the manager is currently using.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetInterCommType
+   * @until //#GetInterCommType
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetInterCommType
+   * @until #//GetInterCommType
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    They type of intercomm currently being used
+   */
+  int GetInterCommType();
+
+  /**
+   * Gets if the Buffer is connected to an intercomm
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetIsConnectedbuffer
+   * @until //#GetIsConnectedbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetIsConnectedbuffer
+   * @until #//GetIsConnectedbuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    Whether the buffer is connected
+   */
+  bool GetIsConnected();
+
+  /**
+   * Gets if the buffer is a DSM server.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetIsServerbuffer
+   * @until //#GetIsServerbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetIsServerbuffer
+   * @until #//GetIsServerbuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    If the Buffer is a DSM server
+   */
+  bool GetIsServer();
+
+  /**
+   * The length of the buffer per core.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetLength
+   * @until //#GetLength
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetLength
+   * @until #//GetLength
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The length of the data buffer per core
+   */
+  long GetLength();
+
+  /**
+   * Gets the maximum size of the local buffer on server cores.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetLocalBufferSizeMBytes
+   * @until //#GetLocalBufferSizeMBytes
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetLocalBufferSizeMBytes
+   * @until #//GetLocalBufferSizeMBytes
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    the maximum size of the data buffer on server cores
+   */
+  unsigned int GetLocalBufferSizeMBytes();
+
+  /**
+   * Gets the factor by which the size is multiplied when resizing the local buffer.
+   * A factor of 1 doubles the size of the local buffer when resizing.
+   * A factor of 0.5 adds half the original size of the buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   *
+   * @return    The factor by which the buffer is resized.
+   */
+  double GetResizeFactor();
+
+  /**
+   * Gets the address at the beginning of the DSM buffer for this buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetStartAddress
+   * @until //#GetStartAddress
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetStartAddress
+   * @until #//GetStartAddress
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The beginning address of the DSM buffer
+   */
+  int GetStartAddress();
+
+  /**
+   * Gets the id of the first of the server cores that handle the DSM buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetStartServerId
+   * @until //#GetStartServerId
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetStartServerId
+   * @until #//GetStartServerId
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The id of the first core that serves as a DSM server
+   */
+  int GetStartServerId();
+
+  /**
+   * The total length of the data buffer when combining the buffers in all cores.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetTotalLength
+   * @until //#GetTotalLength
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetTotalLength
+   * @until #//GetTotalLength
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The total length of the data buffer
+   */
+  long GetTotalLength();
+
+  /**
+   * Probes inter and intra comms until a command is found.
+   * Then sets the comm that the command was found on to the provided variable
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#CommandHeader
+   * @until //#CommandHeader
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed via wrapped code
+   *
+   *
+   *
+   * @param     comm    a pointer to the variable that the integer code for the
+   *                    comm is placed in
+   */
+  void ProbeCommandHeader(int *comm);
+
+  /**
+   * Puts data to the server cores.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PutGet
+   * @until //#PutGet
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   * via wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   *
+   *
+   * @param     Address         The starting address that the data will
+   *                            be placed at
+   * @param     aLength         The length of the data to be sent
+   * @param     Data            A pointer to the data to be sent
+   */
+  void Put(long Address, long aLength, const void *Data);
+
+  /**
+   * Puts data to the server cores.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PutGetPaged
+   * @until //#PutGetPaged
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   * via wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   * @param     pages           A pointer to the list of pages to be read from
+   * @param     numPages        The number of pages in the provided pointer
+   * @param     Address         The starting address that the data will
+   *                            be placed at
+   * @param     aLength         The length of the data to be sent
+   * @param     Data            A pointer to the data to be sent
+   */
+  void Put(unsigned int * pages, unsigned int numPages, haddr_t Address, haddr_t aLength, const void *Data);
+
+  /**
+   * Recieves an integer as an acknowledgement from the specified core.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#SendRecvAcknowledgement
+   * @until //#SendRecvAcknowledgement
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//SendAcknowledgment
+   * @until #//SendAcknowledgment
+   * @skipline #//ReceiveAcknowledgment
+   * @until #//ReceiveAcknowledgment
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     source  The core to recieve from
+   * @param     data    The integer that the recieved data will be stored in
+   * @param     tag     The tag associated with the acknowledgement
+   * @param     comm    The comm over which the acknowldedgement will occur
+   */
+  void ReceiveAcknowledgment(int source, int &data, int tag, int comm);
+
+  /**
+   * Recieves command data from either a specified or unspecified source.
+   * If remoteSource is not provided any source currently sending a command is used.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#CommandHeader
+   * @until //#CommandHeader
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   *  via wrapped code
+   *
+   * @param     opcode          A pointer to the location where the code
+   *                            associated with the operation will be stored
+   * @param     source          A pointer to the location where the index of
+   *                            the source core will be stored
+   *                            (will be the same as remoteSource if provided)
+   * @param     address         A pointer to the location where the address
+   *                            specified by the command will be stored
+   * @param     aLength         A pointer to the location where the length of
+   *                            the data specified by the command will be stored
+   * @param     comm            The communicator over which the transmission
+   *                            will occur
+   * @param     remoteSource    If provided, the core being recieved from
+   */
+  void ReceiveCommandHeader(int *opcode, int *source, int *address, int *aLength, int comm, int remoteSource = -1);
+
+  /**
+   * Recieves data from a specific core and stores it in a pointer.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#SendRecvData
+   * @until //#SendRecvData
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   * via wrapped code
+   *
+   *
+   *
+   * @param     source          The core data will be recieved from
+   * @param     data            The pointer where the recieved data will be
+   *                            stored
+   * @param     aLength         The length of the data transmitted
+   * @param     tag             The communication tag to be used for the
+   *                            transmission
+   * @param     aAddress        The location where the data will be written on
+   *                            the data buffer
+   * @param     comm            The comunicator over which the data transfer
+   *                            will occur
+   */
+  void ReceiveData(int source, char * data, int aLength, int tag, int aAddress, int comm);
+
+  /**
+   * With the Comm with ID 0 recieve information
+   * about a server from another core on the intercomm.
+   * Used to recieve server data from different managers.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#SendRecvInfo
+   * @until //#SendRecvInfo
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//SendRecvInfo
+   * @until #//SendRecvInfo
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void ReceiveInfo();
+
+  /**
+   * Registers a file with the provided information. Overwrites previously registered files.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PageInfo
+   * @until //#PageInfo
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   * via wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   * @param     name            The name of the file to be registered
+   * @param     pages           The pages associated with the file to be registered
+   * @param     numPages        The number of pages associated with the file to be registered
+   * @param     start           The starting address for the file to be registered
+   * @param     end             The ending address for the file to be registered
+   */
+  int RegisterFile(char * name,
+                   unsigned int * pages,
+                   unsigned int numPages,
+                   haddr_t start,
+                   haddr_t end);
+
+  /**
+   * Requests a file's information from the DSM.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PageInfo
+   * @until //#PageInfo
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   * via wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   * @param     name            The name of the file
+   * @param     pages           The pages associated with the file (output)
+   * @param     numPages        The number of pages associated with the file (output)
+   * @param     start           The starting address for the file (output)
+   * @param     end             The ending address for the file (output)
+   * @return                    XDMF_DSM_FAIL if the file does not exist in DSM,
+   *                            otherwise XDMF_DSM_SUCCESS
+   */
+  int RequestFileDescription(char * name,
+                             std::vector<unsigned int> & pages,
+                             unsigned int & numPages,
+                             haddr_t & start,
+                             haddr_t & end);
+
+  /**
+   * Requests additional pages to cover needed data.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#PutGetPaged
+   * @until //#PutGetPaged
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python:
+   * Unusable in python unless an object of a cpointer type is passed
+   * via wrapped code
+   * Use the XdmfHDF5WriterDSM for this functionality
+   *
+   * @param     name            The name of the file
+   * @param     spaceRequired   The space needed in bytes to fit the data needed
+   * @param     pages           The pages associated with the file (output)
+   * @param     numPages        The number of pages associated with the file (output)
+   * @param     start           The starting address for the file (output)
+   * @param     end             The ending address for the file (output)
+   */
+  void RequestPages(char * name,
+                    haddr_t spaceRequired,
+                    std::vector<unsigned int> & pages,
+                    unsigned int & numPages,
+                    haddr_t & start,
+                    haddr_t & end);
+
+  /**
+   * Tells the server cores to prepare to accept a new connection.
+   * Then readies to accept a new connection.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   *
+   * @param     numConnects     The number of incoming connections to accept
+   */
+  void SendAccept(unsigned int numConnects);
+
+  /**
+   * Sends an integer as an acknowledgement to the specified core.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#SendRecvAcknowledgement
+   * @until //#SendRecvAcknowledgement
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//SendAcknowledgment
+   * @until #//SendAcknowledgment
+   * @skipline #//ReceiveAcknowledgment
+   * @until #//ReceiveAcknowledgment
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     dest    The core to send to
+   * @param     data    The integer to send
+   * @param     tag     The tag associated with the acknowledgement
+   * @param     comm    The comm over which the acknowldedgement will occur
+   */
+  void SendAcknowledgment(int dest, int data, int tag, int comm);
+
+  /**
+   * Sends command data to a specified core.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#CommandHeader
+   * @until //#CommandHeader
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//SendCommandHeader
+   * @until #//SendCommandHeader
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     opcode          The code for the command to be sent
+   * @param     dest            The core that the command is to be sent to
+   * @param     address         The address to be referenced by the command
+   * @param     aLength         The length of the data to be used by the command
+   * @param     comm            The communicator over which the transmission will occur
+   */
+  void SendCommandHeader(int opcode, int dest, int address, int aLength, int comm);
+
+  /**
+   * Sends data from a pointer to a specified core.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#SendRecvData
+   * @until //#SendRecvData
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//SendData
+   * @until #//SendData
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     dest            The core that the data will be sent to
+   * @param     data            A pointer to the location of the data being sent
+   * @param     aLength         The length of the data being sent
+   * @param     tag             The communication tag to be used for the transmission
+   * @param     aAddress        The address on the recieveing core's buffer that
+   *                            the data is to be placed in
+   * @param     comm            The communicator over which the data transfer
+   *                            will take place
+   */
+  void SendData(int dest, char * data, int aLength, int tag, int aAddress, int comm);
+
+  /**
+   * Ends the service loop server cores associated with this buffer
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#SendDone
+   * @until //#SendDone
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//SendDone
+   * @until #//SendDone
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void SendDone();
+
+  /**
+   * From the Comm with ID 0 send out information
+   * about the server to another core on the intercomm.
+   * Used to send server data to different managers.
+   * It is not advised to use this function manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#SendRecvInfo
+   * @until //#SendRecvInfo
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//SendRecvInfo
+   * @until #//SendRecvInfo
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void SendInfo();
+
+  /**
+   * Sets the size of the blocks used in the data buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetBlockLengthbuffer
+   * @until //#GetBlockLengthbuffer
+   * @skipline //#SetBlockLengthbuffer
+   * @until //#SetBlockLengthbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetBlockLength
+   * @until #//GetBlockLength
+   * @skipline #//SetBlockLength
+   * @until #//SetBlockLength
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newBlock        The new block size to be used
+   */
+  void SetBlockLength(long newBlock);
+
+  /**
+   * Sets the Comm to be used to facilitate the communications for the DSM
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#SetComm
+   * @until //#SetComm
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//SetComm
+   * @until #//SetComm
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newComm         The communicator that is to be used by the DSM
+   */
+  void SetComm(XdmfDSMCommMPI * newComm);
+
+  /**
+   * Sets the DSM type to the provided type.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#SetDsmTypebuffer
+   * @until //#SetDsmTypebuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//SetDsmTypebuffer
+   * @until #//SetDsmTypebuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newDsmType      The Dsm type that the buffer will be changed to
+   */
+  void SetDsmType(int newDsmType);
+
+  /**
+   * Sets the type of intercomm that the DSM will use.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#SetInterCommType
+   * @until //#SetInterCommType
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//SetInterCommType
+   * @until #//SetInterCommType
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newType         The type of intercomm to be generated for now on
+   */
+  void SetInterCommType(int newType);
+
+  /**
+   * Sets the Buffer's connection status. Used if the XdmfDSMCommMPI is
+   * connected or disconnected manually.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetIsConnectedbuffer
+   * @until //#GetIsConnectedbuffer
+   * @skipline //#SetIsConnectedbuffer
+   * @until //#SetIsConnectedbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetIsConnectedbuffer
+   * @until #//GetIsConnectedbuffer
+   * @skipline #//SetIsConnectedbuffer
+   * @until #//SetIsConnectedbuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newStatus       The new connection status
+   */
+  void SetIsConnected(bool newStatus);
+
+  /**
+   * Sets the maximum size of the local buffer when generating data buffers for server cores.
+   * When using blocked mode it generates a buffer that is a multiple of the block size
+   * that is less than or equal to this number.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetLocalBufferSizeMBytes
+   * @until //#GetLocalBufferSizeMBytes
+   * @skipline //#SetLocalBufferSizeMBytes
+   * @until //#SetLocalBufferSizeMBytes
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetLocalBufferSizeMBytes
+   * @until #//GetLocalBufferSizeMBytes
+   * @skipline #//SetLocalBufferSizeMBytes
+   * @until #//SetLocalBufferSizeMBytes
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newSize         The new maximum size of the data buffer on the server cores
+   */
+  void SetLocalBufferSizeMBytes(unsigned int newSize);
+
+  /**
+   * Sets whether the buffer is a DSM server.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetIsServerbuffer
+   * @until //#GetIsServerbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetIsServerbuffer
+   * @until #//GetIsServerbuffer
+   * @skipline #//SetIsServerbuffer
+   * @until #//SetIsServerbuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newIsServer     Whether the buffer is to be a DSM server or not
+   */
+  void SetIsServer(bool newIsServer);
+
+  /**
+   * Gets the factor by which the size is multiplied when resizing the local buffer.
+   * A factor of 1 doubles the size of the local buffer when resizing.
+   * A factor of 0.5 adds half the original size of the buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   *
+   * @param     newFactor       The factor by which the buffer is resized.
+   */
+  void SetResizeFactor(double newFactor);
+
+  /**
+   * Manually update the length of an individual core's buffer.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetLength
+   * @until //#GetLength
+   * @skipline //#UpdateLength
+   * @until //#UpdateLength
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetLength
+   * @until #//GetLength
+   * @skipline #//UpdateLength
+   * @until #//UpdateLength
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newLength       The new buffer length, in bytes.
+   */
+  void UpdateLength(unsigned int newLength);
+
+  /**
+   * Releases all processes waiting on a specified dataset. Sends those processes a specified code.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest2.cpp
+   * @skipline //#initDSMWriterConnectRequired
+   * @until //#initDSMWriterConnectRequired
+   * @skipline //#buffernotify
+   * @until //#buffernotify
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest2.py
+   * @skipline #//initDSMWriterConnectRequired
+   * @until #//initDSMWriterConnectRequired
+   * @skipline #//buffernotify
+   * @until #//buffernotify
+   *
+   * @param     filename        The filename of the dataset to wait on.
+   * @param     datasetname     The dataset name of the dataset to wait on.
+   * @param     code            The code to be transmitted to waiting processes.
+   */
+  void WaitRelease(std::string filename, std::string datasetname, int code);
+
+  /**
+   * Blocks until released by the a waitRelease on the corresponding dataset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest2.cpp
+   * @skipline //#initDSMWriterConnectRequired
+   * @until //#initDSMWriterConnectRequired
+   * @skipline //#buffernotify
+   * @until //#buffernotify
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest2.py
+   * @skipline #//initDSMWriterConnectRequired
+   * @until #//initDSMWriterConnectRequired
+   * @skipline #//buffernotify
+   * @until #//buffernotify
+   *
+   * @param     filename        The filename of the dataset to wait on.
+   * @param     datasetname     The dataset name of the dataset to wait on.
+   * @return                    The code send from the release.
+   */
+  int WaitOn(std::string filename, std::string datasetname);
+
+protected:
+
+class XDMF_file_desc
+{
+  public:
+    XDMF_file_desc()
+    {
+      name = NULL;
+      start = 0;
+      end = 0;
+      numPages = 0;
+      pages = NULL;
+    }
+
+    ~XDMF_file_desc()
+    {
+    }
+
+    char * name;           /* filename                                */
+    haddr_t start;   /* current DSM start address               */
+    haddr_t end;     /* current DSM end address                 */
+    unsigned int numPages; /* number of pages assigned to the file    */
+    unsigned int * pages;  /* list of pages assigned to the file      */
+};
+
+  int AddressToId(int Address);
+
+  void Lock(char * filename);
+
+  int PageToId(int pageId);
+
+  int PageToAddress(int pageId);
+
+  void Unlock(char * filename);
+
+private:
+
+  void SetLength(long aLength);
+
+  class                 CommandMsg;
+  class                 InfoMsg;
+
+  bool                  IsServer;
+
+  int                   EndAddress;
+  int                   StartAddress;
+
+  int                   StartServerId;
+  int                   EndServerId;
+
+  unsigned int          LocalBufferSizeMBytes;
+  unsigned int          Length;
+  unsigned int          TotalLength;
+  unsigned int          BlockLength;
+
+  XdmfDSMCommMPI *      Comm;
+
+  char *                DataPointer;
+  unsigned int          NumPages;
+  unsigned int          PagesAssigned;
+
+  int                   DsmType;
+
+  int                   InterCommType;
+
+  int                   CommChannel;
+  bool                  IsConnected;
+
+  double                ResizeFactor;
+
+  std::map<std::string, std::vector<unsigned int> > WaitingMap;
+
+  std::map<std::string, std::queue<unsigned int> > LockedMap;
+  std::map<std::string, int> FileOwners;
+
+  std::map<std::string, XdmfDSMBuffer::XDMF_file_desc *> FileDefinitions;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFDSMBUFFER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFDSMBUFFER XDMFDSMBUFFER;
+
+XDMFDSM_EXPORT XDMFDSMBUFFER * XdmfDSMBufferNew();
+
+XDMFDSM_EXPORT void XdmfDSMBufferFree(XDMFDSMBUFFER * item);
+
+XDMFDSM_EXPORT int XdmfDSMBufferAddressToId(XDMFDSMBUFFER * buffer, int Address, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferBroadcastComm(XDMFDSMBUFFER * buffer, int *comm, int root, int * status);
+
+XDMFDSM_EXPORT int XdmfDSMBufferBufferService(XDMFDSMBUFFER * buffer, int *returnOpcode, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferBufferServiceLoop(XDMFDSMBUFFER * buffer, int *returnOpcode, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferConfigureUniform(XDMFDSMBUFFER * buffer,
+                                                  XDMFDSMCOMMMPI * Comm,
+                                                  long Length,
+                                                  int StartId,
+                                                  int EndId,
+                                                  long aBlockLength,
+                                                  int random,
+                                                  int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferConnect(XDMFDSMBUFFER * buffer, int persist, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferCreate(XDMFDSMBUFFER * buffer, MPI_Comm comm, int startId, int endId, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferDisconnect(XDMFDSMBUFFER * buffer, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferGet(XDMFDSMBUFFER * buffer, long Address, long aLength, void * Data, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferGetAddressRangeForId(XDMFDSMBUFFER * buffer, int Id, int * Start, int * End, int * status);
+
+XDMFDSM_EXPORT long XdmfDSMBufferGetBlockLength(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT XDMFDSMCOMMMPI * XdmfDSMBufferGetComm(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT char * XdmfDSMBufferGetDataPointer(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetDsmType(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetEndAddress(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetEndServerId(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetInterCommType(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetIsConnected(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetIsServer(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT long XdmfDSMBufferGetLength(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT unsigned int XdmfDSMBufferGetLocalBufferSizeMBytes(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT double XdmfDSMBufferGetResizeFactor(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetStartAddress(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT int XdmfDSMBufferGetStartServerId(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT long XdmfDSMBufferGetTotalLength(XDMFDSMBUFFER * buffer);
+
+XDMFDSM_EXPORT void XdmfDSMBufferProbeCommandHeader(XDMFDSMBUFFER * buffer, int * comm, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferPut(XDMFDSMBUFFER * buffer, long Address, long aLength, void * Data, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferReceiveAcknowledgment(XDMFDSMBUFFER * buffer,
+                                                       int source,
+                                                       int * data,
+                                                       int tag,
+                                                       int comm,
+                                                       int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferReceiveCommandHeader(XDMFDSMBUFFER * buffer,
+                                                      int * opcode,
+                                                      int * source,
+                                                      int * address,
+                                                      int * aLength,
+                                                      int comm,
+                                                      int remoteSource,
+                                                      int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferReceiveData(XDMFDSMBUFFER * buffer,
+                                             int source,
+                                             char * data,
+                                             int aLength,
+                                             int tag,
+                                             int aAddress,
+                                             int comm,
+                                             int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferReceiveInfo(XDMFDSMBUFFER * buffer,
+                                             int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSendAccept(XDMFDSMBUFFER * buffer, unsigned int numConnects);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSendAcknowledgment(XDMFDSMBUFFER * buffer,
+                                                    int dest,
+                                                    int data,
+                                                    int tag,
+                                                    int comm,
+                                                    int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSendCommandHeader(XDMFDSMBUFFER * buffer,
+                                                   int opcode,
+                                                   int dest,
+                                                   int address,
+                                                   int aLength,
+                                                   int comm,
+                                                   int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSendData(XDMFDSMBUFFER * buffer,
+                                          int dest,
+                                          char * data,
+                                          int aLength,
+                                          int tag,
+                                          int aAddress,
+                                          int comm,
+                                          int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSendDone(XDMFDSMBUFFER * buffer, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSendInfo(XDMFDSMBUFFER * buffer, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetBlockLength(XDMFDSMBUFFER * buffer, long newBlock);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetComm(XDMFDSMBUFFER * buffer, XDMFDSMCOMMMPI * newComm);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetDsmType(XDMFDSMBUFFER * buffer, int newDsmType);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetInterCommType(XDMFDSMBUFFER * buffer, int newType);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetIsConnected(XDMFDSMBUFFER * buffer, int newStatus);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetIsServer(XDMFDSMBUFFER * buffer, int newIsServer);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetLocalBufferSizeMBytes(XDMFDSMBUFFER * buffer, unsigned int newSize);
+
+XDMFDSM_EXPORT void XdmfDSMBufferSetResizeFactor(XDMFDSMBUFFER * buffer, double newFactor);
+
+XDMFDSM_EXPORT void XdmfDSMBufferWaitRelease(XDMFDSMBUFFER * buffer, char * filename, char * datasetname, int code);
+
+XDMFDSM_EXPORT int XdmfDSMBufferWaitOn(XDMFDSMBUFFER * buffer, char * filename, char * datasetname);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFDSMBUFFER_HPP_ */
+
diff --git a/core/dsm/XdmfDSMCommMPI.cpp b/core/dsm/XdmfDSMCommMPI.cpp
new file mode 100644
index 0000000..9008760
--- /dev/null
+++ b/core/dsm/XdmfDSMCommMPI.cpp
@@ -0,0 +1,1196 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMCommMPI.cpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+/*=========================================================================
+  This code is derived from an earlier work and is distributed
+  with permission from, and thanks to ...
+=========================================================================*/
+
+/*============================================================================
+
+  Project                 : H5FDdsm
+  Module                  : H5FDdsmCommMpi.cxx
+
+  Authors:
+     John Biddiscombe     Jerome Soumagne
+     biddisco at cscs.ch     soumagne at cscs.ch
+
+  Copyright (C) CSCS - Swiss National Supercomputing Centre.
+  You may use modify and and distribute this code freely providing
+  1) This copyright notice appears on all copies of source code
+  2) An acknowledgment appears with any substantial usage of the code
+  3) If this code is contributed to any other open source project, it
+  must not be reformatted such that the indentation, bracketing or
+  overall style is modified significantly.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  This work has received funding from the European Community's Seventh
+  Framework Programme (FP7/2007-2013) under grant agreement 225967 âxtMuSEâOC
+
+============================================================================*/
+
+#include <XdmfDSMCommMPI.hpp>
+#include <XdmfError.hpp>
+#include <mpi.h>
+#include <string.h>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+
+bool XdmfDSMCommMPI::UseEnvFileName = false;
+
+XdmfDSMCommMPI::XdmfDSMCommMPI()
+{
+  IntraComm = MPI_COMM_NULL;
+  Id = -1;
+  IntraSize = -1;
+  InterComm = MPI_COMM_NULL;
+  InterId = -1;
+  InterSize = -1;
+  SetDsmPortName("");
+  // This is the default file name for the config file.
+  DsmFileName = "dsmconnect.cfg";
+  if (XdmfDSMCommMPI::UseEnvFileName)
+  {
+    // Grab from ENV
+    if (std::getenv("XDMFDSM_CONFIG_FILE") != NULL)
+    {
+      DsmFileName = std::getenv("XDMFDSM_CONFIG_FILE");
+    }
+  }
+  InterCommType = XDMF_DSM_COMM_MPI;
+  HasOpenedPort = false;
+  ApplicationName = "Application";
+}
+
+XdmfDSMCommMPI::~XdmfDSMCommMPI()
+{
+#ifndef OPEN_MPI
+  if (InterComm != MPI_COMM_NULL) {
+    int status = MPI_Comm_free(&InterComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to free intercomm Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  if (IntraComm != MPI_COMM_NULL) {
+    int status = MPI_Comm_free(&IntraComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to free intercomm Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+#endif
+}
+
+void
+XdmfDSMCommMPI::Accept(unsigned int numConnections)
+{
+#ifndef XDMF_DSM_IS_CRAY
+  int status;
+  int acceptingLeadId;
+  while (numConnections > 0) {
+    if (InterComm == MPI_COMM_NULL) {
+      acceptingLeadId = this->IntraSize;
+      // If there is no InterComm, then accept from IntraComm and merge into InterComm
+      MPI_Comm tempComm;
+      int * portCheck = new int[GetInterSize()]();
+      int portStatus;
+      portStatus = 0;
+      if (HasOpenedPort) {
+        portStatus = 1;
+      }
+      MPI_Allgather(&portStatus, 1, MPI_INT, &(portCheck[0]), 1, MPI_INT, InterComm);
+      int index = 0;
+      for (index = 0; index < GetInterSize(); ++index) {
+        if (portCheck[index] == 1) {
+          break;
+        }
+      }
+      int status = MPI_Comm_accept(DsmPortName, MPI_INFO_NULL, index, IntraComm, &tempComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          std::string message = "Failed to accept port ";
+          message = message + DsmPortName;
+          XdmfError::message(XdmfError::FATAL, message);
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      // False is specified for high so that the index of the cores doesn't change
+      MPI_Comm mergedComm;
+      status = MPI_Intercomm_merge(tempComm, false, &mergedComm);
+      this->DupInterComm(mergedComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          XdmfError::message(XdmfError::FATAL, "Failed to merge intercomm");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      else {
+        MPI_Comm_rank(InterComm, &InterId);
+        MPI_Comm_size(InterComm, &InterSize);
+      }
+    }
+    else {
+      acceptingLeadId = this->InterSize;
+      // If there is an InterComm, accept into the InterComm and merge
+      MPI_Comm tempComm;
+      int * portCheck = new int[GetInterSize()]();
+      int portStatus;
+      portStatus = 0;
+      if (HasOpenedPort) {
+        portStatus = 1;
+      }
+      MPI_Allgather(&portStatus, 1, MPI_INT, &(portCheck[0]), 1, MPI_INT, InterComm);
+      int index = 0;
+      for (index = 0; index < GetInterSize(); ++index) {
+        if (portCheck[index] == 1) {
+          break;
+        }
+      }
+      int status = MPI_Comm_accept(DsmPortName, MPI_INFO_NULL, index, InterComm, &tempComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          std::string message = "Failed to accept port ";
+          message = message + DsmPortName;
+          XdmfError::message(XdmfError::FATAL, message);
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      // False is specified for high so that the index of the cores doesn't change
+      MPI_Comm mergedComm;
+      status = MPI_Intercomm_merge(tempComm, false, &mergedComm);
+      this->DupInterComm(mergedComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          XdmfError::message(XdmfError::FATAL, "Failed to merge InterComm");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      else {
+        MPI_Comm_rank(InterComm, &InterId);
+        MPI_Comm_size(InterComm, &InterSize);
+      }
+    }
+
+    //regen Intra comm from Inter Comm
+    MPI_Group IntraGroup, InterGroup;
+    MPI_Comm_group(InterComm, &InterGroup);
+    int * ServerIds = (int *)calloc(this->IntraSize, sizeof(int));
+    unsigned int index = 0;
+    for(int i=this->InterId - this->Id; i < this->InterId - this->Id + this->IntraSize; ++i)
+    {
+      ServerIds[index++] = i;
+    }
+    MPI_Group_incl(InterGroup, this->IntraSize, ServerIds, &IntraGroup);
+    MPI_Comm_create(InterComm, IntraGroup, &IntraComm);
+    cfree(ServerIds);
+
+    // Since this is accept, we will be recieving the local data from the new core and
+    // sending the overarching data to the connecting cores
+    unsigned int length;
+    char * appname;
+    unsigned int appsize;
+    if (DsmProcessStructure.size() == 0)
+    {
+      DsmProcessStructure.push_back(std::pair<std::string, unsigned int>(this->ApplicationName, this->IntraSize));
+    }
+    int numSections = DsmProcessStructure.size();
+    if (InterId == 0)
+    {
+      // Loop in the applicaiton names of the already existing sections of the DSM
+      // Get the number of application sections
+      MPI_Send(&numSections, 1, MPI_INT, acceptingLeadId, XDMF_DSM_EXCHANGE_TAG, this->InterComm);
+      for (unsigned int i = 0; i < numSections; ++i)
+      {
+        length = DsmProcessStructure[i].first.size();
+        // Get the length of the name
+        MPI_Send(&length, 1, MPI_UNSIGNED, acceptingLeadId, XDMF_DSM_EXCHANGE_TAG, InterComm);
+        // Get the string of characters
+        appname = new char[length]();
+        strcpy(appname, DsmProcessStructure[i].first.c_str());
+        MPI_Send(appname, length, MPI_CHAR, acceptingLeadId, XDMF_DSM_EXCHANGE_TAG, InterComm);
+        delete appname;
+        // Get associated numprocs
+        appsize = DsmProcessStructure[i].second;
+        MPI_Send(&appsize, 1, MPI_UNSIGNED, acceptingLeadId, XDMF_DSM_EXCHANGE_TAG, InterComm);
+      }
+    }
+    // Add the information for the newly added application
+    // For each application in the connecting set.
+    MPI_Bcast(&numSections, 1, MPI_UNSIGNED, acceptingLeadId, InterComm);
+    for (unsigned int i = 0; i < numSections; ++i)
+    {
+      MPI_Bcast(&length, 1, MPI_UNSIGNED, acceptingLeadId, InterComm);
+      appname = new char[length+1]();
+      MPI_Bcast(appname, length, MPI_CHAR, acceptingLeadId, InterComm);
+      appname[length] = 0;
+      MPI_Bcast(&appsize, 1, MPI_UNSIGNED, acceptingLeadId, InterComm);
+      DsmProcessStructure.push_back(std::pair<std::string, unsigned int>(std::string(appname), appsize));
+    }
+    --numConnections;
+    MPI_Bcast(&numConnections, 1, MPI_INT, 0, InterComm);
+  }
+#endif
+}
+
+void
+XdmfDSMCommMPI::AllGather(void *sendbuf,
+                          int sendbytes,
+                          void *recvbuf,
+                          int recvbytes,
+                          int comm)
+{
+  if (comm == XDMF_DSM_INTRA_COMM)
+  {
+    MPI_Allgather(sendbuf,
+                  sendbytes,
+                  MPI_UNSIGNED_CHAR,
+                  recvbuf,
+                  recvbytes,
+                  MPI_UNSIGNED_CHAR,
+                  IntraComm);
+  }
+  else if (comm == XDMF_DSM_INTER_COMM)
+  {
+    MPI_Allgather(sendbuf,
+                  sendbytes,
+                  MPI_UNSIGNED_CHAR,
+                  recvbuf,
+                  recvbytes,
+                  MPI_UNSIGNED_CHAR,
+                  InterComm);
+  }
+}
+
+void
+XdmfDSMCommMPI::Barrier(int comm)
+{
+  int status;
+
+  if (comm == XDMF_DSM_INTRA_COMM)
+  {
+    status = MPI_Barrier(IntraComm);
+  }
+  else if (comm == XDMF_DSM_INTER_COMM)
+  {
+    status = MPI_Barrier(InterComm);
+  }
+}
+
+void
+XdmfDSMCommMPI::Broadcast(void * pointer,
+                          int sizebytes,
+                          int root,
+                          int comm)
+{
+  int status;
+
+  if (comm == XDMF_DSM_INTRA_COMM)
+  {
+    status = MPI_Bcast(pointer, sizebytes, MPI_UNSIGNED_CHAR, root, IntraComm);
+  }
+  else if (comm == XDMF_DSM_INTER_COMM)
+  {
+    status = MPI_Bcast(pointer, sizebytes, MPI_UNSIGNED_CHAR, root, InterComm);
+  }
+}
+
+void
+XdmfDSMCommMPI::ClosePort()
+{
+#ifndef XDMF_DSM_IS_CRAY
+  if (Id == 0) {
+    int status;
+    for (unsigned int i = 0; i < PreviousDsmPortNames.size(); ++i)
+    {
+      status = MPI_Close_port(PreviousDsmPortNames[i]);
+      if (status != MPI_SUCCESS) {
+        try {// OpenMPI iterate through open ports in order to close the multiple needed
+          std::string message = "Failed to close port ";
+          message = message + PreviousDsmPortNames[i];
+          XdmfError::message(XdmfError::FATAL, message);
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+  }
+#endif
+  HasOpenedPort = false;
+}
+
+int
+XdmfDSMCommMPI::Connect()
+{
+#ifndef XDMF_DSM_IS_CRAY
+  int status;
+  MPI_Status mpistatus;
+  if (InterComm == MPI_COMM_NULL) {
+    this->DupInterComm(IntraComm);
+  }
+  MPI_Comm tempComm;
+  MPI_Comm tempConnectComm;
+  MPI_Comm_dup(InterComm, &tempConnectComm);
+  MPI_Errhandler_set(InterComm, MPI_ERRORS_RETURN);
+  status = MPI_Comm_connect(DsmPortName, MPI_INFO_NULL, 0, tempConnectComm, &tempComm);
+  MPI_Errhandler_set(InterComm, MPI_ERRORS_ARE_FATAL);
+  if (status != MPI_SUCCESS) {
+    try {
+      std::string message = "Failed to connect to port ";
+      message = message + DsmPortName;
+      XdmfError::message(XdmfError::FATAL, message);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  MPI_Comm mergedComm;
+  status = MPI_Intercomm_merge(tempComm, true, &mergedComm);
+  this->DupInterComm(mergedComm);
+  if (status != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Failed to merge InterComm");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    status = MPI_Comm_rank(InterComm, &InterId);
+    status = MPI_Comm_size(InterComm, &InterSize);
+  }
+
+  //regen Intra comm from Inter Comm
+  MPI_Group IntraGroup, InterGroup;
+  MPI_Comm_group(InterComm, &InterGroup);
+  int * ServerIds = (int *)calloc(this->IntraSize, sizeof(int));
+  unsigned int index = 0;
+  for(int i=this->InterId - this->Id; i < this->InterId - this->Id + this->IntraSize; ++i)
+  {
+    ServerIds[index++] = i;
+  }
+  MPI_Group_incl(InterGroup, this->IntraSize, ServerIds, &IntraGroup);
+  MPI_Comm_create(InterComm, IntraGroup, &IntraComm);
+  cfree(ServerIds);
+
+  // Here the process will send information about itself to the server and
+  // the server will diseminate that info across all the connected processes
+  std::vector<std::pair<std::string, unsigned int> > structureArchive;
+  // Archive old structure if it exists
+  if (DsmProcessStructure.size() > 0)
+  {
+    for (unsigned int i = 0; i < DsmProcessStructure.size(); ++i)
+    {
+      structureArchive.push_back(DsmProcessStructure[i]);
+    }
+    DsmProcessStructure.clear();
+  }
+  // Loop in the applicaiton names of the already existing sections of the DSM
+  // Get the number of application sections
+  int numSections;
+  if (this->Id == 0)
+  {
+    MPI_Recv(&numSections, 1, MPI_INT, 0, XDMF_DSM_EXCHANGE_TAG, this->InterComm, &mpistatus);
+  }
+  MPI_Bcast(&numSections, 1, MPI_INT, 0, IntraComm);
+  unsigned int length;
+  char * appname;
+  unsigned int appsize;
+  for (unsigned int i = 0; i < numSections; ++i)
+  {
+    if (this->Id == 0)
+    {
+      // Get the length of the name
+      MPI_Recv(&length, 1, MPI_UNSIGNED, 0, XDMF_DSM_EXCHANGE_TAG, InterComm, &mpistatus);
+      // Get the string of characters
+      appname = new char[length+1]();
+      MPI_Recv(appname, length, MPI_CHAR, 0, XDMF_DSM_EXCHANGE_TAG, InterComm, &mpistatus);
+      appname[length] = 0;
+      // Get associated numprocs
+      MPI_Recv(&appsize, 1, MPI_UNSIGNED, 0, XDMF_DSM_EXCHANGE_TAG, InterComm, &mpistatus);
+    }
+    // Broadcast to local comm
+    MPI_Bcast(&length, 1, MPI_UNSIGNED, 0, IntraComm);
+    if (this->Id != 0)
+    {
+      appname = new char[length+1]();
+    }
+    MPI_Bcast(appname, length+1, MPI_CHAR, 0, IntraComm);
+    MPI_Bcast(&appsize, 1, MPI_UNSIGNED, 0, IntraComm);
+
+    DsmProcessStructure.push_back(std::pair<std::string, unsigned int>(std::string(appname), appsize));
+  }
+  if (structureArchive.size() == 0)
+  {
+    numSections = 1;
+    MPI_Bcast(&numSections, 1, MPI_INT, InterId-Id, InterComm);
+    length = ApplicationName.size();
+    appsize = this->IntraSize;
+    MPI_Bcast(&length, 1, MPI_UNSIGNED, InterId-Id, InterComm);
+    appname = new char[length]();
+    strcpy(appname, ApplicationName.c_str());
+    MPI_Bcast(appname, length, MPI_CHAR, InterId-Id, InterComm);
+    delete appname;
+    MPI_Bcast(&appsize, 1, MPI_UNSIGNED, InterId-Id, InterComm);
+    DsmProcessStructure.push_back(std::pair<std::string, unsigned int>(ApplicationName, appsize));
+  }
+  else
+  {
+    numSections = structureArchive.size();
+    MPI_Bcast(&numSections, 1, MPI_UNSIGNED, InterId-Id, InterComm);
+    for (unsigned int i = 0; i < numSections; ++i)
+    {
+      length = structureArchive[i].first.size();
+      appsize = structureArchive[i].second;
+      MPI_Bcast(&length, 1, MPI_UNSIGNED, InterId-Id, InterComm);
+      appname = new char[length]();
+      strcpy(appname, structureArchive[i].first.c_str());
+      MPI_Bcast(appname, length, MPI_CHAR, InterId-Id, InterComm);
+      delete appname;
+      MPI_Bcast(&appsize, 1, MPI_UNSIGNED, InterId-Id, InterComm);
+      DsmProcessStructure.push_back(std::pair<std::string, unsigned int>(structureArchive[i].first, appsize));
+    }
+  }
+  int numAccepts = 0;
+  MPI_Bcast(&numAccepts, 1, MPI_INT, 0, InterComm);
+#ifdef OPEN_MPI
+    if (numAccepts > 0) {
+      MPI_Bcast(DsmPortName, MPI_MAX_PORT_NAME, MPI_CHAR, 0, InterComm);
+    }
+#endif
+  Accept(numAccepts);
+  return MPI_SUCCESS;
+#endif
+  return MPI_SUCCESS;
+}
+
+void
+XdmfDSMCommMPI::Disconnect()
+{
+#ifndef XDMF_DSM_IS_CRAY
+#ifndef OPEN_MPI
+  if (InterComm != MPI_COMM_NULL) {
+    int status = MPI_Comm_free(&InterComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to disconnect Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+#endif
+#endif
+  InterComm = MPI_COMM_NULL;
+}
+
+void
+XdmfDSMCommMPI::DupComm(MPI_Comm comm)
+{
+  if (IntraComm != comm) {
+    int status;
+#ifndef OPEN_MPI
+    if (IntraComm != MPI_COMM_NULL) {
+      status = MPI_Comm_free(&IntraComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          XdmfError::message(XdmfError::FATAL, "Failed to disconnect Comm");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+#endif
+    if (comm != MPI_COMM_NULL) {
+      status = MPI_Comm_dup(comm, &IntraComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          XdmfError::message(XdmfError::FATAL, "Failed to duplicate Comm");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      else {
+        status = MPI_Comm_size(IntraComm, &IntraSize);
+        status = MPI_Comm_rank(IntraComm, &Id);
+      }
+    }
+  }
+}
+
+void
+XdmfDSMCommMPI::DupInterComm(MPI_Comm comm)
+{
+  if (InterComm != comm) {
+    int status;
+#ifndef OPEN_MPI
+    if (InterComm != MPI_COMM_NULL) {
+      status = MPI_Comm_free(&InterComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          XdmfError::message(XdmfError::FATAL, "Failed to disconnect Comm");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+#endif
+    if (comm != MPI_COMM_NULL) {
+      status = MPI_Comm_dup(comm, &InterComm);
+      if (status != MPI_SUCCESS) {
+        try {
+          XdmfError::message(XdmfError::FATAL, "Failed to duplicate Comm");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      else {
+        status = MPI_Comm_rank(InterComm, &InterId);
+        status = MPI_Comm_size(InterComm, &InterSize);
+      }
+    }
+    else {
+      InterId = -1;
+      InterSize = -1;
+    }
+  }
+}
+
+std::string
+XdmfDSMCommMPI::GetApplicationName()
+{
+  return ApplicationName;
+}
+
+std::string
+XdmfDSMCommMPI::GetDsmFileName()
+{
+  return DsmFileName;
+}
+
+char *
+XdmfDSMCommMPI::GetDsmPortName()
+{
+  return DsmPortName;
+}
+
+std::vector<std::pair<std::string, unsigned int> >
+XdmfDSMCommMPI::GetDsmProcessStructure()
+{
+  return DsmProcessStructure;
+}
+
+int
+XdmfDSMCommMPI::GetId()
+{
+  return this->Id;
+}
+
+MPI_Comm
+XdmfDSMCommMPI::GetInterComm()
+{
+  return InterComm;
+}
+
+int
+XdmfDSMCommMPI::GetInterCommType()
+{
+  return this->InterCommType;
+}
+
+int
+XdmfDSMCommMPI::GetInterId()
+{
+  return this->InterId;
+}
+
+int
+XdmfDSMCommMPI::GetInterSize()
+{
+  return this->InterSize;
+}
+
+MPI_Comm
+XdmfDSMCommMPI::GetIntraComm()
+{
+  return IntraComm;
+}
+
+int
+XdmfDSMCommMPI::GetIntraSize()
+{
+  return this->IntraSize;
+}
+
+bool
+XdmfDSMCommMPI::GetUseEnvFileName()
+{
+  return XdmfDSMCommMPI::UseEnvFileName;
+}
+
+void
+XdmfDSMCommMPI::Init()
+{
+  int size, rank;
+  if (MPI_Comm_size(this->IntraComm, &size) != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Failed to initialize size");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  if (MPI_Comm_rank(this->IntraComm, &rank) != MPI_SUCCESS) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Failed to initialize rank");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  this->Id = rank;
+  this->IntraSize = size;
+}
+
+void
+XdmfDSMCommMPI::OpenPort()
+{
+  if (Id == 0) {
+#ifndef XDMF_DSM_IS_CRAY
+    int status = MPI_Open_port(MPI_INFO_NULL, DsmPortName);
+    if (status != MPI_SUCCESS) {
+      try {
+        std::string message = "Failed to open port ";
+        message = message + DsmPortName;
+        XdmfError::message(XdmfError::FATAL, message);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    PreviousDsmPortNames.push_back(DsmPortName);
+#endif
+    std::ofstream connectFile (DsmFileName.c_str());
+    if (connectFile.is_open()) {
+      connectFile << DsmPortName;
+      connectFile.close();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to write port to file");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    HasOpenedPort = true;
+  }
+#ifndef XDMF_DSM_IS_CRAY
+  MPI_Bcast(DsmPortName, MPI_MAX_PORT_NAME, MPI_CHAR, 0, IntraComm);
+#endif
+}
+
+void
+XdmfDSMCommMPI::Probe(int *comm)
+{
+  // Used for finding a comm that has a waiting command, then sets the comm
+  int status = XDMF_DSM_FAIL;
+  MPI_Status signalStatus;
+
+  int flag;
+  MPI_Comm probeComm =
+    this->GetIntraComm();
+
+  // Spin until a message is found on one of the communicators
+  while (status != XDMF_DSM_SUCCESS) {
+    status = MPI_Iprobe(XDMF_DSM_ANY_SOURCE,
+                        XDMF_DSM_ANY_TAG,
+                        probeComm,
+                        &flag,
+                        &signalStatus);
+    if (status != MPI_SUCCESS)
+    {
+       try {
+         XdmfError::message(XdmfError::FATAL,
+                            "Error: Failed to probe for command header");
+       }
+       catch (XdmfError & e) {
+         throw e;
+       }
+    }
+    if (flag) {
+      status = XDMF_DSM_SUCCESS;
+    }
+    else {
+      if (this->GetInterComm() != MPI_COMM_NULL) {
+        if (probeComm == this->GetIntraComm()) {
+          probeComm = this->GetInterComm();
+        }
+        else {
+          probeComm = this->GetIntraComm();
+        }
+      }
+    }
+  }
+  if (probeComm == this->GetInterComm()) {
+    *comm = XDMF_DSM_INTER_COMM;
+  }
+  else
+  {
+    *comm = XDMF_DSM_INTRA_COMM;
+  }
+
+  probeComm = MPI_COMM_NULL;
+}
+
+void
+XdmfDSMCommMPI::ReadDsmPortName()
+{
+#ifndef XDMF_DSM_IS_CRAY
+  std::ifstream connectFile(DsmFileName.c_str());
+  std::string connectLine;
+  if (connectFile.is_open()) {
+    getline(connectFile, connectLine);
+  }
+  strcpy(DsmPortName, connectLine.c_str());
+#endif
+}
+
+void
+XdmfDSMCommMPI::Send(void * pointer,
+                     int sizebytes,
+                     int coreTo,
+                     int comm,
+                     int tag)
+{
+  int status;
+  if (comm == XDMF_DSM_INTRA_COMM) {
+    status = MPI_Send(pointer,
+                      sizebytes,
+                      MPI_UNSIGNED_CHAR,
+                      coreTo,
+                      tag,
+                      IntraComm);
+  }
+  else if (comm == XDMF_DSM_INTER_COMM) {
+    status = MPI_Send(pointer,
+                      sizebytes,
+                      MPI_UNSIGNED_CHAR,
+                      coreTo,
+                      tag,
+                      InterComm);
+  }
+}
+
+void
+XdmfDSMCommMPI::Receive(void * pointer,
+                        int sizebytes,
+                        int coreFrom,
+                        int comm,
+                        int tag)
+{
+  int status;
+  MPI_Status signalStatus;
+  if (comm == XDMF_DSM_INTRA_COMM) {
+    status = MPI_Recv(pointer,
+                      sizebytes,
+                      MPI_UNSIGNED_CHAR,
+                      coreFrom,
+                      tag,
+                      IntraComm,
+                      &signalStatus);
+  }
+  else if (comm == XDMF_DSM_INTER_COMM) {
+    status = MPI_Recv(pointer,
+                      sizebytes,
+                      MPI_UNSIGNED_CHAR,
+                      coreFrom,
+                      tag,
+                      InterComm,
+                      &signalStatus);
+  }
+}
+
+void
+XdmfDSMCommMPI::SetApplicationName(std::string newName)
+{
+  ApplicationName = newName;
+}
+
+void
+XdmfDSMCommMPI::SetDsmFileName(std::string filename)
+{
+  DsmFileName = filename;
+}
+
+void
+XdmfDSMCommMPI::SetDsmPortName(const char *hostName)
+{
+  strcpy(DsmPortName, hostName);
+}
+
+void
+XdmfDSMCommMPI::SetDsmProcessStructure(std::vector<std::pair<std::string, unsigned int> > & newStructure)
+{
+  DsmProcessStructure = newStructure;
+}
+
+void
+XdmfDSMCommMPI::SetUseEnvFileName(bool status)
+{
+  XdmfDSMCommMPI::UseEnvFileName = status;
+}
+
+// C Wrappers
+
+XDMFDSMCOMMMPI * XdmfDSMCommMPINew()
+{
+  try
+  {
+    return (XDMFDSMCOMMMPI *)((void *)(new XdmfDSMCommMPI()));
+  }
+  catch (...)
+  {
+    return (XDMFDSMCOMMMPI *)((void *)(new XdmfDSMCommMPI()));
+  }
+}
+
+void XdmfDSMCommMPIFree(XDMFDSMCOMMMPI * item)
+{
+  if (item != NULL) {
+    delete ((XdmfDSMCommMPI *)item);
+  }
+  item = NULL;
+}
+
+void XdmfDSMCommMPIAccept(XDMFDSMCOMMMPI * dsmComm, unsigned int numConnections, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->Accept(numConnections);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMCommMPIClosePort(XDMFDSMCOMMMPI * dsmComm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->ClosePort();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+int XdmfDSMCommMPIConnect(XDMFDSMCOMMMPI * dsmComm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  return ((XdmfDSMCommMPI *)dsmComm)->Connect();
+  XDMF_ERROR_WRAP_END(status)
+  return -1;
+}
+
+void XdmfDSMCommMPIDisconnect(XDMFDSMCOMMMPI * dsmComm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->Disconnect();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMCommMPIDupComm(XDMFDSMCOMMMPI * dsmComm, MPI_Comm comm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->DupComm(comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMCommMPIDupInterComm(XDMFDSMCOMMMPI * dsmComm, MPI_Comm comm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->DupInterComm(comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+char * XdmfDSMCommMPIGetApplicationName(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfDSMCommMPI *)dsmComm)->GetApplicationName().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfDSMCommMPI *)dsmComm)->GetApplicationName().c_str());
+    return returnPointer;
+  }
+}
+
+char * XdmfDSMCommMPIGetDsmFileName(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    char * returnPointer = strdup(((XdmfDSMCommMPI *)dsmComm)->GetDsmFileName().c_str());
+    return returnPointer;
+  }
+  catch (...)
+  {
+    char * returnPointer = strdup(((XdmfDSMCommMPI *)dsmComm)->GetDsmFileName().c_str());
+    return returnPointer;
+  }
+}
+
+char * XdmfDSMCommMPIGetDsmPortName(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetDsmPortName();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetDsmPortName();
+  }
+}
+
+void XdmfDSMCommMPIGetDsmProcessStructure(XDMFDSMCOMMMPI * dsmComm,
+                                          char ** names,
+                                          unsigned int * coreCount,
+                                          int * numApplications)
+{
+  try
+  {
+    std::vector<std::pair<std::string, unsigned int> > structure =
+      ((XdmfDSMCommMPI *)dsmComm)->GetDsmProcessStructure();
+    *numApplications = structure.size();
+    coreCount = new unsigned int[*numApplications]();
+    names = new char *[*numApplications]();
+    for (unsigned int i = 0; i < *numApplications; ++i)
+    {
+      coreCount[i] = structure[i].second;
+      names[i] = strdup(structure[i].first.c_str());
+    }
+  }
+  catch (...)
+  {
+    std::vector<std::pair<std::string, unsigned int> > structure =
+      ((XdmfDSMCommMPI *)dsmComm)->GetDsmProcessStructure();
+    *numApplications = structure.size();
+    coreCount = new unsigned int[*numApplications]();
+    names = new char *[*numApplications]();
+    for (unsigned int i = 0; i < *numApplications; ++i)
+    {
+      coreCount[i] = structure[i].second;
+      names[i] = strdup(structure[i].first.c_str());
+    }
+  }
+}
+
+int XdmfDSMCommMPIGetId(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetId();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetId();
+  }
+}
+
+MPI_Comm XdmfDSMCommMPIGetInterComm(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterComm();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterComm();
+  }
+}
+
+int XdmfDSMCommMPIGetInterCommType(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterCommType();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterCommType();
+  }
+}
+
+int XdmfDSMCommMPIGetInterId(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterId();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterId();
+  }
+}
+
+int XdmfDSMCommMPIGetInterSize(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterSize();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetInterSize();
+  }
+}
+
+MPI_Comm XdmfDSMCommMPIGetIntraComm(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetIntraComm();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetIntraComm();
+  }
+}
+
+int XdmfDSMCommMPIGetIntraSize(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetIntraSize();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetIntraSize();
+  }
+}
+
+int XdmfDSMCommMPIGetUseEnvFileName(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetUseEnvFileName();
+  }
+  catch (...)
+  {
+    return ((XdmfDSMCommMPI *)dsmComm)->GetUseEnvFileName();
+  }
+}
+
+void XdmfDSMCommMPIInit(XDMFDSMCOMMMPI * dsmComm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->Init();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMCommMPIOpenPort(XDMFDSMCOMMMPI * dsmComm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfDSMCommMPI *)dsmComm)->OpenPort();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfDSMCommMPIReadDsmPortName(XDMFDSMCOMMMPI * dsmComm)
+{
+  try
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->ReadDsmPortName();
+  }
+  catch (...)
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->ReadDsmPortName();
+  }
+}
+
+void XdmfDSMCommMPISetApplicationName(XDMFDSMCOMMMPI * dsmComm, char * newName)
+{
+  try
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetApplicationName(std::string(newName));
+  }
+  catch (...)
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetApplicationName(std::string(newName));
+  }
+}
+
+void XdmfDSMCommMPISetDsmFileName(XDMFDSMCOMMMPI * dsmComm, char * filename)
+{
+  try
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetDsmFileName(std::string(filename));
+  }
+  catch (...)
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetDsmFileName(std::string(filename));
+  }
+}
+
+void XdmfDSMCommMPISetDsmPortName(XDMFDSMCOMMMPI * dsmComm, char * hostName)
+{
+  try
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetDsmPortName(hostName);
+  }
+  catch (...)
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetDsmPortName(hostName);
+  }
+}
+
+void XdmfDSMCommMPISetUseEnvFileName(XDMFDSMCOMMMPI * dsmComm, int status)
+{
+  try
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetUseEnvFileName(status);
+  }
+  catch (...)
+  {
+    ((XdmfDSMCommMPI *)dsmComm)->SetUseEnvFileName(status);
+  }
+}
diff --git a/core/dsm/XdmfDSMCommMPI.hpp b/core/dsm/XdmfDSMCommMPI.hpp
new file mode 100644
index 0000000..02d7ccd
--- /dev/null
+++ b/core/dsm/XdmfDSMCommMPI.hpp
@@ -0,0 +1,1548 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMCommMPI.hpp                                                  */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFDSMCOMMMPI_HPP_
+#define XDMFDSMCOMMMPI_HPP_
+
+// C Compatible Includes
+#include <XdmfDSM.hpp>
+#include <mpi.h>
+
+// Definitions
+
+#define XDMF_DSM_COMM_MPI       0x11
+
+#define XDMF_DSM_INTRA_COMM  0x00
+#define XDMF_DSM_INTER_COMM  0x01
+#define XDMF_DSM_ANY_COMM    0x02
+
+#define XDMF_DSM_SERVER_ID          XDMF_DSM_INTRA_COMM
+#define XDMF_DSM_CLIENT_ID          XDMF_DSM_INTER_COMM
+#define XDMF_DSM_NUM_CONNECTION_IDS 0x02
+
+#define XDMF_DSM_DEFAULT_TAG    0x80
+#define XDMF_DSM_COMMAND_TAG    0x81
+#define XDMF_DSM_SERVER_ACK_TAG 0x82
+#define XDMF_DSM_CLIENT_ACK_TAG 0x83
+#define XDMF_DSM_PUT_DATA_TAG   0x84
+#define XDMF_DSM_GET_DATA_TAG   0x85
+#define XDMF_DSM_EXCHANGE_TAG   0x86
+
+#define XDMF_DSM_ANY_TAG        -1
+#define XDMF_DSM_ANY_SOURCE     -2
+
+#define XDMF_DSM_SUCCESS  1
+#define XDMF_DSM_FAIL    -1
+
+#ifdef __cplusplus
+
+// Forward Declarations
+
+// Includes
+#include <string>
+#include <vector>
+
+/**
+ * @brief Holds communicators for interacting with H5FD dsm.
+ *
+ * XdmfDSMCommMPI takes the place of the H5FDdsmComm defined in H5FD.
+ * It provides more access to the the intra and inter communicators.
+ * It is primarily for allowing the XdmfDSM to interact with HDF5 dsm without threads.
+ */
+class XDMFDSM_EXPORT XdmfDSMCommMPI {
+
+public:
+
+  // To allow these classes to set
+  // Process structure directly.
+  friend class XdmfDSMBuffer;
+
+  XdmfDSMCommMPI();
+  ~XdmfDSMCommMPI();
+
+  /**
+   * Accepts connections to the port currently named by DsmPortName.
+   * Called on server side, accepts from core 0.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#manualAccept
+   * @until //#manualAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//manualAccept
+   * @until #//manualAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   */
+  void Accept(unsigned int numConnections = 1);
+
+  /**
+   * Equivalent to MPI_Allgather.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DSMAllGather
+   * @until //#DSMAllGather
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * Unusable in python unless an object of a cpointer type is passed via
+   * wrapped code
+   *
+   * @param     sendbuf          The Buffer that the gathered values will be placed in.
+   * @param     sendbytes        The size of the values to be gathered per core.
+   * @param     recvbuf          The Buffer that the gathered values will be taken from.
+   * @param     recvbytes        The size of the values to be sent per core.
+   * @param     comm             The Int code for the communicator to be used.
+   */
+  void AllGather(void *sendbuf,
+                 int sendbytes,
+                 void *recvbuf,
+                 int recvbytes,
+                 int comm);
+
+  /**
+   * Equivalent to MPI_Barrier
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DSMBarrier
+   * @until //#DSMBarrier
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//DSMBarrier
+   * @until #//DSMBarrier
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     comm             The Int code for the communicator to be used.
+   */
+  void Barrier(int comm);
+
+  /**
+   * Equivalent to MPI_Bcast
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DSMBroadcast
+   * @until //#DSMBroadcast
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * Unusable in python unless an object of a cpointer type is passed via
+   * wrapped code
+   *
+   * @param     pointer          Pointer to what is being broadcasted
+   * @param     sizebytes        Size of the pointer to be broadcast.
+   * @param     root             Core that the broadcast originates from
+   * @param     comm             The Int code for the communicator to be used.
+   */
+  void Broadcast(void * pointer,
+                 int sizebytes,
+                 int root,
+                 int comm);
+
+  /**
+   * Closes the port currently named by DsmPortName.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   */
+  void ClosePort();
+
+  /**
+   * If core ID is 0 then attempts to connect to the port currently named by DsmPortName
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#manualConnect
+   * @until //#manualConnect
+   * @skipline //#Disconnectcomm
+   * @until //#Disconnectcomm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//manualConnect
+   * @until #//manualConnect
+   * @skipline #//Disconnectcomm
+   * @until #//Disconnectcomm
+   *
+   * @return     Whether the connection was successful or not
+   */
+  int Connect();
+
+  /**
+   * Disconnects the intercomm if not in static intercomm mode.
+   * Then sets the intercomm to MPI_COMM_NULL.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#manualConnect
+   * @until //#manualConnect
+   * @skipline //#Disconnectcomm
+   * @until //#Disconnectcomm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//manualConnect
+   * @until #//manualConnect
+   * @skipline #//Disconnectcomm
+   * @until #//Disconnectcomm
+   */
+  void Disconnect();
+
+  /**
+   * Sets the IntraComm to the provided comm by duplicating it.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#commsplit
+   * @until //#commsplit
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DupComm
+   * @until //#DupComm
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//DupComm
+   * @until #//DupComm
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     comm    The comm to be used as the IntraComm
+   */
+  void DupComm(MPI_Comm comm);
+
+  /**
+   * Sets the intercomm to the communicator provided by duplicating it.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#commsplit
+   * @until //#commsplit
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#DupInterComm
+   * @until //#DupInterComm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//GetInterComm
+   * @until #//GetInterComm
+   * @skipline #//DupInterComm
+   * @until #//DupInterComm
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     comm    The comm to be used as the intercomm
+   */
+  void DupInterComm(MPI_Comm comm);
+
+  /**
+   * Gets the name by which this application will be referenced in the DSM process structure.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline #//SetApplicationName
+   * @until #//SetApplicationName
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#Connect
+   * @until //#Connect
+   * @skipline #//GetApplicationName
+   * @until #//GetApplicationName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//SetApplicationName
+   * @until #//SetApplicationName
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//Connect
+   * @until #//Connect
+   * @skipline #//GetApplicationName
+   * @until #//GetApplicationName
+   *
+   * @return    The name by which the current application is referenced.
+   */
+  std::string GetApplicationName();
+
+  /**
+   * Gets the current file name that connection info will be written to.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#GetDsmFileName
+   * @until //#GetDsmFileName
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//GetDsmFileName
+   * @until #//GetDsmFileName
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   *
+   * @return    The file name where connection info will be written
+   */
+  std::string GetDsmFileName();
+
+  /**
+   * Gets the port name that will be connected to when Connect/Accept is called.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#GetDsmPortName
+   * @until //#GetDsmPortName
+   * @skipline //#manualConnect
+   * @until //#manualConnect
+   * @skipline //#Disconnectcomm
+   * @until //#Disconnectcomm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//GetDsmPortName
+   * @until #//GetDsmPortName
+   * @skipline #//manualConnect
+   * @until #//manualConnect
+   * @skipline #//Disconnectcomm
+   * @until #//Disconnectcomm
+   *
+   * @return    a pointer to the character string that specifies the port
+   */
+  char * GetDsmPortName();
+
+  /**
+   * Gets the process structure within the dsm. Process 0 is at index 0 of the vector.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline #//SetApplicationName
+   * @until #//SetApplicationName
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#Connect
+   * @until //#Connect
+   * @skipline #//GetApplicationName
+   * @until #//GetApplicationName
+   * @skipline #//GetDsmProcessStructure
+   * @until #//GetDsmProcessStructure
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//SetApplicationName
+   * @until #//SetApplicationName
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//Connect
+   * @until #//Connect
+   * @skipline #//GetApplicationName
+   * @until #//GetApplicationName
+   * @skipline #//GetDsmProcessStructure
+   * @until #//GetDsmProcessStructure
+   *
+   * @return    A vector that contains a list of application names and numbers of cores allocated.
+   */
+  std::vector<std::pair<std::string, unsigned int> > GetDsmProcessStructure();
+
+  /**
+   * Gets the Id with regards to the IntraComm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#GetId
+   * @until //#GetId
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//GetId
+   * @until #//GetId
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The Id of the core with regards to the IntraComm
+   */
+  int GetId();
+
+  /**
+   * Gets the communicator that is currently functioning as the intercomm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#GetInterComm
+   * @until //#GetInterComm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//GetInterComm
+   * @until #//GetInterComm
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return     The communicator currently serving as the intercomm.
+   */
+  MPI_Comm GetInterComm();
+
+  /**
+   * Gets the type of the InterComm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#GetInterCommType
+   * @until //#GetInterCommType
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//GetInterCommType
+   * @until #//GetInterCommType
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    An integer representation of the InterComm's type
+   */
+  int GetInterCommType();
+
+  /**
+   * Gets the Id with regards to the InterComm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#GetInterId
+   * @until //#GetInterId
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//GetInterId
+   * @until #//GetInterId
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The Id of the core with regards to the IntraComm
+   */
+  int GetInterId();
+
+  /**
+   * Gets the number of cores contained in the InterComm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#GetInterSize
+   * @until //#GetInterSize
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//GetInterSize
+   * @until #//GetInterSize
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The number of cores in the InterComm
+   */
+  int GetInterSize();
+
+  /**
+   * Gets the communicator that is currently functioning as the intracomm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#GetIntraComm
+   * @until //#GetIntraComm
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//GetIntraComm
+   * @until #//GetIntraComm
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The communicator currently serving as the intracomm.
+   */
+  MPI_Comm GetIntraComm();
+
+  /**
+   * Gets the number of cores contained in the IntraComm.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#GetIntraSize
+   * @until //#GetIntraSize
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//GetIntraSize
+   * @until #//GetIntraSize
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The number of cores in the IntraComm
+   */
+  int GetIntraSize();
+
+  /**
+   * If this is true then any created Comms will pull their dsm file name
+   * from the environment instead of using the default.
+   * The default value for this is false.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   *
+   * @return    Whether the filename is being pulled from the environment.
+   */
+  static bool GetUseEnvFileName();
+
+  /**
+   * Initializes the Intracomm rank and size to the associated variables
+   * in the internal structure
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#initcomm
+   * @until //#initcomm
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//GetComm
+   * @until #//GetComm
+   * @skipline #//initcomm
+   * @until #//initcomm
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void Init();
+
+  /**
+   * Opens a port and stores the port name in DsmPortName.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   */
+  void OpenPort();
+
+  /**
+   * Equivalent to MPI_Iprobe
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DSMSendRecv
+   * @until //#DSMSendRecv
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * Unusable in python unless an object of a cpointer type is passed via
+   * wrapped code
+   *
+   * @param     comm             The Int code for the communicator to be used. (output)
+   */
+  void Probe(int *comm);
+
+  /**
+   * Reads the connection information from the current DSMfile.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#manualConnect
+   * @until //#manualConnect
+   * @skipline //#Disconnectcomm
+   * @until //#Disconnectcomm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//manualConnect
+   * @until #//manualConnect
+   * @skipline #//Disconnectcomm
+   * @until #//Disconnectcomm
+   */
+  void ReadDsmPortName();
+
+  /**
+   * Equivalent to MPI_recv
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DSMSendRecv
+   * @until //#DSMSendRecv
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * Unusable in python unless an object of a cpointer type is passed via
+   * wrapped code
+   *
+   * @param     pointer          The pointer to place recieved data into.
+   * @param     sizebytes        The size of the buffer being transmitted.
+   * @param     coreFrom         The core to recieve data from.
+   * @param     comm             The Int code for the communicator to be used.
+   * @param     tag              The tag for the communication.
+   */
+  void Receive(void * pointer,
+               int sizebytes,
+               int coreFrom,
+               int comm,
+               int tag);
+
+  /**
+   * Equivalent to MPI_send
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#GetComm
+   * @until //#GetComm
+   * @skipline //#DSMSendRecv
+   * @until //#DSMSendRecv
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * Unusable in python unless an object of a cpointer type is passed via
+   * wrapped code
+   *
+   * @param     pointer          The pointer to send.
+   * @param     sizebytes        The size of the buffer being transmitted.
+   * @param     coreTo           The core to send data to.
+   * @param     comm             The Int code for the communicator to be used.
+   * @param     tag              The tag for the communication.
+   */
+  void Send(void * pointer,
+            int sizebytes,
+            int coreTo,
+            int comm,
+            int tag);
+
+  /**
+   * Sets the name by which this process will be referenced in the DSM process structure.
+   *
+   * Default is "Application"
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline #//SetApplicationName
+   * @until #//SetApplicationName
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//SetApplicationName
+   * @until #//SetApplicationName
+   *
+   * @param     newName The name by which the application will now be referenced.
+   */
+  void SetApplicationName(std::string newName);
+
+  /**
+   * Sets the file name that connection info will be written to.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfAcceptTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#GetDsmFileName
+   * @until //#GetDsmFileName
+   * @skipline //#SetDsmFileName
+   * @until //#SetDsmFileName
+   * @skipline //#OpenPort
+   * @until //#OpenPort
+   * @skipline //#SendAccept
+   * @until //#SendAccept
+   * @skipline //#finishwork
+   * @until //#finishwork
+   * @skipline //#ClosePort
+   * @until //#ClosePort
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleAcceptTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//GetDsmFileName
+   * @until #//GetDsmFileName
+   * @skipline #//SetDsmFileName
+   * @until #//SetDsmFileName
+   * @skipline #//OpenPort
+   * @until #//OpenPort
+   * @skipline #//SendAccept
+   * @until #//SendAccept
+   * @skipline #//finishwork
+   * @until #//finishwork
+   * @skipline #//ClosePort
+   * @until #//ClosePort
+   *
+   * @param     filename        The file name where connection info will be written
+   */
+  void SetDsmFileName(std::string filename);
+
+  /**
+   * Sets the port name that will be connected to when Connect/Accept is called.
+   * Data is copied, so the provided string is not modified.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#ReadDsmPortName
+   * @until //#ReadDsmPortName
+   * @skipline //#GetDsmPortName
+   * @until //#GetDsmPortName
+   * @skipline //#manualConnect
+   * @until //#manualConnect
+   * @skipline //#Disconnectcomm
+   * @until //#Disconnectcomm
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//ReadDsmPortName
+   * @until #//ReadDsmPortName
+   * @skipline #//GetDsmPortName
+   * @until #//GetDsmPortName
+   * @skipline #//SetDsmPortName
+   * @until #//SetDsmPortName
+   * @skipline #//manualConnect
+   * @until #//manualConnect
+   * @skipline #//Disconnectcomm
+   * @until #//Disconnectcomm
+   *
+   * @param     hostName        a pointer to the character string that specifies the port
+   */
+  void SetDsmPortName(const char *hostName);
+
+  /**
+   * Sets whether created comms should use a filename specified
+   * in the environment or the default value.
+   * Default value is false (use default file name).
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   *
+   * @param     status  Whether to pull the filename from the environment.
+   */
+  static void SetUseEnvFileName(bool status);
+
+protected:
+
+  void SetDsmProcessStructure(std::vector<std::pair<std::string, unsigned int> > & newStructure);
+
+private:
+  MPI_Comm      IntraComm;
+  int           Id;
+  int           IntraSize;
+  MPI_Comm      InterComm;
+  int           InterId;
+  int           InterSize;
+  int           InterCommType;
+  char          DsmPortName[MPI_MAX_PORT_NAME];
+  std::string   DsmFileName;
+  static bool   UseEnvFileName;
+  bool          HasOpenedPort;
+  std::string   ApplicationName;
+
+  // This is a vector of <application name, numprocs>
+  std::vector<std::pair<std::string, unsigned int> > DsmProcessStructure;
+
+//#ifdef OPEN_MPI
+  std::vector<char *> PreviousDsmPortNames;
+//#endif
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFDSMCOMMMPI; // Simply as a typedef to ensure correct typing
+typedef struct XDMFDSMCOMMMPI XDMFDSMCOMMMPI;
+
+XDMFDSM_EXPORT XDMFDSMCOMMMPI * XdmfDSMCommMPINew();
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIFree(XDMFDSMCOMMMPI * item);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIAccept(XDMFDSMCOMMMPI * dsmComm, unsigned int numConnections, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIClosePort(XDMFDSMCOMMMPI * dsmComm, int * status);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIConnect(XDMFDSMCOMMMPI * dsmComm, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIDisconnect(XDMFDSMCOMMMPI * dsmComm, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIDupComm(XDMFDSMCOMMMPI * dsmComm, MPI_Comm comm, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIDupInterComm(XDMFDSMCOMMMPI * dsmComm, MPI_Comm comm, int * status);
+
+XDMFDSM_EXPORT char * XdmfDSMCommMPIGetApplicationName(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT char * XdmfDSMCommMPIGetDsmFileName(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT char * XdmfDSMCommMPIGetDsmPortName(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIGetDsmProcessStructure(XDMFDSMCOMMMPI * dsmComm,
+                                                         char ** names,
+                                                         unsigned int * coreCount,
+                                                         int * numApplications);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIGetId(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT MPI_Comm XdmfDSMCommMPIGetInterComm(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIGetInterCommType(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIGetInterId(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIGetInterSize(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT MPI_Comm XdmfDSMCommMPIGetIntraComm(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIGetIntraSize(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT int XdmfDSMCommMPIGetUseEnvFileName(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIInit(XDMFDSMCOMMMPI * dsmComm, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIOpenPort(XDMFDSMCOMMMPI * dsmComm, int * status);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPIReadDsmPortName(XDMFDSMCOMMMPI * dsmComm);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPISetApplicationName(XDMFDSMCOMMMPI * dsmComm, char * newName);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPISetDsmFileName(XDMFDSMCOMMMPI * dsmComm, char * filename);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPISetDsmPortName(XDMFDSMCOMMMPI * dsmComm, char * hostName);
+
+XDMFDSM_EXPORT void XdmfDSMCommMPISetUseEnvFileName(XDMFDSMCOMMMPI * dsmComm, int status);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFDSMCOMMMPI_HPP_ */
+
diff --git a/core/dsm/XdmfDSMDescription.cpp b/core/dsm/XdmfDSMDescription.cpp
new file mode 100644
index 0000000..9d1478d
--- /dev/null
+++ b/core/dsm/XdmfDSMDescription.cpp
@@ -0,0 +1,115 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMDescription.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+#include <utility>
+#include "XdmfError.hpp"
+#include "XdmfDSMDescription.hpp"
+#include "XdmfSharedPtr.hpp"
+#include "XdmfVisitor.hpp"
+#include <iostream>
+#include "string.h"
+
+shared_ptr<XdmfDSMDescription>
+XdmfDSMDescription::New()
+{
+  shared_ptr<XdmfDSMDescription> p(new XdmfDSMDescription());
+  return p;
+}
+
+XdmfDSMDescription::XdmfDSMDescription()
+{
+}
+
+XdmfDSMDescription::XdmfDSMDescription(XdmfDSMDescription & refDescription) :
+  XdmfHeavyDataDescription(refDescription)
+{
+}
+
+XdmfDSMDescription::~XdmfDSMDescription()
+{
+}
+
+const std::string XdmfDSMDescription::ItemTag = "DSM";
+
+std::map<std::string, std::string>
+XdmfDSMDescription::getItemProperties() const
+{
+  std::map<std::string, std::string> descriptionProperties;
+
+  descriptionProperties["Port"] = mPortDescription;
+
+  return descriptionProperties;
+}
+
+std::string
+XdmfDSMDescription::getItemTag() const
+{
+  return ItemTag;
+}
+
+std::string
+XdmfDSMDescription::getPortDescription() const
+{
+  return mPortDescription;
+}
+
+void
+XdmfDSMDescription::populateItem(const std::map<std::string, std::string> & itemProperties,
+                              const std::vector<shared_ptr<XdmfItem> > & childItems,
+                              const XdmfCoreReader * const reader)
+{
+  XdmfItem::populateItem(itemProperties, childItems, reader);
+}
+
+void
+XdmfDSMDescription::setPortDescription(std::string portDesc)
+{
+  mPortDescription = portDesc;
+  this->setIsChanged(true);
+}
+
+void
+XdmfDSMDescription::traverse(const shared_ptr<XdmfBaseVisitor> visitor)
+{
+
+}
+
+XDMFDSMDESCRIPTION *
+XdmfDSMDescriptionNew(char * key, char * value)
+{
+  try
+  {
+    std::string createKey(key);
+    std::string createValue(value);
+    shared_ptr<XdmfDSMDescription> generatedDesc = XdmfDSMDescription::New();
+    return (XDMFDSMDESCRIPTION *)((void *)(new XdmfDSMDescription(*generatedDesc.get())));
+  }
+  catch (...)
+  {
+    std::string createKey(key);
+    std::string createValue(value);
+    shared_ptr<XdmfDSMDescription> generatedDesc = XdmfDSMDescription::New();
+    return (XDMFDSMDESCRIPTION *)((void *)(new XdmfDSMDescription(*generatedDesc.get())));
+  }
+}
+
+XDMF_ITEM_C_CHILD_WRAPPER(XdmfDSMDescription, XDMFDSMDESCRIPTION)
diff --git a/core/dsm/XdmfDSMDescription.hpp b/core/dsm/XdmfDSMDescription.hpp
new file mode 100644
index 0000000..c968828
--- /dev/null
+++ b/core/dsm/XdmfDSMDescription.hpp
@@ -0,0 +1,113 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMDescription.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+#ifndef XDMFDSMDESCRIPTION_HPP_
+#define XDMFDSMDESCRIPTION_HPP_
+
+// C Compatible Includes
+#include "XdmfCore.hpp"
+#include "XdmfItem.hpp"
+#include "XdmfHeavyDataDescription.hpp"
+
+#ifdef __cplusplus
+
+/**
+ * @brief Holds information about a dsm buffer so that a process can connect.
+ *
+ * XdmfDSMDescription stores the information required to connect
+ * to an existing DSM buffer
+ */
+class XDMFCORE_EXPORT XdmfDSMDescription : public XdmfHeavyDataDescription {
+
+public:
+
+  /**
+   * 
+   */
+  static shared_ptr<XdmfDSMDescription> New();
+
+  virtual ~XdmfDSMDescription();
+
+  LOKI_DEFINE_VISITABLE(XdmfDSMDescription, XdmfItem)
+  static const std::string ItemTag;
+
+  std::map<std::string, std::string> getItemProperties() const;
+
+  virtual std::string getItemTag() const;
+
+  std::string getPortDescription() const;
+
+  using XdmfItem::insert;
+
+  void setPortDescription(std::string portDesc);
+
+  virtual void traverse(const shared_ptr<XdmfBaseVisitor> visitor);
+
+  XdmfDSMDescription(XdmfDSMDescription &);
+
+protected:
+
+  XdmfDSMDescription();
+
+  virtual void
+  populateItem(const std::map<std::string, std::string> & itemProperties,
+               const std::vector<shared_ptr<XdmfItem> > & childItems,
+               const XdmfCoreReader * const reader);
+
+private:
+
+  XdmfDSMDescription(const XdmfDSMDescription &);  // Not implemented.
+  void operator=(const XdmfDSMDescription &);  // Not implemented.
+
+  std::string mPortDescription;
+};
+
+#ifdef _WIN32
+XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
+shared_ptr<Loki::BaseVisitor>;
+XDMFCORE_TEMPLATE template class XDMFCORE_EXPORT
+Loki::Visitor<shared_ptr<XdmfDSMDescription>,
+              shared_ptr<XdmfItem> >;
+#endif
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFDSMDESCRIPTION; // Simply as a typedef to ensure correct typing
+typedef struct XDMFDSMDESCRIPTION XDMFDSMDESCRIPTION;
+
+XDMFCORE_EXPORT XDMFDSMDESCRIPTION * XdmfDSMDescriptionNew();
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_ITEM_C_CHILD_DECLARE(XdmfDSMDescription, XDMFDSMDESCRIPTION, XDMFCORE)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFDSMDESCRIPTION_HPP_ */
diff --git a/core/dsm/XdmfDSMDriver.cpp b/core/dsm/XdmfDSMDriver.cpp
new file mode 100644
index 0000000..422ed3d
--- /dev/null
+++ b/core/dsm/XdmfDSMDriver.cpp
@@ -0,0 +1,1333 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMDriver.cpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+/*=========================================================================
+  This code is derived from an earlier work and is distributed
+  with permission from, and thanks to ...
+=========================================================================*/
+
+/*============================================================================
+
+  Project                 : H5FDdsm
+  Module                  : H5FDdsmDriver.cxx H5FDdsm.c
+
+  Authors:
+     John Biddiscombe     Jerome Soumagne
+     biddisco at cscs.ch     soumagne at cscs.ch
+
+  Copyright (C) CSCS - Swiss National Supercomputing Centre.
+  You may use modify and and distribute this code freely providing
+  1) This copyright notice appears on all copies of source code
+  2) An acknowledgment appears with any substantial usage of the code
+  3) If this code is contributed to any other open source project, it
+  must not be reformatted such that the indentation, bracketing or
+  overall style is modified significantly.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  This work has received funding from the European Community's Seventh
+  Framework Programme (FP7/2007-2013) under grant agreement 225967 âxtMuSEâOC
+
+============================================================================*/
+
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+#include <XdmfError.hpp>
+#include <mpi.h>
+
+#include <H5public.h>
+#include <hdf5.h>
+
+#include <sstream>
+#include <map>
+
+typedef struct XDMF_dsm_t
+{
+  H5FD_t pub;            /* public stuff, must be first             */
+  char *name;            /* for equivalence testing                 */
+  void *local_buf_ptr;   /* underlying local DSM buffer             */
+  size_t local_buf_len;  /* local DSM buffer length                 */
+  haddr_t eoa;           /* end of address marker                   */
+  haddr_t eof;           /* end of file marker                      */
+  haddr_t start;         /* current DSM start address               */
+  haddr_t end;           /* current DSM end address                 */
+  hbool_t read_only;     /* file access is read-only                */
+  hbool_t dirty;         /* dirty marker                            */
+  unsigned int numPages; /* number of pages assigned to the file    */
+} XDMF_dsm_t;
+
+typedef struct XDMF_dsm_fapl_t
+{
+  void  *local_buf_ptr;     /* local buffer pointer        */
+  size_t local_buf_len;     /* local buffer length         */
+} XDMF_dsm_fapl_t;
+
+typedef struct
+{
+  long start;
+  long end;
+} XdmfDSMEntry;
+
+/* The driver identification number, initialized at runtime */
+static hid_t XDMF_DSM_g = 0;
+
+//from driver
+XdmfDSMBuffer *dsmBuffer = NULL;
+std::map<std::string, unsigned int> fileEOF; // holding previously created files
+std::map<std::string, std::vector<unsigned int> > filePages;
+
+#define MAXADDR                 ((haddr_t)((~(size_t)0)-1))
+#define ADDR_OVERFLOW(A)        (HADDR_UNDEF==(A) || (A) > (haddr_t)MAXADDR)
+#define SIZE_OVERFLOW(Z)        ((Z) > (hsize_t)MAXADDR)
+#define REGION_OVERFLOW(A,Z)    (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) ||      \
+                                 HADDR_UNDEF==(A)+(Z) ||                      \
+                                 (size_t)((A)+(Z))<(size_t)(A))
+
+extern "C" {
+
+#include "H5FDprivate.h"  /* File drivers           */
+#include "H5private.h"    /* Generic Functions      */
+#include "H5ACprivate.h"  /* Metadata cache         */
+#include "H5Dprivate.h"   /* Dataset functions      */
+#include "H5Eprivate.h"   /* Error handling         */
+#include "H5Fprivate.h"   /* File access            */
+#include "H5FDmpi.h"      /* MPI-based file drivers */
+#include "H5Iprivate.h"   /* IDs                    */
+#include "H5Pprivate.h"   /* Property lists         */
+
+#include <XdmfDSMDriver.hpp>
+
+/* Private Prototypes */
+static void    *XDMF_dsm_fapl_get(H5FD_t *_file);
+static void    *XDMF_dsm_fapl_copy(const void *_old_fa);
+static herr_t   XDMF_dsm_fapl_free(void *_fa);
+static H5FD_t  *XDMF_dsm_open(const char *name, unsigned flags, hid_t fapl_id,
+    haddr_t maxaddr);
+static herr_t   XDMF_dsm_close(H5FD_t *_file);
+static herr_t   XDMF_dsm_query(const H5FD_t *_f1, unsigned long *flags);
+static haddr_t  XDMF_dsm_get_eoa(const H5FD_t *_file, H5FD_mem_t type);
+static herr_t   XDMF_dsm_set_eoa(H5FD_t * _file, H5FD_mem_t type, haddr_t addr);
+static haddr_t  XDMF_dsm_get_eof(const H5FD_t *_file);
+static herr_t   XDMF_dsm_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id,
+    haddr_t addr, size_t size, void *buf);
+static herr_t   XDMF_dsm_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id,
+    haddr_t addr, size_t size, const void *buf);
+static herr_t   XDMF_dsm_flush(H5FD_t *_file, hid_t dxpl_id, unsigned closing);
+static int      XDMF_dsm_mpi_rank(const H5FD_t *_file);
+static int      XDMF_dsm_mpi_size(const H5FD_t *_file);
+static MPI_Comm XDMF_dsm_communicator(const H5FD_t *_file);
+
+/* The DSM file driver information */
+static const H5FD_class_mpi_t XDMF_dsm_g = {
+    {
+        "dsm",                                  /* name                 */
+        MAXADDR,                                /* maxaddr              */
+        H5F_CLOSE_SEMI,                         /* fc_degree            */
+#if H5_VERSION_GE(1,9,0)
+        XDMF_dsm_term,                          /* terminate            */
+#endif
+        NULL,                                   /* sb_size              */
+        NULL,                                   /* sb_encode            */
+        NULL,                                   /* sb_decode            */
+        sizeof(XDMF_dsm_fapl_t),                /* fapl_size            */
+        XDMF_dsm_fapl_get,                      /* fapl_get             */
+        XDMF_dsm_fapl_copy,                     /* fapl_copy            */
+        XDMF_dsm_fapl_free,                     /* fapl_free            */
+        0,                                      /* dxpl_size            */
+        NULL,                                   /* dxpl_copy            */
+        NULL,                                   /* dxpl_free            */
+        XDMF_dsm_open,                          /* open                 */
+        XDMF_dsm_close,                         /* close                */
+        NULL,                                   /* cmp                  */
+        XDMF_dsm_query,                         /* query                */
+        NULL,                                   /* get_type_map         */
+        NULL,                                   /* alloc                */
+        NULL,                                   /* free                 */
+#ifdef H5_HAVE_VFD_EXTENSIONS
+        XDMF_dsm_term,                          /* terminate            */
+#endif
+        XDMF_dsm_get_eoa,                       /* get_eoa              */
+        XDMF_dsm_set_eoa,                       /* set_eoa              */
+        XDMF_dsm_get_eof,                       /* get_eof              */
+        NULL,                                   /* get_handle           */
+        XDMF_dsm_read,                          /* read                 */
+        XDMF_dsm_write,                         /* write                */
+        XDMF_dsm_flush,                         /* flush                */
+        NULL,                                   /* truncate             */
+        NULL,                                   /* lock                 */
+        NULL,                                   /* unlock               */
+        H5FD_FLMAP_SINGLE                       /* fl_map               */
+    },
+    XDMF_dsm_mpi_rank,                          /* get_rank             */
+    XDMF_dsm_mpi_size,                          /* get_size             */
+    XDMF_dsm_communicator                       /* get_comm             */
+};
+
+#define H5_INTERFACE_INIT_FUNC  XDMF_dsm_init_interface
+
+static herr_t
+XDMF_dsm_init_interface(void)
+{
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_init_interface)
+#endif
+
+  FUNC_LEAVE_NOAPI(XDMF_dsm_init())
+}
+
+void
+XdmfUnused(void)
+{
+  //To remove warning about XDMF_dsm_init_interface being unused
+  XDMF_dsm_init_interface();
+}
+
+hid_t
+XDMF_dsm_init(void)
+{
+  hid_t ret_value; /* Return value */
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI(FAIL)
+#else
+  FUNC_ENTER_NOAPI(XDMF_dsm_init, FAIL)
+#endif
+
+  if (H5I_VFL != H5Iget_type(XDMF_DSM_g)) {// registering the driver
+    XDMF_DSM_g = H5FD_register(&XDMF_dsm_g, sizeof(H5FD_class_mpi_t), FALSE);
+  }
+
+  /* Set return value */
+  ret_value = XDMF_DSM_g;// return value is the new id of the driver
+
+// Removed because error handling isn't called in this function
+//done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+#if H5_VERSION_GE(1,9,0)
+herr_t
+#else
+void
+#endif
+XDMF_dsm_term(void)
+{
+#if H5_VERSION_GE(1,9,0)
+  herr_t ret_value = SUCCEED;
+
+  FUNC_ENTER_NOAPI(FAIL)
+#else
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_term)
+#endif
+#endif
+
+  if (SUCCEED != xdmf_dsm_free()) {
+#if H5_VERSION_GE(1,9,0)
+    HGOTO_ERROR(H5E_VFL, H5E_CANTFREE, FAIL, "dsm_free failed");
+#endif
+  }
+
+  /* Reset VFL ID */
+  XDMF_DSM_g = 0;
+
+#if H5_VERSION_GE(1,9,0)
+done:
+  FUNC_LEAVE_NOAPI(ret_value)
+#else
+  FUNC_LEAVE_NOAPI_VOID
+#endif
+}
+
+herr_t
+XDMF_dsm_set_options(unsigned long flags)
+{
+  herr_t ret_value = SUCCEED;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI(FAIL)
+#else
+  FUNC_ENTER_NOAPI(XDMF_dsm_set_options, FAIL)
+#endif
+
+  if (SUCCEED != xdmf_dsm_set_options(flags))
+    HGOTO_ERROR(H5E_VFL, H5E_CANTMODIFY, FAIL, "cannot set options")
+
+done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+herr_t
+XDMF_dsm_set_manager(void *manager)
+{
+  herr_t ret_value = SUCCEED;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI(FAIL)
+#else
+  FUNC_ENTER_NOAPI(XDMF_dsm_set_manager, FAIL)
+#endif
+
+  xdmf_dsm_set_manager(manager);
+
+// Removed because error handling isn't called in this function
+//done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+herr_t
+XDMFH5Pset_fapl_dsm(hid_t fapl_id, MPI_Comm intra_comm, void *local_buf_ptr,
+                    size_t local_buf_len)
+{
+//printf("XDMFH5Pset_fapl_dsm\n");
+  XDMF_dsm_fapl_t fa;
+  herr_t ret_value = SUCCEED;
+  H5P_genplist_t *plist; /* Property list pointer */
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_API(FAIL)
+#else
+  FUNC_ENTER_API(XDMFH5Pset_fapl_dsm, FAIL)
+#endif
+  /* Check arguments */
+  if (NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+
+  if (!xdmf_dsm_get_manager()) {
+	// throw error here instead of calling alloc
+        XdmfError::message(XdmfError::FATAL, "Error: In set_fapl_dsm No manager set");
+  }
+
+  if (SUCCEED != xdmf_dsm_get_properties(NULL, &fa.local_buf_ptr, &fa.local_buf_len))
+    HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "cannot get DSM properties")
+
+  if (!xdmf_dsm_is_server() && !xdmf_dsm_is_connected()) {
+
+    //it should already be connected when this is called
+    //potentially the connect will connect via port
+    xdmf_dsm_connect();
+  }
+
+  /* duplication is done during driver setting */
+  ret_value = H5P_set_driver(plist, XDMF_DSM, &fa);
+
+done:
+  FUNC_LEAVE_API(ret_value)
+}
+
+herr_t
+XDMFH5Pget_fapl_dsm(hid_t fapl_id, MPI_Comm *intra_comm /* out */,
+    void **local_buf_ptr_ptr /* out */, size_t *local_buf_len_ptr /* out */)
+{
+  XDMF_dsm_fapl_t *fa;
+  MPI_Comm intra_comm_tmp = MPI_COMM_NULL;
+  H5P_genplist_t *plist; /* Property list pointer */
+  herr_t ret_value = SUCCEED;
+  int mpi_code;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_API(FAIL)
+#else
+  FUNC_ENTER_API(XDMFH5Pget_fapl_dsm, FAIL)
+#endif
+
+  if (NULL == (plist = (H5P_genplist_t*) H5P_object_verify(fapl_id, H5P_FILE_ACCESS)))
+    HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list")
+  if (XDMF_DSM != H5P_get_driver(plist))
+    HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "incorrect VFL driver")
+  if (NULL == (fa = (XDMF_dsm_fapl_t*) H5P_get_driver_info(plist)))
+    HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad VFL driver info")
+
+  if (intra_comm) {
+    if (MPI_SUCCESS != (mpi_code = MPI_Comm_dup(dsmBuffer->GetComm()->GetIntraComm(), &intra_comm_tmp)))
+      HMPI_GOTO_ERROR(FAIL, "MPI_Comm_dup failed", mpi_code)
+    *intra_comm = intra_comm_tmp;
+  }
+
+  if (local_buf_ptr_ptr) *local_buf_ptr_ptr = fa->local_buf_ptr;
+
+  if (local_buf_len_ptr) *local_buf_len_ptr = fa->local_buf_len;
+
+done:
+  if (FAIL == ret_value) {
+    /* need to free anything created here */
+  }
+
+  FUNC_LEAVE_API(ret_value)
+}
+
+static void *
+XDMF_dsm_fapl_get(H5FD_t *_file)
+{
+//printf("XDMF_dsm_fapl_get\n");
+  XDMF_dsm_t *file = (XDMF_dsm_t*) _file;
+  XDMF_dsm_fapl_t *fa = NULL;
+  void *ret_value = NULL;
+  int mpi_code;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_fapl_get)
+#endif
+
+  HDassert(file);
+  HDassert(XDMF_DSM == file->pub.driver_id);
+
+  if (NULL == (fa = (XDMF_dsm_fapl_t *) calloc((size_t)1, sizeof(XDMF_dsm_fapl_t))))
+    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+  fa->local_buf_ptr = file->local_buf_ptr;
+  fa->local_buf_len = file->local_buf_len;
+
+  /* Set return value */
+  ret_value = fa;
+
+done:
+  if ((NULL == ret_value) && err_occurred) {
+    /* need to free anything created here */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static void *
+XDMF_dsm_fapl_copy(const void *_old_fa)
+{
+//printf("XDMF_dsm_fapl_copy\n");
+  void *ret_value = NULL;
+  const XDMF_dsm_fapl_t *old_fa = (const XDMF_dsm_fapl_t*)_old_fa;
+  XDMF_dsm_fapl_t *new_fa = NULL;
+  int mpi_code;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_fapl_copy)
+#endif
+
+  if(NULL == (new_fa = (XDMF_dsm_fapl_t *) calloc((size_t)1, sizeof(XDMF_dsm_fapl_t))))
+    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+  /* Copy the general information */
+  HDmemcpy(new_fa, old_fa, sizeof(XDMF_dsm_fapl_t));
+
+  ret_value = new_fa;
+
+done:
+  if ((NULL == ret_value) && err_occurred) {
+    /* cleanup */
+    if (new_fa) free(new_fa);
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
+XDMF_dsm_fapl_free(void *_fa)
+{
+  herr_t ret_value = SUCCEED;
+  XDMF_dsm_fapl_t *fa = (XDMF_dsm_fapl_t*)_fa;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_fapl_free)
+#endif
+
+  assert(fa);
+
+  free(fa);
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static H5FD_t *
+XDMF_dsm_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr)
+{
+  XDMF_dsm_t *file = NULL;
+  int mpi_rank; /* MPI rank of this process */
+  int mpi_size; /* Total number of MPI processes */
+  int mpi_code;  /* mpi return code */
+  const XDMF_dsm_fapl_t *fa = NULL;
+  H5P_genplist_t *plist; /* Property list pointer */
+  H5FD_t *ret_value = NULL;
+  herr_t dsm_code = SUCCEED;
+
+  unsigned int * newpages = NULL;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_open)
+#endif
+
+  /* Check arguments */
+  if(!name || !*name)
+    HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid file name")
+  if (0 == maxaddr || HADDR_UNDEF == maxaddr)
+    HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, NULL, "bogus maxaddr")
+  if (ADDR_OVERFLOW(maxaddr))
+    HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, NULL, "maxaddr overflow")
+
+
+  if (H5P_DEFAULT != fapl_id) {
+
+    if (NULL == (plist = (H5P_genplist_t*) H5I_object(fapl_id)))
+      HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list")
+    fa = (const XDMF_dsm_fapl_t *) H5P_get_driver_info(plist);
+    assert(fa);
+  }
+
+  /* Get the MPI rank of this process and the total number of processes */
+  mpi_rank = dsmBuffer->GetComm()->GetId();
+  mpi_size = dsmBuffer->GetComm()->GetIntraSize();
+
+  /* Build the return value and initialize it */
+  if (NULL == (file = (XDMF_dsm_t *) calloc((size_t)1, sizeof(XDMF_dsm_t))))
+    HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+  if (name && *name) {
+    file->name = HDstrdup(name);
+  }
+
+  /* Get address information from DSM */
+  if (!xdmf_dsm_get_manager())
+    HGOTO_ERROR(H5E_VFL, H5E_NOTFOUND, NULL, "DSM buffer not found")
+
+  file->local_buf_ptr = fa->local_buf_ptr;
+  file->local_buf_len = fa->local_buf_len;
+
+  // Poll DSM for file information
+  // If file exists fill data from the DSM's results
+  // Otherwise reset data.
+  // For now, multiple files are only supported by paged mode.
+  if (dsmBuffer->GetComm()->GetId() == 0)
+  {
+    if (dsmBuffer->RequestFileDescription(file->name,
+                                          filePages[file->name],
+                                          file->numPages,
+                                          file->start,
+                                          file->end) == XDMF_DSM_FAIL)
+    {
+      // File not found
+      file->numPages = 0;
+      file->start = 0;
+      file->end = 0;
+    }
+  }
+
+
+
+  dsmBuffer->GetComm()->Broadcast(&file->start,
+                                  sizeof(haddr_t),
+                                  0,
+                                  XDMF_DSM_INTRA_COMM);
+
+  dsmBuffer->GetComm()->Broadcast(&file->end,
+                                  sizeof(haddr_t),
+                                  0,
+                                  XDMF_DSM_INTRA_COMM);
+
+  dsmBuffer->GetComm()->Broadcast(&file->numPages,
+                                  sizeof(unsigned int),
+                                  0,
+                                  XDMF_DSM_INTRA_COMM);
+
+  if (file->numPages > 0)
+  {
+    if (dsmBuffer->GetComm()->GetId() != 0)
+    {
+      filePages[file->name].clear();
+      for (unsigned int i = 0; i < file->numPages; ++i)
+      {
+        filePages[file->name].push_back(0);
+      }
+    }
+    dsmBuffer->GetComm()->Broadcast(&(filePages[file->name][0]),
+                                    sizeof(unsigned int) * file->numPages,
+                                    0,
+                                    XDMF_DSM_INTRA_COMM);
+  }
+
+  if (H5F_ACC_RDWR & flags) {
+    file->read_only = FALSE;
+  } else {
+    file->read_only = TRUE;
+  }
+
+  if (H5F_ACC_CREAT & flags) {
+    /* Reset start and end markers */
+    if (fileEOF.count(name) == 0) // Need to store the eof and eoa of the files here
+    {
+      file->start = 0;
+      file->end = 0;
+      file->eof = 0;
+      fileEOF[name] = 0;
+    }
+    else
+    {
+      file->eof = fileEOF[name];
+    }
+
+  } else {
+    file->eof = file->end - file->start;
+  }
+
+  // Poll DSM for page info if in paged mode
+
+  /* Don't let any proc return until all have created the file. */
+  if ((H5F_ACC_CREAT & flags)) {
+    dsmBuffer->GetComm()->Barrier(XDMF_DSM_INTRA_COMM);
+  }
+
+  /* Set return value */
+  ret_value = (H5FD_t *) file;
+
+done:
+  if((ret_value == NULL) && err_occurred) {
+    if (file && file->name) HDfree(file->name);
+    if (file) free(file);
+  } /* end if */
+
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
+XDMF_dsm_close(H5FD_t *_file)
+{
+  XDMF_dsm_t *file = (XDMF_dsm_t*) _file;
+  herr_t ret_value = SUCCEED; /* Return value */
+  int mpi_code;
+  herr_t dsm_code = SUCCEED;
+  unsigned long unlock_flag;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_close)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  if (!file->read_only) {
+    if (dsmBuffer->GetComm()->GetId() == 0)
+    {
+      // Update DSM file description
+      if (dsmBuffer->RegisterFile(file->name,
+                              &(filePages[file->name][0]),
+                              file->numPages,
+                              file->start,
+                              file->end) == XDMF_DSM_FAIL)
+      {
+        dsm_code = FAIL;
+      }
+    }
+
+    /* Wait for the DSM entry to be updated */
+    dsmBuffer->GetComm()->Broadcast(&dsm_code,
+                                    sizeof(herr_t),
+                                    0,
+                                    XDMF_DSM_INTRA_COMM);
+
+    if (SUCCEED != dsm_code)
+      HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "cannot update DSM entries")
+
+      /*
+       * Be sure that everyone's here before releasing resources (done with
+       * collective op). Gather all the dirty flags because some processes may
+       * not have written yet.
+       */
+      hbool_t * dirtyaccum = new hbool_t[dsmBuffer->GetComm()->GetIntraSize()]();
+
+      dsmBuffer->GetComm()->AllGather(&file->dirty,
+                                      sizeof(hbool_t),
+                                      dirtyaccum,
+                                      sizeof(hbool_t),
+                                      XDMF_DSM_INTRA_COMM);
+
+      for (unsigned int i = 0; i < dsmBuffer->GetComm()->GetIntraSize(); ++i)
+      {
+        if (dirtyaccum[i] > file->dirty)
+        {
+          file->dirty = dirtyaccum[i];
+        }
+      }
+
+      delete dirtyaccum;
+  }
+
+  /* if ReleaseLockOnClose was set, unlocks using whatever notification
+   * unlock_flag was set.
+   */
+  unlock_flag = (file->dirty) ? XDMF_DSM_NOTIFY_DATA : XDMF_DSM_NOTIFY_NONE;
+
+  /* Release resources */
+  if (file->name) HDfree(file->name);
+  HDmemset(file, 0, sizeof(XDMF_dsm_t));
+  free(file);
+
+done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
+XDMF_dsm_query(const H5FD_t UNUSED *_file, unsigned long *flags /* out */)
+{
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_query)
+#endif
+
+  /* Set the VFL feature flags that this driver supports */
+  if (flags) {
+    *flags = 0;
+    *flags |= H5FD_FEAT_AGGREGATE_METADATA;  /* OK to aggregate metadata allocations */
+    *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */
+#ifdef H5FD_FEAT_HAS_MPI
+    *flags |= H5FD_FEAT_HAS_MPI;             /* This driver uses MPI */
+#endif
+#ifdef H5FD_FEAT_ALLOCATE_EARLY
+    *flags |= H5FD_FEAT_ALLOCATE_EARLY;      /* Allocate space early instead of late */
+#endif
+
+  } /* end if */
+
+  FUNC_LEAVE_NOAPI(SUCCEED)
+}
+
+static haddr_t
+XDMF_dsm_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type)
+{
+  const XDMF_dsm_t *file = (const XDMF_dsm_t*) _file;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_get_eoa)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  FUNC_LEAVE_NOAPI(file->eoa)
+}
+
+static herr_t
+XDMF_dsm_set_eoa(H5FD_t * _file, H5FD_mem_t UNUSED type, haddr_t addr)
+{
+  XDMF_dsm_t *file = (XDMF_dsm_t*) _file;
+  herr_t ret_value = SUCCEED; /* Return value */
+  int mpi_code;
+  herr_t dsm_code = SUCCEED;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_set_eoa)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  if (ADDR_OVERFLOW(addr))
+    HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "address overflow")
+
+  file->eoa = addr;
+
+  // If EoA is smaller than the end of the file the address is within page boundaries
+  // If this is not the case then we need to reserve more pages.
+  if ((file->start + file->eoa) > file->end &&
+      (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_BLOCK_CYCLIC ||
+      ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_BLOCK_RANDOM) &&
+      !file->read_only)
+  {
+    unsigned int pageCount = file->numPages;
+    unsigned int * newpages;
+    if (dsmBuffer->GetComm()->GetId() == 0)
+    {
+      // Request additional pages to store data
+      dsmBuffer->RequestPages(file->name,
+                              file->start + file->eoa - file->end,
+                              filePages[file->name],
+                              file->numPages,
+                              file->start,
+                              file->end);
+    }
+
+    // If requesting pages resized the pointer
+    // Reset the total length to match the new size.
+    unsigned int currentLength = dsmBuffer->GetLength();
+    dsmBuffer->GetComm()->Broadcast(&currentLength,
+                                    sizeof(unsigned int),
+                                    0,
+                                    XDMF_DSM_INTRA_COMM);
+    if (currentLength != dsmBuffer->GetLength()) {
+      dsmBuffer->UpdateLength(currentLength);
+    }
+
+    dsmBuffer->GetComm()->Broadcast(&file->end,
+                                    sizeof(haddr_t),
+                                    0,
+                                    XDMF_DSM_INTRA_COMM);
+
+    dsmBuffer->GetComm()->Broadcast(&file->numPages,
+                                    sizeof(unsigned int),
+                                    0,
+                                    XDMF_DSM_INTRA_COMM);
+
+    if (pageCount != file->numPages) 
+    {
+      if (dsmBuffer->GetComm()->GetId() != 0)
+      {
+        filePages[file->name].clear();
+        for (unsigned int i = 0; i < file->numPages; ++i)
+        {
+          filePages[file->name].push_back(0);
+        }
+      }
+
+      dsmBuffer->GetComm()->Broadcast(&(filePages[file->name][0]),
+                                      sizeof(unsigned int) * file->numPages,
+                                      0,
+                                      XDMF_DSM_INTRA_COMM);
+    }
+  }
+
+  file->end = MAX((file->start + file->eoa), file->end);
+  file->eof = file->end - file->start;
+  fileEOF[file->name] = file->eof;
+  if (!file->read_only) {
+
+    if (dsmBuffer->GetComm()->GetId() == 0)
+    {
+      // Update DSM file description
+      if (dsmBuffer->RegisterFile(file->name,
+                                  &(filePages[file->name][0]),
+                                  file->numPages,
+                                  file->start,
+                                  file->end) == XDMF_DSM_FAIL)
+      {
+        dsm_code = FAIL;
+      }
+
+    }
+
+    /* Wait for the DSM entry to be updated */
+      dsmBuffer->GetComm()->Broadcast(&dsm_code,
+                                      sizeof(herr_t),
+                                      0,
+                                      XDMF_DSM_INTRA_COMM);
+    if (SUCCEED != dsm_code)
+      HGOTO_ERROR(H5E_VFL, H5E_CANTUPDATE, FAIL, "cannot update DSM entries")
+  }
+done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static haddr_t
+XDMF_dsm_get_eof(const H5FD_t *_file)
+{
+  const XDMF_dsm_t *file = (const XDMF_dsm_t*) _file;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_get_eof)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  FUNC_LEAVE_NOAPI(MAX(file->eof, file->eoa))
+}
+
+static herr_t
+XDMF_dsm_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id,
+    haddr_t addr, size_t size, void *buf /* out */)
+{
+  XDMF_dsm_t *file = (XDMF_dsm_t*) _file;
+  herr_t ret_value = SUCCEED; /* Return value */
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_read)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+  assert(buf);
+
+  /* Check for overflow conditions */
+  if (HADDR_UNDEF == addr)
+    HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
+  if (REGION_OVERFLOW(addr, size))
+    HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
+  if (addr + size > file->eoa)
+    HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
+
+  /* Read the part which is before the EOF marker */
+  if (addr < file->eof) {
+    size_t  nbytes;
+    hsize_t temp_nbytes;
+
+    temp_nbytes = file->eof - addr;
+    H5_CHECK_OVERFLOW(temp_nbytes,hsize_t,size_t);
+    nbytes = MIN(size,(size_t)temp_nbytes);
+
+
+    if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_BLOCK_CYCLIC ||
+        ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_BLOCK_RANDOM)
+    {
+      xdmf_dsm_read_pages(&(filePages[file->name][0]), file->numPages, addr, nbytes, buf);
+      size -= nbytes;
+      addr += nbytes;
+      buf = (char*) buf + nbytes;
+    }
+    else if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_UNIFORM ||
+             ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_UNIFORM_RANGE)
+    {
+      /* Read from DSM to BUF */
+      if (SUCCEED != xdmf_dsm_read(file->start + addr, nbytes, buf)) {
+        HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "cannot read from DSM")
+      } else {
+        size -= nbytes;
+        addr += nbytes;
+        buf = (char*) buf + nbytes;
+      }
+    }
+    else
+    {
+      HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "invalid DSM type")
+    }
+  }
+  /* Read zeros for the part which is after the EOF markers */
+  if (size > 0) HDmemset(buf, 0, size);
+
+done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
+XDMF_dsm_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id,
+    haddr_t addr, size_t size, const void *buf)
+{
+  XDMF_dsm_t *file = (XDMF_dsm_t*) _file;
+  herr_t ret_value = SUCCEED; /* Return value */
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT
+#else
+  FUNC_ENTER_NOAPI_NOINIT(XDMF_dsm_write)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+  assert(buf);
+
+  if (file->read_only)
+    HGOTO_ERROR(H5E_IO, H5E_RESOURCE, FAIL, "cannot write to DSM open in read-only")
+
+  /* Check for overflow conditions */
+  if (REGION_OVERFLOW(addr, size))
+    HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
+  if (addr + size > file->eoa)
+    HGOTO_ERROR(H5E_IO, H5E_OVERFLOW, FAIL, "file address overflowed")
+
+  /* For now, do not allow dynamic reallocation of the DSM */
+  if (addr + size > file->eof)
+    HGOTO_ERROR(H5E_IO, H5E_NOSPACE, FAIL, "not enough space in DSM")
+
+  if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_BLOCK_CYCLIC ||
+      ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_BLOCK_RANDOM)
+  {
+    xdmf_dsm_write_pages(&(filePages[file->name][0]), file->numPages, addr, size, buf);
+  }
+  else if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_UNIFORM ||
+           ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetDsmType() == XDMF_DSM_TYPE_UNIFORM_RANGE)
+  {
+    /* Write from BUF to DSM */
+    if (SUCCEED != xdmf_dsm_write(file->start + addr, size, buf))
+      HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "cannot write to DSM")
+  }
+  else
+  {
+    HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "invalid DSM type")
+  }
+  /* Set dirty flag so that we know someone has written something */
+  file->dirty = TRUE;
+done:
+  if (err_occurred) {
+    /* Nothing */
+  }
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static herr_t
+XDMF_dsm_flush(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing)
+{
+  herr_t ret_value = SUCCEED; /* Return value */
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_flush)
+#endif
+
+  FUNC_LEAVE_NOAPI(ret_value)
+}
+
+static int
+XDMF_dsm_mpi_rank(const H5FD_t *_file)
+{
+  const XDMF_dsm_t *file = (const XDMF_dsm_t*) _file;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_mpi_rank)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  FUNC_LEAVE_NOAPI(dsmBuffer->GetComm()->GetId())
+}
+
+static int
+XDMF_dsm_mpi_size(const H5FD_t *_file)
+{
+  const XDMF_dsm_t *file = (const XDMF_dsm_t*) _file;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_mpi_size)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  FUNC_LEAVE_NOAPI(dsmBuffer->GetComm()->GetIntraSize())
+}
+
+static MPI_Comm
+XDMF_dsm_communicator(const H5FD_t *_file)
+{
+  const XDMF_dsm_t *file = (const XDMF_dsm_t*) _file;
+
+#if H5_VERSION_GE(1,8,9)
+  FUNC_ENTER_NOAPI_NOINIT_NOERR
+#else
+  FUNC_ENTER_NOAPI_NOINIT_NOFUNC(XDMF_dsm_communicator)
+#endif
+
+  assert(file);
+  assert(XDMF_DSM == file->pub.driver_id);
+
+  FUNC_LEAVE_NOAPI(dsmBuffer->GetComm()->GetIntraComm())
+}
+
+}
+
+void*
+xdmf_dsm_get_manager()
+{
+  void *ret_value = NULL;
+  if (dsmBuffer) ret_value = static_cast <void*> (dsmBuffer);  
+  return(ret_value);
+}
+
+herr_t
+xdmf_dsm_get_properties(MPI_Comm *intra_comm, void **buf_ptr_ptr, size_t *buf_len_ptr)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  if (dsmBuffer->GetIsServer()) {
+    if (buf_ptr_ptr) *buf_ptr_ptr =
+        dsmBuffer->GetDataPointer();
+    if (buf_len_ptr) *buf_len_ptr =
+        dsmBuffer->GetLength();
+  } else {
+    if (buf_ptr_ptr) *buf_ptr_ptr = NULL;
+    if (buf_len_ptr) *buf_len_ptr = 0;
+  }
+
+  return(SUCCEED);
+}
+
+void
+xdmf_dsm_set_manager(void *manager)
+{
+  dsmBuffer = static_cast <XdmfDSMBuffer*> (manager);
+}
+
+herr_t
+xdmf_dsm_free()
+{
+  if (dsmBuffer) {
+    /* probably not required, since the autoallocation is not on
+    */
+  }
+
+  return(SUCCEED);
+}
+
+hbool_t
+xdmf_dsm_is_server()
+{
+  hbool_t ret_value = TRUE;
+
+  if (!dsmBuffer) {
+    XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+  }
+
+  ret_value = dsmBuffer->GetIsServer();
+
+  return(ret_value);
+}
+
+herr_t
+xdmf_dsm_set_options(unsigned long flags)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  // Currently no options to set
+  // All options are set via the dsmBuffer during the dsm's creation
+
+  return(SUCCEED);
+}
+
+hbool_t
+xdmf_dsm_is_connected()
+{
+  hbool_t ret_value = TRUE;
+
+  if (!dsmBuffer) {
+    XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+  }
+
+  ret_value = dsmBuffer->GetIsConnected();
+
+  return(ret_value);
+}
+
+herr_t
+xdmf_dsm_connect()
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  // Initialize the connection if it has not been done already
+  if (dsmBuffer->GetIsConnected()) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Already Connected");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  try {
+    dsmBuffer->Connect();
+  }
+  catch (XdmfError & e) {
+    return FAIL;
+  }
+
+  return(SUCCEED);
+}
+
+herr_t
+xdmf_dsm_lock(char * filename)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  return(SUCCEED);
+}
+
+herr_t
+xdmf_dsm_unlock(char * filename, unsigned long flag)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  return(SUCCEED);
+}
+
+
+// When writing and reading, we want to provide a list of pages that the file contains.
+// The appropriate subsections can be retrieved from the pages this way.
+// We may be able to eliminate these calls and just call straight from the buffer in the file driver.
+
+herr_t
+xdmf_dsm_read(haddr_t addr, size_t len, void *buf_ptr)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  try {
+    dsmBuffer->Get(addr, len, buf_ptr);
+  }
+  catch (XdmfError & e) {
+    return FAIL;
+  }
+  return(SUCCEED);
+}
+
+herr_t
+xdmf_dsm_read_pages(unsigned int * pages, unsigned int numPages,  haddr_t addr, size_t len, void *buf_ptr)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  try {
+    dsmBuffer->Get(pages, numPages, addr, len, buf_ptr);
+  }
+  catch (XdmfError & e) {
+    return FAIL;
+  }
+  return(SUCCEED);
+}
+
+herr_t
+xdmf_dsm_write(haddr_t addr, size_t len, const void *buf_ptr)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  try {
+    dsmBuffer->Put(addr, len, buf_ptr);
+  }
+  catch (XdmfError & e) {
+    return FAIL;
+  }
+  return(SUCCEED);
+}
+
+herr_t
+xdmf_dsm_write_pages(unsigned int * pages, unsigned int numPages, haddr_t addr, size_t len, const void *buf_ptr)
+{
+  if (!dsmBuffer) {
+    try {
+      XdmfError::message(XdmfError::FATAL, "No DSM manager found");
+    }
+    catch (XdmfError & e) {
+      return FAIL;
+    }
+  }
+
+  try {
+    dsmBuffer->Put(pages, numPages, addr, len, buf_ptr);
+  }
+  catch (XdmfError & e) {
+    return FAIL;
+  }
+  return(SUCCEED);
+}
diff --git a/core/dsm/XdmfDSMDriver.hpp b/core/dsm/XdmfDSMDriver.hpp
new file mode 100644
index 0000000..28760b3
--- /dev/null
+++ b/core/dsm/XdmfDSMDriver.hpp
@@ -0,0 +1,147 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMDriver.hpp                                                   */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+/*=========================================================================
+  This code is derived from an earlier work and is distributed
+  with permission from, and thanks to ...
+=========================================================================*/
+
+/*=========================================================================
+
+  Project                 : H5FDdsm
+  Module                  : H5FDdsmDriver.h H5FDdsm.h
+
+  Authors:
+     John Biddiscombe     Jerome Soumagne
+     biddisco at cscs.ch     soumagne at cscs.ch
+
+  Copyright (C) CSCS - Swiss National Supercomputing Centre.
+  You may use modify and and distribute this code freely providing
+  1) This copyright notice appears on all copies of source code
+  2) An acknowledgment appears with any substantial usage of the code
+  3) If this code is contributed to any other open source project, it
+  must not be reformatted such that the indentation, bracketing or
+  overall style is modified significantly.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  This work has received funding from the European Community's Seventh
+  Framework Programme (FP7/2007-2013) under grant agreement 225967 âxtMuSEâOB
+=========================================================================*/
+
+#ifndef XDMFDSMDRIVER_HPP_
+#define XDMFDSMDRIVER_HPP_
+
+// Forward Declarations
+
+// Includes
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+//#include <XdmfDSMManager.hpp>
+#include <XdmfDSM.hpp>
+#include <mpi.h>
+
+#include "H5Ipublic.h"
+#include "H5FDpublic.h"
+
+#ifndef H5_HAVE_PARALLEL
+  #pragma Error : The XdmfDSM virtual File Driver for HDF5 can only be compiled against an HDF5 library with parallel IO support
+#endif
+
+#define XDMF_DSM_NOTIFY_NONE         0x0000
+#define XDMF_DSM_NOTIFY_DATA         0x0001 /* this is the default */
+#define XDMF_DSM_NOTIFY_INFORMATION  0x0002
+/* Internal notifications */
+#define XDMF_DSM_NOTIFY_WAIT         0x0003
+#define XDMF_DSM_NOTIFY_CONNECTED    0x0004
+#define XDMF_DSM_NOTIFY_DISCONNECTED 0x0005
+/* User notifications */
+#define XDMF_DSM_NOTIFY_USER         0x0010 
+
+#define XDMF_DSM (XDMF_dsm_init())
+
+#define IS_XDMF_DSM(f) /* (H5F_t *f) */    \
+    (XDMF_DSM==H5F_DRIVER_ID(f))
+
+#ifndef H5_HAVE_VFD_EXTENSIONS
+  #include "H5FDmpio.h"
+
+  #ifndef H5FD_FEAT_HAS_MPI
+    // This is a temporary solution to allow interface with standard hdf5 in addition to hdf5vfd
+    // Hopefully a better solution will be made in the future
+    #define XDMF_dsm_init H5FD_mpio_init
+    //#pragma message(": warning Xdmf: H5FD mpiposix file driver replaced to enable dsm compatibility with hdf5")
+  #endif
+#endif /* H5_HAVE_VFD_EXTENSIONS */
+
+extern "C" {
+  XDMFDSM_EXPORT hid_t  XDMF_dsm_init(void);
+#if H5_VERSION_GE(1,9,0)
+  XDMFDSM_EXPORT herr_t XDMF_dsm_term(void);
+#else
+  XDMFDSM_EXPORT void XDMF_dsm_term(void);
+#endif
+  // lock and unlock are currently disabled the user has to make allowances
+  // to prevent race conditions
+  XDMFDSM_EXPORT herr_t XDMF_dsm_lock(void);
+  XDMFDSM_EXPORT herr_t XDMF_dsm_unlock(unsigned long flag);
+  // Currently no options to set
+  XDMFDSM_EXPORT herr_t XDMF_dsm_set_options(unsigned long flags);
+  XDMFDSM_EXPORT herr_t XDMF_dsm_set_manager(void *manager);
+  XDMFDSM_EXPORT herr_t XDMFH5Pset_fapl_dsm(hid_t fapl_id, MPI_Comm intra_comm,
+      void *local_buf_ptr, size_t local_buf_len);
+  XDMFDSM_EXPORT herr_t XDMFH5Pget_fapl_dsm(hid_t fapl_id, MPI_Comm *intra_comm /* out */,
+      void **local_buf_ptr_ptr /* out */, size_t *local_buf_len_ptr /* out */);
+
+
+
+
+  XDMFDSM_EXPORT void   *xdmf_dsm_get_manager();
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_get_properties(MPI_Comm *intra_comm,
+      void **buf_ptr_ptr, size_t *buf_len_ptr);
+  XDMFDSM_EXPORT void    xdmf_dsm_set_manager(void *manager);
+
+/*
+  // Probably a bad idea to create managers automatically for the non-threaded version
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_alloc(MPI_Comm intra_comm, void *buf_ptr, size_t buf_len);
+*/
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_free();
+
+  XDMFDSM_EXPORT hbool_t xdmf_dsm_is_server();
+  // Currently no options to set
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_set_options(unsigned long flags);
+
+  XDMFDSM_EXPORT hbool_t xdmf_dsm_is_connected();
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_connect();
+
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_lock(char * filename);
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_unlock(char * filename, unsigned long flag);
+
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_read(haddr_t addr, size_t len, void *buf_ptr);
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_read_pages(unsigned int * pages, unsigned int numPages, haddr_t addr, size_t len, void *buf_ptr);
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_write(haddr_t addr, size_t len, const void *buf_ptr);
+  XDMFDSM_EXPORT herr_t  xdmf_dsm_write_pages(unsigned int * pages, unsigned int numPages, haddr_t addr, size_t len, const void *buf_ptr);
+}
+
+#endif /* XDMFDSMDRIVER_HPP_ */
diff --git a/core/dsm/XdmfDSMItemFactory.cpp b/core/dsm/XdmfDSMItemFactory.cpp
new file mode 100644
index 0000000..a768957
--- /dev/null
+++ b/core/dsm/XdmfDSMItemFactory.cpp
@@ -0,0 +1,391 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMItemFactory.cpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cctype>
+#include <boost/tokenizer.hpp>
+#include "XdmfInformation.hpp"
+#include "XdmfDSMDescription.hpp"
+#include "XdmfDSMDriver.hpp"
+#include "XdmfDSMBuffer.hpp"
+#include "XdmfDSMCommMPI.hpp"
+#include "XdmfDSMItemFactory.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfError.hpp"
+
+#include "stdio.h"
+
+shared_ptr<XdmfDSMItemFactory>
+XdmfDSMItemFactory::New()
+{
+  shared_ptr<XdmfDSMItemFactory> p(new XdmfDSMItemFactory());
+  return p;
+}
+
+XdmfDSMItemFactory::XdmfDSMItemFactory()
+{
+  if (xdmf_dsm_get_manager())
+  {
+    XdmfDSMItemFactory::mDSMBuffer = (XdmfDSMBuffer *)xdmf_dsm_get_manager();
+  }
+  else
+  {
+    // If Null create a new one, or throw error?
+    XdmfDSMItemFactory::mDSMBuffer = new XdmfDSMBuffer();
+    XdmfDSMItemFactory::mDSMBuffer->SetComm(new XdmfDSMCommMPI());
+  }
+}
+
+XdmfDSMItemFactory::~XdmfDSMItemFactory()
+{
+}
+
+shared_ptr<XdmfItem>
+XdmfDSMItemFactory::createItem(const std::string & itemTag,
+                               const std::map<std::string, std::string> & itemProperties,
+                               const std::vector<shared_ptr<XdmfItem> > & childItems) const
+{
+  shared_ptr<XdmfItem> newItem =
+    XdmfCoreItemFactory::createItem(itemTag, itemProperties, childItems);
+
+  if(newItem) {
+    return newItem;
+  }
+
+  if(itemTag.compare(XdmfDSMDescription::ItemTag) == 0) {
+    // Connect DSM Buffer to DSM Description.
+//  void SetDsmPortName(const char *hostName);
+
+//    XdmfDSMItemFactory::mDSMBuffer = new XdmfDSMBuffer();
+
+    const char * dsmPortName;
+    std::map<std::string, std::string>::const_iterator property =
+      itemProperties.find("Port");
+    if(property != itemProperties.end()) {
+      dsmPortName = property->second.c_str();
+    }
+    XdmfDSMItemFactory::mDSMBuffer->GetComm()->SetDsmPortName(dsmPortName);
+
+    XdmfDSMItemFactory::mDSMBuffer->Connect();
+
+    return XdmfDSMDescription::New();
+  }
+  return shared_ptr<XdmfItem>();
+}
+
+std::vector<shared_ptr<XdmfHeavyDataController> >
+XdmfDSMItemFactory::generateHeavyDataControllers(const std::map<std::string, std::string> & itemProperties,
+                                                  const std::vector<unsigned int> & passedDimensions,
+                                                  shared_ptr<const XdmfArrayType> passedArrayType,
+                                                  const std::string & passedFormat) const
+{
+  std::vector<shared_ptr<XdmfHeavyDataController> > returnControllers =
+    XdmfCoreItemFactory::generateHeavyDataControllers(itemProperties,
+                                                      passedDimensions,
+                                                      passedArrayType,
+                                                      passedFormat);
+
+  if (returnControllers.size() > 0)
+  {
+    return returnControllers;
+  }
+
+  std::string formatVal;
+
+  if (passedFormat.size() > 0)
+  {
+    formatVal = passedFormat;
+  }
+  else
+  {
+    // create a version that passes these in directly
+    std::map<std::string, std::string>::const_iterator format =
+      itemProperties.find("Format");
+    if(format == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "'Format' not found in generateHeavyControllers in "
+                         "XdmfCoreItemFactory");
+    }
+    formatVal = format->second;
+  }
+
+  std::map<std::string, std::string>::const_iterator content =
+  itemProperties.find("Content");
+
+  if(content == itemProperties.end()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "'Content' not found in generateHeavyControllers in "
+                       "XdmfCoreItemFactory");
+  }
+
+  unsigned int contentIndex;
+
+  const std::string & contentVal = content->second;
+  std::vector<std::string> contentVals;
+
+  // Split the content based on "|" characters
+  size_t barSplit = 0;
+  std::string splitString(contentVal);
+  std::string subcontent;
+  while (barSplit != std::string::npos) {
+    barSplit = 0;
+    barSplit = splitString.find_first_of("|", barSplit);
+    if (barSplit == std::string::npos) {
+      subcontent = splitString;
+    }
+    else {
+      subcontent = splitString.substr(0, barSplit);
+      splitString = splitString.substr(barSplit+1);
+      barSplit++;
+    }
+    contentVals.push_back(subcontent);
+  }
+
+  std::vector<unsigned int> dimVector;
+
+  if (passedDimensions.size() > 0)
+  {
+    dimVector = passedDimensions;
+  }
+  else
+  {
+    std::map<std::string, std::string>::const_iterator dimensions =
+      itemProperties.find("Dimensions");
+    if(dimensions == itemProperties.end()) {
+      XdmfError::message(XdmfError::FATAL,
+                         "'Dimensions' not found in generateHeavyControllers in "
+                         "XdmfCoreItemFactory");
+    }
+    boost::tokenizer<> tokens(dimensions->second);
+    for(boost::tokenizer<>::const_iterator iter = tokens.begin();
+        iter != tokens.end();
+        ++iter) {
+      dimVector.push_back(atoi((*iter).c_str()));
+    }
+  }
+
+  shared_ptr<const XdmfArrayType> arrayType;
+  if (passedArrayType)
+  {
+    arrayType = passedArrayType;
+  }
+  else
+  {
+    arrayType = XdmfCoreItemFactory::getArrayType(itemProperties);
+  }
+
+  if (contentVals.size() == 0) {
+    return returnControllers;
+  }
+
+  if(formatVal.compare("HDFDSM") == 0) {
+    // TODO, generate DSM Buffer here, if different from previous
+
+    contentIndex = 0;
+    int contentStep = 2;
+    while (contentIndex < contentVals.size()) {
+      size_t colonLocation = contentVals[contentIndex].find(":");
+      if(colonLocation == std::string::npos) {
+        XdmfError::message(XdmfError::FATAL,
+                           "':' not found in content generateHeavyControllers in "
+                           "XdmfCoreItemFactory -- double check an HDF5 "
+                           "data set is specified for the file");
+      }
+
+      std::string hdf5Path =
+        contentVals[contentIndex].substr(0, colonLocation);
+      std::string dataSetPath =
+        contentVals[contentIndex].substr(colonLocation+1);
+
+      hdf5Path = getFullHeavyDataPath(hdf5Path,
+                                      itemProperties);
+
+      // Parse dimensions from the content
+      std::vector<unsigned int> contentStarts;
+      std::vector<unsigned int> contentStrides;
+      std::vector<unsigned int> contentDims;
+      std::vector<unsigned int> contentDataspaces;
+      if (contentVals.size() > contentIndex+1) {
+        // This is the string that contains the dimensions
+        std::string dataspaceDescription = contentVals[contentIndex+1];
+        std::vector<std::string> dataspaceVector;
+        size_t colonSplit = 0;
+        while (colonSplit != std::string::npos) {
+          colonSplit = 0;
+          colonSplit = dataspaceDescription.find_first_of(":", colonSplit);
+          if (colonSplit == std::string::npos) {
+            subcontent = dataspaceDescription;
+          }
+          else {
+            subcontent = dataspaceDescription.substr(0, colonSplit);
+            dataspaceDescription = dataspaceDescription.substr(colonSplit+1);
+            colonSplit++;
+          }
+          dataspaceVector.push_back(subcontent);
+        }
+
+        // split the description based on tokens
+        boost::tokenizer<> dimtokens(std::string(""));
+        if (dataspaceVector.size() == 1) {
+          dimtokens = boost::tokenizer<>(dataspaceDescription);
+        }
+        else if (dataspaceVector.size() == 4) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[2]);
+        }
+        for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+            iter != dimtokens.end();
+            ++iter) {
+          contentDims.push_back(atoi((*iter).c_str()));
+        }
+
+        if (dataspaceVector.size() == 4) {
+          dimtokens = boost::tokenizer<>(dataspaceVector[0]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStarts.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[1]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentStrides.push_back(atoi((*iter).c_str()));
+          }
+          dimtokens = boost::tokenizer<>(dataspaceVector[3]);
+          for(boost::tokenizer<>::const_iterator iter = dimtokens.begin();
+              iter != dimtokens.end();
+              ++iter) {
+            contentDataspaces.push_back(atoi((*iter).c_str()));
+          }
+        }
+        contentStep = 2;
+        // If this works then the dimension content should be skipped over
+      }
+      else {
+        // If it fails then it means that the next content is not a dimension string
+        // In this case it is assumed that the controller will have
+        // dimensions equal to the array
+        for (unsigned int j = 0; j < dimVector.size(); ++j) {
+          contentDims.push_back(dimVector[j]);
+        }
+        contentStep = 1;
+      }
+      if (contentDataspaces.size() == 0) {
+        returnControllers.push_back(
+          XdmfHDF5ControllerDSM::New(hdf5Path,
+                                     dataSetPath,
+                                     arrayType,
+                                     std::vector<unsigned int>(contentDims.size(),
+                                                               0),
+                                     std::vector<unsigned int>(contentDims.size(),
+                                                               1),
+                                     contentDims,
+                                     contentDims,
+                                     XdmfDSMItemFactory::mDSMBuffer)
+          );
+      }
+      else {
+        returnControllers.push_back(
+          XdmfHDF5ControllerDSM::New(hdf5Path,
+                                     dataSetPath,
+                                     arrayType,
+                                     contentStarts,
+                                     contentStrides,
+                                     contentDims,
+                                     contentDataspaces,
+                                     XdmfDSMItemFactory::mDSMBuffer)
+          );
+      }
+      contentIndex+=contentStep;
+    }
+  }
+  return returnControllers;
+}
+
+shared_ptr<XdmfHeavyDataWriter>
+XdmfDSMItemFactory::generateHeavyDataWriter(std::string typeName, std::string path) const
+{
+  shared_ptr<XdmfHeavyDataWriter> returnWriter =
+    XdmfCoreItemFactory::generateHeavyDataWriter(typeName, path);
+
+  if (returnWriter)
+  {
+    return returnWriter;
+  }
+
+/*
+  if (typeName.compare("HDF") == 0) {
+    return XdmfHDF5Writer::New(path);
+  }
+*/
+  return shared_ptr<XdmfHeavyDataWriter>();
+}
+
+XdmfDSMBuffer *
+XdmfDSMItemFactory::getDSMBuffer()
+{
+  return XdmfDSMItemFactory::mDSMBuffer;
+}
+
+bool
+XdmfDSMItemFactory::isArrayTag(char * tag) const
+{
+  if (XdmfCoreItemFactory::isArrayTag(tag))
+  {
+    return true;
+  }
+  // No DSM specific cases
+/*
+  else if (XdmfAggregate::ItemTag.compare(tag) == 0) {
+    return true;
+  }
+*/
+  else {
+    return false;
+  }
+}
+
+void
+XdmfDSMItemFactory::setDSMBuffer(XdmfDSMBuffer * newBuffer)
+{
+  XdmfDSMItemFactory::mDSMBuffer = newBuffer;
+}
+
+XdmfItem *
+XdmfDSMItemFactory::DuplicatePointer(shared_ptr<XdmfItem> original) const
+{
+  XdmfItem * returnPointer = XdmfCoreItemFactory::DuplicatePointer(original);
+
+  if (returnPointer) {
+    return returnPointer;
+  }
+  else {
+    //Right now DSM has no pointers to duplicate.
+/*
+   if (original->getItemTag().compare(XdmfTime::ItemTag) == 0) {
+     return new XdmfTime(*((XdmfTime *)original.get()));
+   }
+*/
+  }
+  return NULL;
+}
diff --git a/core/dsm/XdmfDSMItemFactory.hpp b/core/dsm/XdmfDSMItemFactory.hpp
new file mode 100644
index 0000000..9bc8c94
--- /dev/null
+++ b/core/dsm/XdmfDSMItemFactory.hpp
@@ -0,0 +1,114 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDSMItemFactory.hpp                                              */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFDSMITEMFACTORY_HPP_
+#define XDMFDSMITEMFACTORY_HPP_
+
+// C Compatible Includes
+#include "Xdmf.hpp"
+#include "XdmfCoreItemFactory.hpp"
+#include "XdmfDSMBuffer.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfItem;
+
+// Includes
+
+/**
+ * @brief Factory for constructing XdmfItems from their ItemTag and
+ * ItemProperties.
+ */
+class XDMFDSM_EXPORT XdmfDSMItemFactory : public XdmfCoreItemFactory {
+
+public:
+
+  /**
+   * Create a new XdmfItemFactory.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfItemFactory.cpp
+   * @skipline //#initialization
+   * @until //#initialization
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleItemFactory.py
+   * @skipline #//initialization
+   * @until #//initialization
+   *
+   * @return    Constructed XdmfItemFactory.
+   */
+  static shared_ptr<XdmfDSMItemFactory> New();
+
+  virtual ~XdmfDSMItemFactory();
+
+  virtual shared_ptr<XdmfItem>
+  createItem(const std::string & itemTag,
+             const std::map<std::string, std::string> & itemProperties,
+             const std::vector<shared_ptr<XdmfItem> > & childItems) const;
+
+  virtual std::vector<shared_ptr<XdmfHeavyDataController> >
+  generateHeavyDataControllers(const std::map<std::string, std::string> & itemProperties,
+                               const std::vector<unsigned int> & passedDimensions,
+                               shared_ptr<const XdmfArrayType> passedArrayType,
+                               const std::string & passedFormat) const;
+
+
+  virtual shared_ptr<XdmfHeavyDataWriter>
+  generateHeavyDataWriter(std::string typeName, std::string path) const;
+
+  XdmfDSMBuffer *
+  getDSMBuffer();
+
+  virtual bool isArrayTag(char * tag) const;
+
+  void
+  setDSMBuffer(XdmfDSMBuffer * newBuffer);
+
+  virtual XdmfItem *
+  DuplicatePointer(shared_ptr<XdmfItem> original) const;
+
+protected:
+
+  XdmfDSMItemFactory();
+
+private:
+
+  XdmfDSMItemFactory(const XdmfDSMItemFactory &);  // Not implemented.
+  void operator=(const XdmfDSMItemFactory &);  // Not implemented.
+
+  XdmfDSMBuffer * mDSMBuffer;
+};
+
+#ifdef _WIN32
+XDMF_TEMPLATE template class XDMF_EXPORT shared_ptr<XdmfDSMItemFactory>;
+#endif
+
+#endif
+
+#endif /* XDMFDSMITEMFACTORY_HPP_ */
diff --git a/core/dsm/XdmfHDF5ControllerDSM.cpp b/core/dsm/XdmfHDF5ControllerDSM.cpp
new file mode 100644
index 0000000..c456eed
--- /dev/null
+++ b/core/dsm/XdmfHDF5ControllerDSM.cpp
@@ -0,0 +1,1016 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5ControllerDSM.cpp                                           */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <H5public.h>
+#include <hdf5.h>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+#include "XdmfDSMBuffer.hpp"
+#include "XdmfDSMCommMPI.hpp"
+#include "XdmfDSMDriver.hpp"
+#include "XdmfError.hpp"
+
+// Server/ nonthreaded versions
+shared_ptr<XdmfHDF5ControllerDSM>
+XdmfHDF5ControllerDSM::New(const std::string & hdf5FilePath,
+                           const std::string & dataSetPath,
+                           const shared_ptr<const XdmfArrayType> type,
+                           const std::vector<unsigned int> & start,
+                           const std::vector<unsigned int> & stride,
+                           const std::vector<unsigned int> & dimensions,
+                           const std::vector<unsigned int> & datspaceDimensions,
+                           XdmfDSMBuffer * const dsmBuffer)
+{
+  shared_ptr<XdmfHDF5ControllerDSM>
+    p(new XdmfHDF5ControllerDSM(hdf5FilePath,
+                                dataSetPath,
+                                type,
+                                start,
+                                stride,
+                                dimensions,
+                                datspaceDimensions,
+                                dsmBuffer));
+  return p;
+}
+
+shared_ptr<XdmfHDF5ControllerDSM>
+XdmfHDF5ControllerDSM::New(const std::string & hdf5FilePath,
+                           const std::string & dataSetPath,
+                           const shared_ptr<const XdmfArrayType> type,
+                           const std::vector<unsigned int> & start,
+                           const std::vector<unsigned int> & stride,
+                           const std::vector<unsigned int> & dimensions,
+                           const std::vector<unsigned int> & datspaceDimensions,
+                           MPI_Comm comm,
+                           unsigned int bufferSize,
+                           int startCoreIndex,
+                           int endCoreIndex,
+                           std::string applicationName)
+{
+  shared_ptr<XdmfHDF5ControllerDSM>
+    p(new XdmfHDF5ControllerDSM(hdf5FilePath,
+                                dataSetPath,
+                                type,
+                                start,
+                                stride,
+                                dimensions,
+                                datspaceDimensions,
+                                comm,
+                                bufferSize,
+                                startCoreIndex,
+                                endCoreIndex,
+                                applicationName));
+  return p;
+}
+
+shared_ptr<XdmfHDF5ControllerDSM>
+XdmfHDF5ControllerDSM::New(const std::string & hdf5FilePath,
+                           const std::string & dataSetPath,
+                           const shared_ptr<const XdmfArrayType> type,
+                           const std::vector<unsigned int> & start,
+                           const std::vector<unsigned int> & stride,
+                           const std::vector<unsigned int> & dimensions,
+                           const std::vector<unsigned int> & datspaceDimensions,
+                           MPI_Comm comm,
+                           unsigned int bufferSize,
+                           unsigned int blockSize,
+                           double resizeFactor,
+                           int startCoreIndex,
+                           int endCoreIndex,
+                           std::string applicationName)
+{
+  shared_ptr<XdmfHDF5ControllerDSM>
+    p(new XdmfHDF5ControllerDSM(hdf5FilePath,
+                                dataSetPath,
+                                type,
+                                start,
+                                stride,
+                                dimensions,
+                                datspaceDimensions,
+                                comm,
+                                bufferSize,
+                                blockSize,
+                                resizeFactor,
+                                startCoreIndex,
+                                endCoreIndex,
+                                applicationName));
+  return p;
+}
+
+XdmfHDF5ControllerDSM::XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
+                                             const std::string & dataSetPath,
+                                             const shared_ptr<const XdmfArrayType> type,
+                                             const std::vector<unsigned int> & start,
+                                             const std::vector<unsigned int> & stride,
+                                             const std::vector<unsigned int> & dimensions,
+                                             const std::vector<unsigned int> & dataspaceDimensions,
+                                             XdmfDSMBuffer * const dsmBuffer) :
+  XdmfHDF5Controller(hdf5FilePath,
+                     dataSetPath,
+                     type,
+                     start,
+                     stride,
+                     dimensions,
+                     dataspaceDimensions),
+  mDSMServerBuffer(dsmBuffer),
+  mServerMode(true)
+{
+  mWorkerComm = mDSMServerBuffer->GetComm()->GetIntraComm();
+  if (xdmf_dsm_get_manager() == NULL) {
+    XDMF_dsm_set_manager(mDSMServerBuffer);
+  }
+  else {
+    xdmf_dsm_set_manager(mDSMServerBuffer);
+  }
+}
+
+XdmfHDF5ControllerDSM::XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
+                                             const std::string & dataSetPath,
+                                             const shared_ptr<const XdmfArrayType> type,
+                                             const std::vector<unsigned int> & start,
+                                             const std::vector<unsigned int> & stride,
+                                             const std::vector<unsigned int> & dimensions,
+                                             const std::vector<unsigned int> & dataspaceDimensions,
+                                             MPI_Comm comm,
+                                             unsigned int bufferSize,
+                                             int startCoreIndex,
+                                             int endCoreIndex,
+                                             std::string applicationName) :
+  XdmfHDF5Controller(hdf5FilePath,
+                     dataSetPath,
+                     type,
+                     start,
+                     stride,
+                     dimensions,
+                     dataspaceDimensions),
+  mServerMode(true)
+
+{
+  int rank, size;
+#ifdef XDMF_DSM_IS_CRAY
+
+  MPI_Comm InterComm = comm;
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<std::pair<std::string, unsigned int> > newStructure;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    newStructure.push_back(std::pair<std::string, unsigned int>(std::string(coreTag), coreSplit.size()));
+    coreSplit.clear();
+    ++splitid;
+  }
+
+
+  // Use MPI_Comm_split
+  MPI_Group IntraGroup, InterGroup;
+  MPI_Comm IntraComm;
+  MPI_Comm_group(comm, &InterGroup);
+  MPI_Group_incl(InterGroup, splitsize, splitIds, &IntraGroup);
+  MPI_Comm_create(comm, IntraGroup, &IntraComm);
+  cfree(splitIds);
+
+  int intraid = 0;
+  int intrasize = 0;
+
+  MPI_Comm_rank(IntraComm, &intraid);
+  MPI_Comm_size(IntraComm, &intrasize);
+
+  comm = IntraComm;
+#endif
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  // Negative values will be changed to maximum range
+  if (startCoreIndex < 0) {
+    startCoreIndex = 0;
+  }
+  if (endCoreIndex < 0) {
+    endCoreIndex = size - 1;
+  }
+
+  // Ensure start index is less than end index
+  if (startCoreIndex > endCoreIndex) {
+    int tempholder = startCoreIndex;
+    startCoreIndex = endCoreIndex;
+    endCoreIndex = tempholder;
+  }
+
+  MPI_Comm serverComm;
+
+  MPI_Group workers, dsmgroup, serversplit, servergroup;
+
+  int * ServerIds = (int *)calloc((3), sizeof(int));
+  unsigned int index = 0;
+  for(int i=startCoreIndex ; i <= endCoreIndex ; ++i) {
+    ServerIds[index++] = i;
+  }
+
+  MPI_Comm_group(comm, &serversplit);
+  MPI_Group_incl(serversplit, index, ServerIds, &servergroup);
+  MPI_Comm_create(comm, servergroup, &serverComm);
+  MPI_Comm_group(comm, &dsmgroup);
+  MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+  MPI_Comm_create(comm, workers, &mWorkerComm);
+  cfree(ServerIds);
+
+  // Create the manager
+  mDSMServerBuffer = new XdmfDSMBuffer();
+
+  mDSMServerBuffer->SetLocalBufferSizeMBytes(bufferSize);
+  mDSMServerBuffer->SetInterCommType(XDMF_DSM_COMM_MPI);
+  mDSMServerBuffer->SetDsmType(XDMF_DSM_TYPE_UNIFORM);
+  if (rank >= startCoreIndex && rank <= endCoreIndex)
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName("Server");
+  }
+  else
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName(applicationName);
+  }
+
+  if (rank >= startCoreIndex && rank <= endCoreIndex) {
+    mDSMServerBuffer->Create(serverComm);
+  }
+  else {
+    mDSMServerBuffer->Create(mWorkerComm, startCoreIndex, endCoreIndex);
+  }
+
+  XDMF_dsm_set_manager(mDSMServerBuffer);
+
+#ifdef XDMF_DSM_IS_CRAY
+  mDSMServerBuffer->GetComm()->DupInterComm(InterComm);
+#else
+  mDSMServerBuffer->GetComm()->DupInterComm(comm);
+#endif
+  mDSMServerBuffer->SetIsConnected(true);
+
+  if (startCoreIndex < size) {
+    if (rank >= startCoreIndex && rank <= endCoreIndex) {
+      mDSMServerBuffer->ReceiveInfo();
+    }
+    else {
+      mDSMServerBuffer->SendInfo();
+    }
+  }
+
+  MPI_Barrier(comm);
+
+  // Loop needs to be started before anything can be done to the file
+  // since the service is what sets up the file
+
+  if (rank < startCoreIndex || rank > endCoreIndex) {
+    // Turn off the server designation
+    mDSMServerBuffer->SetIsServer(false);
+    // If this is set to false then the buffer will attempt to
+    // connect to the intercomm for DSM stuff
+  }
+  else {
+    // On cores where memory is set up, start the service loop
+    // This should iterate infinitely until a value to end the loop is passed
+    int returnOpCode;
+    try {
+      mDSMServerBuffer->BufferServiceLoop(&returnOpCode);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+XdmfHDF5ControllerDSM::XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
+                                             const std::string & dataSetPath,
+                                             const shared_ptr<const XdmfArrayType> type,
+                                             const std::vector<unsigned int> & start,
+                                             const std::vector<unsigned int> & stride,
+                                             const std::vector<unsigned int> & dimensions,
+                                             const std::vector<unsigned int> & dataspaceDimensions,
+                                             MPI_Comm comm,
+                                             unsigned int bufferSize,
+                                             unsigned int blockSize,
+                                             double resizeFactor,
+                                             int startCoreIndex,
+                                             int endCoreIndex,
+                                             std::string applicationName) :
+  XdmfHDF5Controller(hdf5FilePath,
+                     dataSetPath,
+                     type,
+                     start,
+                     stride,
+                     dimensions,
+                     dataspaceDimensions),
+  mServerMode(true)
+
+{
+  int rank, size;
+#ifdef XDMF_DSM_IS_CRAY
+
+  MPI_Comm InterComm = comm;
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<std::pair<std::string, unsigned int> > newStructure;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    newStructure.push_back(std::pair<std::string, unsigned int>(std::string(coreTag), coreSplit.size()));
+    coreSplit.clear();
+    ++splitid;
+  }
+
+
+  // Use MPI_Comm_split
+  MPI_Group IntraGroup, InterGroup;
+  MPI_Comm IntraComm;
+  MPI_Comm_group(comm, &InterGroup);
+  MPI_Group_incl(InterGroup, splitsize, splitIds, &IntraGroup);
+  MPI_Comm_create(comm, IntraGroup, &IntraComm);
+  cfree(splitIds);
+
+  int intraid = 0;
+  int intrasize = 0;
+
+  MPI_Comm_rank(IntraComm, &intraid);
+  MPI_Comm_size(IntraComm, &intrasize);
+
+  comm = IntraComm;
+
+#endif
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  // Negative values will be changed to maximum range
+  if (startCoreIndex < 0) {
+    startCoreIndex = 0;
+  }
+  if (endCoreIndex < 0) {
+    endCoreIndex = size - 1;
+  }
+
+  // Ensure start index is less than end index
+  if (startCoreIndex > endCoreIndex) {
+    int tempholder = startCoreIndex;
+    startCoreIndex = endCoreIndex;
+    endCoreIndex = tempholder;
+  }
+
+  MPI_Comm serverComm;
+
+  MPI_Group workers, dsmgroup, serversplit, servergroup;
+
+  int * ServerIds = (int *)calloc((3), sizeof(int));
+  unsigned int index = 0;
+  for(int i=startCoreIndex ; i <= endCoreIndex ; ++i) {
+    ServerIds[index++] = i;
+  }
+
+  MPI_Comm_group(comm, &serversplit);
+  MPI_Group_incl(serversplit, index, ServerIds, &servergroup);
+  MPI_Comm_create(comm, servergroup, &serverComm);
+  MPI_Comm_group(comm, &dsmgroup);
+  MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+  MPI_Comm_create(comm, workers, &mWorkerComm);
+  cfree(ServerIds);
+
+  // Create the manager
+  mDSMServerBuffer = new XdmfDSMBuffer();
+
+  mDSMServerBuffer->SetLocalBufferSizeMBytes(bufferSize);
+  mDSMServerBuffer->SetInterCommType(XDMF_DSM_COMM_MPI);
+  mDSMServerBuffer->SetBlockLength(blockSize);
+  mDSMServerBuffer->SetDsmType(XDMF_DSM_TYPE_BLOCK_CYCLIC);
+  mDSMServerBuffer->SetResizeFactor(resizeFactor);
+  if (rank >= startCoreIndex && rank <= endCoreIndex)
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName("Server");
+  }
+  else
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName(applicationName);
+  }
+
+  if (rank >= startCoreIndex && rank <= endCoreIndex) {
+    mDSMServerBuffer->Create(serverComm);
+  }
+  else {
+    mDSMServerBuffer->Create(mWorkerComm, startCoreIndex, endCoreIndex);
+  }
+
+  XDMF_dsm_set_manager(mDSMServerBuffer);
+
+#ifdef XDMF_DSM_IS_CRAY
+  mDSMServerBuffer->GetComm()->DupInterComm(InterComm);
+#else
+  mDSMServerBuffer->GetComm()->DupInterComm(comm);
+#endif
+  mDSMServerBuffer->SetIsConnected(true);
+
+  if (startCoreIndex < size) {
+    if (rank >= startCoreIndex && rank <= endCoreIndex) {
+      mDSMServerBuffer->ReceiveInfo();
+    }
+    else {
+      mDSMServerBuffer->SendInfo();
+    }
+  }
+
+  MPI_Barrier(comm);
+
+  // Loop needs to be started before anything can be done to the file
+  // since the service is what sets up the file
+
+  if (rank < startCoreIndex || rank > endCoreIndex) {
+    // Turn off the server designation
+    mDSMServerBuffer->SetIsServer(false);
+    // If this is set to false then the buffer will attempt to
+    // connect to the intercomm for DSM stuff
+  }
+  else {
+    // On cores where memory is set up, start the service loop
+    // This should iterate infinitely until a value to end the loop is passed
+    int returnOpCode;
+    try {
+      mDSMServerBuffer->BufferServiceLoop(&returnOpCode);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+XdmfHDF5ControllerDSM::XdmfHDF5ControllerDSM(XdmfHDF5ControllerDSM & refController):
+  XdmfHDF5Controller(refController),
+  mDSMServerBuffer(refController.getServerBuffer()),
+  mServerMode(refController.getServerMode())
+{
+  mWorkerComm = mDSMServerBuffer->GetComm()->GetIntraComm();
+}
+
+XdmfHDF5ControllerDSM::~XdmfHDF5ControllerDSM()
+{
+}
+
+std::string XdmfHDF5ControllerDSM::getName() const
+{
+  return "HDFDSM";
+}
+
+XdmfDSMBuffer * XdmfHDF5ControllerDSM::getServerBuffer()
+{
+  return mDSMServerBuffer;
+}
+
+bool XdmfHDF5ControllerDSM::getServerMode() const
+{
+  return mServerMode;
+}
+
+MPI_Comm XdmfHDF5ControllerDSM::getWorkerComm() const
+{
+  MPI_Comm returnComm = MPI_COMM_NULL;
+  if (mWorkerComm != MPI_COMM_NULL) {
+    MPI_Comm_dup(mWorkerComm, &returnComm);
+  }
+  return returnComm;
+}
+
+void XdmfHDF5ControllerDSM::setBuffer(XdmfDSMBuffer * newBuffer)
+{
+  mDSMServerBuffer = newBuffer;
+}
+
+void XdmfHDF5ControllerDSM::setServerMode(bool newMode)
+{
+  mServerMode = newMode;
+}
+
+void XdmfHDF5ControllerDSM::setWorkerComm(MPI_Comm comm)
+{
+  int status;
+#ifndef OPEN_MPI
+  if (mWorkerComm != MPI_COMM_NULL) {
+    status = MPI_Comm_free(&mWorkerComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to disconnect Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+#endif
+  if (comm != MPI_COMM_NULL) {
+    status = MPI_Comm_dup(comm, &mWorkerComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to duplicate Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  mDSMServerBuffer->GetComm()->DupComm(comm);
+}
+
+void XdmfHDF5ControllerDSM::stopDSM()
+{
+  if (mServerMode) {
+    // Send manually
+    for (int i = mDSMServerBuffer->GetStartServerId();
+         i <= mDSMServerBuffer->GetEndServerId();
+         ++i) {
+      try {
+        mDSMServerBuffer->SendCommandHeader(XDMF_DSM_OPCODE_DONE, i, 0, 0, XDMF_DSM_INTER_COMM);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Stopping DSM manually only available in server mode.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void XdmfHDF5ControllerDSM::restartDSM()
+{
+  if (mServerMode) {
+    if (mDSMServerBuffer->GetComm()->GetInterId() >=
+          mDSMServerBuffer->GetStartServerId() &&
+        mDSMServerBuffer->GetComm()->GetInterId() <=
+          mDSMServerBuffer->GetEndServerId()) {
+      int returnOpCode;
+      try {
+        mDSMServerBuffer->BufferServiceLoop(&returnOpCode);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Restarting DSM only available in server mode.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void XdmfHDF5ControllerDSM::read(XdmfArray * const array)
+{
+  // Set file access property list for DSM
+  hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
+
+  // Use DSM driver
+  if (mWorkerComm != MPI_COMM_NULL) {
+    XDMFH5Pset_fapl_dsm(fapl, mWorkerComm, mDSMServerBuffer, 0);
+  }
+
+  // Read from DSM Buffer
+  XdmfHDF5Controller::read(array, fapl);
+
+  // Close file access property list
+  H5Pclose(fapl);
+}
+
+// C Wrappers
+
+XDMFHDF5CONTROLLERDSM * XdmfHDF5ControllerDSMNewFromServerBuffer(char * hdf5FilePath,
+                                                                 char * dataSetPath,
+                                                                 int type,
+                                                                 unsigned int * start,
+                                                                 unsigned int * stride,
+                                                                 unsigned int * dimensions,
+                                                                 unsigned int * dataspaceDimensions,
+                                                                 unsigned int numDims,
+                                                                 void * dsmBuffer,
+                                                                 int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> startVector(start, start + numDims);
+  std::vector<unsigned int> strideVector(stride, stride + numDims);
+  std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+  std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+  shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+  switch (type) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      buildType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      buildType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      buildType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      buildType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      buildType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      buildType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      buildType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      buildType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      buildType = XdmfArrayType::Float64();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+  }
+  shared_ptr<XdmfHDF5ControllerDSM> generatedController = XdmfHDF5ControllerDSM::New(std::string(hdf5FilePath),
+                                                                                     std::string(dataSetPath),
+                                                                                     buildType,
+                                                                                     startVector,
+                                                                                     strideVector,
+                                                                                     dimVector,
+                                                                                     dataspaceVector,
+                                                                                     (XdmfDSMBuffer *) dsmBuffer);
+  return (XDMFHDF5CONTROLLERDSM *)((void *)(new XdmfHDF5ControllerDSM(*generatedController.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFHDF5CONTROLLERDSM * XdmfHDF5ControllerDSMNew(char * hdf5FilePath,
+                                                 char * dataSetPath,
+                                                 int type,
+                                                 unsigned int * start,
+                                                 unsigned int * stride,
+                                                 unsigned int * dimensions,
+                                                 unsigned int * dataspaceDimensions,
+                                                 unsigned int numDims,
+                                                 MPI_Comm comm,
+                                                 unsigned int bufferSize,
+                                                 int startCoreIndex,
+                                                 int endCoreIndex,
+                                                 char * applicationName,
+                                                 int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> startVector(start, start + numDims);
+  std::vector<unsigned int> strideVector(stride, stride + numDims);
+  std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+  std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+  shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+  switch (type) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      buildType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      buildType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      buildType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      buildType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      buildType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      buildType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      buildType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      buildType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      buildType = XdmfArrayType::Float64();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+  }
+  shared_ptr<XdmfHDF5ControllerDSM> generatedController = XdmfHDF5ControllerDSM::New(std::string(hdf5FilePath),
+                                                                                     std::string(dataSetPath),
+                                                                                     buildType,
+                                                                                     startVector,
+                                                                                     strideVector,
+                                                                                     dimVector,
+                                                                                     dataspaceVector,
+                                                                                     comm,
+                                                                                     bufferSize,
+                                                                                     startCoreIndex,
+                                                                                     endCoreIndex,
+                                                                                     std::string(applicationName));
+  return (XDMFHDF5CONTROLLERDSM *)((void *)(new XdmfHDF5ControllerDSM(*generatedController.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFHDF5CONTROLLERDSM * XdmfHDF5ControllerDSMNewPaged(char * hdf5FilePath,
+                                                      char * dataSetPath,
+                                                      int type,
+                                                      unsigned int * start,
+                                                      unsigned int * stride,
+                                                      unsigned int * dimensions,
+                                                      unsigned int * dataspaceDimensions,
+                                                      unsigned int numDims,
+                                                      MPI_Comm comm,
+                                                      unsigned int bufferSize,
+                                                      unsigned int blockSize,
+                                                      double resizeFactor,
+                                                      int startCoreIndex,
+                                                      int endCoreIndex,
+                                                      char * applicationName,
+                                                      int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  std::vector<unsigned int> startVector(start, start + numDims);
+  std::vector<unsigned int> strideVector(stride, stride + numDims);
+  std::vector<unsigned int> dimVector(dimensions, dimensions + numDims);
+  std::vector<unsigned int> dataspaceVector(dataspaceDimensions, dataspaceDimensions + numDims);
+  shared_ptr<const XdmfArrayType> buildType = shared_ptr<XdmfArrayType>();
+  switch (type) {
+    case XDMF_ARRAY_TYPE_UINT8:
+      buildType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      buildType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      buildType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_INT8:
+      buildType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      buildType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      buildType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      buildType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      buildType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      buildType = XdmfArrayType::Float64();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid ArrayType.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      break;
+  }
+  shared_ptr<XdmfHDF5ControllerDSM> generatedController = XdmfHDF5ControllerDSM::New(std::string(hdf5FilePath),
+                                                                                     std::string(dataSetPath),
+                                                                                     buildType,
+                                                                                     startVector,
+                                                                                     strideVector,
+                                                                                     dimVector,
+                                                                                     dataspaceVector,
+                                                                                     comm,
+                                                                                     bufferSize,
+                                                                                     blockSize,
+                                                                                     resizeFactor,
+                                                                                     startCoreIndex,
+                                                                                     endCoreIndex,
+                                                                                     std::string(applicationName));
+  return (XDMFHDF5CONTROLLERDSM *)((void *)(new XdmfHDF5ControllerDSM(*generatedController.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFDSMBUFFER * XdmfHDF5ControllerDSMGetServerBuffer(XDMFHDF5CONTROLLERDSM * controller)
+{
+  return (XDMFDSMBUFFER *)((void *)(((XdmfHDF5ControllerDSM *)controller)->getServerBuffer()));
+}
+
+int XdmfHDF5ControllerDSMGetServerMode(XDMFHDF5CONTROLLERDSM * controller)
+{
+  return ((XdmfHDF5ControllerDSM *)controller)->getServerMode();
+}
+
+MPI_Comm XdmfHDF5ControllerDSMGetWorkerComm(XDMFHDF5CONTROLLERDSM * controller)
+{
+  return ((XdmfHDF5ControllerDSM *)controller)->getWorkerComm();
+}
+
+void XdmfHDF5ControllerDSMSetServerBuffer(XDMFHDF5CONTROLLERDSM * controller, XDMFDSMBUFFER * newBuffer)
+{
+  ((XdmfHDF5ControllerDSM *)controller)->setBuffer((XdmfDSMBuffer *)newBuffer);
+}
+
+void XdmfHDF5ControllerDSMSetServerMode(XDMFHDF5CONTROLLERDSM * controller, int newMode)
+{
+  ((XdmfHDF5ControllerDSM *)controller)->setServerMode(newMode);
+}
+
+void XdmfHDF5ControllerDSMSetWorkerComm(XDMFHDF5CONTROLLERDSM * controller, MPI_Comm comm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5ControllerDSM *)controller)->setWorkerComm(comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHDF5ControllerDSMStopDSM(XDMFHDF5CONTROLLERDSM * controller, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5ControllerDSM *)controller)->stopDSM();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHDF5ControllerDSMRestartDSM(XDMFHDF5CONTROLLERDSM * controller, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5ControllerDSM *)controller)->restartDSM();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+// C Wrappers for parent classes are generated by macros
+
+XDMF_HEAVYCONTROLLER_C_CHILD_WRAPPER(XdmfHDF5ControllerDSM, XDMFHDF5CONTROLLERDSM)
+XDMF_HDF5CONTROLLER_C_CHILD_WRAPPER(XdmfHDF5ControllerDSM, XDMFHDF5CONTROLLERDSM)
diff --git a/core/dsm/XdmfHDF5ControllerDSM.hpp b/core/dsm/XdmfHDF5ControllerDSM.hpp
new file mode 100644
index 0000000..f522c0e
--- /dev/null
+++ b/core/dsm/XdmfHDF5ControllerDSM.hpp
@@ -0,0 +1,749 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5ControllerDSM.cpp                                           */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFHDF5CONTROLLERDSM_HPP_
+#define XDMFHDF5CONTROLLERDSM_HPP_
+
+// C Compatible Includes
+#include "XdmfDSM.hpp"
+#include "XdmfDSMBuffer.hpp"
+#include "XdmfHDF5Controller.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+
+// Includes
+#include "XdmfDSMDescription.hpp"
+
+/**
+ * @brief Couples an XdmfArray with HDF5 data stored in a DSM buffer.
+ *
+ * Serves as an interface between data stored in XdmfArrays and data
+ * stored in DSM buffers.  When an Xdmf file is read from or written
+ * to a DSM buffer an XdmfHDF5ControllerDSM is attached to XdmfArrays.
+ * This allows data to be released from memory but still be accessible
+ * or have its location written to light data.
+ */
+class XDMFDSM_EXPORT XdmfHDF5ControllerDSM : public XdmfHDF5Controller {
+
+public:
+
+  virtual ~XdmfHDF5ControllerDSM();
+
+  /**
+   * Create a new controller for an DSM data set.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#initcontrollerwithbuffer
+   * @until //#initcontrollerwithbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//initcontrollerwithbuffer
+   * @until #//initcontrollerwithbuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     hdf5FilePath            The path to the hdf5 file that the controller will be accessing
+   * @param     dataSetPath             The location within the file of the data the controller with be accessing
+   * @param     type                    The data type of the data Ex: XdmfArrayType::Int32()
+   * @param     start                   A vector of the start indexes for all dimensions of the data
+   * @param     stride                  A vector of the distance between reads for all dimensions of the data
+   * @param     dimensions              A vector of the number of values read from all dimensions of the data
+   * @param     dataspaceDimensions     A vecotr containing the total size of the dimension in the data space
+   * @param     dsmBuffer               A pointer to the dsm buffer
+   */
+  static shared_ptr<XdmfHDF5ControllerDSM>
+  New(const std::string & hdf5FilePath,
+      const std::string & dataSetPath,
+      const shared_ptr<const XdmfArrayType> type,
+      const std::vector<unsigned int> & start,
+      const std::vector<unsigned int> & stride,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaceDimensions,
+      XdmfDSMBuffer * const dsmBuffer);
+
+  /**
+   * Create a new controller for an DSM data set.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     hdf5FilePath            The path to the hdf5 file that the controller will be accessing
+   * @param     dataSetPath             The location within the file of the data the controller with be accessing
+   * @param     type                    The data type of the data Ex: XdmfArrayType::Int32()
+   * @param     start                   A vector of the start indexes for all dimensions of the data
+   * @param     start                   A vector of the start indexes for all dimensions of the data
+   * @param     stride                  A vector of the distance between reads for all dimensions of the data
+   * @param     dimensions              A vector of the number of values read from all dimensions of the data
+   * @param     dataspaceDimensions     A vecotr containing the total size of the dimension in the data space
+   * @param     comm                    The communicator that the DSM buffer will reference
+   * @param     bufferSize              The size of the buffer to be created on the core calling this function
+   * @param     startCoreIndex          The index at which the server cores for the buffer start
+   * @param     endCoreIndex            The index at which the server cores for the buffer end
+   * @param     applicationName         The name in the process description for this process
+   * @return                            A constructed HDF5DSM controller.
+   */
+  static shared_ptr<XdmfHDF5ControllerDSM>
+  New(const std::string & hdf5FilePath,
+      const std::string & dataSetPath,
+      const shared_ptr<const XdmfArrayType> type,
+      const std::vector<unsigned int> & start,
+      const std::vector<unsigned int> & stride,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaceDimensions,
+      MPI_Comm comm,
+      unsigned int bufferSize,
+      int startCoreIndex,
+      int endCoreIndex,
+      std::string applicationName = "Application");
+
+  /**
+   * Create a new controller for an DSM data set.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollerpagedgenerate
+   * @until //#initcontrollerpagedgenerate
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollerpagedgenerate
+   * @until #//initcontrollerpagedgenerate
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     hdf5FilePath            The path to the hdf5 file that the controller will be accessing
+   * @param     dataSetPath             The location within the file of the data the controller with be accessing
+   * @param     type                    The data type of the data Ex: XdmfArrayType::Int32()
+   * @param     start                   A vector of the start indexes for all dimensions of the data
+   * @param     start                   A vector of the start indexes for all dimensions of the data
+   * @param     stride                  A vector of the distance between reads for all dimensions of the data
+   * @param     dimensions              A vector of the number of values read from all dimensions of the data
+   * @param     dataspaceDimensions     A vecotr containing the total size of the dimension in the data space
+   * @param     comm                    The communicator that the DSM buffer will reference
+   * @param     bufferSize              The size of the buffer to be created on the core calling this function
+   * @param     blockSize               The size of the paged in the buffer
+   * @param     resizeFactor            The factor by which the buffer will be resized when pages are added.
+   * @param     startCoreIndex          The index at which the server cores for the buffer start
+   * @param     endCoreIndex            The index at which the server cores for the buffer end
+   * @param     applicationName         The name in the process description for this process
+   * @return                            A constructed HDF5DSM controller.
+   */
+  static shared_ptr<XdmfHDF5ControllerDSM>
+  New(const std::string & hdf5FilePath,
+      const std::string & dataSetPath,
+      const shared_ptr<const XdmfArrayType> type,
+      const std::vector<unsigned int> & start,
+      const std::vector<unsigned int> & stride,
+      const std::vector<unsigned int> & dimensions,
+      const std::vector<unsigned int> & dataspaceDimensions,
+      MPI_Comm comm,
+      unsigned int bufferSize,
+      unsigned int blockSize,
+      double resizeFactor,
+      int startCoreIndex,
+      int endCoreIndex,
+      std::string applicationName = "Application");
+
+  /**
+   * Gets the buffer for the non-threaded version of DSM
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBuffercontroller
+   * @until //#getServerBuffercontroller
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBuffercontroller
+   * @until #//getServerBuffercontroller
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The XdmfDSMBuffer that is controlling the data for the DSM
+   */
+  XdmfDSMBuffer * getServerBuffer();
+
+  /**
+   * Checks if the DSM is in server mode or not.
+   * True is server mode, false is threaded
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getServerModecontroller
+   * @until //#getServerModecontroller
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerModecontroller
+   * @until #//getServerModecontroller
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    If the DSM is in server mode or not
+   */
+  bool getServerMode() const;
+
+  std::string getName() const;
+
+  /**
+   * Gets the Communicator that the workers are using to communicate between themselves
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getWorkerCommcontroller
+   * @until //#getWorkerCommcontroller
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getWorkerCommcontroller
+   * @until #//getWorkerCommcontroller
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The comm that the workers are using.
+   */
+  MPI_Comm getWorkerComm() const;
+
+  /**
+   * Sets the controller's dsmBuffer to the provided buffer
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBuffercontroller
+   * @until //#getServerBuffercontroller
+   * @skipline //#setBuffercontroller
+   * @until //#setBuffercontroller
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBuffercontroller
+   * @until #//getServerBuffercontroller
+   * @skipline #//setBuffercontroller
+   * @until #//setBuffercontroller
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newBuffer       A pointer to the buffer to be set
+   */
+  void setBuffer(XdmfDSMBuffer * newBuffer);
+
+  /**
+   * Used to switch between server and threaded mode.
+   * True is server mode, false is threaded mode.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#setServerModecontroller
+   * @until //#setServerModecontroller
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//setServerModecontroller
+   * @until #//setServerModecontroller
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newMode         The mode that the writer is to be set to.
+   */
+  void setServerMode(bool newMode);
+
+  /**
+   * Sets the comm that the workers will use to communicate
+   * with other worker cores
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getWorkerCommcontroller
+   * @until //#getWorkerCommcontroller
+   * @skipline //#setWorkerCommcontroller
+   * @until //#setWorkerCommcontroller
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getWorkerCommcontroller
+   * @until #//getWorkerCommcontroller
+   * @skipline #//setWorkerCommcontroller
+   * @until #//setWorkerCommcontroller
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     comm    The communicator that the worker will be using to
+   *                    communicate with the other worker cores.
+   */
+  void setWorkerComm(MPI_Comm comm);
+
+  /**
+   * Sends a stop command to all the server cores that the controller is
+   * connected to, ending the DSM.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until //initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void stopDSM();
+
+  void read(XdmfArray * const array);
+
+  /**
+   * Restarts the DSM when called on server cores.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initcontrollergenerate
+   * @until //#initcontrollergenerate
+   * @skipline //#stopDSMcontroller
+   * @until //#stopDSMcontroller
+   * @skipline //#restartDSMcontroller
+   * @until //#restartDSMcontroller
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initcontrollergenerate
+   * @until #//initcontrollergenerate
+   * @skipline #//stopDSMcontroller
+   * @until #//stopDSMcontroller
+   * @skipline #//restartDSMcontroller
+   * @until #//restartDSMcontroller
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void restartDSM();
+
+  XdmfHDF5ControllerDSM(XdmfHDF5ControllerDSM &);
+
+protected:
+
+  XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
+                        const std::string & dataSetPath,
+                        const shared_ptr<const XdmfArrayType> type,
+                        const std::vector<unsigned int> & start,
+                        const std::vector<unsigned int> & stride,
+                        const std::vector<unsigned int> & dimensions,
+                        const std::vector<unsigned int> & dataspaceDimensions,
+                        MPI_Comm comm,
+                        unsigned int bufferSize,
+                        int startCoreIndex,
+                        int endCoreIndex,
+                        std::string applicationName);
+
+  XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
+                        const std::string & dataSetPath,
+                        const shared_ptr<const XdmfArrayType> type,
+                        const std::vector<unsigned int> & start,
+                        const std::vector<unsigned int> & stride,
+                        const std::vector<unsigned int> & dimensions,
+                        const std::vector<unsigned int> & dataspaceDimensions,
+                        MPI_Comm comm,
+                        unsigned int bufferSize,
+                        unsigned int blockSize,
+                        double resizeFactor,
+                        int startCoreIndex,
+                        int endCoreIndex,
+                        std::string applicationName);
+
+  XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
+                        const std::string & dataSetPath,
+                        const shared_ptr<const XdmfArrayType> type,
+                        const std::vector<unsigned int> & start,
+                        const std::vector<unsigned int> & stride,
+                        const std::vector<unsigned int> & dimensions,
+                        const std::vector<unsigned int> & dataspaceDimensions,
+                        XdmfDSMBuffer * const dsmBuffer);
+
+private:
+
+//  XdmfHDF5ControllerDSM(const XdmfHDF5Controller &);  // Not implemented.
+  void operator=(const XdmfHDF5Controller &);  // Not implemented.
+
+  XdmfDSMBuffer * mDSMServerBuffer;
+  MPI_Comm mWorkerComm;
+  bool mServerMode;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFHDF5CONTROLLERDSM; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHDF5CONTROLLERDSM XDMFHDF5CONTROLLERDSM;
+
+XDMFDSM_EXPORT XDMFHDF5CONTROLLERDSM * XdmfHDF5ControllerDSMNewFromServerBuffer(char * hdf5FilePath,
+                                                                                char * dataSetPath,
+                                                                                int type,
+                                                                                unsigned int * start,
+                                                                                unsigned int * stride,
+                                                                                unsigned int * dimensions,
+                                                                                unsigned int * dataspaceDimensions,
+                                                                                unsigned int numDims,
+                                                                                void * dsmBuffer,
+                                                                                int * status);
+
+XDMFDSM_EXPORT XDMFHDF5CONTROLLERDSM * XdmfHDF5ControllerDSMNew(char * hdf5FilePath,
+                                                                char * dataSetPath,
+                                                                int type,
+                                                                unsigned int * start,
+                                                                unsigned int * stride,
+                                                                unsigned int * dimensions,
+                                                                unsigned int * dataspaceDimensions,
+                                                                unsigned int numDims,
+                                                                MPI_Comm comm,
+                                                                unsigned int bufferSize,
+                                                                int startCoreIndex,
+                                                                int endCoreIndex,
+                                                                char * applicationName,
+                                                                int * status);
+
+XDMFDSM_EXPORT XDMFHDF5CONTROLLERDSM * XdmfHDF5ControllerDSMNewPaged(char * hdf5FilePath,
+                                                                     char * dataSetPath,
+                                                                     int type,
+                                                                     unsigned int * start,
+                                                                     unsigned int * stride,
+                                                                     unsigned int * dimensions,
+                                                                     unsigned int * dataspaceDimensions,
+                                                                     unsigned int numDims,
+                                                                     MPI_Comm comm,
+                                                                     unsigned int bufferSize,
+                                                                     unsigned int blockSize,
+                                                                     double resizeFactor,
+                                                                     int startCoreIndex,
+                                                                     int endCoreIndex,
+                                                                     char * applicationName,
+                                                                     int * status);
+
+XDMFDSM_EXPORT XDMFDSMBUFFER * XdmfHDF5ControllerDSMGetServerBuffer(XDMFHDF5CONTROLLERDSM * controller);
+
+XDMFDSM_EXPORT int XdmfHDF5ControllerDSMGetServerMode(XDMFHDF5CONTROLLERDSM * controller);
+
+XDMFDSM_EXPORT MPI_Comm XdmfHDF5ControllerDSMGetWorkerComm(XDMFHDF5CONTROLLERDSM * controller);
+
+XDMFDSM_EXPORT void XdmfHDF5ControllerDSMSetServerBuffer(XDMFHDF5CONTROLLERDSM * controller, XDMFDSMBUFFER * newBuffer);
+
+XDMFDSM_EXPORT void XdmfHDF5ControllerDSMSetServerMode(XDMFHDF5CONTROLLERDSM * controller, int newMode);
+
+XDMFDSM_EXPORT void XdmfHDF5ControllerDSMSetWorkerComm(XDMFHDF5CONTROLLERDSM * controller, MPI_Comm comm, int * status);
+
+XDMFDSM_EXPORT void XdmfHDF5ControllerDSMStopDSM(XDMFHDF5CONTROLLERDSM * controller, int * status);
+
+XDMFDSM_EXPORT void XdmfHDF5ControllerDSMRestartDSM(XDMFHDF5CONTROLLERDSM * controller, int * status);
+
+XDMF_HEAVYCONTROLLER_C_CHILD_DECLARE(XdmfHDF5ControllerDSM, XDMFHDF5CONTROLLERDSM, XDMFDSM)
+XDMF_HDF5CONTROLLER_C_CHILD_DECLARE(XdmfHDF5ControllerDSM, XDMFHDF5CONTROLLERDSM, XDMFDSM)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHDF5CONTROLLER_HPP_ */
diff --git a/core/dsm/XdmfHDF5WriterDSM.cpp b/core/dsm/XdmfHDF5WriterDSM.cpp
new file mode 100644
index 0000000..635fff2
--- /dev/null
+++ b/core/dsm/XdmfHDF5WriterDSM.cpp
@@ -0,0 +1,1235 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5WriterDSM.cpp                                               */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <hdf5.h>
+#include <XdmfArray.hpp>
+#include <XdmfDSMCommMPI.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMDriver.hpp>
+#include "XdmfHDF5ControllerDSM.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfError.hpp"
+#include <string.h>
+#include <iostream>
+
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSMImpl::XdmfHDF5WriterDSMImpl():
+  XdmfHDF5WriterImpl(),
+  mDSMIsInit(false),
+  mDSMLocked(false)
+{
+};
+
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSMImpl::~XdmfHDF5WriterDSMImpl()
+{
+  closeFile();
+};
+
+int
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSMImpl::openFile(const std::string & filePath,
+                                             const int mDataSetId)
+{
+  if(mHDF5Handle >= 0) {
+    // Perhaps we should throw a warning.
+    closeFile();
+  }
+  // Save old error handler and turn off error handling for now
+  H5E_auto_t old_func;
+  void * old_client_data;
+  H5Eget_auto(0, &old_func, &old_client_data);
+  H5Eset_auto2(0, NULL, NULL);
+
+  int toReturn = 0;
+
+  mOpenFile.assign(filePath);
+
+  std::vector<unsigned int> pages;
+  haddr_t start, end;
+  unsigned int numPages;
+
+  if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetComm()->GetId() == 0 && !mDSMLocked)
+  {
+    ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->Lock(strdup(filePath.c_str()));
+    mDSMLocked = true;
+  }
+
+
+//  if (mDSMIsInit) {//  if(XdmfDsmFileInDSM(filePath.c_str()) > 0) {
+  if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->RequestFileDescription(strdup(filePath.c_str()),
+                                                                               pages,
+                                                                               numPages,
+                                                                               start,
+                                                                               end)
+      == XDMF_DSM_SUCCESS)
+  {
+    mHDF5Handle = H5Fopen(filePath.c_str(),
+                          H5F_ACC_RDWR,
+                          mFapl);
+    if(mDataSetId == 0) {
+      hsize_t numObjects;
+      /*herr_t status = */H5Gget_num_objs(mHDF5Handle,
+                                          &numObjects);
+      toReturn = numObjects;
+    }
+    else {
+      toReturn = mDataSetId;
+    }
+  }
+  else {
+    mHDF5Handle = H5Fcreate(filePath.c_str(),
+                            H5F_ACC_TRUNC,
+                            H5P_DEFAULT,
+                            mFapl);
+    mDSMIsInit = true;
+  }
+
+  // Restore previous error handler
+  H5Eset_auto2(0, old_func, old_client_data);
+
+  return toReturn;
+};
+
+void
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSMImpl::closeFile()
+{
+  if(mHDF5Handle >= 0) {
+    H5Fclose(mHDF5Handle);
+    mHDF5Handle = -1;
+  }
+
+  if (mDSMLocked)
+  {
+    if (((XdmfDSMBuffer *)xdmf_dsm_get_manager())->GetComm()->GetId() == 0)
+    {
+      ((XdmfDSMBuffer *)xdmf_dsm_get_manager())->Unlock(strdup(mOpenFile.c_str()));
+      mDSMLocked = false;
+    }
+  }
+  mOpenFile = "";
+};
+
+shared_ptr<XdmfHDF5WriterDSM>
+XdmfHDF5WriterDSM::New(const std::string & filePath,
+                       XdmfDSMBuffer * const dsmBuffer)
+{
+  shared_ptr<XdmfHDF5WriterDSM> p(new XdmfHDF5WriterDSM(filePath,
+                                                        dsmBuffer));
+  return p;
+}
+
+shared_ptr<XdmfHDF5WriterDSM>
+XdmfHDF5WriterDSM::New(const std::string & filePath,
+                       MPI_Comm comm,
+                       unsigned int bufferSize,
+                       int startCoreIndex,
+                       int endCoreIndex,
+                       std::string applicationName)
+{
+  shared_ptr<XdmfHDF5WriterDSM> p(new XdmfHDF5WriterDSM(filePath,
+                                                        comm,
+                                                        bufferSize,
+                                                        startCoreIndex,
+                                                        endCoreIndex,
+                                                        applicationName));
+  return p;
+}
+
+shared_ptr<XdmfHDF5WriterDSM>
+XdmfHDF5WriterDSM::New(const std::string & filePath,
+                       MPI_Comm comm,
+                       unsigned int bufferSize,
+                       unsigned int blockSize,
+                       double resizeFactor,
+                       int startCoreIndex,
+                       int endCoreIndex,
+                       std::string applicationName)
+{
+  shared_ptr<XdmfHDF5WriterDSM> p(new XdmfHDF5WriterDSM(filePath,
+                                                        comm,
+                                                        bufferSize,
+                                                        blockSize,
+                                                        resizeFactor,
+                                                        startCoreIndex,
+                                                        endCoreIndex,
+                                                        applicationName));
+  return p;
+}
+
+shared_ptr<XdmfHDF5WriterDSM>
+XdmfHDF5WriterDSM::New(const std::string & filePath,
+                       MPI_Comm comm,
+                       std::string applicationName)
+{
+  shared_ptr<XdmfHDF5WriterDSM> p(new XdmfHDF5WriterDSM(filePath,
+                                                        comm,
+                                                        applicationName));
+  return p;
+}
+
+// The database/nonthreaded version
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSM(const std::string & filePath,
+                                     XdmfDSMBuffer * const dsmBuffer) :
+  XdmfHDF5Writer(filePath),
+  mDSMServerBuffer(dsmBuffer),
+  mServerMode(true),
+  mNotifyOnWrite(true)
+{
+  if (mImpl)
+  {
+    delete mImpl;
+  }
+  mImpl = new XdmfHDF5WriterDSMImpl();
+
+  mImpl->mFapl = -1;
+  mWorkerComm = mDSMServerBuffer->GetComm()->GetIntraComm();
+  if (xdmf_dsm_get_manager() == NULL) {
+    XDMF_dsm_set_manager(mDSMServerBuffer);
+  }
+  else {
+    xdmf_dsm_set_manager(mDSMServerBuffer);
+  }
+}
+
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSM(const std::string & filePath,
+                                     MPI_Comm comm,
+                                     unsigned int bufferSize,
+                                     int startCoreIndex,
+                                     int endCoreIndex,
+                                     std::string applicationName) :
+  XdmfHDF5Writer(filePath),
+  mServerMode(true)
+{
+  int rank, size;
+
+#ifdef XDMF_DSM_IS_CRAY
+
+  MPI_Comm InterComm = comm;
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    assert(coreTag);
+    coreSplit.clear();
+    ++splitid;
+  }
+
+  // Use MPI_Comm_split
+  MPI_Group IntraGroup, InterGroup;
+  MPI_Comm IntraComm;
+  MPI_Comm_group(comm, &InterGroup);
+  MPI_Group_incl(InterGroup, splitsize, splitIds, &IntraGroup);
+  MPI_Comm_create(comm, IntraGroup, &IntraComm);
+  cfree(splitIds);
+
+  int intraid = 0;
+  int intrasize = 0;
+
+  MPI_Comm_rank(IntraComm, &intraid);
+  MPI_Comm_size(IntraComm, &intrasize);
+
+  comm = IntraComm;
+#endif
+
+  if (mImpl)
+  {
+    delete mImpl;
+  }
+  mImpl = new XdmfHDF5WriterDSMImpl();
+
+  mImpl->mFapl = -1;
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  // Negative values will be changed to maximum range
+  if (startCoreIndex < 0) {
+    startCoreIndex = 0;
+  }
+  if (endCoreIndex < 0) {
+    endCoreIndex = size - 1;
+  }
+
+  // Ensure start index is less than end index
+  if (startCoreIndex > endCoreIndex) {
+    int tempholder = startCoreIndex;
+    startCoreIndex = endCoreIndex;
+    endCoreIndex = tempholder;
+  }
+
+  MPI_Comm serverComm;
+
+  MPI_Group workers, dsmgroup, serversplit, servergroup;
+
+  int * ServerIds = (int *)calloc((endCoreIndex - startCoreIndex + 1), sizeof(int));
+  unsigned int index = 0;
+  for(int i=startCoreIndex ; i <= endCoreIndex ; ++i) {
+    ServerIds[index++] = i;
+  }
+
+  MPI_Comm_group(comm, &serversplit);
+  MPI_Group_incl(serversplit, index, ServerIds, &servergroup);
+  MPI_Comm_create(comm, servergroup, &serverComm);
+  MPI_Comm_group(comm, &dsmgroup);
+  MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+  MPI_Comm_create(comm, workers, &mWorkerComm);
+  cfree(ServerIds);
+
+  // Create the manager
+  mDSMServerBuffer = new XdmfDSMBuffer();
+  mDSMServerBuffer->SetLocalBufferSizeMBytes(bufferSize);
+  mDSMServerBuffer->SetInterCommType(XDMF_DSM_COMM_MPI);
+  mDSMServerBuffer->SetDsmType(XDMF_DSM_TYPE_UNIFORM);
+  MPI_Barrier(comm);
+
+  if (rank >= startCoreIndex && rank <= endCoreIndex) {
+    mDSMServerBuffer->Create(serverComm);
+  }
+  else {
+    mDSMServerBuffer->Create(mWorkerComm, startCoreIndex, endCoreIndex);
+    mDSMServerBuffer->SetIsServer(false);
+  }
+
+  XDMF_dsm_set_manager(mDSMServerBuffer);
+
+#ifdef XDMF_DSM_IS_CRAY
+  mDSMServerBuffer->GetComm()->DupInterComm(InterComm);
+#else
+  mDSMServerBuffer->GetComm()->DupInterComm(comm);
+#endif
+  if (rank >= startCoreIndex && rank <= endCoreIndex)
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName("Server");
+  }
+  else
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName(applicationName);
+  }
+  mDSMServerBuffer->SetIsConnected(true);
+
+  if (startCoreIndex < size) {
+    if (rank >= startCoreIndex && rank <= endCoreIndex) {
+      mDSMServerBuffer->ReceiveInfo();
+    }
+    else {
+      mDSMServerBuffer->SendInfo();
+    }
+  }
+
+  MPI_Barrier(comm);
+
+  // Loop needs to be started before anything can be done to the file
+  // since the service is what sets up the file
+  if (rank < startCoreIndex || rank > endCoreIndex) {
+    // Turn off the server designation
+    mDSMServerBuffer->SetIsServer(false);
+    // If this is set to false then the buffer will attempt to connect
+    // to the intercomm for DSM communications
+  }
+  else {
+    // On cores where memory is set up, start the service loop
+    // This should iterate infinitely until a value to end the loop is passed
+    int returnOpCode;
+    try {
+      mDSMServerBuffer->BufferServiceLoop(&returnOpCode);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSM(const std::string & filePath,
+                                     MPI_Comm comm,
+                                     unsigned int bufferSize,
+                                     unsigned int blockSize,
+                                     double resizeFactor,
+                                     int startCoreIndex,
+                                     int endCoreIndex,
+                                     std::string applicationName) :
+  XdmfHDF5Writer(filePath),
+  mServerMode(true)
+{
+  int rank, size;
+
+#ifdef XDMF_DSM_IS_CRAY
+
+  MPI_Comm InterComm = comm;
+
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  MPI_Comm_rank(comm, &rank);
+  MPI_Comm_size(comm, &size);
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    assert(coreTag);
+    coreSplit.clear();
+    ++splitid;
+  }
+
+  // Use MPI_Comm_split
+  MPI_Group IntraGroup, InterGroup;
+  MPI_Comm IntraComm;
+  MPI_Comm_group(comm, &InterGroup);
+  MPI_Group_incl(InterGroup, splitsize, splitIds, &IntraGroup);
+  MPI_Comm_create(comm, IntraGroup, &IntraComm);
+  cfree(splitIds);
+
+  int intraid = 0;
+  int intrasize = 0;
+
+  MPI_Comm_rank(IntraComm, &intraid);
+  MPI_Comm_size(IntraComm, &intrasize);
+
+  comm = IntraComm;
+#endif
+
+  if (mImpl)
+  {
+    delete mImpl;
+  }
+  mImpl = new XdmfHDF5WriterDSMImpl();
+
+  mImpl->mFapl = -1;
+
+// Cray Specific stuff has to occur here
+
+  MPI_Comm_size(comm, &size);
+  MPI_Comm_rank(comm, &rank);
+
+  // Negative values will be changed to maximum range
+  if (startCoreIndex < 0) {
+    startCoreIndex = 0;
+  }
+  if (endCoreIndex < 0) {
+    endCoreIndex = size - 1;
+  }
+
+  // Ensure start index is less than end index
+  if (startCoreIndex > endCoreIndex) {
+    int tempholder = startCoreIndex;
+    startCoreIndex = endCoreIndex;
+    endCoreIndex = tempholder;
+  }
+
+  MPI_Comm serverComm;
+
+  MPI_Group workers, dsmgroup, serversplit, servergroup;
+
+  int * ServerIds = (int *)calloc((endCoreIndex - startCoreIndex + 1), sizeof(int));
+  unsigned int index = 0;
+  for(int i=startCoreIndex ; i <= endCoreIndex ; ++i) {
+    ServerIds[index++] = i;
+  }
+
+  MPI_Comm_group(comm, &serversplit);
+  MPI_Group_incl(serversplit, index, ServerIds, &servergroup);
+  MPI_Comm_create(comm, servergroup, &serverComm);
+  MPI_Comm_group(comm, &dsmgroup);
+  MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+  MPI_Comm_create(comm, workers, &mWorkerComm);
+  cfree(ServerIds);
+
+  // Create the manager
+  mDSMServerBuffer = new XdmfDSMBuffer();
+  mDSMServerBuffer->SetLocalBufferSizeMBytes(bufferSize);
+  mDSMServerBuffer->SetInterCommType(XDMF_DSM_COMM_MPI);
+  mDSMServerBuffer->SetBlockLength(blockSize);
+  mDSMServerBuffer->SetDsmType(XDMF_DSM_TYPE_BLOCK_CYCLIC);
+  mDSMServerBuffer->SetResizeFactor(resizeFactor);
+  MPI_Barrier(comm);
+
+  if (rank >= startCoreIndex && rank <= endCoreIndex) {
+    mDSMServerBuffer->Create(serverComm);
+  }
+  else {
+    mDSMServerBuffer->Create(mWorkerComm, startCoreIndex, endCoreIndex);
+    mDSMServerBuffer->SetIsServer(false);
+  }
+
+  XDMF_dsm_set_manager(mDSMServerBuffer);
+
+#ifdef XDMF_DSM_IS_CRAY
+  mDSMServerBuffer->GetComm()->DupInterComm(InterComm);
+#else
+  mDSMServerBuffer->GetComm()->DupInterComm(comm);
+#endif
+  if (rank >= startCoreIndex && rank <= endCoreIndex)
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName("Server");
+  }
+  else
+  {
+    mDSMServerBuffer->GetComm()->SetApplicationName(applicationName);
+  }
+  mDSMServerBuffer->SetIsConnected(true);
+
+  if (startCoreIndex < size) {
+    if (rank >= startCoreIndex && rank <= endCoreIndex) {
+      mDSMServerBuffer->ReceiveInfo();
+    }
+    else {
+      mDSMServerBuffer->SendInfo();
+    }
+  }
+
+  MPI_Barrier(comm);
+
+  // Loop needs to be started before anything can be done to the file
+  // since the service is what sets up the file
+  if (rank < startCoreIndex || rank > endCoreIndex) {
+    // Turn off the server designation
+    mDSMServerBuffer->SetIsServer(false);
+    // If this is set to false then the buffer will attempt to connect
+    // to the intercomm for DSM communications
+  }
+  else {
+    // On cores where memory is set up, start the service loop
+    // This should iterate infinitely until a value to end the loop is passed
+    int returnOpCode;
+    try {
+      mDSMServerBuffer->BufferServiceLoop(&returnOpCode);
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSM(const std::string & filePath,
+                                     MPI_Comm comm,
+                                     std::string applicationName) :
+  XdmfHDF5Writer(filePath),
+  mServerMode(true),
+  mNotifyOnWrite(true)
+{
+  int rank, size;
+
+#ifdef XDMF_DSM_IS_CRAY
+
+  MPI_Comm InterComm = comm;
+
+  // Cray needs to be launched via the colon notation so that it
+  // can properly create a merged communicator
+
+  MPI_Comm_rank(comm, &rank);
+  MPI_Comm_size(comm, &size);
+
+  int currentCore = 0;
+  int * checkstatus = new int[size]();
+  int localCheck = 0;
+
+  char * coreTag;
+  int tagSize = 0;
+
+  std::vector<int> coreSplit;
+  unsigned int splitid = 0;
+
+  int * splitIds;
+  unsigned int splitsize = 0;
+
+  while (currentCore < size)
+  {
+    if (rank == currentCore)
+    {
+      tagSize = applicationName.size();
+    }
+    MPI_Bcast(&tagSize, 1, MPI_INT, currentCore, comm);
+    coreTag = new char[tagSize+1]();
+
+    if (rank == currentCore)
+    {
+      strcpy(coreTag, applicationName.c_str());
+    }
+    MPI_Bcast(coreTag, tagSize, MPI_CHAR, currentCore, comm);
+
+    coreTag[tagSize] = 0;
+
+    if (strcmp(coreTag, applicationName.c_str()) == 0)
+    {
+      localCheck = 1;
+    }
+    else
+    {
+      localCheck = 0;
+    }
+
+    checkstatus[rank] = localCheck;
+
+    MPI_Allgather(&localCheck, 1, MPI_INT,
+                  checkstatus, 1, MPI_INT,
+                  comm);
+
+    bool insplit = false;
+    while (checkstatus[currentCore])
+    {
+      if (rank == currentCore)
+      {
+        insplit = true;
+      }
+      coreSplit.push_back(currentCore);
+      ++currentCore;
+      if (currentCore >= size)
+      {
+        break;
+      }
+    }
+    if (insplit)
+    {
+      splitIds = (int *)calloc(coreSplit.size(), sizeof(int));
+      memcpy(splitIds, &(coreSplit[0]), coreSplit.size() * sizeof(int));
+      splitsize = coreSplit.size();
+    }
+    assert(coreTag);
+    coreSplit.clear();
+    ++splitid;
+  }
+
+  // Use MPI_Comm_split
+  MPI_Group IntraGroup, InterGroup;
+  MPI_Comm IntraComm;
+  MPI_Comm_group(comm, &InterGroup);
+  MPI_Group_incl(InterGroup, splitsize, splitIds, &IntraGroup);
+  MPI_Comm_create(comm, IntraGroup, &IntraComm);
+  cfree(splitIds);
+
+  int intraid = 0;
+  int intrasize = 0;
+
+  MPI_Comm_rank(IntraComm, &intraid);
+  MPI_Comm_size(IntraComm, &intrasize);
+
+  comm = IntraComm;
+#endif
+
+  if (mImpl)
+  {
+    delete mImpl;
+  }
+  mImpl = new XdmfHDF5WriterDSMImpl();
+
+  mImpl->mFapl = -1;
+
+  // Retrieve the Buffer
+  mDSMServerBuffer = new XdmfDSMBuffer();
+  mDSMServerBuffer->SetIsServer(false);
+  mDSMServerBuffer->SetInterCommType(XDMF_DSM_COMM_MPI);
+
+  // Create a Comm object
+  XdmfDSMCommMPI * newComm = new XdmfDSMCommMPI();
+  newComm->DupComm(comm);
+#ifdef XDMF_DSM_IS_CRAY
+  newComm->DupInterComm(InterComm);
+#else
+  newComm->DupInterComm(comm);
+#endif
+  newComm->Init();
+  newComm->SetApplicationName(applicationName);
+
+  // Set the Comm to the buffer
+  mDSMServerBuffer->SetComm(newComm);
+
+  // Register the manager with the driver
+  XDMF_dsm_set_manager(mDSMServerBuffer);
+
+#ifdef XDMF_DSM_IS_CRAY
+  mDSMServerBuffer->ReceiveInfo();
+#endif
+
+  MPI_Barrier(comm);
+}
+
+XdmfHDF5WriterDSM::XdmfHDF5WriterDSM(XdmfHDF5WriterDSM & refWriter):
+  XdmfHDF5Writer(refWriter),
+  mDSMServerBuffer(refWriter.getServerBuffer()),
+  mWorkerComm(refWriter.getWorkerComm()),
+  mServerMode(refWriter.getServerMode()),
+  mNotifyOnWrite(refWriter.mNotifyOnWrite)
+{
+  mImpl->mFapl = -1;
+}
+
+XdmfHDF5WriterDSM::~XdmfHDF5WriterDSM()
+{
+  
+}
+
+shared_ptr<XdmfHeavyDataController>
+XdmfHDF5WriterDSM::createController(const std::string & hdf5FilePath,
+                                    const std::string & dataSetPath,
+                                    const shared_ptr<const XdmfArrayType> type,
+                                    const std::vector<unsigned int> & start,
+                                    const std::vector<unsigned int> & stride,
+                                    const std::vector<unsigned int> & dimensions,
+                                    const std::vector<unsigned int> & dataspaceDimensions)
+{
+  if (mDSMServerBuffer != NULL) {
+        return XdmfHDF5ControllerDSM::New(hdf5FilePath,
+                                      dataSetPath,
+                                      type,
+                                      start,
+                                      stride,
+                                      dimensions,
+                                      dataspaceDimensions,
+                                      mDSMServerBuffer);
+  }
+  else {
+    return shared_ptr<XdmfHDF5ControllerDSM>();
+  }
+}
+
+void
+XdmfHDF5WriterDSM::closeFile()
+{
+  if(mImpl->mFapl >= 0) {
+    H5Pclose(mImpl->mFapl);
+    mImpl->mFapl = -1;
+  }
+  XdmfHDF5Writer::closeFile();
+}
+
+int
+XdmfHDF5WriterDSM::getDataSetSize(const std::string & fileName, const std::string & dataSetName)
+{
+  bool closeFAPL = false;
+
+  if(mImpl->mFapl < 0) {
+    // Set file access property list for DSM
+    mImpl->mFapl = H5Pcreate(H5P_FILE_ACCESS);
+    // Use DSM driver
+    if (mWorkerComm != MPI_COMM_NULL) {
+      XDMFH5Pset_fapl_dsm(mImpl->mFapl, mWorkerComm, mDSMServerBuffer, 0);
+    }
+
+    closeFAPL = true;
+  }
+
+  hid_t handle = -1;
+  H5E_auto_t old_func;
+  void * old_client_data;
+  herr_t status;
+  H5Eget_auto(0, &old_func, &old_client_data);
+  H5Eset_auto2(0, NULL, NULL);
+  bool mustClose = false;
+  if (XdmfSystemUtils::getRealPath(fileName) != mImpl->mOpenFile) {
+    // Save old error handler and turn off error handling for now
+      handle = H5Fopen(fileName.c_str(),
+                       H5F_ACC_RDWR,
+                       mImpl->mFapl);
+    mustClose = true;
+  }
+  else {
+    handle = mImpl->mHDF5Handle;
+  }
+
+  // Restore previous error handler
+  H5Eset_auto2(0, old_func, old_client_data);
+
+  if (!H5Lexists(handle,
+                 dataSetName.c_str(),
+                 H5P_DEFAULT))
+  {
+    if (handle != mImpl->mHDF5Handle) {
+      H5Fclose(handle);
+    }
+
+    if(closeFAPL) {
+      // Close file access property list
+      H5Pclose(mImpl->mFapl);
+      mImpl->mFapl = -1;
+    }
+
+     return 0;
+  }
+
+  hid_t checkset = H5Dopen(handle,
+                           dataSetName.c_str(),
+                           H5P_DEFAULT);
+
+  hid_t checkspace = H5S_ALL;
+  checkspace = H5Dget_space(checkset);
+  hssize_t checksize = H5Sget_simple_extent_npoints(checkspace);
+
+  if(checkspace != H5S_ALL) {
+    status = H5Sclose(checkspace);
+  }
+  status = H5Dclose(checkset);
+
+  if (handle != mImpl->mHDF5Handle || mustClose) {
+    H5Fclose(handle);
+  }
+
+  if(closeFAPL) {
+    // Close file access property list
+    H5Pclose(mImpl->mFapl);
+    mImpl->mFapl = -1;
+  }
+
+  return checksize;
+}
+
+bool
+XdmfHDF5WriterDSM::getNotifyOnWrite()
+{
+  return mNotifyOnWrite;
+}
+
+XdmfDSMBuffer * XdmfHDF5WriterDSM::getServerBuffer()
+{
+  return mDSMServerBuffer;
+}
+
+bool XdmfHDF5WriterDSM::getServerMode()
+{
+  return mServerMode;
+}
+
+MPI_Comm XdmfHDF5WriterDSM::getWorkerComm()
+{
+  MPI_Comm returnComm = MPI_COMM_NULL;
+  if (mWorkerComm != MPI_COMM_NULL) {
+    MPI_Comm_dup(mWorkerComm, &returnComm);
+  }
+  return returnComm;
+}
+
+void XdmfHDF5WriterDSM::setAllowSetSplitting(bool newAllow)
+{
+  //overrides to disable the parent version
+  XdmfHDF5Writer::setAllowSetSplitting(false); 
+}
+
+void XdmfHDF5WriterDSM::setBuffer(XdmfDSMBuffer * newBuffer)
+{
+  mDSMServerBuffer = newBuffer;
+}
+
+void XdmfHDF5WriterDSM::setNotifyOnWrite(bool status)
+{
+  mNotifyOnWrite = status;
+}
+
+void XdmfHDF5WriterDSM::setServerMode(bool newMode)
+{
+  mServerMode = newMode;
+}
+
+void XdmfHDF5WriterDSM::setWorkerComm(MPI_Comm comm)
+{
+  int status;
+#ifndef OPEN_MPI
+  if (mWorkerComm != MPI_COMM_NULL) {
+    status = MPI_Comm_free(&mWorkerComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to disconnect Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+#endif
+  if (comm != MPI_COMM_NULL) {
+    status = MPI_Comm_dup(comm, &mWorkerComm);
+    if (status != MPI_SUCCESS) {
+      try {
+        XdmfError::message(XdmfError::FATAL, "Failed to duplicate Comm");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  mDSMServerBuffer->GetComm()->DupComm(comm);
+}
+
+void XdmfHDF5WriterDSM::stopDSM()
+{
+  if (mServerMode) {
+    // Send manually
+    for (int i = mDSMServerBuffer->GetStartServerId();
+         i <= mDSMServerBuffer->GetEndServerId();
+         ++i) {
+      try {
+        mDSMServerBuffer->SendCommandHeader(XDMF_DSM_OPCODE_DONE, i, 0, 0, XDMF_DSM_INTER_COMM);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Stopping DSM manually only available in server mode.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void XdmfHDF5WriterDSM::restartDSM()
+{
+  if (mServerMode) {
+    if (mDSMServerBuffer->GetComm()->GetInterId() >=
+          mDSMServerBuffer->GetStartServerId() &&
+        mDSMServerBuffer->GetComm()->GetInterId() <=
+          mDSMServerBuffer->GetEndServerId()) {
+      int returnOpCode;
+      try {
+        mDSMServerBuffer->BufferServiceLoop(&returnOpCode);
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Restarting DSM only available in server mode.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void 
+XdmfHDF5WriterDSM::openFile()
+{
+  if(mImpl->mFapl >= 0) {
+    this->closeFile();
+  }
+
+  // Set file access property list for DSM
+  mImpl->mFapl = H5Pcreate(H5P_FILE_ACCESS);
+
+  if (mWorkerComm != MPI_COMM_NULL) {
+    XDMFH5Pset_fapl_dsm(mImpl->mFapl, mWorkerComm, mDSMServerBuffer, 0);
+  }
+  XdmfHDF5Writer::openFile();
+}
+
+void XdmfHDF5WriterDSM::visit(XdmfArray & array,
+                              const shared_ptr<XdmfBaseVisitor>)
+{
+  bool closeFAPL = false;
+
+  if(mImpl->mFapl < 0) {
+    // Set file access property list for DSM
+    mImpl->mFapl = H5Pcreate(H5P_FILE_ACCESS);
+    // Use DSM driver
+    if (mWorkerComm != MPI_COMM_NULL) {
+      XDMFH5Pset_fapl_dsm(mImpl->mFapl, mWorkerComm, mDSMServerBuffer, 0);
+    }
+
+    closeFAPL = true;
+  }
+
+  // Write to DSM Buffer
+  this->write(array);
+
+  if(closeFAPL) {
+    // Close file access property list
+    H5Pclose(mImpl->mFapl);
+    mImpl->mFapl = -1;
+  }
+
+  if (mNotifyOnWrite)
+  {
+    for (unsigned int i = 0; i < array.getNumberHeavyDataControllers(); ++i)
+    {
+      if (array.getHeavyDataController(i)->getName().compare("HDFDSM") == 0)
+      {
+        this->waitRelease(array.getHeavyDataController(i)->getFilePath(),
+                          shared_dynamic_cast<XdmfHDF5ControllerDSM>(array.getHeavyDataController(i))->getDataSetPath());
+      }
+    }
+  }
+}
+
+void
+XdmfHDF5WriterDSM::waitRelease(std::string fileName, std::string datasetName, int code)
+{
+  mDSMServerBuffer->WaitRelease(fileName, datasetName, code);
+}
+
+int
+XdmfHDF5WriterDSM::waitOn(std::string fileName, std::string datasetName)
+{
+  return mDSMServerBuffer->WaitOn(fileName, datasetName);
+}
+
+// C Wrappers
+
+XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNewFromServerBuffer(char * filePath,
+                                                         void * dsmBuffer,
+                                                         int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfHDF5WriterDSM> createdWriter = XdmfHDF5WriterDSM::New(std::string(filePath), (XdmfDSMBuffer *)dsmBuffer);
+  return (XDMFHDF5WRITERDSM *)((void *)(new XdmfHDF5WriterDSM(* createdWriter.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNew(char * filePath,
+                                         MPI_Comm comm,
+                                         unsigned int bufferSize,
+                                         int startCoreIndex,
+                                         int endCoreIndex,
+                                         char * applicationName,
+                                         int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfHDF5WriterDSM> createdWriter = XdmfHDF5WriterDSM::New(std::string(filePath), comm, bufferSize, startCoreIndex, endCoreIndex, std::string(applicationName));
+  return (XDMFHDF5WRITERDSM *)((void *)(new XdmfHDF5WriterDSM(*createdWriter.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNewPaged(char * filePath,
+                                              MPI_Comm comm,
+                                              unsigned int bufferSize,
+                                              unsigned int blockSize,
+                                              double resizeFactor,
+                                              int startCoreIndex,
+                                              int endCoreIndex,
+                                              char * applicationName,
+                                              int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfHDF5WriterDSM> createdWriter = XdmfHDF5WriterDSM::New(std::string(filePath), comm, bufferSize, blockSize, resizeFactor, startCoreIndex, endCoreIndex, std::string(applicationName));
+  return (XDMFHDF5WRITERDSM *)((void *)(new XdmfHDF5WriterDSM(*createdWriter.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+XDMFHDF5WRITERDSM *
+XdmfHDF5WriterDSMNewConnectRequired(char * filePath,
+                                    MPI_Comm comm,
+                                    char * applicationName,
+                                    int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfHDF5WriterDSM> createdWriter = XdmfHDF5WriterDSM::New(std::string(filePath), comm, std::string(applicationName));
+  return (XDMFHDF5WRITERDSM *)((void *)(new XdmfHDF5WriterDSM(*createdWriter.get())));
+  XDMF_ERROR_WRAP_END(status)
+  return NULL;
+}
+
+int XdmfHDF5WriterDSMGetDataSetSize(XDMFHDF5WRITERDSM * writer, char * fileName, char * dataSetName)
+{
+  return ((XdmfHDF5WriterDSM *) writer)->getDataSetSize(std::string(fileName), std::string(dataSetName));
+}
+
+XDMFDSMBUFFER * XdmfHDF5WriterDSMGetServerBuffer(XDMFHDF5WRITERDSM * writer)
+{
+  return (XDMFDSMBUFFER *)((void *)(((XdmfHDF5WriterDSM *) writer)->getServerBuffer()));
+}
+
+int XdmfHDF5WriterDSMGetServerMode(XDMFHDF5WRITERDSM * writer)
+{
+  return ((XdmfHDF5WriterDSM *) writer)->getServerMode();
+}
+
+MPI_Comm XdmfHDF5WriterDSMGetWorkerComm(XDMFHDF5WRITERDSM * writer)
+{
+  return ((XdmfHDF5WriterDSM *) writer)->getWorkerComm();
+}
+
+void XdmfHDF5WriterDSMSetServerBuffer(XDMFHDF5WRITERDSM * writer, XDMFDSMBUFFER * newBuffer)
+{
+  ((XdmfHDF5WriterDSM *) writer)->setBuffer((XdmfDSMBuffer *)newBuffer);
+}
+
+void XdmfHDF5WriterDSMSetServerMode(XDMFHDF5WRITERDSM * writer, int newMode)
+{
+  ((XdmfHDF5WriterDSM *) writer)->setServerMode(newMode);
+}
+
+void XdmfHDF5WriterDSMSetWorkerComm(XDMFHDF5WRITERDSM * writer, MPI_Comm comm, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5WriterDSM *) writer)->setWorkerComm(comm);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHDF5WriterDSMStopDSM(XDMFHDF5WRITERDSM * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5WriterDSM *) writer)->stopDSM();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHDF5WriterDSMRestartDSM(XDMFHDF5WRITERDSM * writer, int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  ((XdmfHDF5WriterDSM *) writer)->restartDSM();
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void XdmfHDF5WriterDSMWaitRelease(XDMFHDF5WRITERDSM * writer, char * fileName, char * datasetName, int code)
+{
+  ((XdmfHDF5WriterDSM *) writer)->waitRelease(std::string(fileName), std::string(datasetName), code);
+}
+
+int XdmfHDF5WriterDSMWaitOn(XDMFHDF5WRITERDSM * writer, char * fileName, char * datasetName)
+{
+  return ((XdmfHDF5WriterDSM *) writer)->waitOn(std::string(fileName), std::string(datasetName));
+}
+
+XDMF_HDF5WRITER_C_CHILD_WRAPPER(XdmfHDF5WriterDSM, XDMFHDF5WRITERDSM)
+XDMF_HEAVYWRITER_C_CHILD_WRAPPER(XdmfHDF5WriterDSM, XDMFHDF5WRITERDSM)
diff --git a/core/dsm/XdmfHDF5WriterDSM.hpp b/core/dsm/XdmfHDF5WriterDSM.hpp
new file mode 100644
index 0000000..e6ccb13
--- /dev/null
+++ b/core/dsm/XdmfHDF5WriterDSM.hpp
@@ -0,0 +1,923 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfHDF5WriterDSM.hpp                                               */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFHDF5WRITERDSM_HPP_
+#define XDMFHDF5WRITERDSM_HPP_
+
+// C Compatible Includes
+#include <XdmfHDF5Writer.hpp> 
+#include <XdmfDSMBuffer.hpp> 
+#include <XdmfDSMCommMPI.hpp>
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfDSMBuffer;
+
+// Includes
+
+/**
+ * @brief Traverse the Xdmf graph and write heavy data stored in
+ * XdmfArrays to a DSM buffer.
+ *
+ * XdmfHDF5WriterDSM traverses an Xdmf graph structure and writes data
+ * stored in XdmfArrays to a DSM buffer. Writing begins by calling the
+ * accept() operation on any XdmfItem and supplying this writer as the
+ * parameter. The writer will write all XdmfArrays under the XdmfItem
+ * to a DSM Buffer. It will also attach an XdmfHDF5ControllerDSM to
+ * all XdmfArrays.
+ *
+ * This writer supports all heavy data writing modes listed in
+ * XdmfHeavyDataWriter.
+ */
+class XDMFDSM_EXPORT XdmfHDF5WriterDSM : public XdmfHDF5Writer {
+
+public:
+
+  friend class XdmfDSMBuffer;
+
+  /**
+   * Contruct XdmfHDF5WriterDSM, nonthreaded version
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#initwriterwithbuffer
+   * @until //#initwriterwithbuffer
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//initwriterwithbuffer
+   * @until #//initwriterwithbuffer
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     filePath        The location of the hdf5 file to output to on disk.
+   * @param     dsmBuffer       The Buffer to write to.
+   * @return                    A New XdmfHDF5WriterDSM
+   */
+  static shared_ptr<XdmfHDF5WriterDSM>
+  New(const std::string & filePath,
+      XdmfDSMBuffer * const dsmBuffer);
+
+  /**
+   * Contruct XdmfHDF5WriterDSM, nonthreaded version
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     filePath        The location of the hdf5 file to output to on disk.
+   * @param     comm            The communicator that the buffer will be created in.
+   * @param     bufferSize      The size of the created buffer.
+   * @param     startCoreIndex  The index of the first core in the server block
+   * @param     endCoreIndex    The index of the last core in the server block
+   * @param     applicationName The name in the process description for this process
+   * @return                    A New XdmfHDF5WriterDSM
+   */
+  static shared_ptr<XdmfHDF5WriterDSM>
+  New(const std::string & filePath,
+      MPI_Comm comm,
+      unsigned int bufferSize,
+      int startCoreIndex,
+      int endCoreIndex,
+      std::string applicationName = "Application");
+
+  /**
+   * Contruct XdmfHDF5WriterDSM, nonthreaded version
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwriterpagedgenerate
+   * @until //#initwriterpagedgenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwriterpagedgenerate
+   * @until #//initwriterpagedgenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     filePath        The location of the hdf5 file to output to on disk.
+   * @param     comm            The communicator that the buffer will be created in.
+   * @param     bufferSize      The size of the created buffer.
+   * @param     blockSize       The size of the pages in the buffer.
+   * @param     resizeFactor    The size of by which the buffer gets resized when
+   *                            requesting beyond the size.
+   * @param     startCoreIndex  The index of the first core in the server block
+   * @param     endCoreIndex    The index of the last core in the server block
+   * @param     applicationName The name in the process description for this process
+   * @return                    A New XdmfHDF5WriterDSM
+   */
+  static shared_ptr<XdmfHDF5WriterDSM>
+  New(const std::string & filePath,
+      MPI_Comm comm,
+      unsigned int bufferSize,
+      unsigned int blockSize,
+      double resizeFactor,
+      int startCoreIndex,
+      int endCoreIndex,
+      std::string applicationName = "Application");
+
+  /**
+   * Contruct XdmfHDF5WriterDSM, nonthreaded version. Does not start up a buffer
+   * and must be connected to a DSMBuffer to function.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest2.cpp
+   * @skipline //#initDSMWriterConnectRequired
+   * @until //#initDSMWriterConnectRequired 
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest2.py
+   * @skipline #//initDSMWriterConnectRequired
+   * @until #//initDSMWriterConnectRequired
+   *
+   * @param     filePath        The location of the hdf5 file to output to on disk.
+   * @param     comm            The local communicator.
+   */
+  static shared_ptr<XdmfHDF5WriterDSM>
+  New(const std::string & filePath,
+      MPI_Comm comm,
+      std::string applicationName = "Application");
+
+  virtual ~XdmfHDF5WriterDSM();
+
+  void closeFile();
+
+  /**
+   * Gets the number of values contained in the specified dataset.
+   *
+   * @param     fileName        The filename of the dataset to get the size of.
+   * @param     dataSetName     The dataset name of the dataset to get the size of.
+   * @return                    The size of the dataset queried.
+   */
+  virtual int getDataSetSize(const std::string & fileName, const std::string & dataSetName);
+
+  /**
+   * Get if each write to dsm will send a notification to the accociated file name.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getNotifyOnWrite
+   * @until //#getNotifyOnWrite
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getNotifyOnWrite
+   * @until #//getNotifyOnWrite
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    Whether a notification will be sent
+   */
+  bool getNotifyOnWrite();
+
+  /**
+   * Gets the buffer for the non-threaded version of DSM
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The XdmfDSMBuffer that is controlling the data for the DSM
+   */
+  XdmfDSMBuffer * getServerBuffer();
+
+  /**
+   * Checks if the DSM is in server mode or not.
+   * True is server mode, false is threaded
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getServerModewriter
+   * @until //#getServerModewriter
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerModewriter
+   * @until #//getServerModewriter
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    If the DSM is in server mode or not
+   */
+  bool getServerMode();
+
+  /**
+   * Gets the Communicator that the workers are using to communicate between themselves
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getWorkerCommwriter
+   * @until //#getWorkerCommwriter
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getWorkerCommwriter
+   * @until #//getWorkerCommwriter
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @return    The comm that the workers are using.
+   */
+  MPI_Comm getWorkerComm();
+
+  /**
+   * Sets whether to allow the HDF5 writer to split data sets when writing to hdf5.
+   * Splitting should only occur for massive data sets.
+   * Setting to false assures compatibility with previous editions.
+   * Default setting is false
+   * In DSM this function has no effect because splitting would prevent the algorithm from working
+   *
+   * @param     newAllow        Whether to allow data sets to be split across hdf5 files.
+   */
+  void setAllowSetSplitting(bool newAllow);
+
+  /**
+   * Sets the Writer's dsmBuffer to the provided buffer
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#declarebuffer
+   * @until //#declarebuffer
+   * @skipline //#getServerBufferwriter
+   * @until //#getServerBufferwriter
+   * @skipline //#setBufferwriter
+   * @until //#setBufferwriter
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getServerBufferwriter
+   * @until #//getServerBufferwriter
+   * @skipline #//setBufferwriter
+   * @until #//setBufferwriter
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newBuffer       A pointer to the buffer to be set
+   */
+  void setBuffer(XdmfDSMBuffer * newBuffer);
+
+  /**
+   * Used to switch between server and threaded mode.
+   * True is server mode, false is threaded mode.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#setServerModewriter
+   * @until //#setServerModewriter
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//setServerModewriter
+   * @until #//setServerModewriter
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     newMode         The mode that the writer is to be set to.
+   */
+  void setServerMode(bool newMode);
+
+  /**
+   * If true each write to dsm will send a notification to the accociated file name.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#setNotifyOnWrite
+   * @until //#setNotifyOnWrite
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//setNotifyOnWrite
+   * @until #//setNotifyOnWrite
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     status          Whether to send a notification
+   */
+  void setNotifyOnWrite(bool status);
+
+  /**
+   * Sets the comm that the workers will use to communicate with other worker cores
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#startworksection
+   * @until //#startworksection
+   * @skipline //#getWorkerCommwriter
+   * @until //#getWorkerCommwriter
+   * @skipline //#setWorkerCommwriter
+   * @until //#setWorkerCommwriter
+   * @skipline //#endworksection
+   * @until //#endworksection
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//startworksection
+   * @until #//startworksection
+   * @skipline #//getWorkerCommwriter
+   * @until #//getWorkerCommwriter
+   * @skipline #//setWorkerCommwriter
+   * @until #//setWorkerCommwriter
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   *
+   * @param     comm    The communicator that the worker will be using to communicate with the other worker cores.
+   */
+  void setWorkerComm(MPI_Comm comm);
+
+  /**
+   * Sends a stop command to all the server cores that the writer is connected to, ending the DSM.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void stopDSM();
+
+  /**
+   * Restarts the DSM when called on server cores.
+   * 
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude ExampleXdmfDSMNoThread.cpp
+   * @skipline //#initMPI
+   * @until //#initMPI
+   * @skipline //#initwritevector
+   * @until //#initwritevector
+   * @skipline //#initwritergenerate
+   * @until //#initwritergenerate
+   * @skipline //#stopDSMwriter
+   * @until //#stopDSMwriter
+   * @skipline //#finalizeMPI
+   * @until //#finalizeMPI
+   * @skipline //#restartDSMwriter
+   * @until //#restartDSMwriter
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleDSMNoThread.py
+   * @skipline #//initMPI
+   * @until #//initMPI
+   * @skipline #//initwritevector
+   * @until #//initwritevector
+   * @skipline #//initwritergenerate
+   * @until #//initwritergenerate
+   * @skipline #//stopDSMwriter
+   * @until #//stopDSMwriter
+   * @skipline #//restartDSMwriter
+   * @until #//restartDSMwriter
+   * @skipline #//finalizeMPI
+   * @until #//finalizeMPI
+   */
+  void restartDSM();
+
+  void openFile();
+
+  using XdmfHeavyDataWriter::visit;
+  void visit(XdmfArray & array,
+             const shared_ptr<XdmfBaseVisitor> visitor);
+
+  /**
+   * Releases all processes waiting on a specified dataset. Sends those processes a specified code.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest2.cpp
+   * @skipline //#initDSMWriterConnectRequired
+   * @until //#initDSMWriterConnectRequired
+   * @skipline //#notify
+   * @until //#notify
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest2.py
+   * @skipline #//initDSMWriterConnectRequired
+   * @until #//initDSMWriterConnectRequired
+   * @skipline #//notify
+   * @until #//notify
+   *
+   * @param     fileName        The filename of the dataset to wait on.
+   * @param     datasetName     The dataset name of the dataset to wait on.
+   * @param     code            The code to be transmitted to waiting processes.
+   */
+  void waitRelease(std::string fileName, std::string datasetName, int code = 0);
+
+  /**
+   * Blocks until released by the a waitRelease on the corresponding dataset.
+   *
+   * Example of use:
+   *
+   * C++
+   *
+   * @dontinclude XdmfConnectTest2.cpp
+   * @skipline //#initDSMWriterConnectRequired
+   * @until //#initDSMWriterConnectRequired
+   * @skipline //#notify
+   * @until //#notify
+   *
+   * Python
+   *
+   * @dontinclude XdmfExampleConnectTest2.py
+   * @skipline #//initDSMWriterConnectRequired
+   * @until #//initDSMWriterConnectRequired
+   * @skipline #//notify
+   * @until #//notify
+   *
+   * @param     fileName        The filename of the dataset to wait on.
+   * @param     datasetName     The dataset name of the dataset to wait on.
+   * @return                    The code send from the release.
+   */
+  int waitOn(std::string fileName, std::string datasetName);
+
+  XdmfHDF5WriterDSM(XdmfHDF5WriterDSM &);
+
+protected:
+
+  XdmfHDF5WriterDSM(const std::string & filePath,
+                    XdmfDSMBuffer * const dsmBuffer);
+
+  XdmfHDF5WriterDSM(const std::string & filePath,
+                    MPI_Comm comm,
+                    unsigned int bufferSize,
+                    int startCoreIndex,
+                    int endCoreIndex,
+                    std::string applicationName);
+
+  XdmfHDF5WriterDSM(const std::string & filePath,
+                    MPI_Comm comm,
+                    unsigned int bufferSize,
+                    unsigned int blockSize,
+                    double resizeFactor,
+                    int startCoreIndex,
+                    int endCoreIndex,
+                    std::string applicationName);
+
+  XdmfHDF5WriterDSM(const std::string & filePath,
+                    MPI_Comm comm,
+                    std::string applicationName);
+
+  virtual shared_ptr<XdmfHeavyDataController>
+  createController(const std::string & hdf5FilePath,
+                       const std::string & descriptor,
+                       const shared_ptr<const XdmfArrayType> type,
+                       const std::vector<unsigned int> & start,
+                       const std::vector<unsigned int> & stride,
+                       const std::vector<unsigned int> & dimensions,
+                       const std::vector<unsigned int> & dataspaceDimensions);
+
+  /**
+   * PIMPL
+   */
+  class XdmfHDF5WriterDSMImpl : public XdmfHDF5WriterImpl
+  {
+  public:
+
+    XdmfHDF5WriterDSMImpl();
+
+    virtual ~XdmfHDF5WriterDSMImpl();
+
+    virtual int
+    openFile(const std::string & filePath,
+             const int mDataSetId);
+
+    void
+    closeFile();
+
+    bool mDSMIsInit;
+    bool mDSMLocked;
+  };
+
+private:
+
+  XdmfHDF5WriterDSM(const XdmfHDF5WriterDSM &);  // Not implemented.
+  void operator=(const XdmfHDF5WriterDSM &);  // Not implemented.
+
+  XdmfDSMBuffer * mDSMServerBuffer;
+  MPI_Comm mWorkerComm;
+  bool mServerMode;
+  bool mNotifyOnWrite;
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFHDF5WRITERDSM; // Simply as a typedef to ensure correct typing
+typedef struct XDMFHDF5WRITERDSM XDMFHDF5WRITERDSM;
+
+XDMFDSM_EXPORT XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNewFromServerBuffer(char * filePath,
+                                                                        void * dsmBuffer,
+                                                                        int * status);
+
+XDMFDSM_EXPORT XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNew(char * filePath,
+                                                        MPI_Comm comm,
+                                                        unsigned int bufferSize,
+                                                        int startCoreIndex,
+                                                        int endCoreIndex,
+                                                        char * applicationName,
+                                                        int * status);
+
+XDMFDSM_EXPORT XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNewPaged(char * filePath,
+                                                             MPI_Comm comm,
+                                                             unsigned int bufferSize,
+                                                             unsigned int blockSize,
+                                                             double resizeFactor,
+                                                             int startCoreIndex,
+                                                             int endCoreIndex,
+                                                             char * applicationName,
+                                                             int * status);
+
+XDMFDSM_EXPORT XDMFHDF5WRITERDSM * XdmfHDF5WriterDSMNewConnectRequired(char * filePath,
+                                                                       MPI_Comm comm,
+                                                                       char * applicationName,
+                                                                       int * status);
+
+XDMFDSM_EXPORT int XdmfHDF5WriterDSMGetDataSetSize(XDMFHDF5WRITERDSM * writer, char * fileName, char * dataSetName);
+
+XDMFDSM_EXPORT XDMFDSMBUFFER * XdmfHDF5WriterDSMGetServerBuffer(XDMFHDF5WRITERDSM * writer);
+
+XDMFDSM_EXPORT int XdmfHDF5WriterDSMGetServerMode(XDMFHDF5WRITERDSM * writer);
+
+XDMFDSM_EXPORT MPI_Comm XdmfHDF5WriterDSMGetWorkerComm(XDMFHDF5WRITERDSM * writer);
+
+XDMFDSM_EXPORT void XdmfHDF5WriterDSMSetServerBuffer(XDMFHDF5WRITERDSM * writer, XDMFDSMBUFFER * newBuffer);
+
+XDMFDSM_EXPORT void XdmfHDF5WriterDSMSetServerMode(XDMFHDF5WRITERDSM * writer, int newMode);
+
+XDMFDSM_EXPORT void XdmfHDF5WriterDSMSetWorkerComm(XDMFHDF5WRITERDSM * writer, MPI_Comm comm, int * status);
+
+XDMFDSM_EXPORT void XdmfHDF5WriterDSMStopDSM(XDMFHDF5WRITERDSM * writer, int * status);
+
+XDMFDSM_EXPORT void XdmfHDF5WriterDSMRestartDSM(XDMFHDF5WRITERDSM * writer, int * status);
+
+XDMFDSM_EXPORT void XdmfHDF5WriterDSMWaitRelease(XDMFHDF5WRITERDSM * writer, char * fileName, char * datasetName, int code);
+
+XDMFDSM_EXPORT int XdmfHDF5WriterDSMWaitOn(XDMFHDF5WRITERDSM * writer, char * fileName, char * datasetName);
+
+XDMF_HDF5WRITER_C_CHILD_DECLARE(XdmfHDF5WriterDSM, XDMFHDF5WRITERDSM, XDMFDSM)
+XDMF_HEAVYWRITER_C_CHILD_DECLARE(XdmfHDF5WriterDSM, XDMFHDF5WRITERDSM, XDMFDSM)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFHDF5WRITERDSM_HPP_ */
diff --git a/core/dsm/tests/C/CConnectTest.sh b/core/dsm/tests/C/CConnectTest.sh
new file mode 100755
index 0000000..163f7d9
--- /dev/null
+++ b/core/dsm/tests/C/CConnectTest.sh
@@ -0,0 +1,7 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+$MPIEXEC -n 2 ./CXdmfAcceptTest &
+
+$MPIEXEC -n 2 ./CXdmfConnectTest &
+
+$MPIEXEC -n 2 ./CXdmfConnectTest2
diff --git a/core/dsm/tests/C/CDSMLoopTest.c b/core/dsm/tests/C/CDSMLoopTest.c
new file mode 100644
index 0000000..6315835
--- /dev/null
+++ b/core/dsm/tests/C/CDSMLoopTest.c
@@ -0,0 +1,310 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+	int xdmfStatus = 0;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        // Change this to determine the number of cores used as servers
+        int numServersCores = 2;
+        // Change this to determine the size of the arrays generated when initializing
+        int writeArraySize = 4;
+
+        void *  testArray = XdmfArrayNew();
+        XdmfArrayInitialize(testArray, &writeArraySize, 1,  XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+
+        char * newPath = "dsm";
+        char * newSetPath = "data";
+
+        unsigned int writeStartVector[1];
+        unsigned int writeStrideVector[1];
+        unsigned int writeCountVector[1];
+        unsigned int writeDataSizeVector[1];
+
+        unsigned int readStartVector[1];
+        unsigned int readStrideVector[1];
+        unsigned int readCountVector[1];
+        unsigned int readDataSizeVector[1];
+
+        unsigned int readOutputCountVector[1];
+
+        void * readArray = XdmfArrayNew();
+        XdmfArrayInitialize(readArray, &writeArraySize, 1,  XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+
+        XDMFHDF5CONTROLLERDSM * readController;
+        XDMFHDF5CONTROLLERDSM * readOutputController;
+        XDMFHDF5CONTROLLERDSM * writeController;
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+	int i;
+        for(i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        XDMFHDF5WRITERDSM * exampleWriter = XdmfHDF5WriterDSMNew(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1, "Application", &xdmfStatus);
+
+        XdmfHDF5WriterDSMSetMode(exampleWriter, XDMF_HEAVY_WRITER_MODE_HYPERSLAB, &xdmfStatus);
+
+        //split out sub-comm for the worker cores
+        //server cores will not progress to this point until after the servers are done running
+        if (id < size - numServersCores)
+        {
+                // Split the comm even further
+
+                MPI_Comm readComm, writeComm;
+
+                MPI_Group readingCores, writingCores;
+
+                MPI_Comm_group(workerComm, &workers);
+                int * ServerIds = (int *)calloc(((size - numServersCores) / 2), sizeof(int));
+                unsigned int index = 0;
+                for(i=0 ; i < (int)((size - numServersCores) / 2) ; ++i)
+                {
+                        ServerIds[index++] = i;
+                }
+
+                MPI_Group_excl(workers, index, ServerIds, &readingCores);
+                testval = MPI_Comm_create(workerComm, readingCores, &readComm);
+                MPI_Group_incl(workers, index, ServerIds, &writingCores);
+                testval = MPI_Comm_create(workerComm, writingCores, &writeComm);
+                cfree(ServerIds);
+
+                printf("initializing\n");
+
+                // Initialize values
+                // Writer is first
+                if (id < (int)((size - numServersCores) / 2))
+                {
+                        unsigned int j;
+                        for (j = 1; j <= writeArraySize; ++j)
+                        {
+                                int value = j*(id+1);
+                                XdmfArrayInsertValue(testArray, j-1, &value, XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+                        }
+                        writeStartVector[0] = id*writeArraySize;
+                        writeStrideVector[0] = 1;
+                        writeCountVector[0] = writeArraySize;
+                        writeDataSizeVector[0] = writeArraySize*(int)((size-numServersCores) / 2);
+                        writeController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                                newPath,
+                                newSetPath,
+                                XDMF_ARRAY_TYPE_INT32,
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+				1,
+                                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+                                &xdmfStatus);
+
+                        XdmfArrayInsertHeavyDataController(testArray, (XDMFHEAVYDATACONTROLLER *)writeController, 0);
+
+                        readStartVector[0] = 0;
+                        readStrideVector[0] = 1;
+                        readCountVector[0] = 0;
+                        readDataSizeVector[0] = writeArraySize*(int)((size-numServersCores) / 2);
+
+                        readController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                                newPath,
+                                newSetPath,
+                                XDMF_ARRAY_TYPE_INT32,
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+				1,
+                                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+				&xdmfStatus);
+                        XdmfArrayInsertHeavyDataController(readArray, (XDMFHEAVYDATACONTROLLER *)readController, 0);
+
+                        for (j = 0; j<size-numServersCores; ++j)
+                        {
+                                MPI_Barrier(writeComm);
+                                if (j == id)
+                                {
+                                        unsigned int k;
+                                        for(k=0; k< XdmfArrayGetSize(testArray); ++k)
+                                        {
+						int value = ((int *)XdmfArrayGetValue(testArray, k,  XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0];
+						printf("core # %d testArray[%d] = %d\n", id, k, value);
+                                        }
+                                }
+                        }
+                }
+                else
+                {
+                        // Reader is second
+                        readStartVector[0] = 0;
+                        readStrideVector[0] = 1;
+                        readCountVector[0] = writeArraySize*(int)((size-numServersCores) / 2);
+                        readDataSizeVector[0] = writeArraySize*(int)((size-numServersCores) / 2);
+
+                        readController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                                newPath,
+                                newSetPath,
+                                XDMF_ARRAY_TYPE_INT32,
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+				1,
+                                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+				&xdmfStatus);
+
+                        XdmfArrayInsertHeavyDataController(readArray, (XDMFHEAVYDATACONTROLLER *)readController, 0);
+
+                        readOutputCountVector[0] = 0;
+
+                        readOutputController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                                newPath,
+                                newSetPath,
+                                XDMF_ARRAY_TYPE_INT32,
+                                readStartVector,
+                                readStrideVector,
+                                readOutputCountVector,
+                                readDataSizeVector,
+				1,
+                                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+				&xdmfStatus);
+
+                        writeStartVector[0] = 0;
+                        writeStrideVector[0] = 1;
+                        writeCountVector[0] = 0;
+                        writeDataSizeVector[0] = writeArraySize*(int)((size-numServersCores) / 2);
+                        writeController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                                newPath,
+                                newSetPath,
+                                XDMF_ARRAY_TYPE_INT32,
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                1,
+                                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+				&xdmfStatus);
+
+                        XdmfArrayInsertHeavyDataController(testArray, (XDMFHEAVYDATACONTROLLER *)writeController, 0);
+                }
+
+                XdmfArrayAccept(testArray, (XDMFVISITOR *)exampleWriter, &xdmfStatus);
+
+                MPI_Barrier(workerComm);
+
+		unsigned int iteration;
+                // This is the loop that manipulates the data
+                for (iteration = 0; iteration < 10; ++iteration)
+                {
+                        printf("loop iteration %d on core %d\n", iteration, id);
+
+                        // Read in to the first set of cores
+                        if (id >= (int)((size - numServersCores) / 2))
+                        {
+                                // Controllers are accessed like this since the writer removes them and creates its own.
+				XdmfHDF5ControllerDSMSetWorkerComm((XDMFHDF5CONTROLLERDSM *)XdmfArrayGetHeavyDataController(readArray, 0), readComm, &xdmfStatus);
+                                printf("read on core %d\n", id);
+                                XdmfArrayRead(readArray, &xdmfStatus);
+                                MPI_Barrier(readComm);
+
+                                if (id == (int)((size - numServersCores) / 2))
+                                {
+					unsigned int j;
+                                        for(j=0; j<XdmfArrayGetSize(readArray); ++j)
+                                        {
+                                                int tempVal = ((int *)XdmfArrayGetValue(readArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0];
+                                                tempVal = tempVal * 2;
+                                                XdmfArrayInsertValue(readArray, j, &tempVal, XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+                                                // Pull the value from the array in order to ensure the change has happened
+                                                printf("core #%d readArray[%d] = %d\n", id, j, ((int *)XdmfArrayGetValue(readArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0]);
+                                        }
+                                }
+                        }
+                        XdmfHDF5ControllerDSMSetWorkerComm((XDMFHDF5CONTROLLERDSM *)XdmfArrayGetHeavyDataController(readArray, 0), workerComm, &xdmfStatus);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data
+                                XdmfArrayRemoveHeavyDataController(readArray, 0);
+				XdmfArrayInsertHeavyDataController(readArray, (XDMFHEAVYDATACONTROLLER *)readOutputController, 0);
+                        }
+
+                        XdmfArrayAccept(readArray, (XDMFVISITOR *)exampleWriter, &xdmfStatus);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data
+                                XdmfArrayRemoveHeavyDataController(readArray, 0);
+                                XdmfArrayInsertHeavyDataController(readArray, (XDMFHEAVYDATACONTROLLER *)readController, 0);
+                        }
+
+                        MPI_Barrier(workerComm);
+
+                        printf("on writing cores\n");
+
+                        if (id < (int)((size - numServersCores) / 2))
+                        {
+                                XdmfHDF5ControllerDSMSetWorkerComm((XDMFHDF5CONTROLLERDSM *)XdmfArrayGetHeavyDataController(testArray, 0), writeComm, &xdmfStatus);
+                                XdmfArrayRead(testArray, &xdmfStatus);
+                                MPI_Barrier(writeComm);
+				unsigned int i;
+                                for (i = 0; i<size; ++i)
+                                {
+                                        MPI_Barrier(writeComm);
+                                        if (i == id)
+                                        {
+                                                unsigned int j;
+                                                for(j=0; j<XdmfArrayGetSize(testArray); ++j)
+                                                {
+                                                        int tempVal = ((int *)XdmfArrayGetValue(testArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0];
+                                                        tempVal = tempVal * 3;
+                                                        XdmfArrayInsertValue(testArray, j, &tempVal, XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+                                                        // Pull the value from the array in order to ensure the change has happened
+                                                        printf("core #%d testArray[%d] = %d\n", id, j, ((int *)XdmfArrayGetValue(testArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0]);
+                                                }
+                                        }
+                                }
+                        }
+                        XdmfHDF5ControllerDSMSetWorkerComm(writeController, workerComm, &xdmfStatus);
+                        XdmfArrayAccept(testArray, (XDMFVISITOR *)exampleWriter, &xdmfStatus);
+                }
+        }
+
+        if (id == 0)
+        {
+                XdmfHDF5WriterDSMStopDSM(exampleWriter, &xdmfStatus);
+        }
+
+        MPI_Barrier(comm);
+
+        //the dsmManager must be deleted or else there will be a segfault
+//        XdmfHDF5WriterDSMDeleteManager(exampleWriter);
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/core/dsm/tests/C/CDSMLoopTest.sh b/core/dsm/tests/C/CDSMLoopTest.sh
new file mode 100755
index 0000000..e3d335c
--- /dev/null
+++ b/core/dsm/tests/C/CDSMLoopTest.sh
@@ -0,0 +1 @@
+$MPIEXEC -n 4 ./CDSMLoopTest
diff --git a/core/dsm/tests/C/CMakeLists.txt b/core/dsm/tests/C/CMakeLists.txt
new file mode 100644
index 0000000..77b4333
--- /dev/null
+++ b/core/dsm/tests/C/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Include our test macros
+include(AddTestsC)
+
+# Add any dependencies that the cxx core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_C_DEPENDENCIES("XdmfCore")
+ADD_TEST_C_DEPENDENCIES("XdmfDSM")
+
+# Add any ldpath directories that the cxx tests may need
+ADD_TEST_C_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directoreis that the Cxx tests may need
+ADD_TEST_C_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_PATH("${XDMF_BINARIES}")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_CXX(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    ADD_MPI_TEST_C(CDSMLoopTest.sh CDSMLoopTest)
+    ADD_MPI_TEST_C(CConnectTest.sh CXdmfAcceptTest,CXdmfConnectTest2,CXdmfConnectTest)
+  endif(MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_CXX(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if(XDMF_BUILD_DSM_THREADS)
+    CLEAN_TEST_C(CConnectTest.sh dsmconnect.cfg)
+  endif(XDMF_BUILD_DSM_THREADS)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
diff --git a/core/dsm/tests/C/CXdmfAcceptTest.c b/core/dsm/tests/C/CXdmfAcceptTest.c
new file mode 100644
index 0000000..1110da8
--- /dev/null
+++ b/core/dsm/tests/C/CXdmfAcceptTest.c
@@ -0,0 +1,56 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+
+
+int main(int argc, char *argv[])
+{
+/* This test does not work properly with openmpi*/
+/* due to an issue with the openmpi code*/
+#ifndef OPEN_MPI
+        int size, id, dsmSize;
+	int xdmfStatus = 0;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        char * newPath = "dsm";
+        int numServersCores = size - 1;
+        int numConnections = 2;
+
+
+        XDMFHDF5WRITERDSM * exampleWriter = XdmfHDF5WriterDSMNew(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1, "Accept", &xdmfStatus);
+
+        if (id == 0)
+        {
+                XdmfDSMCommMPIOpenPort(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter)), &xdmfStatus);
+
+                XdmfDSMBufferSendAccept(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter), numConnections);
+
+                MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+        }
+
+        MPI_Barrier(XdmfDSMCommMPIGetInterComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+
+	if (id == 0)
+	{
+	        XdmfDSMCommMPIClosePort(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter)), &xdmfStatus);
+	}
+
+        MPI_Finalize();
+#else
+
+        printf("Interprogram DSM does not work properly with OpenMPI\n");
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/C/CXdmfConnectTest.c b/core/dsm/tests/C/CXdmfConnectTest.c
new file mode 100644
index 0000000..0405805
--- /dev/null
+++ b/core/dsm/tests/C/CXdmfConnectTest.c
@@ -0,0 +1,234 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+/* This test does not work properly with openmpi*/
+/* due to an issue with the openmpi code*/
+#ifndef OPEN_MPI
+        /* initMPI begin */
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+	int xdmfStatus = 0;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+
+        char * newPath = "dsm";
+        char * newSetPath = "Data";
+
+        /* Initializing objects */
+
+        void * testComm = XdmfDSMCommMPINew();
+        XdmfDSMCommMPIDupComm(testComm, comm, &xdmfStatus);
+        XdmfDSMCommMPIInit(testComm, &xdmfStatus);
+        void * testBuffer = XdmfDSMBufferNew();
+        XdmfDSMBufferSetIsServer(testBuffer, 0);
+        XdmfDSMBufferSetComm(testBuffer, testComm);
+        XdmfDSMBufferSetIsConnected(testBuffer, 1);
+
+        XDMFHDF5WRITERDSM * exampleWriter = XdmfHDF5WriterDSMNewFromServerBuffer(newPath, testBuffer, &xdmfStatus);
+
+        #ifdef  _WIN32
+                Sleep(500)
+        #else
+                sleep(5);
+        #endif	
+
+        char * checkFileName = XdmfDSMCommMPIGetDsmFileName(testComm);
+
+	FILE * checkFile = fopen(checkFileName, "r");
+
+	while (checkFile == NULL) {
+		printf("file not found\n");
+		#ifdef  _WIN32
+                        Sleep(500);
+                #else
+                        sleep(5);
+                #endif
+	}
+
+	printf("done check\n");
+
+	fclose(checkFile);
+
+        XdmfDSMCommMPIReadDsmPortName(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter)));
+
+        char * portName = XdmfDSMCommMPIGetDsmPortName(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter)));
+
+        XdmfDSMCommMPISetDsmPortName(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter)), portName);
+
+        XdmfDSMBufferConnect(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter), 0, &xdmfStatus);
+
+        MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+
+        void * writeArray = XdmfArrayNew();
+
+	/* Iterators */
+
+	int i = 0;
+	unsigned int j = 0;
+
+        for (i = 1; i <= 5; ++i)
+        {
+		int value = i*(id+1);
+                XdmfArrayPushBack(writeArray, &value, XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+        }
+
+        unsigned int writeStartVector[1];
+        unsigned int writeStrideVector[1];
+        unsigned int writeCountVector[1];
+        unsigned int writeDataSizeVector[1];
+
+        writeStartVector[0] = id*5;
+        writeStrideVector[0] = 1;
+        writeCountVector[0] = 5;
+        writeDataSizeVector[0] = 5*size;
+
+        XDMFHDF5CONTROLLERDSM * writeController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                newPath,
+                newSetPath,
+                XDMF_ARRAY_TYPE_INT32,
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+		1,
+                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+		&xdmfStatus);
+
+        unsigned int readStartVector[1];
+        unsigned int readStrideVector[1];
+        unsigned int readCountVector[1];
+        unsigned int readDataSizeVector[1];
+
+        readStartVector[0] = 5*id;
+        readStrideVector[0] = 1;
+        readCountVector[0] = 5;
+        readDataSizeVector[0] = 5*size;
+
+        XDMFHDF5CONTROLLERDSM * readController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                newPath,
+                newSetPath,
+                XDMF_ARRAY_TYPE_INT32,
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                1,
+                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+                &xdmfStatus);
+
+        XdmfHDF5WriterDSMSetMode(exampleWriter, XDMF_HEAVY_WRITER_MODE_HYPERSLAB, &xdmfStatus);
+
+        /* Done initializing */
+
+        for (i = 0; i < size; ++i)
+        {
+                MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+                if (i == id)
+                {
+                        printf("Array on core %d contains:\n", XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+                        for (j = 0; j < XdmfArrayGetSize(writeArray); ++j)
+                        {
+                                printf("[%d] = %d\n", j, ((int *)XdmfArrayGetValue(writeArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0]);
+                        }
+                }
+        }
+	unsigned int numloops = 0;
+        for (numloops = 0; numloops < 4; ++numloops)
+        {
+
+                if (XdmfArrayGetNumberHeavyDataControllers(writeArray) > 0)
+                {
+                        XdmfArrayRemoveHeavyDataController(writeArray, 0);
+                }
+                XdmfArrayInsertHeavyDataController(writeArray, (XDMFHEAVYDATACONTROLLER *)writeController, 0);
+
+                if (id == size - 1)
+                {
+                        printf("\n\n");
+                }
+                XdmfArrayAccept(writeArray, (XDMFVISITOR *)exampleWriter, &xdmfStatus);
+
+                if (id == size - 1)
+                {
+                        int sentData = 1;
+                        XdmfDSMBufferSendAcknowledgment(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+                                                        XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))) + 1,
+                                                        sentData,
+                                                        XDMF_DSM_EXCHANGE_TAG,
+                                                        XDMF_DSM_INTER_COMM,
+                                                        &xdmfStatus);
+			XdmfDSMBufferReceiveAcknowledgment(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+                                                           XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))) + 1,
+                                                           &sentData,
+                                                           XDMF_DSM_EXCHANGE_TAG,
+                                                           XDMF_DSM_INTER_COMM,
+                                                           &xdmfStatus);
+                }
+
+                MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+
+                XdmfArrayRemoveHeavyDataController(writeArray, 0);
+                XdmfArrayInsertHeavyDataController(writeArray, (XDMFHEAVYDATACONTROLLER *)readController, 0);
+                XdmfArrayRelease(writeArray);
+                XdmfArrayRead(writeArray, &xdmfStatus);
+
+                for (i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+                        if (i == id)
+                        {
+                                printf("Array on core %d contains:\n", XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+                                for (j = 0; j < XdmfArrayGetSize(writeArray); ++j)
+                                {
+                                        int tempVal = ((int *)XdmfArrayGetValue(writeArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0];
+                                        tempVal = tempVal * 2;
+                                        XdmfArrayInsertValue(writeArray, j, &tempVal, XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+                                        printf("[%d] = %d\n", j, ((int *)XdmfArrayGetValue(writeArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0]);
+                                }
+                        }
+                }
+        }
+
+        if (id == size - 1)
+        {
+                int sentData = 1;
+                XdmfDSMBufferSendAcknowledgment(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+                                                XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))) + 1,
+                                                sentData,
+                                                XDMF_DSM_EXCHANGE_TAG,
+                                                XDMF_DSM_INTER_COMM,
+                                                &xdmfStatus);
+        }
+
+        MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+
+        MPI_Barrier(XdmfDSMCommMPIGetInterComm(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+
+        XdmfDSMBufferDisconnect(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter), &xdmfStatus);
+
+        XdmfDSMCommMPIDisconnect(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter)), &xdmfStatus);
+
+        MPI_Finalize();
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/C/CXdmfConnectTest2.c b/core/dsm/tests/C/CXdmfConnectTest2.c
new file mode 100644
index 0000000..f910a6e
--- /dev/null
+++ b/core/dsm/tests/C/CXdmfConnectTest2.c
@@ -0,0 +1,229 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+/* This test does not work properly with openmpi*/
+/* due to an issue with the openmpi code*/
+#ifndef OPEN_MPI
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+	int xdmfStatus = 0;
+
+	/* Iterators */
+
+	int i = 0;
+	unsigned int j = 0;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        char * newPath = "dsm";
+        char * newSetPath = "Data";
+
+        /* Initializing objects */
+
+        /* 
+         * Since the start and end ids are larger than the size there are no buffers alloted
+         * thus, no blockage occurs
+         */
+        void * testComm = XdmfDSMCommMPINew();
+        XdmfDSMCommMPIDupComm(testComm, comm, &xdmfStatus);
+        XdmfDSMCommMPIInit(testComm, &xdmfStatus);
+        void * testBuffer = XdmfDSMBufferNew();
+        XdmfDSMBufferSetIsServer(testBuffer, 0);
+        XdmfDSMBufferSetComm(testBuffer, testComm);
+        XdmfDSMBufferSetIsConnected(testBuffer, 1);
+
+        unsigned int readStartVector[1];
+        unsigned int readStrideVector[1];
+        unsigned int readCountVector[1];
+        unsigned int readDataSizeVector[1];
+
+        readStartVector[0] = 5*id;
+        readStrideVector[0] = 1;
+        readCountVector[0] = 5;
+        readDataSizeVector[0] = 5*size;
+
+        void * readArray = XdmfArrayNew();
+
+	int arraySize[1] = {5};
+
+	XdmfArrayInitialize(readArray, arraySize, 1,  XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+
+        XDMFHDF5CONTROLLERDSM * readController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                newPath,
+                newSetPath,
+                XDMF_ARRAY_TYPE_INT32,
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+		1,
+                testBuffer,
+		&xdmfStatus);
+
+        #ifdef  _WIN32
+                Sleep(1000)
+        #else
+                sleep(10);
+        #endif
+
+        char * checkFileName = XdmfDSMCommMPIGetDsmFileName(testComm);
+
+        FILE * checkFile = fopen(checkFileName, "r");
+
+        while (checkFile == NULL) {
+		printf("file not found\n");
+                #ifdef  _WIN32
+                        Sleep(500)
+                #else
+                        sleep(5);
+                #endif
+        }
+
+	printf("done check\n");
+
+	fclose(checkFile);
+
+        XdmfDSMCommMPIReadDsmPortName(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController)));
+
+        XdmfDSMBufferConnect(XdmfHDF5ControllerDSMGetServerBuffer(readController), 0, &xdmfStatus);
+
+        XDMFHDF5WRITERDSM * exampleWriter = XdmfHDF5WriterDSMNewFromServerBuffer(newPath, testBuffer, &xdmfStatus);
+
+        unsigned int writeStartVector[1];
+        unsigned int writeStrideVector[1];
+        unsigned int writeCountVector[1];
+        unsigned int writeDataSizeVector[1];
+
+        writeStartVector[0] = id*5;
+        writeStrideVector[0] = 1;
+        writeCountVector[0] = 5;
+        writeDataSizeVector[0] = 5*size;
+
+        XDMFHDF5CONTROLLERDSM * writeController = XdmfHDF5ControllerDSMNewFromServerBuffer(
+                newPath,
+                newSetPath,
+                XDMF_ARRAY_TYPE_INT32,
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                1,
+                XdmfHDF5WriterDSMGetServerBuffer(exampleWriter),
+                &xdmfStatus);
+
+        XdmfHDF5WriterDSMSetMode(exampleWriter, XDMF_HEAVY_WRITER_MODE_HYPERSLAB, &xdmfStatus);
+
+        /* Done initialization */
+
+        MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))));
+
+	unsigned int numloops = 0;
+
+        for (numloops = 0; numloops < 4; ++numloops)
+        {
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        XdmfDSMBufferReceiveAcknowledgment(XdmfHDF5ControllerDSMGetServerBuffer(readController),
+                                                           XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))) - 1,
+                                                           &receiveData,
+                                                           XDMF_DSM_EXCHANGE_TAG,
+                                                           XDMF_DSM_INTER_COMM,
+                                                           &xdmfStatus);
+                }
+
+                MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))));
+
+                if (XdmfArrayGetNumberHeavyDataControllers(readArray) > 0)
+                {
+                        XdmfArrayRemoveHeavyDataController(readArray, 0);
+                }
+                XdmfArrayInsertHeavyDataController(readArray, (XDMFHEAVYDATACONTROLLER *)readController, 0);
+                XdmfArrayRead(readArray, &xdmfStatus);
+
+                for (i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))));
+                        if (i == id)
+                        {
+                                printf("Array on core %d contains:\n", XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5WriterDSMGetServerBuffer(exampleWriter))));
+                                for (j = 0; j < XdmfArrayGetSize(readArray); ++j)
+                                {
+                                        int tempVal = ((int *)XdmfArrayGetValue(readArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0];
+                                        tempVal = tempVal * 3;
+                                        XdmfArrayInsertValue(readArray, j, &tempVal, XDMF_ARRAY_TYPE_INT32, &xdmfStatus);
+                                        printf("[%d] = %d\n", j, ((int *)XdmfArrayGetValue(readArray, j, XDMF_ARRAY_TYPE_INT32, &xdmfStatus))[0]);
+                                }
+                        }
+                }
+
+                MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))));
+
+                if (id == 0)
+                {
+                        printf("\n\n");
+                }
+
+                XdmfArrayRemoveHeavyDataController(readArray, 0);
+                XdmfArrayInsertHeavyDataController(readArray, (XDMFHEAVYDATACONTROLLER *)writeController, 0);
+
+                XdmfArrayAccept(readArray, (XDMFVISITOR *)exampleWriter, &xdmfStatus);
+
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        XdmfDSMBufferSendAcknowledgment(XdmfHDF5ControllerDSMGetServerBuffer(readController),
+                                                        XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))) - 1,
+                                                        receiveData,
+                                                        XDMF_DSM_EXCHANGE_TAG,
+                                                        XDMF_DSM_INTER_COMM,
+                                                        &xdmfStatus);
+                }
+        }
+
+        /* This last acknowledgment is to end the loop. */
+
+        if (id == 0)
+        {
+                int receiveData = 0;
+                XdmfDSMBufferReceiveAcknowledgment(XdmfHDF5ControllerDSMGetServerBuffer(readController),
+                                                   XdmfDSMCommMPIGetInterId(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))) - 1,
+                                                   &receiveData,
+                                                   XDMF_DSM_EXCHANGE_TAG,
+                                                   XDMF_DSM_INTER_COMM,
+                                                   &xdmfStatus);
+        }
+
+        MPI_Barrier(XdmfDSMCommMPIGetIntraComm(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))));
+
+        /* Do work stuff here */
+
+        if (id == 0)
+        {
+                XdmfHDF5ControllerDSMStopDSM(readController, &xdmfStatus);
+        }
+
+        MPI_Barrier(XdmfDSMCommMPIGetInterComm(XdmfDSMBufferGetComm(XdmfHDF5ControllerDSMGetServerBuffer(readController))));
+
+        MPI_Finalize();
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/CMakeLists.txt b/core/dsm/tests/CMakeLists.txt
new file mode 100644
index 0000000..49ba5dd
--- /dev/null
+++ b/core/dsm/tests/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_subdirectory(C)
+add_subdirectory(Cxx)
+
+if(XDMF_WRAP_PYTHON)
+  add_subdirectory(Python)
+endif(XDMF_WRAP_PYTHON)
diff --git a/core/dsm/tests/Cxx/CMakeLists.txt b/core/dsm/tests/Cxx/CMakeLists.txt
new file mode 100644
index 0000000..1b3afd6
--- /dev/null
+++ b/core/dsm/tests/Cxx/CMakeLists.txt
@@ -0,0 +1,61 @@
+# Include our test macros
+include(AddTestsCxx)
+
+# Add any dependencies that the cxx core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_CXX_DEPENDENCIES("XdmfCore")
+ADD_TEST_CXX_DEPENDENCIES("XdmfDSM")
+
+# Add any ldpath directories that the cxx tests may need
+ADD_TEST_CXX_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_CXX_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directoreis that the Cxx tests may need
+ADD_TEST_CXX_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_CXX_PATH("${XDMF_BINARIES}")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_CXX(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+IF (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+  if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+    ADD_MPI_TEST_CXX(DSMLoopTest.sh DSMLoopTest)
+    ADD_MPI_TEST_CXX(DSMLoopTestPaged.sh DSMLoopTestPaged)
+    ADD_MPI_TEST_CXX(DSMLoopTestPagedSingleCore.sh DSMLoopTestPagedSingleCore)
+    ADD_MPI_TEST_CXX(ConnectTest.sh
+                     XdmfAcceptTest,XdmfConnectTest2,XdmfConnectTest)
+    ADD_MPI_TEST_CXX(ConnectTestPaged.sh
+                     XdmfAcceptTestPaged,XdmfConnectTest2Paged,XdmfConnectTestPaged)
+  else ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+    ADD_MPI_TEST_CXX(DSMLoopTestPagedSingleCore.sh DSMLoopTestPagedSingleCore)
+    ADD_MPI_TEST_CXX(CrayConnectTest.sh
+                     XdmfAcceptTest,XdmfConnectTest2,XdmfConnectTest)
+  endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+ENDIF(MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_CXX(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+IF (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+  if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  CLEAN_TEST_CXX(DSMLoopTest.sh)
+  CLEAN_TEST_CXX(DSMLoopTestPaged.sh)
+  if ("$ENV{XDMFDSM_CONFIG_FILE}" STREQUAL "")
+    CLEAN_TEST_CXX(ConnectTest.sh dsmconnect.cfg)
+    CLEAN_TEST_CXX(ConnectTestPaged.sh dsmconnect.cfg)
+  else ("$ENV{XDMFDSM_CONFIG_FILE}" STREQUAL "")
+    CLEAN_TEST_CXX(ConnectTest.sh "$ENV{XDMFDSM_CONFIG_FILE}")
+    CLEAN_TEST_CXX(ConnectTestPaged.sh "$ENV{XDMFDSM_CONFIG_FILE}")
+  endif ("$ENV{XDMFDSM_CONFIG_FILE}" STREQUAL "")
+  else ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+      CLEAN_TEST_CXX(DSMLoopTestPagedSingleCore.sh)
+    if ("$ENV{XDMFDSM_CONFIG_FILE}" STREQUAL "")
+      CLEAN_TEST_CXX(CrayConnectTest.sh dsmconnect.cfg)
+    else ("$ENV{XDMFDSM_CONFIG_FILE}" STREQUAL "")
+      CLEAN_TEST_CXX(CrayConnectTest.sh "$ENV{XDMFDSM_CONFIG_FILE}")
+    endif ("$ENV{XDMFDSM_CONFIG_FILE}" STREQUAL "")
+  endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+ENDIF (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
diff --git a/core/dsm/tests/Cxx/ConnectTest.sh b/core/dsm/tests/Cxx/ConnectTest.sh
new file mode 100755
index 0000000..c2c301b
--- /dev/null
+++ b/core/dsm/tests/Cxx/ConnectTest.sh
@@ -0,0 +1,7 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+$MPIEXEC -n 2 ./XdmfAcceptTest &
+
+$MPIEXEC -n 2 ./XdmfConnectTest &
+
+$MPIEXEC -n 2 ./XdmfConnectTest2
diff --git a/core/dsm/tests/Cxx/ConnectTestPaged.sh b/core/dsm/tests/Cxx/ConnectTestPaged.sh
new file mode 100755
index 0000000..30c1966
--- /dev/null
+++ b/core/dsm/tests/Cxx/ConnectTestPaged.sh
@@ -0,0 +1,7 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+$MPIEXEC -n 2 ./XdmfAcceptTestPaged &
+
+$MPIEXEC -n 2 ./XdmfConnectTestPaged &
+
+$MPIEXEC -n 2 ./XdmfConnectTest2Paged
diff --git a/core/dsm/tests/Cxx/CrayConnectTest.sh b/core/dsm/tests/Cxx/CrayConnectTest.sh
new file mode 100755
index 0000000..6e1932a
--- /dev/null
+++ b/core/dsm/tests/Cxx/CrayConnectTest.sh
@@ -0,0 +1,3 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+aprun -n 2 ./XdmfAcceptTest : -n 2 ./XdmfConnectTest : -n 2 ./XdmfConnectTest2
diff --git a/core/dsm/tests/Cxx/DSMLoopTest.cpp b/core/dsm/tests/Cxx/DSMLoopTest.cpp
new file mode 100644
index 0000000..c357975
--- /dev/null
+++ b/core/dsm/tests/Cxx/DSMLoopTest.cpp
@@ -0,0 +1,376 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+#include <cmath>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+        testArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> testArray2 = XdmfArray::New();
+        testArray2->initialize<int>(0);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "dataspace";
+        std::string secondSetPath = "data2";
+
+        // Change this to determine the number of cores used as servers
+        unsigned int numServersCores = 2;
+        // Change this to determine the size of the arrays generated when initializing
+        unsigned int writeArraySize = 4;
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        std::vector<unsigned int> readOutputCountVector;
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> readArray2 = XdmfArray::New();
+        readArray2->initialize<int>(0);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController;
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController2;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController2;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController2;
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+        for(int i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1);
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        //split out sub-comm for the worker cores
+        //server cores will not progress to this point until after the servers are done running
+
+        if (id < size - (int)numServersCores)
+        {
+                // Split the comm even further
+
+                MPI_Comm readComm, writeComm;
+
+                MPI_Group readingCores, writingCores;
+
+                MPI_Comm_group(workerComm, &workers);
+                int * ServerIds = (int *)calloc(((size - numServersCores) / 2), sizeof(int));
+                unsigned int index = 0;
+                for(int i=0 ; i < (int)((size - numServersCores) / 2) ; ++i)
+                {
+                        ServerIds[index++] = i;
+                }
+
+                MPI_Group_excl(workers, index, ServerIds, &readingCores);
+                testval = MPI_Comm_create(workerComm, readingCores, &readComm);
+                MPI_Group_incl(workers, index, ServerIds, &writingCores);
+                testval = MPI_Comm_create(workerComm, writingCores, &writeComm);
+                cfree(ServerIds);
+
+                std::cout << "initializing" << std::endl;
+
+                // Initialize values
+                // Writer is first
+                if (id < (int)((size - numServersCores) / 2))
+                {
+                        for (unsigned int i = 1; i <= writeArraySize; ++i)
+                        {
+                                testArray->pushBack(i*(id+1));
+                        }
+
+                        for (unsigned int i = 1; i <= writeArraySize; ++i)
+                        {
+                                testArray2->pushBack(5*i*(id+1));
+                        }
+
+                        writeStartVector.push_back(id*writeArraySize);
+                        writeStrideVector.push_back(1);
+                        writeCountVector.push_back(writeArraySize);
+                        writeDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        writeController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray->insert(writeController);
+
+                        writeController2 = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                secondSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray2->insert(writeController2);
+
+                        readStartVector.push_back(0);
+                        readStrideVector.push_back(1);
+                        readCountVector.push_back(0);
+                        readDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+
+                        readController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+                        readArray->insert(readController);
+
+                        for (unsigned int i = 0; i<size-numServersCores; ++i)
+                        {
+                                MPI_Barrier(writeComm);
+                                if (i == (unsigned int)id)
+                                {
+                                        for(unsigned int i=0; i<testArray->getSize(); ++i)
+                                        {
+                                                std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+
+                        for (unsigned int i = 0; i<size-numServersCores; ++i)
+                        {
+                                MPI_Barrier(writeComm);
+                                if (i == (unsigned int)id)
+                                {
+                                        for(unsigned int i=0; i<testArray2->getSize(); ++i)
+                                        {
+                                                std::cout << "core #" << id <<" testArray2[" << i << "] = " << testArray2->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+                }
+                else
+                {
+                        // Reader is second
+                        readStartVector.push_back(0);
+                        readStrideVector.push_back(1);
+                        readCountVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        readDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+
+                        readController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        readArray->insert(readController);
+
+                        readOutputCountVector.push_back(0);
+
+                        readOutputController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readOutputCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        writeStartVector.push_back(0);
+                        writeStrideVector.push_back(1);
+                        writeCountVector.push_back(0);
+                        writeDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        writeController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        writeController2 = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                secondSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray2->insert(writeController2);
+
+                        testArray->insert(writeController);
+                }
+
+                testArray->accept(exampleWriter);
+                MPI_Barrier(workerComm);
+
+//                exampleWriter->openFile();
+///*
+                std::cout << "getting dataset size" << std::endl;
+                int checkedsize = exampleWriter->getDataSetSize(newPath, newSetPath);
+                std::cout << "polled size " << checkedsize << " from file should be " << writeArraySize*(int)((size-numServersCores) / 2) << std::endl;
+                assert(checkedsize == writeArraySize*(int)((size-numServersCores) / 2));
+                checkedsize = exampleWriter->getDataSetSize(newPath, "empty");
+                std::cout << "polled nonexistant set size =  " << checkedsize << std::endl;
+                assert(checkedsize == 0);
+//*/
+                MPI_Barrier(workerComm);
+//                exampleWriter->closeFile();
+
+                testArray2->accept(exampleWriter);
+
+                MPI_Barrier(workerComm);
+
+                // This is the loop that manipulates the data
+                for (unsigned int iteration = 0; iteration < 10; ++iteration)
+                {
+                        std::cout << "loop iteration " << iteration << " on core " << id << std::endl;
+
+                        // Read in to the first set of cores
+                        if (id >= (int)((size - numServersCores) / 2))
+                        {
+                                // Controllers are accessed like this since the writer removes them and creates its own.
+                                shared_dynamic_cast<XdmfHDF5ControllerDSM>(readArray->getHeavyDataController(0))->setWorkerComm(readComm);
+
+                                readArray->read();
+
+                                MPI_Barrier(readComm);
+
+                                if (id == (int)((size - numServersCores) / 2))
+                                {
+                                        for(unsigned int i=0; i<readArray->getSize(); ++i)
+                                        {
+                                                int tempVal = readArray->getValue<int>(i);
+                                                tempVal = tempVal * 2;
+                                                readArray->insert(i, tempVal);
+                                                // Pull the value from the array in order to ensure the change has happened
+                                                std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+                        shared_dynamic_cast<XdmfHDF5ControllerDSM>(readArray->getHeavyDataController(0))->setWorkerComm(workerComm);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data 
+                                readArray->removeHeavyDataController(0);
+                                readArray->insert(readOutputController);
+                        }
+
+                        readArray->accept(exampleWriter);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data
+                                readArray->removeHeavyDataController(0);
+                                readArray->insert(readController);
+                        }
+
+                        MPI_Barrier(workerComm);
+
+                        std::cout << "on writing cores" << std::endl;
+
+                        if (id < (int)((size - numServersCores) / 2))
+                        {
+                                shared_dynamic_cast<XdmfHDF5ControllerDSM>(testArray->getHeavyDataController(0))->setWorkerComm(writeComm);
+                                testArray->read();
+                                MPI_Barrier(writeComm);
+                                for (unsigned int i = 0; i<(unsigned int)size; ++i)
+                                {
+                                        MPI_Barrier(writeComm);
+                                        if (i == (unsigned int)id)
+                                        {
+                                                for(unsigned int i=0; i<testArray->getSize(); ++i)
+                                                {
+                                                        int tempVal = testArray->getValue<int>(i);
+                                                        unsigned int multiplier1 = std::pow(2, iteration+1);
+                                                        unsigned int multiplier2 = std::pow(3, iteration);
+                                                        assert(tempVal == (i+1)*(id+1) * multiplier1 * multiplier2);
+                                                        tempVal = tempVal * 3;
+                                                        testArray->insert(i, tempVal);
+                                                        // Pull the value from the array in order to ensure the change has happened
+                                                        std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                                                }
+                                        }
+                                }
+                                testArray2->read();
+                                for (unsigned int i = 1; i <= writeArraySize; ++i)
+                                {
+                                        unsigned int tempVal = testArray2->getValue<unsigned int>(i - 1);
+                                        unsigned int multiplier = std::pow(5, iteration);
+                                        assert(5*i*(id+1) * multiplier == tempVal);
+                                        testArray2->insert(i - 1, tempVal * 5);
+                                        std::cout << "core #" << id <<" testArray2[" << i-1 << "] = " << testArray2->getValue<int>(i-1) << std::endl;
+                                }
+                        }
+                        writeController->setWorkerComm(workerComm);
+                        testArray->accept(exampleWriter);
+                        testArray2->accept(exampleWriter);
+                }
+
+        }
+
+        if (id == 0)
+        {
+                exampleWriter->stopDSM();
+        }
+
+        MPI_Barrier(comm);
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/DSMLoopTest.sh b/core/dsm/tests/Cxx/DSMLoopTest.sh
new file mode 100755
index 0000000..653b93b
--- /dev/null
+++ b/core/dsm/tests/Cxx/DSMLoopTest.sh
@@ -0,0 +1 @@
+$MPIEXEC -n 4 ./DSMLoopTest
diff --git a/core/dsm/tests/Cxx/DSMLoopTestPaged.cpp b/core/dsm/tests/Cxx/DSMLoopTestPaged.cpp
new file mode 100644
index 0000000..70f8559
--- /dev/null
+++ b/core/dsm/tests/Cxx/DSMLoopTestPaged.cpp
@@ -0,0 +1,376 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+#include <cmath>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+        testArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> testArray2 = XdmfArray::New();
+        testArray2->initialize<int>(0);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "dataspace";
+        std::string secondSetPath = "data2";
+
+        // Change this to determine the number of cores used as servers
+        unsigned int numServersCores = 2;
+        // Change this to determine the size of the arrays generated when initializing
+        unsigned int writeArraySize = 4;
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        std::vector<unsigned int> readOutputCountVector;
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> readArray2 = XdmfArray::New();
+        readArray2->initialize<int>(0);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController;
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController2;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController2;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController2;
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+        for(int i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, 1024, 1, size-numServersCores, size-1);
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        //split out sub-comm for the worker cores
+        //server cores will not progress to this point until after the servers are done running
+
+        if (id < size - (int)numServersCores)
+        {
+                // Split the comm even further
+
+                MPI_Comm readComm, writeComm;
+
+                MPI_Group readingCores, writingCores;
+
+                MPI_Comm_group(workerComm, &workers);
+                int * ServerIds = (int *)calloc(((size - numServersCores) / 2), sizeof(int));
+                unsigned int index = 0;
+                for(int i=0 ; i < (int)((size - numServersCores) / 2) ; ++i)
+                {
+                        ServerIds[index++] = i;
+                }
+
+                MPI_Group_excl(workers, index, ServerIds, &readingCores);
+                testval = MPI_Comm_create(workerComm, readingCores, &readComm);
+                MPI_Group_incl(workers, index, ServerIds, &writingCores);
+                testval = MPI_Comm_create(workerComm, writingCores, &writeComm);
+                cfree(ServerIds);
+
+                std::cout << "initializing" << std::endl;
+
+                // Initialize values
+                // Writer is first
+                if (id < (int)((size - numServersCores) / 2))
+                {
+                        for (unsigned int i = 1; i <= writeArraySize; ++i)
+                        {
+                                testArray->pushBack(i*(id+1));
+                        }
+
+                        for (unsigned int i = 1; i <= writeArraySize; ++i)
+                        {
+                                testArray2->pushBack(5*i*(id+1));
+                        }
+
+                        writeStartVector.push_back(id*writeArraySize);
+                        writeStrideVector.push_back(1);
+                        writeCountVector.push_back(writeArraySize);
+                        writeDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        writeController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray->insert(writeController);
+
+                        writeController2 = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                secondSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray2->insert(writeController2);
+
+                        readStartVector.push_back(0);
+                        readStrideVector.push_back(1);
+                        readCountVector.push_back(0);
+                        readDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+
+                        readController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+                        readArray->insert(readController);
+
+                        for (unsigned int i = 0; i<size-numServersCores; ++i)
+                        {
+                                MPI_Barrier(writeComm);
+                                if (i == (unsigned int)id)
+                                {
+                                        for(unsigned int i=0; i<testArray->getSize(); ++i)
+                                        {
+                                                std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+
+                        for (unsigned int i = 0; i<size-numServersCores; ++i)
+                        {
+                                MPI_Barrier(writeComm);
+                                if (i == (unsigned int)id)
+                                {
+                                        for(unsigned int i=0; i<testArray2->getSize(); ++i)
+                                        {
+                                                std::cout << "core #" << id <<" testArray2[" << i << "] = " << testArray2->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+                }
+                else
+                {
+                        // Reader is second
+                        readStartVector.push_back(0);
+                        readStrideVector.push_back(1);
+                        readCountVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        readDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+
+                        readController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        readArray->insert(readController);
+
+                        readOutputCountVector.push_back(0);
+
+                        readOutputController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readOutputCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        writeStartVector.push_back(0);
+                        writeStrideVector.push_back(1);
+                        writeCountVector.push_back(0);
+                        writeDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        writeController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        writeController2 = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                secondSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray2->insert(writeController2);
+
+                        testArray->insert(writeController);
+                }
+
+                testArray->accept(exampleWriter);
+                MPI_Barrier(workerComm);
+
+//                exampleWriter->openFile();
+/*
+                std::cout << "getting dataset size" << std::endl;
+                int checkedsize = exampleWriter->getDataSetSize(newPath, newSetPath);
+                std::cout << "polled size " << checkedsize << " from file should be " << writeArraySize*(int)((size-numServersCores) / 2) << std::endl;
+                assert(checkedsize == writeArraySize*(int)((size-numServersCores) / 2));
+                checkedsize = exampleWriter->getDataSetSize(newPath, "empty");
+                std::cout << "polled nonexistant set size =  " << checkedsize << std::endl;
+                assert(checkedsize == 0);
+*/
+                MPI_Barrier(workerComm);
+//                exampleWriter->closeFile();
+
+                testArray2->accept(exampleWriter);
+
+                MPI_Barrier(workerComm);
+
+                // This is the loop that manipulates the data
+                for (unsigned int iteration = 0; iteration < 10; ++iteration)
+                {
+                        std::cout << "loop iteration " << iteration << " on core " << id << std::endl;
+
+                        // Read in to the first set of cores
+                        if (id >= (int)((size - numServersCores) / 2))
+                        {
+                                // Controllers are accessed like this since the writer removes them and creates its own.
+                                shared_dynamic_cast<XdmfHDF5ControllerDSM>(readArray->getHeavyDataController(0))->setWorkerComm(readComm);
+
+                                readArray->read();
+
+                                MPI_Barrier(readComm);
+
+                                if (id == (int)((size - numServersCores) / 2))
+                                {
+                                        for(unsigned int i=0; i<readArray->getSize(); ++i)
+                                        {
+                                                int tempVal = readArray->getValue<int>(i);
+                                                tempVal = tempVal * 2;
+                                                readArray->insert(i, tempVal);
+                                                // Pull the value from the array in order to ensure the change has happened
+                                                std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+                        shared_dynamic_cast<XdmfHDF5ControllerDSM>(readArray->getHeavyDataController(0))->setWorkerComm(workerComm);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data 
+                                readArray->removeHeavyDataController(0);
+                                readArray->insert(readOutputController);
+                        }
+
+                        readArray->accept(exampleWriter);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data
+                                readArray->removeHeavyDataController(0);
+                                readArray->insert(readController);
+                        }
+
+                        MPI_Barrier(workerComm);
+
+                        std::cout << "on writing cores" << std::endl;
+
+                        if (id < (int)((size - numServersCores) / 2))
+                        {
+                                shared_dynamic_cast<XdmfHDF5ControllerDSM>(testArray->getHeavyDataController(0))->setWorkerComm(writeComm);
+                                testArray->read();
+                                MPI_Barrier(writeComm);
+                                for (unsigned int i = 0; i<(unsigned int)size; ++i)
+                                {
+                                        MPI_Barrier(writeComm);
+                                        if (i == (unsigned int)id)
+                                        {
+                                                for(unsigned int i=0; i<testArray->getSize(); ++i)
+                                                {
+                                                        int tempVal = testArray->getValue<int>(i);
+                                                        unsigned int multiplier1 = std::pow(2, iteration+1);
+                                                        unsigned int multiplier2 = std::pow(3, iteration);
+                                                        assert(tempVal == (i+1)*(id+1) * multiplier1 * multiplier2);
+                                                        tempVal = tempVal * 3;
+                                                        testArray->insert(i, tempVal);
+                                                        // Pull the value from the array in order to ensure the change has happened
+                                                        std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                                                }
+                                        }
+                                }
+                                testArray2->read();
+                                for (unsigned int i = 1; i <= writeArraySize; ++i)
+                                {
+                                        unsigned int tempVal = testArray2->getValue<unsigned int>(i - 1);
+                                        unsigned int multiplier = std::pow(5, iteration);
+                                        assert(5*i*(id+1) * multiplier == tempVal);
+                                        testArray2->insert(i - 1, tempVal * 5);
+                                        std::cout << "core #" << id <<" testArray2[" << i-1 << "] = " << testArray2->getValue<int>(i-1) << std::endl;
+                                }
+                        }
+                        writeController->setWorkerComm(workerComm);
+                        testArray->accept(exampleWriter);
+                        testArray2->accept(exampleWriter);
+                }
+
+        }
+
+        if (id == 0)
+        {
+                exampleWriter->stopDSM();
+        }
+
+        MPI_Barrier(comm);
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/DSMLoopTestPaged.sh b/core/dsm/tests/Cxx/DSMLoopTestPaged.sh
new file mode 100755
index 0000000..cd8d0ea
--- /dev/null
+++ b/core/dsm/tests/Cxx/DSMLoopTestPaged.sh
@@ -0,0 +1 @@
+$MPIEXEC -n 4 ./DSMLoopTestPaged
diff --git a/core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.cpp b/core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.cpp
new file mode 100644
index 0000000..3a11f57
--- /dev/null
+++ b/core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.cpp
@@ -0,0 +1,162 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+        testArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> testArray2 = XdmfArray::New();
+        testArray2->initialize<int>(0);
+
+        std::string newPath = "dsm";
+        std::stringstream setPathAggregate;
+        setPathAggregate << "dataspace" << id;
+        std::string newSetPath = setPathAggregate.str();
+        std::string secondSetPath = "data2";
+
+        // Change this to determine the number of cores used as servers
+        unsigned int numServersCores = 2;
+        // Change this to determine the size of the arrays generated when initializing
+        unsigned int writeArraySize = 4;
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        std::vector<unsigned int> readOutputCountVector;
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> readArray2 = XdmfArray::New();
+        readArray2->initialize<int>(0);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController;
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController2;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController2;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController2;
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+        for(int i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, 1024, 1, size-numServersCores, size-1);
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        //split out sub-comm for the worker cores
+        //server cores will not progress to this point until after the servers are done running
+
+        if (id < size - (int)numServersCores)
+        {
+                // Split the comm even further
+
+                // This Comm is for the individual cores
+                MPI_Comm writeComm;
+
+                MPI_Group readingCores, writingCores;
+
+                MPI_Comm_group(workerComm, &workers);
+                int * ServerIds = (int *)calloc(1, sizeof(int));
+                ServerIds[0] = id;
+
+                MPI_Group_incl(workers, 1, ServerIds, &writingCores);
+                testval = MPI_Comm_create(workerComm, writingCores, &writeComm);
+                cfree(ServerIds);
+
+                std::cout << "initializing" << std::endl;
+
+                writeStartVector.push_back(0);
+                writeStrideVector.push_back(1);
+                writeCountVector.push_back(1);
+                writeDataSizeVector.push_back(1);
+
+                writeController = XdmfHDF5ControllerDSM::New(
+                  newPath,
+                  newSetPath,
+                  XdmfArrayType::Int32(),
+                  writeStartVector,
+                  writeStrideVector,
+                  writeCountVector,
+                  writeDataSizeVector,
+                  exampleWriter->getServerBuffer());
+
+                testArray->pushBack(id);
+
+                testArray->insert(writeController);
+
+                exampleWriter->setWorkerComm(writeComm);
+
+                printf("writing to dsm\n");
+
+                testArray->accept(exampleWriter);
+
+                printf("done writing to dsm\n");
+
+                MPI_Barrier(workerComm);
+
+                exampleWriter->setWorkerComm(workerComm);
+
+                printf("reading size\n");
+
+                int readsize = exampleWriter->getDataSetSize(newPath, newSetPath);
+                printf("size of dataset %s:%s = %d\n", newPath.c_str(), newSetPath.c_str(), readsize);
+                assert(readsize == 1);
+
+//                exampleWriter->setWorkerComm(workerComm);
+        }
+
+        if (id == 0)
+        {
+                exampleWriter->stopDSM();
+        }
+
+        MPI_Barrier(comm);
+
+        printf("finalizing\n");
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.sh b/core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.sh
new file mode 100755
index 0000000..22075da
--- /dev/null
+++ b/core/dsm/tests/Cxx/DSMLoopTestPagedSingleCore.sh
@@ -0,0 +1 @@
+$MPIEXEC -n 4 ./DSMLoopTestPagedSingleCore
diff --git a/core/dsm/tests/Cxx/TestXdmfHDF5WriterDSM.cpp b/core/dsm/tests/Cxx/TestXdmfHDF5WriterDSM.cpp
new file mode 100644
index 0000000..d045816
--- /dev/null
+++ b/core/dsm/tests/Cxx/TestXdmfHDF5WriterDSM.cpp
@@ -0,0 +1,117 @@
+#include <H5FDdsm.h>
+#include <H5FDdsmManager.h>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+  int rank, size, provided, dsmSize = 16;
+  MPI_Comm comm = MPI_COMM_WORLD;
+
+  MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &provided);
+  MPI_Comm_rank(comm, &rank);
+  MPI_Comm_size(comm, &size);
+
+  if (rank == 0) {
+    if (provided != MPI_THREAD_MULTIPLE) {
+      std::cout << "# MPI_THREAD_MULTIPLE not set, you may need to recompile your "
+	<< "MPI distribution with threads enabled" << std::endl;
+    }
+    else {
+      std::cout << "# MPI_THREAD_MULTIPLE is OK" << std::endl;
+    }
+  }
+
+  // Create DSM
+  H5FDdsmManager * dsmManager = new H5FDdsmManager();
+  dsmManager->SetMpiComm(comm);
+  dsmManager->SetLocalBufferSizeMBytes(dsmSize / size);
+  dsmManager->SetLocalBufferSizeMBytes(dsmSize / size);
+  dsmManager->SetIsStandAlone(H5FD_DSM_TRUE);
+  dsmManager->Create();
+  H5FD_dsm_set_manager(dsmManager);
+
+  H5FD_dsm_set_options(H5FD_DSM_LOCK_ASYNCHRONOUS);
+
+  H5FDdsmBuffer * dsmBuffer = dsmManager->GetDsmBuffer();
+
+  // Get info from remote server
+  double remoteMB = dsmBuffer->GetTotalLength() / (1024.0 * 1024.0);
+  double numServers = dsmBuffer->GetEndServerId() + 1;
+  if (rank == 0) {
+    std::cout << "DSM server memory size is : "
+              << (int)remoteMB << " MB" << std::endl;
+    std::cout << "DSM server process count  : "
+              <<  (int)numServers << std::endl;
+  }
+
+  // Create Array
+  // Array should be distributed among processes
+  shared_ptr<XdmfArray> array = XdmfArray::New();
+  array->initialize<int>(0);
+  array->pushBack(rank*3);
+  array->pushBack(rank*3 + 1);
+  array->pushBack(rank*3 + 2);
+  shared_ptr<XdmfHDF5ControllerDSM> controller = 
+    XdmfHDF5ControllerDSM::New("dsm.h5",
+                               "data",
+                               XdmfArrayType::Int32(),
+                               std::vector<unsigned int>(1, rank*3),
+                               std::vector<unsigned int>(1, 1),
+                               std::vector<unsigned int>(1, 3),
+                               std::vector<unsigned int>(1, size*3),
+                               dsmBuffer);
+  array->setHeavyDataController(controller);
+
+  // Create DSM Writer and write to DSM space.
+  shared_ptr<XdmfHDF5WriterDSM> writer =
+    XdmfHDF5WriterDSM::New("dsm.h5", dsmBuffer);
+  writer->setMode(XdmfHeavyDataWriter::Hyperslab);
+  array->accept(writer);
+
+  //H5FD_dsm_dump();
+
+  // Release data and read back in to check if we wrote correctly
+  array->release();
+  array->read();
+  std::cout << array->getSize() << "?=" << 3 << std::endl;
+  assert(array->getSize() == 3);
+  std::cout << array->getValue<int>(0) << "?=" << 3*rank << std::endl;
+  assert(array->getValue<int>(0) == 3*rank);
+  std::cout << array->getValue<int>(1) << "?=" << ((3*rank) + 1) << std::endl;
+  assert(array->getValue<int>(1) == 3*rank + 1);
+  std::cout << array->getValue<int>(2) << "?=" << ((3*rank) + 2) << std::endl;
+  assert(array->getValue<int>(2) == 3*rank + 2);
+
+  MPI_Barrier(comm);
+  
+  // Adjust controller to read entire dataset onto each processor
+  shared_ptr<XdmfHDF5ControllerDSM> fullController = 
+    XdmfHDF5ControllerDSM::New("dsm.h5",
+                               "data",
+                               XdmfArrayType::Int32(),
+                               std::vector<unsigned int>(1, 0),
+                               std::vector<unsigned int>(1, 1),
+                               std::vector<unsigned int>(1, size*3),
+                               std::vector<unsigned int>(1, size*3),
+                               dsmBuffer);
+  array->setHeavyDataController(fullController);
+  array->release();
+  array->read();
+  std::cout << array->getSize() << "?=" << (size * 3) << std::endl;
+  assert(array->getSize() == size*3);
+  for(int i=0; i<size*3; ++i) {
+    std::cout << array->getValue<int>(i) << "?=" << i << std::endl;
+    assert(array->getValue<int>(i) == i);
+  }
+
+  // Wait for everyone to have finished reading
+  MPI_Barrier(comm);
+  delete dsmManager;
+
+  MPI_Finalize();
+
+  return 0;
+}
diff --git a/core/dsm/tests/Cxx/XdmfAcceptTest.cpp b/core/dsm/tests/Cxx/XdmfAcceptTest.cpp
new file mode 100644
index 0000000..d99873b
--- /dev/null
+++ b/core/dsm/tests/Cxx/XdmfAcceptTest.cpp
@@ -0,0 +1,118 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+
+int main(int argc, char *argv[])
+{
+// This test does not work properly with openmpi
+// due to an issue with the openmpi code
+#ifndef OPEN_MPI
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        XdmfDSMCommMPI::SetUseEnvFileName(true);
+
+        std::string newPath = "dsm";
+        int numServersCores = size - 1;
+        int numConnections = 2;
+
+//        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1);
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, 1, 1, "Accept");
+
+        if (id == 0)
+        {
+                //#initMPI end
+
+                //#GetDsmFileName begin
+
+                std::string connectionFileName = exampleWriter->getServerBuffer()->GetComm()->GetDsmFileName();
+
+                //#GetDsmFileName end
+
+                //#SetDsmFileName begin
+
+                exampleWriter->getServerBuffer()->GetComm()->SetDsmFileName(connectionFileName);
+
+                //#SetDsmFileName end
+
+                //#OpenPort begin
+
+                exampleWriter->getServerBuffer()->GetComm()->OpenPort();
+
+                //#OpenPort end
+
+                //#SendAccept begin
+
+                exampleWriter->getServerBuffer()->SendAccept(numConnections);
+
+                //#SendAccept end
+
+                /*
+
+                //#manualAccept begin
+
+                // Notify the server cores to accept connections
+                for (int i = exampleWriter->getServerBuffer()->StartServerId; i <= exampleWriter->getServerBuffer()->EndServerId; ++i)
+                {
+                        if (i != exampleWriter->getServerBuffer()->Comm->GetId())
+                        {
+                                exampleWriter->getServerBuffer()->SendCommandHeader(XDMF_DSM_ACCEPT, i, 0, 0, XDMF_DSM_INTER_COMM);
+                                exampleWriter->getServerBuffer()->SendAcknowledgment(i, numConnections, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                        }
+                }
+                // Accept connections
+                exampleWriter->getServerBuffer()->Comm->Accept(numConnections);
+                // Distribute current DSM status
+                exampleWriter->getServerBuffer()->SendInfo();
+
+                //#manualAccept end
+
+                */
+
+                //#finishwork begin
+
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        //#finishwork end
+
+        //#ClosePort begin
+
+	if (id == 0)
+	{
+	        exampleWriter->getServerBuffer()->GetComm()->ClosePort();
+	}
+
+        //#ClosePort end
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+#else
+
+        std::cout << "Interprogram DSM does not work properly with OpenMPI" << std::endl;
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/XdmfAcceptTestPaged.cpp b/core/dsm/tests/Cxx/XdmfAcceptTestPaged.cpp
new file mode 100644
index 0000000..962a481
--- /dev/null
+++ b/core/dsm/tests/Cxx/XdmfAcceptTestPaged.cpp
@@ -0,0 +1,117 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+
+int main(int argc, char *argv[])
+{
+// This test does not work properly with openmpi
+// due to an issue with the openmpi code
+#ifndef OPEN_MPI
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        XdmfDSMCommMPI::SetUseEnvFileName(true);
+
+        std::string newPath = "dsm";
+        int numServersCores = size - 1;
+        int numConnections = 2;
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, 1024, 1, size-numServersCores, size-1);
+
+        if (id == 0)
+        {
+                //#initMPI end
+
+                //#GetDsmFileName begin
+
+                std::string connectionFileName = exampleWriter->getServerBuffer()->GetComm()->GetDsmFileName();
+
+                //#GetDsmFileName end
+
+                //#SetDsmFileName begin
+
+                exampleWriter->getServerBuffer()->GetComm()->SetDsmFileName(connectionFileName);
+
+                //#SetDsmFileName end
+
+                //#OpenPort begin
+
+                exampleWriter->getServerBuffer()->GetComm()->OpenPort();
+
+                //#OpenPort end
+
+                //#SendAccept begin
+
+                exampleWriter->getServerBuffer()->SendAccept(numConnections);
+
+                //#SendAccept end
+
+                /*
+
+                //#manualAccept begin
+
+                // Notify the server cores to accept connections
+                for (int i = exampleWriter->getServerBuffer()->StartServerId; i <= exampleWriter->getServerBuffer()->EndServerId; ++i)
+                {
+                        if (i != exampleWriter->getServerBuffer()->Comm->GetId())
+                        {
+                                exampleWriter->getServerBuffer()->SendCommandHeader(XDMF_DSM_ACCEPT, i, 0, 0, XDMF_DSM_INTER_COMM);
+                                exampleWriter->getServerBuffer()->SendAcknowledgment(i, numConnections, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                        }
+                }
+                // Accept connections
+                exampleWriter->getServerBuffer()->Comm->Accept(numConnections);
+                // Distribute current DSM status
+                exampleWriter->getServerBuffer()->SendInfo();
+
+                //#manualAccept end
+
+                */
+
+                //#finishwork begin
+
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        //#finishwork end
+
+        //#ClosePort begin
+
+	if (id == 0)
+	{
+	        exampleWriter->getServerBuffer()->GetComm()->ClosePort();
+	}
+
+        //#ClosePort end
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+#else
+
+        std::cout << "Interprogram DSM does not work properly with OpenMPI" << std::endl;
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/XdmfConnectTest.cpp b/core/dsm/tests/Cxx/XdmfConnectTest.cpp
new file mode 100644
index 0000000..ca2d872
--- /dev/null
+++ b/core/dsm/tests/Cxx/XdmfConnectTest.cpp
@@ -0,0 +1,320 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+// This test does not work properly with openmpi
+// due to an issue with the openmpi code
+#ifndef OPEN_MPI
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        XdmfDSMCommMPI::SetUseEnvFileName(true);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "Data";
+
+        // Initializing objects
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, "Connect 1");
+
+        MPI_Comm_rank(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm(), &id);
+        MPI_Comm_size(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm(), &size);
+
+//        exampleWriter->getServerBuffer()->GetComm()->SetApplicationName("Connect 1");
+
+/*
+        XdmfDSMCommMPI * testComm = new XdmfDSMCommMPI();
+        testComm->DupComm(comm);
+        testComm->Init();
+        XdmfDSMBuffer * testBuffer = new XdmfDSMBuffer();
+        testBuffer->SetIsServer(false);
+        testBuffer->SetComm(testComm);
+        testBuffer->SetIsConnected(true);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, testBuffer);
+*/
+
+        //#initMPI end
+
+        #ifdef  _WIN32
+                Sleep(500)
+        #else
+                sleep(5);
+        #endif
+
+	char * configFileName = strdup(exampleWriter->getServerBuffer()->GetComm()->GetDsmFileName().c_str());
+
+	std::ifstream testStream;
+        testStream.open(configFileName);
+
+	while (!testStream.good()) { // Wait for the config file to be generated
+		testStream.close();
+		#ifdef  _WIN32
+			Sleep(500)
+		#else
+			sleep(5);
+		#endif
+		testStream.open(configFileName);
+	}
+
+        //#ReadDsmPortName begin
+
+        exampleWriter->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+        //#ReadDsmPortName end
+
+        //#GetDsmPortName begin
+
+        char * portName = exampleWriter->getServerBuffer()->GetComm()->GetDsmPortName();
+
+        //#GetDsmPortName end
+
+        //#SetDsmPortName begin
+
+        exampleWriter->getServerBuffer()->GetComm()->SetDsmPortName(portName);
+
+        //#SetDsmPortName end
+
+        //#Connect begin
+
+        exampleWriter->getServerBuffer()->Connect();
+
+        //#Connect end
+
+        exampleWriter->getServerBuffer()->SetIsConnected(true);
+
+        /*
+
+        //#manualConnect begin
+
+        try
+        {
+                status = exampleWriter->getServerBuffer()->GetComm()->Connect();
+        }
+        catch (XdmfError e)
+        {
+                // Connection failed
+                std::cout << e.what() << std::endl;
+                return 0;
+        }
+        if (status == MPI_SUCCESS)
+        {
+                exampleWriter->getServerBuffer()->SetIsConnected(true);
+                try
+                {
+                        exampleWriter->getServerBuffer()->ReceiveInfo();
+                }
+                catch (XdmfError e)
+                {
+                        //ReceiveInfo failed
+                        std::cout << e.what() << std::endl;
+                        return 0;
+                }
+        }
+
+        //#manualConnect end
+
+        */
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Testing the structure of the DSM
+        if (id == 0)
+        {
+          std::vector<unsigned int> structuresizes;
+          structuresizes.push_back(1);
+          structuresizes.push_back(1);
+          structuresizes.push_back(2);
+          structuresizes.push_back(2);
+          std::vector<std::string> structurenames;
+          structurenames.push_back("Accept");
+          structurenames.push_back("Server");
+          structurenames.push_back("Connect 1");
+          structurenames.push_back("Connect 2");
+          std::vector<std::pair<std::string, unsigned int> > teststructure = exampleWriter->getServerBuffer()->GetComm()->GetDsmProcessStructure();
+          printf("DSM Structure:\n");
+          assert(teststructure.size() == structurenames.size());
+          for (unsigned int i = 0; i < teststructure.size(); ++i)
+          {
+            std::cout << "(" << teststructure[i].first << ", " << teststructure[i].second << ")" << "=="
+            << "(" << structurenames[i] << ", " << structuresizes[i] << ")" << std::endl;
+            assert(teststructure[i].second == structuresizes[i]);
+            assert(teststructure[i].first.compare(structurenames[i]) == 0);
+          }
+        }
+        
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        shared_ptr<XdmfArray> writeArray = XdmfArray::New();
+
+        for (int i = 1; i <= 5; ++i)
+        {
+                writeArray->pushBack(i*(id+1));
+        }
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        // Test Notify
+        int notify = exampleWriter->waitOn(newPath, "notify");
+
+        printf("notification value = %d\n", notify);
+
+        assert(notify == 3);
+
+        // Done initializing
+
+        for (int i = 0; i < size; ++i)
+        {
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+                if (i == id)
+                {
+                        std::stringstream outputstream;
+                        outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                        for (unsigned int j = 0; j < writeArray->getSize(); ++j)
+                        {
+                                outputstream << "[" << j << "]" << writeArray->getValue<int>(j) << std::endl;
+                        }
+                        std::cout << outputstream.str();
+                }
+        }
+
+        for (unsigned int numloops = 0; numloops < 4; ++numloops)
+        {
+                if (writeArray->getNumberHeavyDataControllers() > 0)
+                {
+                        writeArray->removeHeavyDataController(0);
+                }
+                writeArray->insert(writeController);
+        
+
+                if (id == size - 1)
+                {
+                        std::cout << std::endl << std::endl;
+                }
+
+                writeArray->accept(exampleWriter);
+
+                if (id == size - 1)
+                {
+                        int sentData = 1;
+                        exampleWriter->getServerBuffer()->SendAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                        exampleWriter->getServerBuffer()->ReceiveAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+                writeArray->removeHeavyDataController(0);
+                writeArray->insert(readController);
+                writeArray->release();
+                writeArray->read();
+
+                for (int i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+                        if (i == id)
+                        {
+                                std::stringstream outputstream;
+                                outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                                for (unsigned int j = 0; j < writeArray->getSize(); ++j)
+                                {
+                                        int tempVal = writeArray->getValue<int>(j);
+                                        tempVal = tempVal * 2;
+                                        writeArray->insert(j, tempVal);
+                                        outputstream << "[" << j << "]" << writeArray->getValue<int>(j) << std::endl;
+                                }
+                                std::cout << outputstream.str();
+                        }
+                }
+        }
+
+        if (id == size - 1)
+        {
+                int sentData = 1;
+                exampleWriter->getServerBuffer()->SendAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        //#Disconnectmanager begin
+
+        exampleWriter->getServerBuffer()->Disconnect();
+
+        //#Disconnectmanager end
+
+        //#Disconnectcomm begin
+
+        exampleWriter->getServerBuffer()->GetComm()->Disconnect();
+
+        //#Disconnectcomm end
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/XdmfConnectTest2.cpp b/core/dsm/tests/Cxx/XdmfConnectTest2.cpp
new file mode 100644
index 0000000..14c98b1
--- /dev/null
+++ b/core/dsm/tests/Cxx/XdmfConnectTest2.cpp
@@ -0,0 +1,244 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+// This test does not work properly with openmpi
+// due to an issue with the openmpi code
+#ifndef OPEN_MPI
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        XdmfDSMCommMPI::SetUseEnvFileName(true);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "Data";
+
+        // Initializing objects
+
+/*
+        //since the start and end ids are larger than the size there are no buffers alloted
+        //thus, no blockage occurs
+        XdmfDSMCommMPI * testComm = new XdmfDSMCommMPI();
+        testComm->DupComm(comm);
+        testComm->Init();
+        testComm->SetApplicationName("Connect 2");
+        XdmfDSMBuffer * testBuffer = new XdmfDSMBuffer();
+        testBuffer->SetIsServer(false);
+        testBuffer->SetComm(testComm);
+        testBuffer->SetIsConnected(true);
+*/
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, "Connect 2");
+
+        MPI_Comm_rank(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm(), &id);
+        MPI_Comm_size(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm(), &size);
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+
+        readArray->initialize<int>(0);
+        readArray->reserve(5);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        #ifdef  _WIN32
+                Sleep(1000)
+        #else
+                sleep(10);
+        #endif
+
+        char * configFileName = strdup(exampleWriter->getServerBuffer()->GetComm()->GetDsmFileName().c_str());
+
+        std::ifstream testStream;
+        testStream.open(configFileName);
+
+        while (!testStream.good()) { // Wait for the config file to be generated
+                testStream.close();
+                #ifdef  _WIN32
+                        Sleep(500)
+                #else
+                        sleep(5);
+                #endif
+                testStream.open(configFileName);
+        }
+
+        readController->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+        readController->getServerBuffer()->Connect();
+
+//        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, testBuffer);
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        // Done initialization
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Let waits be set up
+        #ifdef  _WIN32
+                Sleep(100)
+        #else
+                sleep(1);
+        #endif
+
+        // Test Notify
+        exampleWriter->waitRelease(newPath, "notify", 3);
+
+        // Testing the structure of the DSM
+        if (id == 0)
+        {
+          std::vector<unsigned int> structuresizes;
+          structuresizes.push_back(1);
+          structuresizes.push_back(1);
+          structuresizes.push_back(2);
+          structuresizes.push_back(2);
+          std::vector<std::string> structurenames;
+          structurenames.push_back("Accept");
+          structurenames.push_back("Server");
+          structurenames.push_back("Connect 1");
+          structurenames.push_back("Connect 2");
+          std::vector<std::pair<std::string, unsigned int> > teststructure = exampleWriter->getServerBuffer()->GetComm()->GetDsmProcessStructure();
+          printf("DSM Structure:\n");
+          for (unsigned int i = 0; i < teststructure.size(); ++i)
+          {
+            std::cout << "(" << teststructure[i].first << ", " << teststructure[i].second << ")" << "=="
+            << "(" << structurenames[i] << ", " << structuresizes[i] << ")" << std::endl;
+            assert(teststructure[i].second == structuresizes[i]);
+            assert(teststructure[i].first.compare(structurenames[i]) == 0);
+          }
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        for (unsigned int numloops = 0; numloops < 4; ++numloops)
+        {
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        readController->getServerBuffer()->ReceiveAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+                if (readArray->getNumberHeavyDataControllers() > 0)
+                {
+                        readArray->removeHeavyDataController(0);
+                }
+                readArray->insert(readController);
+                readArray->read();
+
+                for (int i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+                        if (i == id)
+                        {
+                                std::stringstream outputstream;
+                                outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                                for (unsigned int j = 0; j < readArray->getSize(); ++j)
+                                {
+                                        int tempVal = readArray->getValue<int>(j);
+                                        tempVal = tempVal * 3;
+                                        readArray->insert(j, tempVal);
+                                        outputstream << "[" << j << "]" << readArray->getValue<int>(j) << std::endl;
+                                }
+                                std::cout << outputstream.str();
+                        }
+                }
+
+                MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+                if (id == 0)
+                {
+                        std::cout << std::endl << std::endl;
+                }
+
+                readArray->removeHeavyDataController(0);
+                readArray->insert(writeController);
+
+                readArray->accept(exampleWriter);
+
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        readController->getServerBuffer()->SendAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+        }
+
+        //this last acknowledgment is to end the loop.
+
+        if (id == 0)
+        {
+                int receiveData = 0;
+                readController->getServerBuffer()->ReceiveAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+        }
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Do work stuff here
+
+        if (id == 0)
+        {
+                readController->stopDSM();
+        }
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetInterComm());
+
+        MPI_Finalize();
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/XdmfConnectTest2Paged.cpp b/core/dsm/tests/Cxx/XdmfConnectTest2Paged.cpp
new file mode 100644
index 0000000..1abc46f
--- /dev/null
+++ b/core/dsm/tests/Cxx/XdmfConnectTest2Paged.cpp
@@ -0,0 +1,236 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+// This test does not work properly with openmpi
+// due to an issue with the openmpi code
+#ifndef OPEN_MPI
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        XdmfDSMCommMPI::SetUseEnvFileName(true);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "Data";
+
+        // Initializing objects
+
+        //since the start and end ids are larger than the size there are no buffers alloted
+        //thus, no blockage occurs
+        XdmfDSMCommMPI * testComm = new XdmfDSMCommMPI();
+        testComm->DupComm(comm);
+        testComm->Init();
+        testComm->SetApplicationName("Connect 2");
+        XdmfDSMBuffer * testBuffer = new XdmfDSMBuffer();
+        testBuffer->SetIsServer(false);
+        testBuffer->SetComm(testComm);
+        testBuffer->SetIsConnected(true);
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+
+        readArray->initialize<int>(0);
+        readArray->reserve(5);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                testBuffer);
+
+        #ifdef  _WIN32
+                Sleep(1000)
+        #else
+                sleep(10);
+        #endif
+
+        char * configFileName = strdup(testComm->GetDsmFileName().c_str());
+
+        std::ifstream testStream;
+        testStream.open(configFileName);
+
+        while (!testStream.good()) { // Wait for the config file to be generated
+                testStream.close();
+                #ifdef  _WIN32
+                        Sleep(500)
+                #else
+                        sleep(5);
+                #endif
+                testStream.open(configFileName);
+        }
+
+        readController->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+        readController->getServerBuffer()->Connect();
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, testBuffer);
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        // Done initialization
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Let waits be set up
+        #ifdef  _WIN32
+                Sleep(100)
+        #else
+                sleep(1);
+        #endif
+
+        // Test Notify
+        exampleWriter->waitRelease(newPath, "notify", 3);
+
+        // Testing the structure of the DSM
+        if (id == 0)
+        {
+          std::vector<unsigned int> structuresizes;
+          structuresizes.push_back(1);
+          structuresizes.push_back(1);
+          structuresizes.push_back(2);
+          structuresizes.push_back(2);
+          std::vector<std::string> structurenames;
+          structurenames.push_back("Application");
+          structurenames.push_back("Server");
+          structurenames.push_back("Connect 1");
+          structurenames.push_back("Connect 2");
+          std::vector<std::pair<std::string, unsigned int> > teststructure = exampleWriter->getServerBuffer()->GetComm()->GetDsmProcessStructure();
+          printf("DSM Structure:\n");
+          for (unsigned int i = 0; i < teststructure.size(); ++i)
+          {
+            std::cout << "(" << teststructure[i].first << ", " << teststructure[i].second << ")" << std::endl;
+            assert(teststructure[i].second == structuresizes[i]);
+            assert(teststructure[i].first.compare(structurenames[i]) == 0);
+          }
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        for (unsigned int numloops = 0; numloops < 4; ++numloops)
+        {
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        readController->getServerBuffer()->ReceiveAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+                if (readArray->getNumberHeavyDataControllers() > 0)
+                {
+                        readArray->removeHeavyDataController(0);
+                }
+                readArray->insert(readController);
+                readArray->read();
+
+                for (int i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+                        if (i == id)
+                        {
+                                std::stringstream outputstream;
+                                outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                                for (unsigned int j = 0; j < readArray->getSize(); ++j)
+                                {
+                                        int tempVal = readArray->getValue<int>(j);
+                                        tempVal = tempVal * 3;
+                                        readArray->insert(j, tempVal);
+                                        outputstream << "[" << j << "]" << readArray->getValue<int>(j) << std::endl;
+                                }
+                                std::cout << outputstream.str();
+                        }
+                }
+
+                MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+                if (id == 0)
+                {
+                        std::cout << std::endl << std::endl;
+                }
+
+                readArray->removeHeavyDataController(0);
+                readArray->insert(writeController);
+
+                readArray->accept(exampleWriter);
+
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        readController->getServerBuffer()->SendAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+        }
+
+        //this last acknowledgment is to end the loop.
+
+        if (id == 0)
+        {
+                int receiveData = 0;
+                readController->getServerBuffer()->ReceiveAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+        }
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Do work stuff here
+
+        if (id == 0)
+        {
+                readController->stopDSM();
+        }
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetInterComm());
+
+        MPI_Finalize();
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/Cxx/XdmfConnectTestPaged.cpp b/core/dsm/tests/Cxx/XdmfConnectTestPaged.cpp
new file mode 100644
index 0000000..cbfaa89
--- /dev/null
+++ b/core/dsm/tests/Cxx/XdmfConnectTestPaged.cpp
@@ -0,0 +1,315 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+// This test does not work properly with openmpi
+// due to an issue with the openmpi code
+#ifndef OPEN_MPI
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        XdmfDSMCommMPI::SetUseEnvFileName(true);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "Data";
+
+        // Initializing objects
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm);
+
+        exampleWriter->getServerBuffer()->GetComm()->SetApplicationName("Connect 1");
+
+/*
+        XdmfDSMCommMPI * testComm = new XdmfDSMCommMPI();
+        testComm->DupComm(comm);
+        testComm->Init();
+        XdmfDSMBuffer * testBuffer = new XdmfDSMBuffer();
+        testBuffer->SetIsServer(false);
+        testBuffer->SetComm(testComm);
+        testBuffer->SetIsConnected(true);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, testBuffer);
+*/
+
+        //#initMPI end
+
+        #ifdef  _WIN32
+                Sleep(500)
+        #else
+                sleep(5);
+        #endif
+
+	char * configFileName = strdup(exampleWriter->getServerBuffer()->GetComm()->GetDsmFileName().c_str());
+
+	std::ifstream testStream;
+        testStream.open(configFileName);
+
+	while (!testStream.good()) { // Wait for the config file to be generated
+		testStream.close();
+		#ifdef  _WIN32
+			Sleep(500)
+		#else
+			sleep(5);
+		#endif
+		testStream.open(configFileName);
+	}
+
+        //#ReadDsmPortName begin
+
+        exampleWriter->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+        //#ReadDsmPortName end
+
+        //#GetDsmPortName begin
+
+        char * portName = exampleWriter->getServerBuffer()->GetComm()->GetDsmPortName();
+
+        //#GetDsmPortName end
+
+        //#SetDsmPortName begin
+
+        exampleWriter->getServerBuffer()->GetComm()->SetDsmPortName(portName);
+
+        //#SetDsmPortName end
+
+        //#Connect begin
+
+        exampleWriter->getServerBuffer()->Connect();
+
+        //#Connect end
+
+        exampleWriter->getServerBuffer()->SetIsConnected(true);
+
+        /*
+
+        //#manualConnect begin
+
+        try
+        {
+                status = exampleWriter->getServerBuffer()->GetComm()->Connect();
+        }
+        catch (XdmfError e)
+        {
+                // Connection failed
+                std::cout << e.what() << std::endl;
+                return 0;
+        }
+        if (status == MPI_SUCCESS)
+        {
+                exampleWriter->getServerBuffer()->SetIsConnected(true);
+                try
+                {
+                        exampleWriter->getServerBuffer()->ReceiveInfo();
+                }
+                catch (XdmfError e)
+                {
+                        //ReceiveInfo failed
+                        std::cout << e.what() << std::endl;
+                        return 0;
+                }
+        }
+
+        //#manualConnect end
+
+        */
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Testing the structure of the DSM
+        if (id == 0)
+        {
+          std::vector<unsigned int> structuresizes;
+          structuresizes.push_back(1);
+          structuresizes.push_back(1);
+          structuresizes.push_back(2);
+          structuresizes.push_back(2);
+          std::vector<std::string> structurenames;
+          structurenames.push_back("Application");
+          structurenames.push_back("Server");
+          structurenames.push_back("Connect 1");
+          structurenames.push_back("Connect 2");
+          std::vector<std::pair<std::string, unsigned int> > teststructure = exampleWriter->getServerBuffer()->GetComm()->GetDsmProcessStructure();
+          printf("DSM Structure:\n");
+          for (unsigned int i = 0; i < teststructure.size(); ++i)
+          {
+            std::cout << "(" << teststructure[i].first << ", " << teststructure[i].second << ")" << std::endl;
+            assert(teststructure[i].second == structuresizes[i]);
+            assert(teststructure[i].first.compare(structurenames[i]) == 0);
+          }
+        }
+        
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        shared_ptr<XdmfArray> writeArray = XdmfArray::New();
+
+        for (int i = 1; i <= 5; ++i)
+        {
+                writeArray->pushBack(i*(id+1));
+        }
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        // Test Notify
+        int notify = exampleWriter->waitOn(newPath, "notify");
+
+        printf("notification value = %d\n", notify);
+
+        assert(notify == 3);
+
+        // Done initializing
+
+        for (int i = 0; i < size; ++i)
+        {
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+                if (i == id)
+                {
+                        std::stringstream outputstream;
+                        outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                        for (unsigned int j = 0; j < writeArray->getSize(); ++j)
+                        {
+                                outputstream << "[" << j << "]" << writeArray->getValue<int>(j) << std::endl;
+                        }
+                        std::cout << outputstream.str();
+                }
+        }
+
+        for (unsigned int numloops = 0; numloops < 4; ++numloops)
+        {
+                if (writeArray->getNumberHeavyDataControllers() > 0)
+                {
+                        writeArray->removeHeavyDataController(0);
+                }
+                writeArray->insert(writeController);
+        
+
+                if (id == size - 1)
+                {
+                        std::cout << std::endl << std::endl;
+                }
+
+                writeArray->accept(exampleWriter);
+
+                if (id == size - 1)
+                {
+                        int sentData = 1;
+                        exampleWriter->getServerBuffer()->SendAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                        exampleWriter->getServerBuffer()->ReceiveAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+                writeArray->removeHeavyDataController(0);
+                writeArray->insert(readController);
+                writeArray->release();
+                writeArray->read();
+
+                for (int i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+                        if (i == id)
+                        {
+                                std::stringstream outputstream;
+                                outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                                for (unsigned int j = 0; j < writeArray->getSize(); ++j)
+                                {
+                                        int tempVal = writeArray->getValue<int>(j);
+                                        tempVal = tempVal * 2;
+                                        writeArray->insert(j, tempVal);
+                                        outputstream << "[" << j << "]" << writeArray->getValue<int>(j) << std::endl;
+                                }
+                                std::cout << outputstream.str();
+                        }
+                }
+        }
+
+        if (id == size - 1)
+        {
+                int sentData = 1;
+                exampleWriter->getServerBuffer()->SendAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        //#Disconnectmanager begin
+
+        exampleWriter->getServerBuffer()->Disconnect();
+
+        //#Disconnectmanager end
+
+        //#Disconnectcomm begin
+
+        exampleWriter->getServerBuffer()->GetComm()->Disconnect();
+
+        //#Disconnectcomm end
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+#endif
+
+        return 0;
+}
diff --git a/core/dsm/tests/Python/CMakeLists.txt b/core/dsm/tests/Python/CMakeLists.txt
new file mode 100644
index 0000000..78b9918
--- /dev/null
+++ b/core/dsm/tests/Python/CMakeLists.txt
@@ -0,0 +1,51 @@
+include(AddTestsPython)
+
+# Add any dependencies that the python tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_PYTHON_DEPENDENCIES("XdmfCore")
+ADD_TEST_PYTHON_DEPENDENCIES("XdmfDSM")
+
+# Add any pythonpath directories that the python tests may need
+ADD_TEST_PYTHON_PYTHONPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_PYTHON_PYTHONPATH("${PYTHON_INCLUDE_MPI4PY_DIR}/../..")
+
+# Add any ldpath directories that the python tests may need
+ADD_TEST_PYTHON_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_PYTHON_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directories that the python tests may need
+ADD_TEST_PYTHON_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_PYTHON_PATH("${HDF5_BINARY_DIRS}")
+ADD_TEST_PYTHON_PATH("${LIBXML2_BINARY_DIRS}")
+
+# Add any python tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_PYTHON(testname inputfile))
+#       Read UsePYTHONTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    ADD_MPI_TEST_PYTHON(PythonDSM.sh XdmfExampleDsmTest)
+    ADD_MPI_TEST_PYTHON(PythonConnect.sh XdmfExampleAcceptTest,XdmfExampleConnectTest2,XdmfExampleConnectTest)
+  endif(MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+else ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    ADD_MPI_TEST_PYTHON(CrayPythonConnect.sh XdmfExampleAcceptTest,XdmfExampleConnectTest2,XdmfExampleConnectTest)
+  endif(MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+
+# Add any python cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_PYTHON(testname outputfile1 ...))
+#       Read UsePYTHONTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    CLEAN_TEST_PYTHON(PythonDSM.sh)
+    CLEAN_TEST_PYTHON(PythonConnect.sh dsmconnect.cfg)
+  endif (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+else ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    CLEAN_TEST_PYTHON(CrayPythonConnect.sh dsmconnect.cfg)
+  endif(MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
diff --git a/core/dsm/tests/Python/CrayPythonConnect.sh b/core/dsm/tests/Python/CrayPythonConnect.sh
new file mode 100755
index 0000000..cdc4bf3
--- /dev/null
+++ b/core/dsm/tests/Python/CrayPythonConnect.sh
@@ -0,0 +1,5 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+echo "aprun -n 2 $PYTHON_EXECUTABLE ./XdmfExampleAcceptTest.py : -n 2 $PYTHON_EXECUTABLE ./XdmfExampleConnectTest.py : -n 2 $PYTHON_EXECUTABLE ./XdmfExampleConnectTest2.py"
+
+aprun -n 2 $PYTHON_EXECUTABLE ./XdmfExampleAcceptTest.py : -n 2 $PYTHON_EXECUTABLE ./XdmfExampleConnectTest.py : -n 2 $PYTHON_EXECUTABLE ./XdmfExampleConnectTest2.py
diff --git a/core/dsm/tests/Python/PythonConnect.sh b/core/dsm/tests/Python/PythonConnect.sh
new file mode 100755
index 0000000..c1889b9
--- /dev/null
+++ b/core/dsm/tests/Python/PythonConnect.sh
@@ -0,0 +1,7 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+$MPIEXEC -n 2 $PYTHON_EXECUTABLE ./XdmfExampleAcceptTest.py &
+
+$MPIEXEC -n 2 $PYTHON_EXECUTABLE ./XdmfExampleConnectTest.py &
+
+$MPIEXEC -n 2 $PYTHON_EXECUTABLE ./XdmfExampleConnectTest2.py
diff --git a/core/dsm/tests/Python/PythonDSM.sh b/core/dsm/tests/Python/PythonDSM.sh
new file mode 100755
index 0000000..f609f2e
--- /dev/null
+++ b/core/dsm/tests/Python/PythonDSM.sh
@@ -0,0 +1,3 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+$MPIEXEC -n 4 $PYTHON_EXECUTABLE ./XdmfExampleDsmTest.py
diff --git a/core/dsm/tests/Python/XdmfExampleAcceptTest.py b/core/dsm/tests/Python/XdmfExampleAcceptTest.py
new file mode 100644
index 0000000..04c1ead
--- /dev/null
+++ b/core/dsm/tests/Python/XdmfExampleAcceptTest.py
@@ -0,0 +1,82 @@
+print "Accept"
+
+from mpi4py.MPI import *
+from Xdmf import *
+
+if __name__ == "__main__":
+        if get_vendor()[0] == 'Open MPI':
+          print "Interprogram DSM does not work properly with OpenMPI"
+        else:
+          #//initMPI begin
+
+          dsmSize = 64
+          comm = COMM_WORLD
+
+          id = comm.Get_rank()
+          size = comm.Get_size()
+
+          newPath = "dsm";
+          numServersCores = size - 1;
+          numConnections = 2
+
+          exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, dsmSize/numServersCores, 1, 1, "Accept");
+
+          if id == 0:
+                  #//initMPI end
+
+                  #//GetDsmFileName begin
+
+                  connectionFileName = exampleWriter.getServerBuffer().GetComm().GetDsmFileName()
+
+                  #//GetDsmFileName end
+
+                  #//SetDsmFileName begin
+
+                  exampleWriter.getServerBuffer().GetComm().SetDsmFileName(connectionFileName)
+
+                  #//SetDsmFileName end
+
+                  #//OpenPort begin
+
+                  exampleWriter.getServerBuffer().GetComm().OpenPort()
+
+                  #//OpenPort end
+
+                  #//SendAccept begin
+
+                  exampleWriter.getServerBuffer().SendAccept(numConnections)
+
+                  #//SendAccept end
+
+                  '''
+
+                  #//manualAccept begin
+
+                  # Notify the server cores to accept connections
+                  for i in range(exampleWriter.getServerBuffer().StartServerId, exampleWriter.getServerBuffer().EndServerId+1):
+                          if i != exampleWriter.getServerBuffer().Comm.GetId():
+                                  exampleWriter.getServerBuffer().SendCommandHeader(XDMF_DSM_ACCEPT, i, 0, 0, XDMF_DSM_INTER_COMM)
+                                  exampleWriter.getServerBuffer().SendAcknowledgment(i, numConnections, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+                  # Accept connections
+                  exampleWriter.getServerBuffer().Comm.Accept(numConnections)
+                  # Distribute current DSM status
+                  exampleWriter.getServerBuffer().SendInfo()
+
+                  #//manualAccept end
+
+                  '''
+
+                  #//finishwork begin
+
+                  exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+          exampleWriter.getServerBuffer().GetComm().GetInterComm().Barrier()
+
+          #//finishwork end
+
+          #//ClosePort begin
+
+	  if id == 0:
+	          exampleWriter.getServerBuffer().GetComm().ClosePort()
+
+          #//ClosePort end
diff --git a/core/dsm/tests/Python/XdmfExampleConnectTest.py b/core/dsm/tests/Python/XdmfExampleConnectTest.py
new file mode 100644
index 0000000..621e306
--- /dev/null
+++ b/core/dsm/tests/Python/XdmfExampleConnectTest.py
@@ -0,0 +1,212 @@
+print "Connect 1"
+
+from mpi4py.MPI import *
+from Xdmf import *
+import time
+import os.path
+
+if __name__ == "__main__":
+        if get_vendor()[0] != 'Open MPI':
+          #//initMPI begin
+
+          dsmSize = 64
+          comm = COMM_WORLD
+
+          id = comm.Get_rank()
+          size = comm.Get_size()
+
+          newPath = "dsm"
+          newSetPath = "Data"
+
+          # Initializing objects
+
+          '''
+          testComm = XdmfDSMCommMPI()
+          testComm.DupComm(comm)
+          testComm.Init()
+          testBuffer = XdmfDSMBuffer()
+          testBuffer.SetIsServer(False)
+          testBuffer.SetComm(testComm)
+          testBuffer.SetIsConnected(True)
+          '''
+
+          exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, "Connect 1")
+
+          id = exampleWriter.getServerBuffer().GetComm().GetId()
+          size = exampleWriter.getServerBuffer().GetComm().GetIntraSize()
+
+          testComm = exampleWriter.getServerBuffer().GetComm()
+
+          #//initMPI end
+
+          time.sleep(5)
+
+          configPath = testComm.GetDsmFileName()
+
+          while not os.path.exists(configPath):
+            time.sleep(5)
+
+          #//ReadDsmPortName begin
+
+          exampleWriter.getServerBuffer().GetComm().ReadDsmPortName()
+
+          #//ReadDsmPortName end
+
+          #//GetDsmPortName begin
+
+          portName = exampleWriter.getServerBuffer().GetComm().GetDsmPortName()
+
+          #//GetDsmPortName end
+
+          #//SetDsmPortName begin
+
+          exampleWriter.getServerBuffer().GetComm().SetDsmPortName(portName)
+
+          #//SetDsmPortName end
+
+          #//Connect begin
+
+          exampleWriter.getServerBuffer().Connect()
+
+          #//Connect end
+
+          '''
+
+          #//manualConnect begin
+
+          try:
+                  status = exampleWriter.getServerBuffer().GetComm().Connect()
+                  if status == MPI_SUCCESS:
+                  exampleWriter.getServerBuffer().SetIsConnected(true)
+                  try:
+                          exampleWriter.getServerBuffer().ReceiveInfo()
+                  except RuntimeError as e:
+                          # ReceiveInfo failed
+                          print e.args[0]
+          except RuntimeError as e:
+                  # Connection failed
+                  print e.args[0]
+
+          #//manualConnect end
+
+          '''
+
+          exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+          writeArray = XdmfArray.New()
+
+          for i in range(1, 6):
+                  writeArray.pushBackAsInt32(i*(id+1))
+
+          writeStartVector = UInt32Vector()
+          writeStrideVector = UInt32Vector()
+          writeCountVector = UInt32Vector()
+          writeDataSizeVector = UInt32Vector()
+
+          writeStartVector.push_back(id*5)
+          writeStrideVector.push_back(1)
+          writeCountVector.push_back(5)
+          writeDataSizeVector.push_back(5*size)
+
+          writeController = XdmfHDF5ControllerDSM.New(
+                  newPath,
+                  newSetPath,
+                  XdmfArrayType.Int32(),
+                  writeStartVector,
+                  writeStrideVector,
+                  writeCountVector,
+                  writeDataSizeVector,
+                  exampleWriter.getServerBuffer());
+
+          readStartVector = UInt32Vector()
+          readStrideVector = UInt32Vector()
+          readCountVector = UInt32Vector()
+          readDataSizeVector = UInt32Vector()
+
+          readStartVector.push_back(5*id);
+          readStrideVector.push_back(1);
+          readCountVector.push_back(5);
+          readDataSizeVector.push_back(5*size);
+
+          readController = XdmfHDF5ControllerDSM.New(
+                  newPath,
+                  newSetPath,
+                  XdmfArrayType.Int32(),
+                  readStartVector,
+                  readStrideVector,
+                  readCountVector,
+                  readDataSizeVector,
+                  exampleWriter.getServerBuffer());
+
+          exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab);
+
+          # Done initializing
+
+          print "for i in range", 0, " ", size
+
+          for i in range(0, size):
+                  print "core id checking array", i
+                  exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                  print i, "==", id
+                  if i == id:
+                          outputstream = "Array on core " + str(exampleWriter.getServerBuffer().GetComm().GetInterId()) + " contains:\n"
+                          for j in range(0, writeArray.getSize()):
+                                  outputstream = outputstream + "[" + str(j) + "]" + str(writeArray.getValueAsInt32(j)) + "\n"
+                          print outputstream
+
+          loopamount = 4
+
+          for numloops in range(0, loopamount):
+                  print "loop ", numloops
+                  if writeArray.getNumberHeavyDataControllers() > 0:
+                          writeArray.removeHeavyDataController(0);
+                  writeArray.insert(writeController)
+
+
+                  if id == size - 1:
+                          print "\n\n"
+
+                  writeArray.accept(exampleWriter)
+
+                  if id == size - 1:
+                          sentData = 1
+                          exampleWriter.getServerBuffer().SendAcknowledgment(exampleWriter.getServerBuffer().GetComm().GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+                          exampleWriter.getServerBuffer().ReceiveAcknowledgment(exampleWriter.getServerBuffer().GetComm().GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+                  exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+                  writeArray.removeHeavyDataController(0)
+                  writeArray.insert(readController)
+                  writeArray.release()
+                  writeArray.read()
+
+                  for i in range (0, size):
+                          exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                          if i == id:
+                                  outputstream = "Array on core " + str(exampleWriter.getServerBuffer().GetComm().GetInterId()) + " contains:\n"
+                                  for j in range(0, writeArray.getSize()):
+                                          tempVal = writeArray.getValueAsInt32(j)
+                                          tempVal = tempVal * 2
+                                          writeArray.insertAsInt32(j, [tempVal])
+                                          outputstream = outputstream + "[" + str(j) + "]" + str(writeArray.getValueAsInt32(j)) + "\n"
+                                  print outputstream
+
+          if id == size - 1:
+                  sentData = 1
+                  exampleWriter.getServerBuffer().SendAcknowledgment(exampleWriter.getServerBuffer().GetComm().GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+          exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+          exampleWriter.getServerBuffer().GetComm().GetInterComm().Barrier()
+
+          #//Disconnectmanager begin
+
+          exampleWriter.getServerBuffer().Disconnect()
+
+          #//Disconnectmanager end
+
+          #//Disconnectcomm begin
+
+          exampleWriter.getServerBuffer().GetComm().Disconnect()
+
+          #//Disconnectcomm end
diff --git a/core/dsm/tests/Python/XdmfExampleConnectTest2.py b/core/dsm/tests/Python/XdmfExampleConnectTest2.py
new file mode 100644
index 0000000..4e561c9
--- /dev/null
+++ b/core/dsm/tests/Python/XdmfExampleConnectTest2.py
@@ -0,0 +1,160 @@
+print "Connect 2"
+
+from mpi4py.MPI import *
+from Xdmf import *
+import time
+import os.path
+
+if __name__ == "__main__":
+        if get_vendor()[0] != 'Open MPI':
+          #//initMPI begin
+
+          dsmSize = 64
+          comm = COMM_WORLD
+
+          id = comm.Get_rank()
+          size = comm.Get_size()
+
+          newPath = "dsm"
+          newSetPath = "Data"
+
+          # Initializing objects
+
+          '''
+          testComm = XdmfDSMCommMPI()
+          testComm.DupComm(comm)
+          testComm.Init()
+          testBuffer = XdmfDSMBuffer()
+          testBuffer.SetIsServer(False)
+          testBuffer.SetComm(testComm)
+          testBuffer.SetIsConnected(True)
+          '''
+
+          exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, "Connect 2")
+
+          id = exampleWriter.getServerBuffer().GetComm().GetId()
+          size = exampleWriter.getServerBuffer().GetComm().GetIntraSize()
+
+          testBuffer = exampleWriter.getServerBuffer()
+          testComm = testBuffer.GetComm()
+
+          readStartVector = UInt32Vector()
+          readStrideVector = UInt32Vector()
+          readCountVector = UInt32Vector()
+          readDataSizeVector = UInt32Vector()
+
+          readStartVector.push_back(5*id)
+          readStrideVector.push_back(1)
+          readCountVector.push_back(5)
+          readDataSizeVector.push_back(5*size)
+
+          readArray = XdmfArray.New()
+
+          readArray.initializeAsInt32(0)
+          readArray.reserve(5)
+
+          readController = XdmfHDF5ControllerDSM.New(
+                  newPath,
+                  newSetPath,
+                  XdmfArrayType.Int32(),
+                  readStartVector,
+                  readStrideVector,
+                  readCountVector,
+                  readDataSizeVector,
+                  testBuffer);
+
+          time.sleep(10)
+
+          configPath = testComm.GetDsmFileName()
+
+          while not os.path.exists(configPath):
+                  time.sleep(5)
+
+          readController.getServerBuffer().GetComm().ReadDsmPortName();
+
+          readController.getServerBuffer().Connect();
+
+          exampleWriter = XdmfHDF5WriterDSM.New(newPath, testBuffer);
+
+          writeStartVector = UInt32Vector();
+          writeStrideVector = UInt32Vector();
+          writeCountVector = UInt32Vector();
+          writeDataSizeVector = UInt32Vector();
+
+          writeStartVector.push_back(id*5);
+          writeStrideVector.push_back(1);
+          writeCountVector.push_back(5);
+          writeDataSizeVector.push_back(5*size);
+
+          writeController = XdmfHDF5ControllerDSM.New(
+                  newPath,
+                  newSetPath,
+                  XdmfArrayType.Int32(),
+                  writeStartVector,
+                  writeStrideVector,
+                  writeCountVector,
+                  writeDataSizeVector,
+                  exampleWriter.getServerBuffer());
+
+          exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab);
+
+          # Done initialization
+
+          readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+          loopamount = 4
+
+          print str(range(0, loopamount)) + "'s type = " + str(type(range(0, loopamount)))
+
+          for numloops in range(0, loopamount):
+                  if id == 0:
+                          receiveData = 0
+                          readController.getServerBuffer().ReceiveAcknowledgment(readController.getServerBuffer().GetComm().GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+                  readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+                  if readArray.getNumberHeavyDataControllers() > 0:
+                          readArray.removeHeavyDataController(0)
+                  readArray.insert(readController)
+                  readArray.read()
+
+                  for i in range(0, size):
+                          readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                          if i == id:
+                                  outputstream = " "
+                                  outputstream = outputstream + "Array on core " + str(exampleWriter.getServerBuffer().GetComm().GetInterId()) + " contains:\n"
+                                  for j in range(0, readArray.getSize()):
+                                          tempVal = readArray.getValueAsInt32(j)
+                                          tempVal = tempVal * 3
+                                          readArray.insertAsInt32(j, [tempVal])
+                                          outputstream = outputstream + "[" + str(j) + "]" + str(readArray.getValueAsInt32(j))+ "\n"
+                                  print outputstream
+
+                  readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                  if id == 0:
+                          print "\n\n"
+
+                  readArray.removeHeavyDataController(0)
+                  readArray.insert(writeController)
+
+                  readArray.accept(exampleWriter)
+
+                  if id == 0:
+                          receiveData = 0
+                          readController.getServerBuffer().SendAcknowledgment(readController.getServerBuffer().GetComm().GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+
+          # This last acknowledgment is to end the loop.
+
+          if id == 0:
+                  receiveData = 0;
+                  readController.getServerBuffer().ReceiveAcknowledgment(readController.getServerBuffer().GetComm().GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+          readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+          if id == 0:
+                  readController.stopDSM()
+
+          readController.getServerBuffer().GetComm().GetInterComm().Barrier()
+
+          readController.getServerBuffer().Disconnect()
diff --git a/core/dsm/tests/Python/XdmfExampleDsmTest.py b/core/dsm/tests/Python/XdmfExampleDsmTest.py
new file mode 100644
index 0000000..0631837
--- /dev/null
+++ b/core/dsm/tests/Python/XdmfExampleDsmTest.py
@@ -0,0 +1,621 @@
+from mpi4py.MPI import *
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initMPI begin
+
+        #The total size of the DSM being created
+        dsmSize = 64
+        comm = COMM_WORLD
+
+        id = comm.Get_rank()
+        size = comm.Get_size()
+
+        #//initMPI end
+
+        testArray = XdmfArray.New()
+        testArray.initializeAsInt32(0)
+
+        for i in range(1,5):
+                testArray.pushBackAsInt32(i*(id+1))
+
+        #//initwritevector begin
+
+        newPath = "dsm"
+        newSetPath = "data"
+
+        numServersCores = 2
+
+        writeStartVector = UInt32Vector()
+        writeStartVector.push_back(id*4)
+        #writeStartVector.push_back(id);
+        writeStrideVector = UInt32Vector()
+        writeStrideVector.push_back(1)
+        #writeStrideVector.push_back(size-3);
+        writeCountVector = UInt32Vector()
+        writeCountVector.push_back(4)
+        writeDataSizeVector = UInt32Vector()
+        writeDataSizeVector.push_back(4*(size-numServersCores))
+
+        #//initwritevector end
+
+        #//splitcomm begin
+
+        ServerIds = []
+
+        for i in range(size-numServersCores, size):
+                ServerIds.append(i)
+
+        workers = comm.Get_group().Excl(ServerIds)
+
+        workerComm = comm.Create(workers)
+
+        #//splitcomm end
+
+        #//initwritergenerate begin
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1)
+
+        #//initwritergenerate end
+
+        '''
+        #//initcontrollergenerate begin
+
+        exampleController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                comm,
+                dsmSize/numServersCores,
+                size-numServersCores,
+                size-1)
+
+        #//initcontrollergenerate end
+        '''
+
+        
+
+        # Split out sub-comm for the worker cores
+        # Server cores will not progress to this point until after the servers are done running
+
+        #//startworksection begin
+
+        if (id < size - numServersCores):
+
+                #//startworksection end
+
+                # This section is to demonstrate the functionality of the XdmfDSM classes
+
+                #//setServerModewriter begin
+
+                exampleWriter.setServerMode(True)
+
+                #//setServerModewriter end
+
+                #//getServerModewriter begin
+
+                exampleServerMode = exampleWriter.getServerMode()
+
+                #//getServerModewriter end
+
+                #//getWorkerCommwriter begin
+
+                exampleWorkerComm = exampleWriter.getWorkerComm()
+
+                #//getWorkerCommwriter end
+
+                #//setWorkerCommwriter begin
+
+                exampleWriter.setWorkerComm(exampleWorkerComm)
+
+                #//setWorkerCommwriter end
+
+                '''
+                #//getWorkerCommcontroller begin
+
+                exampleWorkerComm = exampleController.getWorkerComm()
+
+                #//getWorkerCommcontroller end
+
+                #//setWorkerCommcontroller begin
+
+                exampleController.setWorkerComm(exampleWorkerComm)
+
+                #//setWorkerCommcontroller end
+
+                #//setServerModecontroller begin
+
+                exampleController.setServerMode(True)
+
+                #//setServerModecontroller end
+
+                #//getServerModecontroller begin
+
+                exampleControllerServerMode = exampleController.getServerMode()
+
+                #//getServerModecontroller end
+                '''
+
+                #//initcontrollerfrombuffer begin
+
+                writeController = XdmfHDF5ControllerDSM.New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType.Int32(),
+                        writeStartVector,
+                        writeStrideVector,
+                        writeCountVector,
+                        writeDataSizeVector,
+                        exampleWriter.getServerBuffer());
+
+                #//initcontrollerfrombuffer end
+
+                #//initwriterfrombuffer begin
+
+                exampleWriter2 = XdmfHDF5WriterDSM.New(newPath, exampleWriter.getServerBuffer());
+
+                #//initwriterfrombuffer end
+
+                writeController.setServerMode(True)
+                exampleControllerServerMode = writeController.getServerMode()
+
+                #//getServerBufferwriter begin
+
+                exampleBuffer = exampleWriter.getServerBuffer()
+
+                #//getServerBufferwriter end
+
+                #//setBufferwriter begin
+
+                exampleWriter.setBuffer(exampleBuffer)
+
+                #//setBufferwriter end
+
+                '''
+                #//getServerBuffercontroller begin
+
+                exampleBuffer = exampleController.getServerBuffer()
+
+                #//getServerBuffercontroller end
+
+                #//setBuffercontroller begin
+
+                exampleController.setBuffer(exampleBuffer)
+
+                #//setBuffercontroller end
+                '''
+
+                #//GetIsConnectedbuffer begin
+
+                exampleIsConnected = exampleBuffer.GetIsConnected()
+
+                #//GetIsConnectedbuffer end
+
+                #//SetIsConnectedbuffer begin
+
+                exampleBuffer.SetIsConnected(exampleIsConnected)
+
+                #//SetIsConnectedbuffer end
+
+                #//GetDataPointer begin
+
+                exampleDataPointer = exampleBuffer.GetDataPointer()
+
+                #//GetDataPointer end
+
+                #//GetDsmTypebuffer begin
+
+                exampleDSMType = exampleBuffer.GetDsmType()
+
+                #//GetDsmTypebuffer end
+
+                #//SetDsmTypebuffer begin
+
+                exampleBuffer.SetDsmType(XDMF_DSM_TYPE_UNIFORM)
+
+                #//SetDsmTypebuffer end
+
+                #//GetIsServerbuffer begin
+
+                exampleBufferIsServer = exampleBuffer.GetIsServer()
+
+                #//GetIsServerbuffer end
+
+                #//SetIsServerbuffer begin
+
+                exampleBuffer.SetIsServer(exampleBufferIsServer)
+
+                #//SetIsServerbuffer end
+
+                #//GetStartAddress begin
+
+                exampleBufferStart = exampleBuffer.GetStartAddress()
+
+                #//GetStartAddress end
+
+                #//GetEndAddress begin
+
+                exampleBufferEnd = exampleBuffer.GetEndAddress()
+
+                #//GetEndAddress end
+
+                #//GetStartServerId begin
+
+                exampleServerStart = exampleBuffer.GetStartServerId()
+
+                #//GetStartServerId end
+
+                #//GetEndServerid begin
+
+                exampleServerEnd = exampleBuffer.GetEndServerId()
+
+                #//GetEndServerId end
+
+                #//GetLength begin
+
+                exampleBufferLength = exampleBuffer.GetLength()
+
+                #//GetLength end
+
+                #//GetTotalLength begin
+
+                exampleTotalBufferLength = exampleBuffer.GetTotalLength()
+
+                #//GetTotalLength end
+
+                #//GetBlockLengthbuffer begin
+
+                exampleBufferBlockLength = exampleBuffer.GetBlockLength()
+
+                #//GetBlockLengthbuffer end
+
+                #//SetBlockLengthbuffer begin
+
+                exampleBuffer.SetBlockLength(exampleBufferBlockLength)
+
+                #//SetBlockLengthbuffer end
+
+                '''
+                #//ConfigureUniform begin
+
+                exampleBuffer.ConfigureUniform(exampleBuffer.GetComm(), dsmSize/numServersCores, size - numServersCores, size - 1)
+
+                #//ConfigureUniform end
+                '''
+                sendingCore = -1
+
+                #//SendCommandHeader begin
+
+                if (id == sendingCore):
+                        exampleBuffer.SendCommandHeader(XDMF_DSM_OPCODE_DONE, 1, 0, 0, XDMF_DSM_INTER_COMM)
+
+                #//SendCommandHeader end
+
+                #//SendData begin
+
+                if (id == sendingCore):
+                        sentData = "datastring"
+                        exampleBuffer.SendData(1, sentData, 0, XDMF_DSM_PUT_DATA_TAG, 0, XDMF_DSM_INTER_COMM)
+
+                #//SendData end
+
+                #//SendAcknowledgment begin
+
+                if (id == 1):
+                        sentData = 1
+                        exampleBuffer.SendAcknowledgment(0, sentData, XDMF_DSM_PUT_DATA_TAG, XDMF_DSM_INTER_COMM)
+
+                #//SendAcknowledgment end
+
+                #//ReceiveAcknowledgement begin
+
+                if (id == 0):
+                        recvData = 0
+                        exampleBuffer.ReceiveAcknowledgment(1, recvData, XDMF_DSM_PUT_DATA_TAG, XDMF_DSM_INTER_COMM)
+
+                #//ReceiveAcknowledgement end
+
+
+
+                ServerIds = []
+
+                for i in range(0, (size - numServersCores) / 2):
+                        ServerIds.append(i)
+
+                readingCores = workerComm.Get_group().Excl(ServerIds)
+
+                readComm = workerComm.Create(readingCores)
+
+                writingCores = workerComm.Get_group().Incl(ServerIds)
+
+                writeComm = workerComm.Create(writingCores)
+
+                exampleBuffer.GetComm().DupComm(workerComm)
+
+                #//BufferService begin
+
+                if (id == 0):
+                        serviceOut = exampleBuffer.BufferService()
+
+                if (id == 1):
+                        exampleBuffer.SendCommandHeader(XDMF_DSM_OPCODE_DONE, 0, 0, 0, XDMF_DSM_INTER_COMM)
+
+                #//BufferService end
+
+                #//BufferServiceLoop begin
+
+                if (id == 0):
+                        exampleBuffer.BufferServiceLoop()
+
+                if (id == 1):
+                        exampleBuffer.SendCommandHeader(XDMF_DSM_OPCODE_DONE, 0, 0, 0, XDMF_DSM_INTER_COMM)
+
+                #//BufferServiceLoop end
+
+                #//GetComm begin
+
+                exampleDSMComm = exampleBuffer.GetComm()
+
+                #//GetComm end
+
+                #//SetComm begin
+
+                exampleBuffer.SetComm(exampleDSMComm)
+
+                #//SetComm end
+
+                #//GetId begin
+
+                exampleIntraID = exampleDSMComm.GetId()
+
+                #//GetId end
+
+                #//GetIntraSize begin
+
+                exampleIntraSize = exampleDSMComm.GetIntraSize()
+
+                #//GetIntraSize end
+
+                #//GetInterId begin
+
+                exampleInterID = exampleDSMComm.GetInterId()
+
+                #//GetInterId end
+
+                #//GetInterSize begin
+
+                exampleInterSize = exampleDSMComm.GetInterSize()
+
+                #//GetInterSize end
+
+                #//GetInterCommType begin
+
+                exampleInterCommType = exampleDSMComm.GetInterCommType()
+
+                #//GetInterCommType end
+
+                #//initcomm begin
+
+                exampleDSMComm.Init()
+
+                #//initcomm end
+
+                #//GetIntraComm begin
+
+                exampleIntraComm = exampleDSMComm.GetIntraComm()
+
+                #//GetIntraComm end
+
+                #//DupComm begin
+
+                exampleDSMComm.DupComm(exampleIntraComm.Dup())
+
+                #//DupComm end
+
+
+
+                print type(exampleDSMComm.GetDsmPortName())
+                testName = "test"
+                exampleDSMComm.SetDsmPortName(testName)
+                print exampleDSMComm.GetDsmPortName()
+
+                '''
+
+                connectingGroup = True
+                if (id < 5):
+                        connectingGroup = True;
+                else:
+                        connectingGroup = False;
+
+                portString = ""
+
+                if (!connectingGroup):
+                        exampleDSMComm.OpenPort()
+                        portString = exampleDSMComm.GetDsmPortName()
+                        // Send the port string to the connecting group
+                        exampleDSMComm.Accept()
+                        // When done with connection
+                        exampleDSMComm.ClosePort()
+
+                if (connectingGroup):
+                        // Recieve string from Master group
+                        exampleDSMComm.SetDsmPortName(portString)
+                        exampleDSMComm.Connect()
+                        // When done with connection
+                        exampleDSMComm.Disconnect()
+
+                '''
+
+                # This is the end of the Demonstration
+
+                exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab)
+
+                testArray.insert(writeController)
+
+                for i in range(0, size-numServersCores):
+                        workerComm.Barrier()
+                        if (i == id):
+                                print "Core # " + str(id)
+                                print "Controller stats" 
+                                print "datasetpath = " + XdmfHeavyDataController.XdmfHDF5ControllerCast(testArray.getHeavyDataController(0)).getDataSetPath() 
+                                print "filepath = " + testArray.getHeavyDataController(0).getFilePath()
+                                outputVector = XdmfHeavyDataController.XdmfHDF5ControllerCast(testArray.getHeavyDataController(0)).getDataspaceDimensions()
+                                print "Data space dimensions" 
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller Dimensions"
+                                outputVector = testArray.getHeavyDataController(0).getDimensions()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller size"  + str(testArray.getHeavyDataController(0).getSize())
+                                print "Controller starts"
+                                outputVector = XdmfHeavyDataController.XdmfHDF5ControllerCast(testArray.getHeavyDataController(0)).getStart()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller strides"
+                                outputVector = XdmfHeavyDataController.XdmfHDF5ControllerCast(testArray.getHeavyDataController(0)).getStride()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                for j in range(0, testArray.getSize()):
+                                        print "core #" + str(id) + " testArray[" + str(j) + "] = " + str(testArray.getValueAsInt32(j))
+                testArray.accept(exampleWriter)
+
+                readStartVector = UInt32Vector()
+                readStartVector.push_back(4*(size - id - 1 - numServersCores))
+                readStrideVector = UInt32Vector()
+                readStrideVector.push_back(1)
+                readCountVector = UInt32Vector()
+                readCountVector.push_back(4)
+                readDataSizeVector = UInt32Vector()
+                readDataSizeVector.push_back(4*(size-numServersCores))
+
+                readArray = XdmfArray.New()
+
+                readArray.initializeAsInt32(0)
+                readArray.reserve(testArray.getSize())
+
+                readController = XdmfHDF5ControllerDSM.New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType.Int32(),
+                        readStartVector,
+                        readStrideVector,
+                        readCountVector,
+                        readDataSizeVector,
+                        exampleWriter.getServerBuffer())
+
+                readArray.insert(readController)
+
+                if (id == 0):
+                        print "\n\n\n"
+
+                print "testing read"
+                readArray.read()
+
+
+                for i in range (0, size):
+                        workerComm.Barrier()
+                        if (i == id):
+                                print "Core # " + str(id)
+                                print "Controller stats"
+                                print "datasetpath = " + XdmfHeavyDataController.XdmfHDF5ControllerCast(readArray.getHeavyDataController(0)).getDataSetPath()
+                                print "filepath = " + readArray.getHeavyDataController(0).getFilePath()
+                                outputVector = XdmfHeavyDataController.XdmfHDF5ControllerCast(readArray.getHeavyDataController(0)).getDataspaceDimensions()
+                                print "Data space dimensions"
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller Dimensions"
+                                outputVector = readArray.getHeavyDataController(0).getDimensions()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller size" + str(readArray.getHeavyDataController(0).getSize())
+                                print "Controller starts"
+                                outputVector = XdmfHeavyDataController.XdmfHDF5ControllerCast(readArray.getHeavyDataController(0)).getStart()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller strides"
+                                outputVector = XdmfHeavyDataController.XdmfHDF5ControllerCast(readArray.getHeavyDataController(0)).getStride()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                for j in range (0, readArray.getSize()):
+                                        print "core #" + str(id) + " readArray[" + str(j) + "] = " + str(readArray.getValueAsInt32(j))
+
+                workerComm.Barrier()
+
+                # End of Work Section
+
+        #//stopDSMwriter begin
+
+        if (id == 0):
+                exampleWriter.stopDSM()
+
+        #//stopDSMwriter end
+
+        '''
+        #//stopDSMcontroller begin
+
+
+        if (id == 0):
+                exampleController.stopDSM()
+
+        #//stopDSMcontroller end
+
+        #//sendDone begin
+
+        if (id == 0):
+                closeBuffer = exampleWriter.getServerBuffer()
+                closeBuffer.SendDone()
+
+        #//sendDone end
+
+        '''
+        #//GetInterComm begin
+
+        exampleDSMComm = exampleWriter.getServerBuffer().GetComm()
+
+        exampleInterComm = exampleDSMComm.GetInterComm()
+
+        #//GetInterComm end
+
+        #//DupInterComm begin
+
+        exampleDSMComm.DupInterComm(exampleInterComm.Dup())
+
+        #//DupInterComm end
+
+        #//SendRecvInfo begin
+
+        if (id >= size - numServersCores):
+                exampleWriter.getServerBuffer().SendInfo()
+        else:
+                exampleWriter.getServerBuffer().ReceiveInfo()
+
+        #//SendRecvInfo end
+
+        '''
+        #//restartDSMwriter begin
+
+        exampleWriter.restartDSM()
+
+        #//restartDSMwriter end
+
+        #//restartDSMcontroller begin
+
+        exampleController.restartDSM()
+
+        #//restartDSMcontroller end
+        '''
+
+        #//finalizeMPI
+
+#        exampleWriter.deleteManager()
+
+        #//finalizeMPI
+
+        '''
+        exampleController.deleteManager()
+        '''
diff --git a/core/loki/EmptyType.h b/core/loki/EmptyType.h
new file mode 100644
index 0000000..b228e2e
--- /dev/null
+++ b/core/loki/EmptyType.h
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_EMPTYTYPE_INC_
+#define LOKI_EMPTYTYPE_INC_
+
+// $Id: EmptyType.h 751 2006-10-17 19:50:37Z syntheticpp $
+
+
+namespace Loki
+{
+////////////////////////////////////////////////////////////////////////////////
+// class EmptyType
+// Used as a class type that doesn't hold anything
+// Useful as a strawman class
+////////////////////////////////////////////////////////////////////////////////
+
+    class EmptyType {};
+    
+    
+    inline bool operator==(const EmptyType&, const EmptyType&)
+    {
+        return true;
+    }   
+
+    inline bool operator<(const EmptyType&, const EmptyType&)
+    {
+        return false;
+    }
+    
+    inline bool operator>(const EmptyType&, const EmptyType&)
+    {
+        return false;
+    }
+}
+
+#endif // end file guardian
+
diff --git a/core/loki/HierarchyGenerators.h b/core/loki/HierarchyGenerators.h
new file mode 100644
index 0000000..3fa11ff
--- /dev/null
+++ b/core/loki/HierarchyGenerators.h
@@ -0,0 +1,291 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_HIERARCHYGENERATORS_INC_
+#define LOKI_HIERARCHYGENERATORS_INC_
+
+// $Id: HierarchyGenerators.h 751 2006-10-17 19:50:37Z syntheticpp $
+
+
+#include "Typelist.h"
+#include "TypeTraits.h"
+#include "EmptyType.h"
+
+namespace Loki
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#pragma warning( push ) 
+ // 'class1' : base-class 'class2' is already a base-class of 'class3'
+#pragma warning( disable : 4584 )
+#endif // _MSC_VER
+
+////////////////////////////////////////////////////////////////////////////////
+// class template GenScatterHierarchy
+// Generates a scattered hierarchy starting from a typelist and a template
+// Invocation (TList is a typelist, Unit is a template of one arg):
+// GenScatterHierarchy<TList, Unit>
+// The generated class inherits all classes generated by instantiating the 
+// template 'Unit' with the types contained in TList 
+////////////////////////////////////////////////////////////////////////////////
+
+    namespace Private
+    {
+        // The following type helps to overcome subtle flaw in the original 
+        // implementation of GenScatterHierarchy. 
+        // The flaw is revealed when the input type list of GenScatterHierarchy 
+        // contains more then one element of the same type (e.g. LOKI_TYPELIST_2(int, int)). 
+        // In this case GenScatterHierarchy will contain multiple bases of the same 
+        // type and some of them will not be reachable (per 10.3).
+        // For example before the fix the first element of Tuple<LOKI_TYPELIST_2(int, int)>
+        // is not reachable in any way!
+        template<class, class> 
+        struct ScatterHierarchyTag;
+    }
+
+    template <class TList, template <class> class Unit>
+    class GenScatterHierarchy;
+     
+    template <class T1, class T2, template <class> class Unit>
+    class GenScatterHierarchy<Typelist<T1, T2>, Unit>
+        : public GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit>
+        , public GenScatterHierarchy<T2, Unit>
+    {
+    public:
+        typedef Typelist<T1, T2> TList;
+        // Insure that LeftBase is unique and therefore reachable
+        typedef GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> LeftBase;
+        typedef GenScatterHierarchy<T2, Unit> RightBase;
+        template <typename T> struct Rebind
+        {
+            typedef Unit<T> Result;
+        };
+    };
+     
+    // In the middle *unique* class that resolve possible ambiguity
+    template <class T1, class T2, template <class> class Unit>
+    class GenScatterHierarchy<Private::ScatterHierarchyTag<T1, T2>, Unit> 
+        : public GenScatterHierarchy<T1, Unit>
+    {
+    };
+
+    template <class AtomicType, template <class> class Unit>
+    class GenScatterHierarchy : public Unit<AtomicType>
+    {
+        typedef Unit<AtomicType> LeftBase;
+        template <typename T> struct Rebind
+        {
+            typedef Unit<T> Result;
+        };
+    };
+    
+    template <template <class> class Unit>
+    class GenScatterHierarchy<NullType, Unit>
+    {
+        template <typename T> struct Rebind
+        {
+            typedef Unit<T> Result;
+        };
+    };
+     
+////////////////////////////////////////////////////////////////////////////////
+// function template Field
+// Accesses a field in an object of a type generated with GenScatterHierarchy
+// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
+//     T is a type in the typelist used to generate H):
+// Field<T>(obj)
+// returns a reference to Unit<T>, where Unit is the template used to generate H 
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class T, class H>
+    typename H::template Rebind<T>::Result& Field(H& obj)
+    {
+        return obj;
+    }
+     
+    template <class T, class H>
+    const typename H::template Rebind<T>::Result& Field(const H& obj)
+    {
+        return obj;
+    }
+     
+////////////////////////////////////////////////////////////////////////////////
+// function template TupleUnit
+// The building block of tuples 
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class T>
+    struct TupleUnit
+    {
+        T value_;
+        operator T&() { return value_; }
+        operator const T&() const { return value_; }
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Tuple
+// Implements a tuple class that holds a number of values and provides field 
+//     access to them via the Field function (below) 
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class TList>
+    struct Tuple : public GenScatterHierarchy<TList, TupleUnit>
+    {
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+// helper class template FieldHelper
+// See Field below
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class H, unsigned int i> struct FieldHelper;
+    
+    template <class H>
+    struct FieldHelper<H, 0>
+    {
+        typedef typename H::TList::Head ElementType;
+        typedef typename H::template Rebind<ElementType>::Result UnitType;
+        
+        enum
+        {
+            isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
+            isConst = TypeTraits<H>::isConst
+        };
+
+        typedef const typename H::LeftBase ConstLeftBase;
+        
+        typedef typename Select<isConst, ConstLeftBase, 
+            typename H::LeftBase>::Result LeftBase;
+            
+        typedef typename Select<isTuple, ElementType, 
+            UnitType>::Result UnqualifiedResultType;
+
+        typedef typename Select<isConst, const UnqualifiedResultType,
+                        UnqualifiedResultType>::Result ResultType;
+            
+        static ResultType& Do(H& obj)
+        {
+            LeftBase& leftBase = obj;
+            return leftBase;
+        }
+    };
+
+    template <class H, unsigned int i>
+    struct FieldHelper
+    {
+        typedef typename TL::TypeAt<typename H::TList, i>::Result ElementType;
+        typedef typename H::template Rebind<ElementType>::Result UnitType;
+        
+        enum
+        {
+            isTuple = Conversion<UnitType, TupleUnit<ElementType> >::sameType,
+            isConst = TypeTraits<H>::isConst
+        };
+
+        typedef const typename H::RightBase ConstRightBase;
+        
+        typedef typename Select<isConst, ConstRightBase, 
+            typename H::RightBase>::Result RightBase;
+
+        typedef typename Select<isTuple, ElementType, 
+            UnitType>::Result UnqualifiedResultType;
+
+        typedef typename Select<isConst, const UnqualifiedResultType,
+                        UnqualifiedResultType>::Result ResultType;
+            
+        static ResultType& Do(H& obj)
+        {
+            RightBase& rightBase = obj;
+            return FieldHelper<RightBase, i - 1>::Do(rightBase);
+        }
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+// function template Field
+// Accesses a field in an object of a type generated with GenScatterHierarchy
+// Invocation (obj is an object of a type H generated with GenScatterHierarchy,
+//     i is the index of a type in the typelist used to generate H):
+// Field<i>(obj)
+// returns a reference to Unit<T>, where Unit is the template used to generate H
+//     and T is the i-th type in the typelist 
+////////////////////////////////////////////////////////////////////////////////
+
+    template <int i, class H>
+    typename FieldHelper<H, i>::ResultType&
+    Field(H& obj)
+    {
+        return FieldHelper<H, i>::Do(obj);
+    }
+        
+//    template <int i, class H>
+//    const typename FieldHelper<H, i>::ResultType&
+//    Field(const H& obj)
+//    {
+//        return FieldHelper<H, i>::Do(obj);
+//    }
+        
+////////////////////////////////////////////////////////////////////////////////
+// class template GenLinearHierarchy
+// Generates a linear hierarchy starting from a typelist and a template
+// Invocation (TList is a typelist, Unit is a template of two args):
+// GenScatterHierarchy<TList, Unit>
+////////////////////////////////////////////////////////////////////////////////
+
+    template
+    <
+        class TList,
+        template <class AtomicType, class Base> class Unit,
+        class Root = EmptyType
+    >
+    class GenLinearHierarchy;
+    
+    template
+    <
+        class T1,
+        class T2,
+        template <class, class> class Unit,
+        class Root
+    >
+    class GenLinearHierarchy<Typelist<T1, T2>, Unit, Root>
+        : public Unit< T1, GenLinearHierarchy<T2, Unit, Root> >
+    {
+    };
+
+    template
+    <
+        class T,
+        template <class, class> class Unit,
+        class Root
+    >
+    class GenLinearHierarchy<Typelist<T, NullType>, Unit, Root>
+        : public Unit<T, Root>
+    {
+    };
+
+    template
+    <
+        template <class, class> class Unit,
+        class Root
+    >
+    class GenLinearHierarchy<NullType , Unit, Root>
+        : public Root // is this better: Unit<NullType, Root> ?
+    {
+    };
+
+#if defined(_MSC_VER) && _MSC_VER >= 1300
+#pragma warning( pop ) 
+#endif
+}   // namespace Loki
+
+#endif // end file guardian
+
diff --git a/core/loki/NullType.h b/core/loki/NullType.h
new file mode 100644
index 0000000..9403901
--- /dev/null
+++ b/core/loki/NullType.h
@@ -0,0 +1,34 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_NULLTYPE_INC_
+#define LOKI_NULLTYPE_INC_
+
+// $Id: NullType.h 751 2006-10-17 19:50:37Z syntheticpp $
+
+
+namespace Loki
+{
+////////////////////////////////////////////////////////////////////////////////
+// class NullType
+// Used as a placeholder for "no type here"
+// Useful as an end marker in typelists 
+////////////////////////////////////////////////////////////////////////////////
+
+    class NullType {};
+    
+}   // namespace Loki
+
+
+#endif // end file guardian
diff --git a/core/loki/Sequence.h b/core/loki/Sequence.h
new file mode 100644
index 0000000..4e5bd23
--- /dev/null
+++ b/core/loki/Sequence.h
@@ -0,0 +1,49 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2005 by Peter K�mmel
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author makes no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_SEQUENCE_INC_
+#define LOKI_SEQUENCE_INC_
+
+// $Id: Sequence.h 768 2006-10-25 20:40:40Z syntheticpp $
+
+
+#include "Typelist.h"
+
+namespace Loki
+{
+
+    template
+    <
+        class T01=NullType,class T02=NullType,class T03=NullType,class T04=NullType,class T05=NullType,
+        class T06=NullType,class T07=NullType,class T08=NullType,class T09=NullType,class T10=NullType,
+        class T11=NullType,class T12=NullType,class T13=NullType,class T14=NullType,class T15=NullType,
+        class T16=NullType,class T17=NullType,class T18=NullType,class T19=NullType,class T20=NullType
+    >
+    struct Seq
+    {
+    private:
+        typedef typename Seq<     T02, T03, T04, T05, T06, T07, T08, T09, T10,
+                             T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>::Type 
+                         TailResult;
+    public:
+        typedef Typelist<T01, TailResult> Type;
+    };
+        
+    template<>
+    struct Seq<>
+    {
+        typedef NullType Type;
+    };
+
+}   // namespace Loki
+
+#endif // end file guardian
+
diff --git a/core/loki/TypeManip.h b/core/loki/TypeManip.h
new file mode 100644
index 0000000..e08b4e0
--- /dev/null
+++ b/core/loki/TypeManip.h
@@ -0,0 +1,284 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Welsey Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_TYPEMANIP_INC_
+#define LOKI_TYPEMANIP_INC_
+
+// $Id: TypeManip.h 749 2006-10-17 19:49:26Z syntheticpp $
+
+
+namespace Loki
+{
+////////////////////////////////////////////////////////////////////////////////
+// class template Int2Type
+// Converts each integral constant into a unique type
+// Invocation: Int2Type<v> where v is a compile-time constant integral
+// Defines 'value', an enum that evaluates to v
+////////////////////////////////////////////////////////////////////////////////
+
+    template <int v>
+    struct Int2Type
+    {
+        enum { value = v };
+    };
+    
+////////////////////////////////////////////////////////////////////////////////
+// class template Type2Type
+// Converts each type into a unique, insipid type
+// Invocation Type2Type<T> where T is a type
+// Defines the type OriginalType which maps back to T
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct Type2Type
+    {
+        typedef T OriginalType;
+    };
+    
+////////////////////////////////////////////////////////////////////////////////
+// class template Select
+// Selects one of two types based upon a boolean constant
+// Invocation: Select<flag, T, U>::Result
+// where:
+// flag is a compile-time boolean constant
+// T and U are types
+// Result evaluates to T if flag is true, and to U otherwise.
+////////////////////////////////////////////////////////////////////////////////
+
+    template <bool flag, typename T, typename U>
+    struct Select
+    {
+        typedef T Result;
+    };
+    template <typename T, typename U>
+    struct Select<false, T, U>
+    {
+        typedef U Result;
+    };
+    
+////////////////////////////////////////////////////////////////////////////////
+// class template IsSameType
+// Return true iff two given types are the same
+// Invocation: SameType<T, U>::value
+// where:
+// T and U are types
+// Result evaluates to true iff U == T (types equal)
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T, typename U>
+    struct IsSameType
+    {
+        enum { value = false };
+    };
+    
+    template <typename T>
+    struct IsSameType<T,T>
+    {
+        enum { value = true };
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper types Small and Big - guarantee that sizeof(Small) < sizeof(Big)
+////////////////////////////////////////////////////////////////////////////////
+
+    namespace Private
+    {
+        template <class T, class U>
+        struct ConversionHelper
+        {
+            typedef char Small;
+            struct Big { char dummy[2]; };
+            static Big   Test(...);
+            static Small Test(U);
+            static T MakeT();
+        };
+    }
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Conversion
+// Figures out the conversion relationships between two types
+// Invocations (T and U are types):
+// a) Conversion<T, U>::exists
+// returns (at compile time) true if there is an implicit conversion from T
+// to U (example: Derived to Base)
+// b) Conversion<T, U>::exists2Way
+// returns (at compile time) true if there are both conversions from T
+// to U and from U to T (example: int to char and back)
+// c) Conversion<T, U>::sameType
+// returns (at compile time) true if T and U represent the same type
+//
+// Caveat: might not work if T and U are in a private inheritance hierarchy.
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class T, class U>
+    struct Conversion
+    {
+        typedef Private::ConversionHelper<T, U> H;
+#ifndef __MWERKS__
+        enum { exists = sizeof(typename H::Small) == sizeof((H::Test(H::MakeT()))) };
+#else
+        enum { exists = false };
+#endif
+        enum { exists2Way = exists && Conversion<U, T>::exists };
+        enum { sameType = false };
+    };
+    
+    template <class T>
+    struct Conversion<T, T>    
+    {
+        enum { exists = 1, exists2Way = 1, sameType = 1 };
+    };
+    
+    template <class T>
+    struct Conversion<void, T>    
+    {
+        enum { exists = 0, exists2Way = 0, sameType = 0 };
+    };
+    
+    template <class T>
+    struct Conversion<T, void>    
+    {
+        enum { exists = 0, exists2Way = 0, sameType = 0 };
+    };
+    
+    template <>
+    struct Conversion<void, void>    
+    {
+    public:
+        enum { exists = 1, exists2Way = 1, sameType = 1 };
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template SuperSubclass
+// Invocation: SuperSubclass<B, D>::value where B and D are types. 
+// Returns true if B is a public base of D, or if B and D are aliases of the 
+// same type.
+//
+// Caveat: might not work if T and U are in a private inheritance hierarchy.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class T, class U>
+struct SuperSubclass
+{
+    enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
+                  !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
+      
+    // Dummy enum to make sure that both classes are fully defined.
+    enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
+};
+
+template <>
+struct SuperSubclass<void, void> 
+{
+    enum { value = false };
+};
+
+template <class U>
+struct SuperSubclass<void, U> 
+{
+    enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
+                  !::Loki::Conversion<const volatile void*, const volatile void*>::sameType) };
+      
+    // Dummy enum to make sure that both classes are fully defined.
+    enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
+};
+
+template <class T>
+struct SuperSubclass<T, void> 
+{
+    enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
+                  !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
+      
+    // Dummy enum to make sure that both classes are fully defined.
+    enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// class template SuperSubclassStrict
+// Invocation: SuperSubclassStrict<B, D>::value where B and D are types. 
+// Returns true if B is a public base of D.
+//
+// Caveat: might not work if T and U are in a private inheritance hierarchy.
+////////////////////////////////////////////////////////////////////////////////
+
+template<class T,class U>
+struct SuperSubclassStrict
+{
+    enum { value = (::Loki::Conversion<const volatile U*, const volatile T*>::exists &&
+                 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
+                 !::Loki::Conversion<const volatile T*, const volatile U*>::sameType) };
+    
+    // Dummy enum to make sure that both classes are fully defined.
+    enum{ dontUseWithIncompleteTypes = ( sizeof (T) == sizeof (U) ) };
+};
+
+template<>
+struct SuperSubclassStrict<void, void> 
+{
+    enum { value = false };
+};
+
+template<class U>
+struct SuperSubclassStrict<void, U> 
+{
+    enum { value = (::Loki::Conversion<const volatile U*, const volatile void*>::exists &&
+                 !::Loki::Conversion<const volatile void*, const volatile void*>::sameType &&
+                 !::Loki::Conversion<const volatile void*, const volatile U*>::sameType) };
+    
+    // Dummy enum to make sure that both classes are fully defined.
+    enum{ dontUseWithIncompleteTypes = ( 0 == sizeof (U) ) };
+};
+
+template<class T>
+struct SuperSubclassStrict<T, void> 
+{
+    enum { value = (::Loki::Conversion<const volatile void*, const volatile T*>::exists &&
+                 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType &&
+                 !::Loki::Conversion<const volatile T*, const volatile void*>::sameType) };
+    
+    // Dummy enum to make sure that both classes are fully defined.
+    enum{ dontUseWithIncompleteTypes = ( sizeof (T) == 0 ) };
+};
+
+
+}   // namespace Loki
+
+////////////////////////////////////////////////////////////////////////////////
+// macro SUPERSUBCLASS
+// Invocation: SUPERSUBCLASS(B, D) where B and D are types. 
+// Returns true if B is a public base of D, or if B and D are aliases of the 
+// same type.
+//
+// Caveat: might not work if T and U are in a private inheritance hierarchy.
+// Deprecated: Use SuperSubclass class template instead.
+////////////////////////////////////////////////////////////////////////////////
+
+#define LOKI_SUPERSUBCLASS(T, U) \
+    ::Loki::SuperSubclass<T,U>::value
+
+////////////////////////////////////////////////////////////////////////////////
+// macro SUPERSUBCLASS_STRICT
+// Invocation: SUPERSUBCLASS(B, D) where B and D are types. 
+// Returns true if B is a public base of D.
+//
+// Caveat: might not work if T and U are in a private inheritance hierarchy.
+// Deprecated: Use SuperSubclassStrict class template instead.
+////////////////////////////////////////////////////////////////////////////////
+
+#define LOKI_SUPERSUBCLASS_STRICT(T, U) \
+    ::Loki::SuperSubclassStrict<T,U>::value
+
+
+#endif // end file guardian
+
diff --git a/core/loki/TypeTraits.h b/core/loki/TypeTraits.h
new file mode 100644
index 0000000..a592cab
--- /dev/null
+++ b/core/loki/TypeTraits.h
@@ -0,0 +1,2228 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_TYPETRAITS_INC_
+#define LOKI_TYPETRAITS_INC_
+
+// $Id: TypeTraits.h 835 2007-08-02 19:39:02Z syntheticpp $
+
+
+#include "Typelist.h"
+#include "Sequence.h"
+
+#if (defined _MSC_VER) && (_MSC_VER < 1400)
+#include <string>
+#endif
+
+
+#ifdef _MSC_VER
+#pragma warning( push ) 
+#pragma warning( disable : 4180 ) //qualifier applied to function type has no meaning; ignored
+#endif
+
+namespace Loki
+{
+////////////////////////////////////////////////////////////////////////////////
+// class template IsCustomUnsignedInt
+// Offers a means to integrate nonstandard built-in unsigned integral types
+// (such as unsigned __int64 or unsigned long long int) with the TypeTraits 
+//     class template defined below.
+// Invocation: IsCustomUnsignedInt<T> where T is any type
+// Defines 'value', an enum that is 1 iff T is a custom built-in unsigned
+//     integral type
+// Specialize this class template for nonstandard unsigned integral types
+//     and define value = 1 in those specializations
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct IsCustomUnsignedInt
+    {
+        enum { value = 0 };
+    };        
+
+////////////////////////////////////////////////////////////////////////////////
+// class template IsCustomSignedInt
+// Offers a means to integrate nonstandard built-in unsigned integral types
+// (such as unsigned __int64 or unsigned long long int) with the TypeTraits 
+//     class template defined below.
+// Invocation: IsCustomSignedInt<T> where T is any type
+// Defines 'value', an enum that is 1 iff T is a custom built-in signed
+//     integral type
+// Specialize this class template for nonstandard unsigned integral types
+//     and define value = 1 in those specializations
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct IsCustomSignedInt
+    {
+        enum { value = 0 };
+    };        
+
+////////////////////////////////////////////////////////////////////////////////
+// class template IsCustomFloat
+// Offers a means to integrate nonstandard floating point types with the
+//     TypeTraits class template defined below.
+// Invocation: IsCustomFloat<T> where T is any type
+// Defines 'value', an enum that is 1 iff T is a custom built-in
+//     floating point type
+// Specialize this class template for nonstandard unsigned integral types
+//     and define value = 1 in those specializations
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    struct IsCustomFloat
+    {
+        enum { value = 0 };
+    };        
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper types for class template TypeTraits defined below
+////////////////////////////////////////////////////////////////////////////////
+
+    namespace Private
+    {
+#ifndef LOKI_DISABLE_TYPELIST_MACROS    
+        typedef LOKI_TYPELIST_4(unsigned char, unsigned short int,unsigned int, unsigned long int) 
+            StdUnsignedInts;
+        typedef LOKI_TYPELIST_4(signed char, short int,int, long int) 
+            StdSignedInts;
+        typedef LOKI_TYPELIST_3(bool, char, wchar_t) 
+            StdOtherInts;
+        typedef LOKI_TYPELIST_3(float, double, long double) 
+            StdFloats;
+#else
+        typedef Loki::Seq<unsigned char, unsigned short int,unsigned int, unsigned long int>::Type
+            StdUnsignedInts;
+        typedef Loki::Seq<signed char, short int,int, long int>::Type
+            StdSignedInts;
+        typedef Loki::Seq<bool, char, wchar_t>::Type
+            StdOtherInts;
+        typedef Loki::Seq<float, double, long double>::Type
+            StdFloats;
+
+#endif            
+        template <typename U> struct AddPointer
+        {
+            typedef U* Result;
+        };
+
+        template <typename U> struct AddPointer<U&>
+        {
+            typedef U* Result;
+        };
+
+        template <class U> struct AddReference
+        {
+            typedef U & Result;
+        };
+
+        template <class U> struct AddReference<U &>
+        {
+            typedef U & Result;
+        };
+
+        template <> struct AddReference<void>
+        {
+            typedef NullType Result;
+        };
+
+        template <class U> struct AddParameterType
+        {
+            typedef const U & Result;
+        };
+
+        template <class U> struct AddParameterType<U &>
+        {
+            typedef U & Result;
+        };
+
+        template <> struct AddParameterType<void>
+        {
+            typedef NullType Result;
+        };
+    
+        template <typename T>
+        struct IsFunctionPointerRaw
+        {enum{result = 0};};
+
+        template <typename T>
+        struct IsFunctionPointerRaw<T(*)()> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01>
+        struct IsFunctionPointerRaw<T(*)(P01)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20)> 
+        {enum {result = 1};};
+
+        template <typename T>
+        struct IsFunctionPointerRaw<T(*)(
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15,
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsFunctionPointerRaw<T(*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20,
+            ...)> 
+        {enum {result = 1};};
+        
+        
+        template <typename T>
+        struct IsMemberFunctionPointerRaw
+        {enum{result = 0};};
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)()> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(P01)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15,
+            ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, ...)> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20,
+            ...)> 
+        {enum {result = 1};};
+
+        // Const versions
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)() const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(P01) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15,
+            ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, ...) const> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20,
+            ...) const> 
+        {enum {result = 1};};
+
+        // Volatile versions
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)() volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(P01) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15,
+            ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, ...) volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20,
+            ...) volatile> 
+        {enum {result = 1};};
+
+        // Const volatile versions
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)() const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(P01) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05,
+            P06, P07, P08, P09, P10,
+            P11, P12, P13, P14, P15,
+            ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, ...) const volatile> 
+        {enum {result = 1};};
+
+        template <typename T, typename S, 
+            typename P01, typename P02, typename P03, typename P04, typename P05,
+            typename P06, typename P07, typename P08, typename P09, typename P10,
+            typename P11, typename P12, typename P13, typename P14, typename P15,
+            typename P16, typename P17, typename P18, typename P19, typename P20>
+        struct IsMemberFunctionPointerRaw<T (S::*)(
+            P01, P02, P03, P04, P05, 
+            P06, P07, P08, P09, P10, 
+            P11, P12, P13, P14, P15,
+            P16, P17, P18, P19, P20,
+            ...) const volatile> 
+        {enum {result = 1};};
+               
+      }// namespace Private
+        
+////////////////////////////////////////////////////////////////////////////////
+// class template TypeTraits
+//
+// Figures out at compile time various properties of any given type
+// Invocations (T is a type, TypeTraits<T>::Property):
+//
+// - isPointer       : returns true if T is a pointer type
+// - PointeeType     : returns the type to which T points if T is a pointer 
+//                     type, NullType otherwise
+// - isReference     : returns true if T is a reference type
+// - ReferredType    : returns the type to which T refers if T is a reference 
+//                     type, NullType otherwise
+// - isMemberPointer : returns true if T is a pointer to member type
+// - isStdUnsignedInt: returns true if T is a standard unsigned integral type
+// - isStdSignedInt  : returns true if T is a standard signed integral type
+// - isStdIntegral   : returns true if T is a standard integral type
+// - isStdFloat      : returns true if T is a standard floating-point type
+// - isStdArith      : returns true if T is a standard arithmetic type
+// - isStdFundamental: returns true if T is a standard fundamental type
+// - isUnsignedInt   : returns true if T is a unsigned integral type
+// - isSignedInt     : returns true if T is a signed integral type
+// - isIntegral      : returns true if T is a integral type
+// - isFloat         : returns true if T is a floating-point type
+// - isArith         : returns true if T is a arithmetic type
+// - isFundamental   : returns true if T is a fundamental type
+// - ParameterType   : returns the optimal type to be used as a parameter for 
+//                     functions that take Ts
+// - isConst         : returns true if T is a const-qualified type
+// - NonConstType    : Type with removed 'const' qualifier from T, if any
+// - isVolatile      : returns true if T is a volatile-qualified type
+// - NonVolatileType : Type with removed 'volatile' qualifier from T, if any
+// - UnqualifiedType : Type with removed 'const' and 'volatile' qualifiers from 
+//                     T, if any
+// - ParameterType   : returns the optimal type to be used as a parameter 
+//                       for functions that take 'const T's
+//
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename T>
+    class TypeTraits
+    {
+    private:
+    
+        template <class U> struct ReferenceTraits
+        {
+            enum { result = false };
+            typedef U ReferredType;
+        };
+        
+        template <class U> struct ReferenceTraits<U&>
+        {
+            enum { result = true };
+            typedef U ReferredType;
+        };
+               
+        template <class U> struct PointerTraits
+        {
+            enum { result = false };
+            typedef NullType PointeeType;
+        };
+        
+        template <class U> struct PointerTraits<U*>
+        {
+            enum { result = true };
+            typedef U PointeeType;
+        };
+        
+        template <class U> struct PointerTraits<U*&>
+        {
+            enum { result = true };
+            typedef U PointeeType;
+        };
+          
+        template <class U> struct PToMTraits
+        {
+            enum { result = false };
+        };
+        
+        template <class U, class V> struct PToMTraits<U V::*>
+        {
+            enum { result = true };
+        };
+        
+        template <class U, class V> struct PToMTraits<U V::*&>
+        {
+            enum { result = true };
+        };
+        
+        template <class U> struct FunctionPointerTraits
+        {
+            enum{ result = Private::IsFunctionPointerRaw<U>::result };
+        };
+        
+        template <typename U> struct PToMFunctionTraits
+        {
+            enum{ result = Private::IsMemberFunctionPointerRaw<U>::result };
+        };
+         
+        template <class U> struct UnConst
+        {
+            typedef U Result;
+            enum { isConst = 0 };
+        };
+        
+        template <class U> struct UnConst<const U>
+        {
+            typedef U Result;
+            enum { isConst = 1 };
+        };
+
+        template <class U> struct UnConst<const U&>
+        {
+            typedef U& Result;
+            enum { isConst = 1 };
+        };
+  
+        template <class U> struct UnVolatile
+        {
+            typedef U Result;
+            enum { isVolatile = 0 };
+        };
+       
+        template <class U> struct UnVolatile<volatile U>
+        {
+            typedef U Result;
+            enum { isVolatile = 1 };
+        };
+
+        template <class U> struct UnVolatile<volatile U&>
+        {
+            typedef U& Result;
+            enum { isVolatile = 1 };
+        };
+        
+    public:
+        typedef typename UnConst<T>::Result 
+            NonConstType;
+        typedef typename UnVolatile<T>::Result 
+            NonVolatileType;
+        typedef typename UnVolatile<typename UnConst<T>::Result>::Result 
+            UnqualifiedType;
+        typedef typename PointerTraits<UnqualifiedType>::PointeeType 
+            PointeeType;
+        typedef typename ReferenceTraits<T>::ReferredType 
+            ReferredType;
+
+        enum { isConst          = UnConst<T>::isConst };
+        enum { isVolatile       = UnVolatile<T>::isVolatile };
+        enum { isReference      = ReferenceTraits<UnqualifiedType>::result };
+        enum { isFunction       = FunctionPointerTraits<typename Private::AddPointer<T>::Result >::result };
+        enum { isFunctionPointer= FunctionPointerTraits<
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType >::result };
+        enum { isMemberFunctionPointer= PToMFunctionTraits<
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType >::result };
+        enum { isMemberPointer  = PToMTraits<
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
+                                        isMemberFunctionPointer };
+        enum { isPointer        = PointerTraits<
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType >::result ||
+                                        isFunctionPointer };
+        
+        enum { isStdUnsignedInt = TL::IndexOf<Private::StdUnsignedInts, UnqualifiedType>::value >= 0 ||
+                                  TL::IndexOf<Private::StdUnsignedInts, 
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
+        enum { isStdSignedInt   = TL::IndexOf<Private::StdSignedInts, UnqualifiedType>::value >= 0 ||
+                                  TL::IndexOf<Private::StdSignedInts, 
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
+        enum { isStdIntegral    = isStdUnsignedInt || isStdSignedInt ||
+                                  TL::IndexOf<Private::StdOtherInts, UnqualifiedType>::value >= 0 ||
+                                  TL::IndexOf<Private::StdOtherInts, 
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
+        enum { isStdFloat       = TL::IndexOf<Private::StdFloats, UnqualifiedType>::value >= 0 ||
+                                  TL::IndexOf<Private::StdFloats, 
+                                        typename ReferenceTraits<UnqualifiedType>::ReferredType>::value >= 0};
+        enum { isStdArith       = isStdIntegral || isStdFloat };
+        enum { isStdFundamental = isStdArith || isStdFloat || Conversion<T, void>::sameType };
+            
+        enum { isUnsignedInt    = isStdUnsignedInt || IsCustomUnsignedInt<UnqualifiedType>::value };
+        enum { isSignedInt      = isStdSignedInt || IsCustomSignedInt<UnqualifiedType>::value };
+        enum { isIntegral       = isStdIntegral || isUnsignedInt || isSignedInt };
+        enum { isFloat          = isStdFloat || IsCustomFloat<UnqualifiedType>::value };
+        enum { isArith          = isIntegral || isFloat };
+        enum { isFundamental    = isStdFundamental || isArith };
+        
+        typedef typename Select<isStdArith || isPointer || isMemberPointer, T, 
+                typename Private::AddParameterType<T>::Result>::Result 
+            ParameterType;
+    };
+}
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif // _MSC_VER
+
+
+#endif // end file guardian
+
diff --git a/core/loki/Typelist.h b/core/loki/Typelist.h
new file mode 100644
index 0000000..6a88592
--- /dev/null
+++ b/core/loki/Typelist.h
@@ -0,0 +1,459 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Welsey Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_TYPELIST_INC_
+#define LOKI_TYPELIST_INC_
+
+// $Id: Typelist.h 749 2006-10-17 19:49:26Z syntheticpp $
+
+
+#include "NullType.h"
+#include "TypeManip.h"
+#include "TypelistMacros.h"
+
+
+namespace Loki
+{
+////////////////////////////////////////////////////////////////////////////////
+// class template Typelist
+// The building block of typelists of any length
+// Use it through the LOKI_TYPELIST_NN macros
+// Defines nested types:
+//     Head (first element, a non-typelist type by convention)
+//     Tail (second element, can be another typelist)
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class T, class U>
+    struct Typelist
+    {
+       typedef T Head;
+       typedef U Tail;
+    };
+
+// Typelist utility algorithms
+
+    namespace TL
+    {
+
+////////////////////////////////////////////////////////////////////////////////
+// class template MakeTypelist
+// Takes a number of arguments equal to its numeric suffix
+// The arguments are type names.
+// MakeTypelist<T1, T2, ...>::Result
+// returns a typelist that is of T1, T2, ...
+////////////////////////////////////////////////////////////////////////////////
+
+        template
+        <
+            typename T1  = NullType, typename T2  = NullType, typename T3  = NullType,
+            typename T4  = NullType, typename T5  = NullType, typename T6  = NullType,
+            typename T7  = NullType, typename T8  = NullType, typename T9  = NullType,
+            typename T10 = NullType, typename T11 = NullType, typename T12 = NullType,
+            typename T13 = NullType, typename T14 = NullType, typename T15 = NullType,
+            typename T16 = NullType, typename T17 = NullType, typename T18 = NullType
+        > 
+        struct MakeTypelist
+        {
+        private:
+            typedef typename MakeTypelist
+            <
+                T2 , T3 , T4 , 
+                T5 , T6 , T7 , 
+                T8 , T9 , T10, 
+                T11, T12, T13,
+                T14, T15, T16, 
+                T17, T18
+            >
+            ::Result TailResult;
+
+        public:
+            typedef Typelist<T1, TailResult> Result;
+        };
+
+        template<>
+        struct MakeTypelist<>
+        {
+            typedef NullType Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Length
+// Computes the length of a typelist
+// Invocation (TList is a typelist):
+// Length<TList>::value
+// returns a compile-time constant containing the length of TList, not counting
+//     the end terminator (which by convention is NullType)
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList> struct Length;
+        template <> struct Length<NullType>
+        {
+            enum { value = 0 };
+        };
+        
+        template <class T, class U>
+        struct Length< Typelist<T, U> >
+        {
+            enum { value = 1 + Length<U>::value };
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template TypeAt
+// Finds the type at a given index in a typelist
+// Invocation (TList is a typelist and index is a compile-time integral 
+//     constant):
+// TypeAt<TList, index>::Result
+// returns the type in position 'index' in TList
+// If you pass an out-of-bounds index, the result is a compile-time error
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, unsigned int index> struct TypeAt;
+        
+        template <class Head, class Tail>
+        struct TypeAt<Typelist<Head, Tail>, 0>
+        {
+            typedef Head Result;
+        };
+
+        template <class Head, class Tail, unsigned int i>
+        struct TypeAt<Typelist<Head, Tail>, i>
+        {
+            typedef typename TypeAt<Tail, i - 1>::Result Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template TypeAtNonStrict
+// Finds the type at a given index in a typelist
+// Invocations (TList is a typelist and index is a compile-time integral 
+//     constant):
+// a) TypeAt<TList, index>::Result
+// returns the type in position 'index' in TList, or NullType if index is 
+//     out-of-bounds
+// b) TypeAt<TList, index, D>::Result
+// returns the type in position 'index' in TList, or D if index is out-of-bounds
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, unsigned int index,
+            typename DefaultType = NullType>
+        struct TypeAtNonStrict
+        {
+            typedef DefaultType Result;
+        };
+        
+        template <class Head, class Tail, typename DefaultType>
+        struct TypeAtNonStrict<Typelist<Head, Tail>, 0, DefaultType>
+        {
+            typedef Head Result;
+        };
+        
+        template <class Head, class Tail, unsigned int i, typename DefaultType>
+        struct TypeAtNonStrict<Typelist<Head, Tail>, i, DefaultType>
+        {
+            typedef typename 
+                TypeAtNonStrict<Tail, i - 1, DefaultType>::Result Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template IndexOf
+// Finds the index of a type in a typelist
+// Invocation (TList is a typelist and T is a type):
+// IndexOf<TList, T>::value
+// returns the position of T in TList, or NullType if T is not found in TList
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T> struct IndexOf;
+        
+        template <class T>
+        struct IndexOf<NullType, T>
+        {
+            enum { value = -1 };
+        };
+        
+        template <class T, class Tail>
+        struct IndexOf<Typelist<T, Tail>, T>
+        {
+            enum { value = 0 };
+        };
+        
+        template <class Head, class Tail, class T>
+        struct IndexOf<Typelist<Head, Tail>, T>
+        {
+        private:
+            enum { temp = IndexOf<Tail, T>::value };
+        public:
+            enum { value = (temp == -1 ? -1 : 1 + temp) };
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Append
+// Appends a type or a typelist to another
+// Invocation (TList is a typelist and T is either a type or a typelist):
+// Append<TList, T>::Result
+// returns a typelist that is TList followed by T and NullType-terminated
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T> struct Append;
+        
+        template <> struct Append<NullType, NullType>
+        {
+            typedef NullType Result;
+        };
+        
+        template <class T> struct Append<NullType, T>
+        {
+            typedef Typelist<T,NullType> Result;
+        };
+
+        template <class Head, class Tail>
+        struct Append<NullType, Typelist<Head, Tail> >
+        {
+            typedef Typelist<Head, Tail> Result;
+        };
+        
+        template <class Head, class Tail, class T>
+        struct Append<Typelist<Head, Tail>, T>
+        {
+            typedef Typelist<Head, 
+                    typename Append<Tail, T>::Result>
+                Result;
+        };
+        
+////////////////////////////////////////////////////////////////////////////////
+// class template Erase
+// Erases the first occurence, if any, of a type in a typelist
+// Invocation (TList is a typelist and T is a type):
+// Erase<TList, T>::Result
+// returns a typelist that is TList without the first occurence of T
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T> struct Erase;
+        
+        template <class T>                         // Specialization 1
+        struct Erase<NullType, T>
+        {
+            typedef NullType Result;
+        };
+
+        template <class T, class Tail>             // Specialization 2
+        struct Erase<Typelist<T, Tail>, T>
+        {
+            typedef Tail Result;
+        };
+
+        template <class Head, class Tail, class T> // Specialization 3
+        struct Erase<Typelist<Head, Tail>, T>
+        {
+            typedef Typelist<Head, 
+                    typename Erase<Tail, T>::Result>
+                Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template EraseAll
+// Erases all first occurences, if any, of a type in a typelist
+// Invocation (TList is a typelist and T is a type):
+// EraseAll<TList, T>::Result
+// returns a typelist that is TList without any occurence of T
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T> struct EraseAll;
+        template <class T>
+        struct EraseAll<NullType, T>
+        {
+            typedef NullType Result;
+        };
+        template <class T, class Tail>
+        struct EraseAll<Typelist<T, Tail>, T>
+        {
+            // Go all the way down the list removing the type
+            typedef typename EraseAll<Tail, T>::Result Result;
+        };
+        template <class Head, class Tail, class T>
+        struct EraseAll<Typelist<Head, Tail>, T>
+        {
+            // Go all the way down the list removing the type
+            typedef Typelist<Head, 
+                    typename EraseAll<Tail, T>::Result>
+                Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template NoDuplicates
+// Removes all duplicate types in a typelist
+// Invocation (TList is a typelist):
+// NoDuplicates<TList, T>::Result
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList> struct NoDuplicates;
+        
+        template <> struct NoDuplicates<NullType>
+        {
+            typedef NullType Result;
+        };
+
+        template <class Head, class Tail>
+        struct NoDuplicates< Typelist<Head, Tail> >
+        {
+        private:
+            typedef typename NoDuplicates<Tail>::Result L1;
+            typedef typename Erase<L1, Head>::Result L2;
+        public:
+            typedef Typelist<Head, L2> Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Replace
+// Replaces the first occurence of a type in a typelist, with another type
+// Invocation (TList is a typelist, T, U are types):
+// Replace<TList, T, U>::Result
+// returns a typelist in which the first occurence of T is replaced with U
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T, class U> struct Replace;
+        
+        template <class T, class U>
+        struct Replace<NullType, T, U>
+        {
+            typedef NullType Result;
+        };
+
+        template <class T, class Tail, class U>
+        struct Replace<Typelist<T, Tail>, T, U>
+        {
+            typedef Typelist<U, Tail> Result;
+        };
+
+        template <class Head, class Tail, class T, class U>
+        struct Replace<Typelist<Head, Tail>, T, U>
+        {
+            typedef Typelist<Head,
+                    typename Replace<Tail, T, U>::Result>
+                Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template ReplaceAll
+// Replaces all occurences of a type in a typelist, with another type
+// Invocation (TList is a typelist, T, U are types):
+// Replace<TList, T, U>::Result
+// returns a typelist in which all occurences of T is replaced with U
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T, class U> struct ReplaceAll;
+        
+        template <class T, class U>
+        struct ReplaceAll<NullType, T, U>
+        {
+            typedef NullType Result;
+        };
+        
+        template <class T, class Tail, class U>
+        struct ReplaceAll<Typelist<T, Tail>, T, U>
+        {
+            typedef Typelist<U, typename ReplaceAll<Tail, T, U>::Result> Result;
+        };
+        
+        template <class Head, class Tail, class T, class U>
+        struct ReplaceAll<Typelist<Head, Tail>, T, U>
+        {
+            typedef Typelist<Head,
+                    typename ReplaceAll<Tail, T, U>::Result>
+                Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Reverse
+// Reverses a typelist
+// Invocation (TList is a typelist):
+// Reverse<TList>::Result
+// returns a typelist that is TList reversed
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList> struct Reverse;
+        
+        template <>
+        struct Reverse<NullType>
+        {
+            typedef NullType Result;
+        };
+        
+        template <class Head, class Tail>
+        struct Reverse< Typelist<Head, Tail> >
+        {
+            typedef typename Append<
+                typename Reverse<Tail>::Result, Head>::Result Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template MostDerived
+// Finds the type in a typelist that is the most derived from a given type
+// Invocation (TList is a typelist, T is a type):
+// MostDerived<TList, T>::Result
+// returns the type in TList that's the most derived from T
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList, class T> struct MostDerived;
+        
+        template <class T>
+        struct MostDerived<NullType, T>
+        {
+            typedef T Result;
+        };
+        
+        template <class Head, class Tail, class T>
+        struct MostDerived<Typelist<Head, Tail>, T>
+        {
+        private:
+            typedef typename MostDerived<Tail, T>::Result Candidate;
+        public:
+            typedef typename Select<
+                SuperSubclass<Candidate,Head>::value,
+                    Head, Candidate>::Result Result;
+        };
+
+////////////////////////////////////////////////////////////////////////////////
+// class template DerivedToFront
+// Arranges the types in a typelist so that the most derived types appear first
+// Invocation (TList is a typelist):
+// DerivedToFront<TList>::Result
+// returns the reordered TList 
+////////////////////////////////////////////////////////////////////////////////
+
+        template <class TList> struct DerivedToFront;
+        
+        template <>
+        struct DerivedToFront<NullType>
+        {
+            typedef NullType Result;
+        };
+        
+        template <class Head, class Tail>
+        struct DerivedToFront< Typelist<Head, Tail> >
+        {
+        private:
+            typedef typename MostDerived<Tail, Head>::Result
+                TheMostDerived;
+            typedef typename Replace<Tail,
+                TheMostDerived, Head>::Result Temp;
+            typedef typename DerivedToFront<Temp>::Result L;
+        public:
+            typedef Typelist<TheMostDerived, L> Result;
+        };
+        
+    }   // namespace TL
+}   // namespace Loki
+
+
+#endif // end file guardian
+
diff --git a/core/loki/TypelistMacros.h b/core/loki/TypelistMacros.h
new file mode 100644
index 0000000..6c14b34
--- /dev/null
+++ b/core/loki/TypelistMacros.h
@@ -0,0 +1,353 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Welsey Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+#ifndef LOKI_TYPELISTMACROS_INC_
+#define LOKI_TYPELISTMACROS_INC_
+
+// $Id: TypelistMacros.h 749 2006-10-17 19:49:26Z syntheticpp $
+
+
+//#define LOKI_DISABLE_TYPELIST_MACROS
+#ifndef LOKI_DISABLE_TYPELIST_MACROS
+
+////////////////////////////////////////////////////////////////////////////////
+// macros LOKI_TYPELIST_1, LOKI_TYPELIST_2, ... LOKI_TYPELIST_50
+// Each takes a number of arguments equal to its numeric suffix
+// The arguments are type names. LOKI_TYPELIST_NN generates a typelist containing 
+//     all types passed as arguments, in that order.
+// Example: LOKI_TYPELIST_2(char, int) generates a type containing char and int.
+////////////////////////////////////////////////////////////////////////////////
+
+#define LOKI_TYPELIST_1(T1) ::Loki::Typelist<T1, ::Loki::NullType>
+
+#define LOKI_TYPELIST_2(T1, T2) ::Loki::Typelist<T1, LOKI_TYPELIST_1(T2) >
+
+#define LOKI_TYPELIST_3(T1, T2, T3) ::Loki::Typelist<T1, LOKI_TYPELIST_2(T2, T3) >
+
+#define LOKI_TYPELIST_4(T1, T2, T3, T4) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_3(T2, T3, T4) >
+
+#define LOKI_TYPELIST_5(T1, T2, T3, T4, T5) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_4(T2, T3, T4, T5) >
+
+#define LOKI_TYPELIST_6(T1, T2, T3, T4, T5, T6) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_5(T2, T3, T4, T5, T6) >
+
+#define LOKI_TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_6(T2, T3, T4, T5, T6, T7) >
+
+#define LOKI_TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
+
+#define LOKI_TYPELIST_9(T1, T2, T3, T4, T5, T6, T7, T8, T9) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_8(T2, T3, T4, T5, T6, T7, T8, T9) >
+
+#define LOKI_TYPELIST_10(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_9(T2, T3, T4, T5, T6, T7, T8, T9, T10) >
+
+#define LOKI_TYPELIST_11(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_10(T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) >
+
+#define LOKI_TYPELIST_12(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_11(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12) >
+
+#define LOKI_TYPELIST_13(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_12(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13) >
+
+#define LOKI_TYPELIST_14(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_13(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14) >
+
+#define LOKI_TYPELIST_15(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_14(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15) >
+
+#define LOKI_TYPELIST_16(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_15(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16) >
+
+#define LOKI_TYPELIST_17(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_16(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17) >
+
+#define LOKI_TYPELIST_18(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_17(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18) >
+
+#define LOKI_TYPELIST_19(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_18(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19) >
+
+#define LOKI_TYPELIST_20(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_19(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20) >
+
+#define LOKI_TYPELIST_21(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_20(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21) >
+
+#define LOKI_TYPELIST_22(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_21(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22) >
+
+#define LOKI_TYPELIST_23(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_22(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23) >
+
+#define LOKI_TYPELIST_24(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_23(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24) >
+
+#define LOKI_TYPELIST_25(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_24(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25) >
+
+#define LOKI_TYPELIST_26(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_25(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26) >
+
+#define LOKI_TYPELIST_27(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_26(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27) >
+
+#define LOKI_TYPELIST_28(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_27(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28) >
+
+#define LOKI_TYPELIST_29(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_28(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29) >
+
+#define LOKI_TYPELIST_30(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_29(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30) >
+
+#define LOKI_TYPELIST_31(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_30(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31) >
+
+#define LOKI_TYPELIST_32(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_31(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32) >
+
+#define LOKI_TYPELIST_33(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_32(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33) >
+
+#define LOKI_TYPELIST_34(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_33(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, T32, T33, T34) >
+
+#define LOKI_TYPELIST_35(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_34(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35) >
+
+#define LOKI_TYPELIST_36(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_35(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36) >
+
+#define LOKI_TYPELIST_37(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_36(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37) >
+
+#define LOKI_TYPELIST_38(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_37(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38) >
+
+#define LOKI_TYPELIST_39(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_38(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39) >
+
+#define LOKI_TYPELIST_40(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_39(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40) >
+
+#define LOKI_TYPELIST_41(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_40(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41) >
+
+#define LOKI_TYPELIST_42(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_41(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42) >
+
+#define LOKI_TYPELIST_43(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_42(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43) >
+
+#define LOKI_TYPELIST_44(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_43(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44) >
+
+#define LOKI_TYPELIST_45(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_44(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45) >
+
+#define LOKI_TYPELIST_46(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_45(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46) >
+
+#define LOKI_TYPELIST_47(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_46(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47) >
+
+#define LOKI_TYPELIST_48(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47, T48) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_47(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47, T48) >
+
+#define LOKI_TYPELIST_49(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47, T48, T49) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_48(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47, T48, T49) >
+
+#define LOKI_TYPELIST_50(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) \
+    ::Loki::Typelist<T1, LOKI_TYPELIST_49(T2, T3, T4, T5, T6, T7, T8, T9, T10, \
+        T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, \
+        T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, \
+        T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, \
+        T41, T42, T43, T44, T45, T46, T47, T48, T49, T50) >
+
+#endif //LOKI_DISABLE_TYPELIST_MACROS
+
+#endif // end file guardian
+
diff --git a/core/loki/Visitor.h b/core/loki/Visitor.h
new file mode 100644
index 0000000..111abd5
--- /dev/null
+++ b/core/loki/Visitor.h
@@ -0,0 +1,427 @@
+////////////////////////////////////////////////////////////////////////////////
+// The Loki Library
+// Copyright (c) 2001 by Andrei Alexandrescu
+// This code accompanies the book:
+// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design 
+//     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
+// Permission to use, copy, modify, distribute and sell this software for any 
+//     purpose is hereby granted without fee, provided that the above copyright 
+//     notice appear in all copies and that both that copyright notice and this 
+//     permission notice appear in supporting documentation.
+// The author or Addison-Wesley Longman make no representations about the 
+//     suitability of this software for any purpose. It is provided "as is" 
+//     without express or implied warranty.
+////////////////////////////////////////////////////////////////////////////////
+
+// $Header: /cvsroot-fuse/loki-lib/loki/include/loki/Visitor.h,v 1.7 2006/01/16 19:05:09 rich_sposato Exp $
+
+///  \defgroup VisitorGroup Visitor
+
+#ifndef LOKI_VISITOR_INC_
+#define LOKI_VISITOR_INC_
+
+#include "Typelist.h"
+#include "HierarchyGenerators.h"
+#include "XdmfSharedPtr.hpp"
+
+namespace Loki
+{
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class BaseVisitor
+///  
+/// \ingroup VisitorGroup
+/// The base class of any Acyclic Visitor
+////////////////////////////////////////////////////////////////////////////////
+
+    class BaseVisitor
+    {
+    public:
+        virtual ~BaseVisitor() {}
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class Visitor
+///
+/// \ingroup VisitorGroup
+/// The building block of Acyclic Visitor
+///
+/// \par Usage
+///
+/// Defining the visitable class:
+/// 
+/// \code
+/// class RasterBitmap : public BaseVisitable<>
+/// {
+/// public:
+///     LOKI_DEFINE_VISITABLE()
+/// };
+/// \endcode
+///
+/// Way 1 to define a visitor:
+/// \code
+/// class SomeVisitor : 
+///     public BaseVisitor // required
+///     public Visitor<RasterBitmap>,
+///     public Visitor<Paragraph>
+/// {
+/// public:
+///     void Visit(RasterBitmap&); // visit a RasterBitmap
+///     void Visit(Paragraph &);   // visit a Paragraph
+/// };
+/// \endcode
+///
+/// Way 2 to define the visitor:
+/// \code
+/// class SomeVisitor : 
+///     public BaseVisitor // required
+///     public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)>
+/// {
+/// public:
+///     void Visit(RasterBitmap&); // visit a RasterBitmap
+///     void Visit(Paragraph &);   // visit a Paragraph
+/// };
+/// \endcode
+///
+/// Way 3 to define the visitor:
+/// \code
+/// class SomeVisitor : 
+///     public BaseVisitor // required
+///     public Visitor<Seq<RasterBitmap, Paragraph>::Type>
+/// {
+/// public:
+///     void Visit(RasterBitmap&); // visit a RasterBitmap
+///     void Visit(Paragraph &);   // visit a Paragraph
+/// };
+/// \endcode
+///
+/// \par Using const visit functions:
+///
+/// Defining the visitable class (true for const):
+/// 
+/// \code
+/// class RasterBitmap : public BaseVisitable<void, DefaultCatchAll, true>
+/// {
+/// public:
+///     LOKI_DEFINE_CONST_VISITABLE()
+/// };
+/// \endcode
+///
+/// Defining the visitor which only calls const member functions:
+/// \code
+/// class SomeVisitor : 
+///     public BaseVisitor // required
+///     public Visitor<RasterBitmap, void, true>,
+/// {
+/// public:
+///     void Visit(const RasterBitmap&); // visit a RasterBitmap by a const member function
+/// };
+/// \endcode
+///
+/// \par Example:
+///
+/// test/Visitor/main.cpp 
+////////////////////////////////////////////////////////////////////////////////
+
+    template <class T, typename R = void, bool ConstVisit = false>
+    class Visitor;
+
+    template <class T, typename R>
+    class Visitor<T, R, false>
+    {
+    public:
+        typedef R ReturnType;
+        typedef T ParamType;
+        virtual ~Visitor() {}
+        virtual ReturnType visit(ParamType&, shared_ptr<BaseVisitor>) = 0;
+    };
+
+    /*
+    template <class T, typename R>
+    class Visitor<T, R, true>
+    {
+    public:
+        typedef R ReturnType;
+        typedef const T ParamType;
+        virtual ~Visitor() {}
+        virtual ReturnType visit(ParamType&, shared_ptr<BaseVisitor>) = 0;
+    };
+    */
+
+////////////////////////////////////////////////////////////////////////////////
+// class template Visitor (specialization)
+// This specialization is not present in the book. It makes it easier to define
+// Visitors for multiple types in a shot by using a typelist. Example:
+//
+// class SomeVisitor : 
+//     public BaseVisitor // required
+//     public Visitor<LOKI_TYPELIST_2(RasterBitmap, Paragraph)>
+// {
+// public:
+//     void Visit(RasterBitmap&); // visit a RasterBitmap
+//     void Visit(Paragraph &);   // visit a Paragraph
+// };
+////////////////////////////////////////////////////////////////////////////////
+
+/*     template <class Head, class Tail, typename R> */
+/*     class Visitor<Typelist<Head, Tail>, R, false> */
+/*         : public Visitor<Head, R, false>, public Visitor<Tail, R, false> */
+/*     { */
+/*     public: */
+/*         typedef R ReturnType; */
+/*        // using Visitor<Head, R>::Visit; */
+/*        // using Visitor<Tail, R>::Visit; */
+/*     }; */
+    
+/*     template <class Head, typename R> */
+/*     class Visitor<Typelist<Head, NullType>, R, false> : public Visitor<Head, R, false> */
+/*     { */
+/*     public: */
+/*         typedef R ReturnType; */
+/*         using Visitor<Head, R, false>::Visit; */
+/*     }; */
+
+/*     template <class Head, class Tail, typename R> */
+/*     class Visitor<Typelist<Head, Tail>, R, true> */
+/*         : public Visitor<Head, R, true>, public Visitor<Tail, R, true> */
+/*     { */
+/*     public: */
+/*         typedef R ReturnType; */
+/*        // using Visitor<Head, R>::Visit; */
+/*        // using Visitor<Tail, R>::Visit; */
+/*     }; */
+    
+/*     template <class Head, typename R> */
+/*     class Visitor<Typelist<Head, NullType>, R, true> : public Visitor<Head, R, true> */
+/*     { */
+/*     public: */
+/*         typedef R ReturnType; */
+/*         using Visitor<Head, R, true>::visit; */
+/*     }; */
+
+
+////////////////////////////////////////////////////////////////////////////////
+// class template BaseVisitorImpl
+// Implements non-strict visitation (you can implement only part of the Visit
+//     functions)
+////////////////////////////////////////////////////////////////////////////////
+/*
+    template <class TList, typename R = void> class BaseVisitorImpl;
+
+    template <class Head, class Tail, typename R>
+    class BaseVisitorImpl<Typelist<Head, Tail>, R>
+        : public Visitor<Head, R>
+        , public BaseVisitorImpl<Tail, R>
+    {
+    public:
+       // using BaseVisitorImpl<Tail, R>::Visit;
+
+        virtual R visit(Head&, shared_ptr<BaseVisitor>)
+        { return R(); }
+    };
+    
+    template <class Head, typename R>
+    class BaseVisitorImpl<Typelist<Head, NullType>, R>
+        : public Visitor<Head, R>
+    {
+    public:
+        virtual R visit(Head&, shared_ptr<BaseVisitor>)
+        { return R(); }
+    };
+*/
+////////////////////////////////////////////////////////////////////////////////
+// class template BaseVisitable
+////////////////////////////////////////////////////////////////////////////////
+/*
+template <typename R, typename Visited>
+struct DefaultCatchAll
+{
+    static R OnUnknownVisitor(Visited&, BaseVisitor&)
+    { return R(); }
+};
+*/
+////////////////////////////////////////////////////////////////////////////////
+// class template BaseVisitable
+////////////////////////////////////////////////////////////////////////////////
+
+	template
+    <
+        typename R = void,
+        bool ConstVisitable = false
+    >
+    class BaseVisitable;
+
+    template<typename R>
+    class BaseVisitable<R, false>
+    {
+    public:
+        typedef R ReturnType;
+        virtual ~BaseVisitable() {}
+        virtual ReturnType accept(const shared_ptr<BaseVisitor>&) = 0;
+        
+    protected: // give access only to the hierarchy
+
+        template <class T>
+        static ReturnType acceptImpl(T& visited, const shared_ptr<BaseVisitor>& guest)
+        {
+            // Apply the Acyclic Visitor
+            if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(guest.get()))
+            {
+                p->visit(visited, guest);
+            }
+            return;
+        }
+    };
+
+    template<typename R>
+    class BaseVisitable<R, true>
+    {
+    public:
+        typedef R ReturnType;
+        virtual ~BaseVisitable() {}
+        virtual ReturnType accept(BaseVisitor&) const = 0;
+
+    protected: // give access only to the hierarchy
+        template <class T>
+        static ReturnType acceptImpl(const T& visited, const shared_ptr<BaseVisitor>& guest)
+        {
+            // Apply the Acyclic Visitor
+            if (Visitor<T,R,true>* p = dynamic_cast<Visitor<T,R,true>*>(guest.get()))
+            {
+                p->visit(visited, guest);
+            }
+            return;
+        }
+    };
+
+
+    template< >
+    class BaseVisitable<void, false>
+    {
+        typedef void R;
+    public:
+        typedef R ReturnType;
+        virtual ~BaseVisitable() {}
+        virtual ReturnType accept(const shared_ptr<BaseVisitor>&) = 0;
+
+    protected: // give access only to the hierarchy
+
+        template <class T>
+        static ReturnType acceptImpl(T& visited, const shared_ptr<BaseVisitor>& guest)
+        {
+            // Apply the Acyclic Visitor
+            if (Visitor<T,R>* p = dynamic_cast<Visitor<T,R>*>(guest.get()))
+            {
+                p->visit(visited, guest);
+            }
+        }
+    };
+
+    template<>
+    class BaseVisitable<void, true>
+    {
+        typedef void R;
+    public:
+        typedef R ReturnType;
+        virtual ~BaseVisitable() {}
+        virtual ReturnType accept(BaseVisitor&) const = 0;
+
+    protected: // give access only to the hierarchy
+        template <class T>
+        static ReturnType acceptImpl(const T& visited, const shared_ptr<BaseVisitor>& guest)
+        {
+            // Apply the Acyclic Visitor
+            if (Visitor<T,R,true>* p = dynamic_cast<Visitor<T,R,true>*>(guest.get()))
+            {
+                p->visit(visited, guest);
+            }
+        }
+    };
+
+////////////////////////////////////////////////////////////////////////////////
+/// \def LOKI_DEFINE_VISITABLE()
+/// \ingroup VisitorGroup
+/// Put it in every class that you want to make visitable 
+/// (in addition to deriving it from BaseVisitable<R>)
+////////////////////////////////////////////////////////////////////////////////
+
+#define LOKI_DEFINE_VISITABLE_BASE() \
+    virtual void accept(const shared_ptr<Loki::BaseVisitor> &guest) \
+    { acceptImpl(*this, guest); }
+
+#define LOKI_DEFINE_VISITABLE(my_class, my_base) \
+    virtual void accept(const shared_ptr<Loki::BaseVisitor> &guest) \
+    { \
+        Loki::BaseVisitor* t = guest.get();\
+        if (Loki::Visitor<my_class,ReturnType>* p = dynamic_cast<Loki::Visitor<my_class,ReturnType>*>(t)) \
+        { \
+            p->visit(*this, guest); \
+        } \
+        else \
+        { \
+            my_base::accept(guest); \
+        } \
+    }
+
+////////////////////////////////////////////////////////////////////////////////
+/// \def LOKI_DEFINE_CONST_VISITABLE()
+/// \ingroup VisitorGroup
+/// Put it in every class that you want to make visitable by const member 
+/// functions (in addition to deriving it from BaseVisitable<R>)
+////////////////////////////////////////////////////////////////////////////////
+/*
+#define LOKI_DEFINE_CONST_VISITABLE() \
+    virtual ReturnType accept(const shared_ptr< ::Loki::BaseVisitor> guest) const \
+    { return acceptImpl(*this, guest); }
+
+////////////////////////////////////////////////////////////////////////////////
+/// \class CyclicVisitor
+///
+/// \ingroup VisitorGroup
+/// Put it in every class that you want to make visitable (in addition to 
+/// deriving it from BaseVisitable<R>
+////////////////////////////////////////////////////////////////////////////////
+
+    template <typename R, class TList>
+    class CyclicVisitor : public Visitor<TList, R>
+    {
+    public:
+        typedef R ReturnType;
+        // using Visitor<TList, R>::Visit;
+        
+        template <class Visited>
+        ReturnType GenericVisit(Visited& host)
+        {
+            Visitor<Visited, ReturnType>& subObj = *this;
+            return subObj.visit(host);
+        }
+    };
+*/
+////////////////////////////////////////////////////////////////////////////////
+/// \def LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor)
+/// \ingroup VisitorGroup
+/// Put it in every class that you want to make visitable by a cyclic visitor
+////////////////////////////////////////////////////////////////////////////////
+/*
+#define LOKI_DEFINE_CYCLIC_VISITABLE(SomeVisitor) \
+    virtual SomeVisitor::ReturnType accept(SomeVisitor& guest) \
+    { return guest.GenericVisit(*this); }
+*/
+} // namespace Loki
+
+typedef Loki::BaseVisitor XdmfBaseVisitor;
+
+////////////////////////////////////////////////////////////////////////////////
+// Change log:
+// March     20, ????: add default argument DefaultCatchAll to BaseVisitable
+// June      20, 2001: ported by Nick Thurn to gcc 2.95.3. Kudos, Nick!!!
+// September 28, 2004: replaced Loki:: with ::Loki:: in DEFINE_VISITABLE
+// January    2, 2006: add support for visiting constant member functions, Peter K�mmel
+////////////////////////////////////////////////////////////////////////////////
+
+#endif // VISITOR_INC_
+
+// $Log: Visitor.h,v $
+// Revision 1.7  2006/01/16 19:05:09  rich_sposato
+// Added cvs keywords.
+//
diff --git a/core/tests/C/CMakeLists.txt b/core/tests/C/CMakeLists.txt
new file mode 100644
index 0000000..f2ceb74
--- /dev/null
+++ b/core/tests/C/CMakeLists.txt
@@ -0,0 +1,47 @@
+# Include our test macros
+include(AddTestsC)
+
+# Add any dependencies that the cxx core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_C_DEPENDENCIES("XdmfCore")
+
+# Add any ldpath directories that the cxx tests may need
+ADD_TEST_C_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directoreis that the Cxx tests may need
+ADD_TEST_C_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_PATH("${XDMF_BINARIES}")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_C(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+ADD_TEST_C(CTestXdmfArray)
+ADD_TEST_C(CTestXdmfArrayType)
+ADD_TEST_C(CTestXdmfError)
+ADD_TEST_C(CTestXdmfFunction)
+ADD_TEST_C(CTestXdmfHDF5Controller)
+ADD_TEST_C(CTestXdmfInformation)
+ADD_TEST_C(CTestXdmfSparseMatrix)
+ADD_TEST_C(CTestXdmfSubset)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_C(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_C(CTestXdmfArray)
+CLEAN_TEST_C(CTestXdmfArrayType)
+CLEAN_TEST_C(CTestXdmfError)
+CLEAN_TEST_C(CTestXdmfFunction
+  functionfile.xmf
+  functionfile.h5)
+CLEAN_TEST_C(CTestXdmfHDF5Controller
+  testhdf5.h5)
+CLEAN_TEST_C(CTestXdmfInformation)
+CLEAN_TEST_C(CTestXdmfSparseMatrix)
+CLEAN_TEST_C(CTestXdmfSubset
+  subsetfile.xmf
+  subsetfile.h5)
diff --git a/core/tests/C/CTestXdmfArray.c b/core/tests/C/CTestXdmfArray.c
new file mode 100644
index 0000000..f2f6f48
--- /dev/null
+++ b/core/tests/C/CTestXdmfArray.c
@@ -0,0 +1,343 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfInformation.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  int status = 0;
+
+  void * array = XdmfArrayNew();
+
+  XdmfArraySetName(array, "Test Array", &status);
+
+  char * arrayName = XdmfArrayGetName(array);
+
+  printf("%s ?= %s\n", "Test Array", arrayName);
+
+  assert(strcmp("Test Array", arrayName) == 0);
+
+  free(arrayName);
+
+  if (!XdmfArrayIsInitialized(array))
+  {
+    printf("Array is not initialized\n");
+  }
+  else
+  {
+    printf("Array is initialized\n");
+  }
+
+  assert(!XdmfArrayIsInitialized(array));
+
+  // Information coupling
+
+  void * testInformation = XdmfInformationNew("Test Information","Testing");
+
+  XdmfArrayInsertInformation(array, testInformation, 0);
+
+  int numInfo = XdmfArrayGetNumberInformations(array);
+
+  printf("%d ?= %d\n", numInfo, 1);
+
+  assert(numInfo == 1);
+
+  void * returnInformation = XdmfArrayGetInformation(array, 0);
+
+  char * returnInfoName = XdmfInformationGetKey(returnInformation);
+
+  char * returnInfoValue = XdmfInformationGetValue(returnInformation);
+
+  printf("%s ?= %s\n", returnInfoName, "Test Information");
+  printf("%s ?= %s\n", returnInfoValue, "Testing");
+
+  assert(strcmp(returnInfoName, "Test Information") == 0);
+
+  assert(strcmp(returnInfoValue, "Testing") == 0);
+
+  XdmfArrayInsertInformation(array, XdmfInformationNew("Secondary Information", "Also Testing"), 0);
+
+  numInfo = XdmfArrayGetNumberInformations(array);
+
+  printf("%d ?= %d\n", numInfo, 2);
+
+  assert(numInfo == 2);
+
+  XdmfArrayRemoveInformation(array, 0);
+
+  numInfo = XdmfArrayGetNumberInformations(array);
+
+  printf("%d ?= %d\n", numInfo, 1);
+
+  assert(numInfo == 1);
+
+  void * secondReturnInformation = XdmfArrayGetInformation(array, 0);
+
+  char * secondReturnInfoName = XdmfInformationGetKey(secondReturnInformation);
+
+  char * secondReturnInfoValue = XdmfInformationGetValue(secondReturnInformation);
+
+  printf("%s ?= %s\n", secondReturnInfoName, "Secondary Information");
+  printf("%s ?= %s\n", secondReturnInfoValue, "AlsoTesting");
+
+  assert(strcmp(secondReturnInfoName, "Secondary Information") == 0);
+  assert(strcmp(secondReturnInfoValue, "Also Testing") == 0);
+
+  XdmfArrayRemoveInformationByKey(array, "Secondary Information");
+
+  numInfo = XdmfArrayGetNumberInformations(array);
+
+  printf("%d ?= %d\n", numInfo, 0);
+
+  assert(numInfo == 0);
+
+  free(testInformation);
+  free(returnInfoName);
+  free(returnInfoValue);
+  free(secondReturnInformation);
+  free(secondReturnInfoName);
+  free(secondReturnInfoValue);
+
+  printf("%d ?= %d\n", XDMF_ARRAY_READ_MODE_CONTROLLER, XdmfArrayGetReadMode(array, &status));
+
+  assert(XDMF_ARRAY_READ_MODE_CONTROLLER == XdmfArrayGetReadMode(array, &status));
+
+  XdmfArraySetReadMode(array, XDMF_ARRAY_READ_MODE_REFERENCE, &status);
+
+  printf("%d ?= %d\n", XDMF_ARRAY_READ_MODE_REFERENCE, XdmfArrayGetReadMode(array, &status));
+
+  assert(XDMF_ARRAY_READ_MODE_REFERENCE == XdmfArrayGetReadMode(array, &status));
+
+  XdmfArraySetReadMode(array, XDMF_ARRAY_READ_MODE_CONTROLLER, &status);
+
+  int dims[2];
+  dims[0] = 5;
+  dims[1] = 4;
+
+  XdmfArrayResize(array, dims, 2, XDMF_ARRAY_TYPE_INT32, &status);
+
+  printf("%d ?= %d\n", XdmfArrayGetNumberDimensions(array), 2);
+  printf("%d ?= %d\n", XdmfArrayGetSize(array), 20);
+
+  assert(XdmfArrayGetNumberDimensions(array) == 2);
+  assert(XdmfArrayGetSize(array) == 20);
+
+  XdmfArrayReserve(array, 50);
+
+  int capacity = XdmfArrayGetCapacity(array);
+
+  printf("%d ?>= %d\n", capacity, 50);
+
+  assert(capacity >= 50);
+
+  unsigned int * returnDims = XdmfArrayGetDimensions(array);
+
+  printf("%d ?= %d\n", returnDims[0], 5);
+  printf("%d ?= %d\n", returnDims[1], 4);
+
+  assert(returnDims[0] == 5);
+  assert(returnDims[1] == 4);
+
+  char * dimString = XdmfArrayGetDimensionsString(array);
+
+  printf("%s ?= %s\n", "5 4", dimString);
+
+  assert(strcmp("5 4", dimString) == 0);
+
+  free(dimString);
+  free(returnDims);
+
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_INT32, XdmfArrayGetArrayType(array, &status));
+
+  assert(XDMF_ARRAY_TYPE_INT32 == XdmfArrayGetArrayType(array, &status));
+
+  XdmfArrayClear(array);
+
+  XdmfArrayRelease(array);
+
+  int i = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(array, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  char * valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  int * testVal = (int *)XdmfArrayGetValue(array, 3, XDMF_ARRAY_TYPE_INT32, &status);
+
+  printf("%d ?= %d\n", *testVal, 3);
+
+  assert(*testVal == 3);
+
+  free(testVal);
+
+  XdmfArrayErase(array, 3);
+
+  valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  int insertVal = 90;
+
+  XdmfArrayInsertValue(array, 9, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+
+  valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9 90", valueString) == 0);
+
+  free(valueString);
+
+  void * secondaryArray = XdmfArrayNew();
+
+  XdmfArraySetValuesInternal(secondaryArray, XdmfArrayGetValuesInternal(array), XdmfArrayGetSize(array), XdmfArrayGetArrayType(array, &status), 0, &status);
+
+  valueString = XdmfArrayGetValuesString(secondaryArray);
+
+  printf("%s ?= %s\n", "0 1 2 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9 90", valueString) == 0);
+
+  XdmfArrayRelease(secondaryArray);
+
+  free(secondaryArray);
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9 90", valueString) == 0);
+
+  free(valueString);
+
+  secondaryArray = XdmfArrayNew();
+
+  int valArray[3];
+  valArray[0] = 5;
+  valArray[1] = 6;
+  valArray[2] = 7;
+
+  int starts[1];
+  starts[0] = 0;
+
+  int counts[1];
+  counts[0] = 10;
+
+  int strides[1];
+  strides[0] = 1;
+
+  XdmfArrayInsertDataFromXdmfArray(secondaryArray, array, starts, starts, counts, counts, strides, strides, &status);
+
+  valueString = XdmfArrayGetValuesString(secondaryArray);
+
+  printf("%s ?= %s\n", "0 1 2 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9 90", valueString) == 0);
+
+  free(valueString);
+
+  XdmfArrayInsertDataFromPointer(secondaryArray, valArray, XDMF_ARRAY_TYPE_INT32, 0, 3, 1, 1, &status);
+
+  valueString = XdmfArrayGetValuesString(secondaryArray);
+
+  printf("%s ?= %s\n", "5 6 7 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("5 6 7 4 5 6 7 8 9 90", valueString) == 0);
+
+  free(valueString);
+
+  XdmfArrayClear(secondaryArray);
+
+  XdmfArrayInsertDataFromPointer(secondaryArray, valArray, XDMF_ARRAY_TYPE_INT32, 0, 3, 1, 1, &status);
+
+  valueString = XdmfArrayGetValuesString(secondaryArray);
+
+  printf("%s ?= %s\n", "5 6 7", valueString);
+
+  assert(strcmp("5 6 7", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9 90", valueString) == 0);
+
+  free(valueString);
+
+  XdmfArraySwapWithXdmfArray(array, secondaryArray);
+
+  valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "5 6 7", valueString);
+
+  assert(strcmp("5 6 7", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(secondaryArray);
+
+  printf("%s ?= %s\n", "0 1 2 4 5 6 7 8 9 90", valueString);
+
+  assert(strcmp("0 1 2 4 5 6 7 8 9 90", valueString) == 0);
+
+  free(valueString);
+
+  int * swapArray = valArray;
+
+  XdmfArraySwapWithArray(secondaryArray, ((void **)&(swapArray)), 3, XDMF_ARRAY_TYPE_INT32, &status);
+
+  valueString = XdmfArrayGetValuesString(secondaryArray);
+
+  printf("%s ?= %s\n", "5 6 7", valueString);
+
+  assert(strcmp("5 6 7", valueString) == 0);
+
+  for (i = 0; i < 10; ++i)
+  {
+    printf("swapArray[%d] = %d\n", i, swapArray[i]);
+  }
+
+  assert(swapArray[0] == 0);
+  assert(swapArray[1] == 1);
+  assert(swapArray[2] == 2);
+  assert(swapArray[3] == 4);
+  assert(swapArray[4] == 5);
+  assert(swapArray[5] == 6);
+  assert(swapArray[6] == 7);
+  assert(swapArray[7] == 8);
+  assert(swapArray[8] == 9);
+  assert(swapArray[9] == 90);
+
+  free(valueString);
+
+  int *returnArray = (int *)XdmfArrayGetValues(secondaryArray, 0, XDMF_ARRAY_TYPE_INT32, 3, 1, 1, &status);
+
+  for (i = 0; i < 3; ++i)
+  {
+    printf("returnArray[%d] = %d\n", i, returnArray[i]);
+  }
+
+  assert(returnArray[0] == 5);
+  assert(returnArray[1] == 6);
+  assert(returnArray[2] == 7);
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfArrayType.c b/core/tests/C/CTestXdmfArrayType.c
new file mode 100644
index 0000000..0ecf0d1
--- /dev/null
+++ b/core/tests/C/CTestXdmfArrayType.c
@@ -0,0 +1,161 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+
+#include "assert.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+
+int main()
+{
+  int status = 0;
+
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_INT8, XdmfArrayTypeInt8());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_INT16, XdmfArrayTypeInt16());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_INT32, XdmfArrayTypeInt32());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_INT64, XdmfArrayTypeInt64());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_UINT8, XdmfArrayTypeUInt8());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_UINT16, XdmfArrayTypeUInt16());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_UINT32, XdmfArrayTypeUInt32());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_FLOAT32, XdmfArrayTypeFloat32());
+  printf("%d ?= %d\n", XDMF_ARRAY_TYPE_FLOAT64, XdmfArrayTypeFloat64());
+
+
+  assert(XDMF_ARRAY_TYPE_INT8 == XdmfArrayTypeInt8());
+  assert(XDMF_ARRAY_TYPE_INT16 == XdmfArrayTypeInt16());
+  assert(XDMF_ARRAY_TYPE_INT32 == XdmfArrayTypeInt32());
+  assert(XDMF_ARRAY_TYPE_INT64 == XdmfArrayTypeInt64());
+  assert(XDMF_ARRAY_TYPE_UINT8 == XdmfArrayTypeUInt8());
+  assert(XDMF_ARRAY_TYPE_UINT16 == XdmfArrayTypeUInt16());
+  assert(XDMF_ARRAY_TYPE_UINT32 == XdmfArrayTypeUInt32());
+  assert(XDMF_ARRAY_TYPE_FLOAT32 == XdmfArrayTypeFloat32());
+  assert(XDMF_ARRAY_TYPE_FLOAT64 == XdmfArrayTypeFloat64());
+
+  printf("%s ?= %s\n", "Char", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT8, &status));
+  printf("%s ?= %s\n", "Short", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT16, &status));
+  printf("%s ?= %s\n", "Int", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT32, &status));
+  printf("%s ?= %s\n", "Int", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT64, &status));
+  printf("%s ?= %s\n", "UChar", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_UINT8, &status));
+  printf("%s ?= %s\n", "UShort", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_UINT16, &status));
+  printf("%s ?= %s\n", "UInt", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_UINT32, &status));
+  printf("%s ?= %s\n", "Float", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_FLOAT32, &status));
+  printf("%s ?= %s\n", "Float", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_FLOAT64, &status));
+
+  assert(strcmp("Char", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT8, &status)) == 0);
+  assert(strcmp("Short", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT16, &status)) == 0);
+  assert(strcmp("Int", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT32, &status)) == 0);
+  assert(strcmp("Int", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_INT64, &status)) == 0);
+  assert(strcmp("UChar", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_UINT8, &status)) == 0);
+  assert(strcmp("UShort", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_UINT16, &status)) == 0);
+  assert(strcmp("UInt", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_UINT32, &status)) == 0);
+  assert(strcmp("Float", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_FLOAT32, &status)) == 0);
+  assert(strcmp("Float", XdmfArrayTypeGetName(XDMF_ARRAY_TYPE_FLOAT64, &status)) == 0);
+
+  printf("%d ?= %d\n", 1, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT8, &status));
+  printf("%d ?= %d\n", 2, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT16, &status));
+  printf("%d ?= %d\n", 4, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT32, &status));
+  printf("%d ?= %d\n", 8, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT64, &status));
+  printf("%d ?= %d\n", 1, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_UINT8, &status));
+  printf("%d ?= %d\n", 2, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_UINT16, &status));
+  printf("%d ?= %d\n", 4, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_UINT32, &status));
+  printf("%d ?= %d\n", 4, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_FLOAT32, &status));
+  printf("%d ?= %d\n", 8, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_FLOAT64, &status));
+
+  assert(1 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT8, &status));
+  assert(2 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT16, &status));
+  assert(4 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT32, &status));
+  assert(8 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT64, &status));
+  assert(1 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_UINT8, &status));
+  assert(2 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_UINT16, &status));
+  assert(4 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_UINT32, &status));
+  assert(4 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_FLOAT32, &status));
+  assert(8 == XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_FLOAT64, &status));
+
+  int typeCollection[9];
+
+  typeCollection[0] = XDMF_ARRAY_TYPE_INT8;
+  typeCollection[1] = XDMF_ARRAY_TYPE_INT16;
+  typeCollection[2] = XDMF_ARRAY_TYPE_INT32;
+  typeCollection[3] = XDMF_ARRAY_TYPE_INT64;
+  typeCollection[4] = XDMF_ARRAY_TYPE_UINT8;
+  typeCollection[5] = XDMF_ARRAY_TYPE_UINT16;
+  typeCollection[6] = XDMF_ARRAY_TYPE_UINT32;
+  typeCollection[7] = XDMF_ARRAY_TYPE_FLOAT32;
+  typeCollection[8] = XDMF_ARRAY_TYPE_FLOAT64;
+
+  int dims[1];
+  dims[0] = 0;
+  double testValue = -1.25;
+
+  int mergedims[1];
+  mergedims[0] = 1;
+
+  int mergeStarts[1];
+  mergeStarts[0] = 0;
+  int mergeCounts[1];
+  mergeCounts[0] = 1;
+  int mergeStrides[1];
+  mergeStrides[0] = 1;
+
+  int secondMergeStarts[1];
+  secondMergeStarts[0] = 1;
+
+  int valType1;
+  int valType2;
+
+  int valIntersectType;
+
+  unsigned int i = 0;
+  unsigned int j = 0;
+  char mergedoriginal[50];
+
+  void * valTypeArray1;
+  void * valTypeArray2;
+  void * valIntersectArray;
+
+  for (i = 0; i < 9; ++i) {
+    for (j = 0; j < 9; ++j) {
+      valTypeArray1 = XdmfArrayNew();
+      valTypeArray2 = XdmfArrayNew();
+
+      valType1 = typeCollection[j];
+      valType2 = typeCollection[i];
+
+      XdmfArrayInitialize(valTypeArray1, dims, 1, valType1, &status);
+      XdmfArrayInitialize(valTypeArray2, dims, 1, valType2, &status);
+
+      XdmfArrayPushBack(valTypeArray1, &testValue, XDMF_ARRAY_TYPE_FLOAT64, &status);
+      XdmfArrayPushBack(valTypeArray2, &testValue, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+      valIntersectArray = XdmfArrayNew();
+      valIntersectType = XdmfArrayTypeComparePrecision(valType1, valType2, &status);
+      XdmfArrayInitialize(valIntersectArray, mergedims, 1, valIntersectType, &status);
+
+      XdmfArrayInsertDataFromXdmfArray(valIntersectArray, valTypeArray1, mergeStarts, mergeStarts, mergeCounts, mergeCounts, mergeStrides, mergeStrides, &status);
+      XdmfArrayInsertDataFromXdmfArray(valIntersectArray, valTypeArray2, secondMergeStarts, mergeStarts, mergeCounts, mergeCounts, mergeStrides, mergeStrides, &status);
+
+      char * array1output = XdmfArrayGetValuesString(valTypeArray1);
+      char * array2output = XdmfArrayGetValuesString(valTypeArray2);
+      char * resultarrayoutput = XdmfArrayGetValuesString(valIntersectArray);
+
+      sprintf(mergedoriginal, "%s %s", array1output, array2output);
+      printf("%s\n%s\n", mergedoriginal, resultarrayoutput);
+
+      assert(strcmp(mergedoriginal, resultarrayoutput) == 0);
+
+      XdmfArrayRelease(valTypeArray1);
+      XdmfArrayRelease(valTypeArray2);
+      XdmfArrayRelease(valIntersectArray);
+
+      XdmfArrayFree(valTypeArray1);
+      XdmfArrayFree(valTypeArray2);
+      XdmfArrayFree(valIntersectArray);
+
+      free(array1output);
+      free(array2output);
+      free(resultarrayoutput);
+    }
+  }
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfError.c b/core/tests/C/CTestXdmfError.c
new file mode 100644
index 0000000..e93ae50
--- /dev/null
+++ b/core/tests/C/CTestXdmfError.c
@@ -0,0 +1,100 @@
+#include "XdmfError.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfFunction.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  int status = 0;
+
+  int currentLimit = XdmfErrorGetLevelLimit();
+
+  printf("%d ?= %d\n", currentLimit, XDMF_ERROR_FATAL);
+
+  assert(currentLimit == XDMF_ERROR_FATAL);
+
+  int currentSuppression = XdmfErrorGetSuppressionLevel();
+
+  printf("%d ?= %d\n", currentSuppression, XDMF_ERROR_WARNING);
+
+  assert(currentSuppression == XDMF_ERROR_WARNING);
+
+  XdmfErrorSetLevelLimit(XDMF_ERROR_DEBUG, &status);
+
+  XdmfErrorSetSuppressionLevel(XDMF_ERROR_DEBUG, &status);
+
+  currentLimit = XdmfErrorGetLevelLimit();
+
+  printf("%d ?= %d\n", currentLimit, XDMF_ERROR_DEBUG);
+
+  assert(currentLimit == XDMF_ERROR_DEBUG);
+
+  currentSuppression = XdmfErrorGetSuppressionLevel();
+
+  printf("%d ?= %d\n", currentSuppression, XDMF_ERROR_DEBUG);
+
+  assert(currentSuppression == XDMF_ERROR_DEBUG);
+
+  int currentCErrorsAreFatal = XdmfErrorGetCErrorsAreFatal();
+
+  printf("? %d\n", !currentCErrorsAreFatal);
+
+  assert(!currentCErrorsAreFatal);
+
+  XdmfErrorSetCErrorsAreFatal(1);
+
+  currentCErrorsAreFatal = XdmfErrorGetCErrorsAreFatal();
+
+  printf("current error status = %d\n", currentCErrorsAreFatal);
+
+  assert(currentCErrorsAreFatal);
+
+  XdmfErrorSetCErrorsAreFatal(0);
+
+  void * array1 = XdmfArrayNew();
+
+  int i = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(array1, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  } 
+
+  void * array2 = XdmfArrayNew();
+
+  for (i = 10; i < 20; i++) {
+    XdmfArrayPushBack(array2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  char * keys[2];
+
+  keys[0] = "A";
+  keys[1] = "B";
+
+  char * expression = "A^B";
+
+  XDMFARRAY * values[2];
+
+  values[0] = array1;
+  values[1] = array2;
+
+  void * function = XdmfFunctionNewInit(expression, keys, values, 2);
+
+  void * functionResult = NULL;
+
+  functionResult = XdmfFunctionRead(function, &status);
+
+  printf("%d ?= %d\n", status, XDMF_FAIL);
+
+  assert(status == XDMF_FAIL);
+
+  printf("%p ?= %p\n", functionResult, NULL);
+
+  assert(functionResult == NULL);
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfFunction.c b/core/tests/C/CTestXdmfFunction.c
new file mode 100644
index 0000000..fe4397a
--- /dev/null
+++ b/core/tests/C/CTestXdmfFunction.c
@@ -0,0 +1,393 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfWriter.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+XDMFARRAY * maximum(XDMFARRAY ** values, unsigned int numValues);
+
+XDMFARRAY * prepend(XDMFARRAY * val1, XDMFARRAY * val2);
+
+int main()
+{
+  void * array = XdmfArrayNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(array, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  char * valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  void * secondarray = XdmfArrayNew();
+
+  int val;
+
+  for (i = 1; i < 11; i++) {
+    val = i * 10;
+    XdmfArrayPushBack(secondarray, &val, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  valueString = XdmfArrayGetValuesString(secondarray);
+
+  printf("%s ?= %s\n", "10 20 30 40 50 60 70 80 90 100", valueString);
+
+  assert(strcmp("10 20 30 40 50 60 70 80 90 100", valueString) == 0);
+
+  free(valueString);
+
+  XDMFFUNCTION * function = XdmfFunctionNew();
+
+  free(function);
+
+  char * keys[2];
+
+  keys[0] = "A";
+  keys[1] = "B";
+
+  char * expression = "A#B";
+
+  XDMFARRAY * values[2];
+
+  values[0] = array;
+  values[1] = secondarray;
+
+  function = XdmfFunctionNewInit(expression, keys, values, 2);
+
+  void * readArray = XdmfFunctionRead(function, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString);
+
+  assert(strcmp("0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString) == 0);
+
+  free(valueString);
+
+  char * internalExpression = XdmfFunctionGetExpression(function);
+
+  printf("%s ?= %s\n", "A#B", internalExpression);
+
+  assert(strcmp("A#B", internalExpression) == 0);
+
+  unsigned int numVars = XdmfFunctionGetNumberVariables(function);
+
+  printf("%d ?= %d\n", numVars, 2);
+
+  assert(numVars == 2);
+
+  char ** internalVariableList = XdmfFunctionGetVariableList(function);
+
+  printf("%s ?= %s\n", internalVariableList[0], "A");
+  printf("%s ?= %s\n", internalVariableList[1], "B");
+
+  assert(strcmp(internalVariableList[0], "A") == 0);
+  assert(strcmp(internalVariableList[1], "B") == 0);
+
+  void * variable1 = XdmfFunctionGetVariable(function, internalVariableList[0]);
+
+  valueString = XdmfArrayGetValuesString(variable1);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  void * variable2 = XdmfFunctionGetVariable(function, internalVariableList[1]);
+
+  valueString = XdmfArrayGetValuesString(variable2);
+
+  printf("%s ?= %s\n", "10 20 30 40 50 60 70 80 90 100", valueString);
+
+  assert(strcmp("10 20 30 40 50 60 70 80 90 100", valueString) == 0);
+
+  free(valueString);
+
+  void * thirdarray = XdmfArrayNew();
+
+  for (i = 1; i < 11; i++) {
+    val = i * 20;
+    XdmfArrayPushBack(thirdarray, &val, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  valueString = XdmfArrayGetValuesString(thirdarray);
+
+  printf("%s ?= %s\n", "20 40 60 80 100 120 140 160 180 200", valueString);
+
+  assert(strcmp("20 40 60 80 100 120 140 160 180 200", valueString) == 0);
+
+  free(valueString);
+
+  XdmfFunctionRemoveVariable(function, "B");
+
+  XdmfFunctionInsertVariable(function, "B", thirdarray, 0);
+
+  free(readArray);
+
+  readArray = XdmfFunctionRead(function, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 20 1 40 2 60 3 80 4 100 5 120 6 140 7 160 8 180 9 200", valueString);
+
+  assert(strcmp("0 20 1 40 2 60 3 80 4 100 5 120 6 140 7 160 8 180 9 200", valueString) == 0);
+
+  free(valueString);
+
+  XdmfFunctionSetExpression(function, "A|B", &status);
+
+  free(readArray);
+
+  readArray = XdmfFunctionRead(function, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9 20 40 60 80 100 120 140 160 180 200", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9 20 40 60 80 100 120 140 160 180 200", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfFunctionGetItemTag(function);
+
+  printf("%s ?= %s\n", "Function", valueString);
+
+  assert(strcmp("Function", valueString) == 0);
+
+  free(valueString);
+
+  char * constructedTag = XdmfArrayGetItemTag(array);
+
+  XdmfFunctionSetConstructedType(function, constructedTag);
+
+  XdmfFunctionSetConstructedProperties(function, array);
+
+  char * internalTag = XdmfFunctionGetConstructedType(function);
+
+  printf("%s ?= %s\n", "DataItem", internalTag);
+
+  assert(strcmp(internalTag, "DataItem") == 0);
+
+  char * validoperations = XdmfFunctionGetSupportedOperations();
+
+  printf("%s ?= %s\n", "-+/*|#()", validoperations);
+
+  assert(strcmp("-+/*|#()", validoperations) == 0);
+
+  char * validdigits = XdmfFunctionGetValidDigitChars();
+
+  printf("%s ?= %s\n", "1234567890.", validdigits);
+
+  assert(strcmp("1234567890.", validdigits) == 0);
+
+  char * validvariablechars = XdmfFunctionGetValidVariableChars();
+
+  printf("%s ?= %s\n", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_:.", validvariablechars);
+
+  assert(strcmp("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_:.", validvariablechars) == 0);
+
+  unsigned int priority = XdmfFunctionGetOperationPriority('#');
+
+  assert(priority == 1);
+
+  XdmfFunctionAddFunction("MAX", maximum, &status);
+
+  XdmfFunctionAddOperation('%', prepend, 2, &status);
+
+  void * evaluatedarray = XdmfFunctionEvaluateOperation(array, secondarray, '%', &status);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "10 20 30 40 50 60 70 80 90 100 0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("10 20 30 40 50 60 70 80 90 100 0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  XDMFARRAY * evaluatedpointers[3] = {array, secondarray, thirdarray};
+
+  evaluatedarray = XdmfFunctionEvaluateFunction(evaluatedpointers, 3, "MAX", &status);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "200", valueString);
+
+  assert(strcmp("200", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  char * secondkeys[3];
+
+  secondkeys[0] = "A";
+  secondkeys[1] = "B";
+  secondkeys[2] = "C";
+
+  evaluatedarray = XdmfFunctionEvaluateExpression("MAX(A|B|C)", secondkeys, evaluatedpointers, 3, &status);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "200", valueString);
+
+  assert(strcmp("200", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  unsigned int numSupportedFunctions = XdmfFunctionGetNumberSupportedFunctions();
+
+  printf("%d functions supported\n", numSupportedFunctions);
+
+  printf("%d ?= %d\n", numSupportedFunctions, 15);
+
+  assert(numSupportedFunctions == 15);
+
+  char ** functionsSupported = XdmfFunctionGetSupportedFunctions();
+
+  for (i = 0; i < numSupportedFunctions; ++i)
+  {
+    printf("%s\n", functionsSupported[i]);
+  }
+
+  assert(strcmp(functionsSupported[0], "ABS") == 0);
+  assert(strcmp(functionsSupported[1], "ABS_TOKEN") == 0);
+  assert(strcmp(functionsSupported[2], "ACOS") == 0);
+  assert(strcmp(functionsSupported[3], "ASIN") == 0);
+  assert(strcmp(functionsSupported[4], "ATAN") == 0);
+  assert(strcmp(functionsSupported[5], "AVE") == 0);
+  assert(strcmp(functionsSupported[6], "COS") == 0);
+  assert(strcmp(functionsSupported[7], "EXP") == 0);
+  assert(strcmp(functionsSupported[8], "JOIN") == 0);
+  assert(strcmp(functionsSupported[9], "LOG") == 0);
+  assert(strcmp(functionsSupported[10], "MAX") == 0);
+  assert(strcmp(functionsSupported[11], "SIN") == 0);
+  assert(strcmp(functionsSupported[12], "SQRT") == 0);
+  assert(strcmp(functionsSupported[13], "SUM") == 0);
+  assert(strcmp(functionsSupported[14], "TAN") == 0);
+
+  evaluatedarray = XdmfFunctionChunk(array, secondarray, &status);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  evaluatedarray = XdmfFunctionInterlace(array, secondarray, &status);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString);
+
+  assert(strcmp("0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  evaluatedarray = XdmfFunctionAverage(evaluatedpointers, 3);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "56.5", valueString);
+
+  assert(strcmp("56.5", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  evaluatedarray = XdmfFunctionSum(evaluatedpointers, 3);
+
+  valueString = XdmfArrayGetValuesString(evaluatedarray);
+
+  printf("%s ?= %s\n", "1695", valueString);
+
+  assert(strcmp("1695", valueString) == 0);
+
+  free(valueString);
+
+  free(evaluatedarray);
+
+  XDMFWRITER * writer = XdmfWriterNew("functionfile.xmf");
+
+  XdmfFunctionAccept(function, (XDMFVISITOR *)writer, &status);
+
+  unsigned int numInfo = XdmfFunctionGetNumberInformations(function);
+
+  printf("%d ?= %d\n", numInfo, 0);
+
+  assert(numInfo == 0);
+
+  return 0;
+}
+
+XDMFARRAY * maximum(XDMFARRAY ** values, unsigned int numValues)
+{
+  int status = 0;
+  int type = XdmfArrayGetArrayType(values[0], &status);
+  if (type < XDMF_ARRAY_TYPE_INT8 || type > XDMF_ARRAY_TYPE_FLOAT64) {
+    // If not a supported type
+    return NULL;
+  }
+  else {
+    // convert all to doubles and return the largest
+    double maxVal = ((double *)XdmfArrayGetValue(values[0], 0, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    int limit;
+    double currentVal;
+    int i;
+    int j;
+    for (i = 0; i < numValues; ++i) {
+      limit = XdmfArrayGetSize(values[i]);
+      for (j = 0; j < limit; ++j) {
+        currentVal = ((double *)XdmfArrayGetValue(values[i], j, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+        if (maxVal < currentVal) {
+          maxVal = currentVal;
+        }
+      }
+    }
+    XDMFARRAY * returnArray = XdmfArrayNew();
+    XdmfArrayPushBack(returnArray, &maxVal, XDMF_ARRAY_TYPE_FLOAT64, &status);
+    return returnArray;
+  }
+}
+
+XDMFARRAY * prepend(XDMFARRAY * val1, XDMFARRAY * val2)
+{
+  //joins into new array and returns it
+  XDMFARRAY * returnArray = XdmfArrayNew();
+  unsigned int val1size = XdmfArrayGetSize(val1);
+  unsigned int val2size = XdmfArrayGetSize(val2);
+  int starts[1] = {0};
+  int secondstarts[1] = {0};
+  int strides[1] = {1};
+  int dimensions[1] = {val2size};
+  int status = 0;
+  XdmfArrayInsertDataFromXdmfArray(returnArray, val2, secondstarts, starts, dimensions, dimensions, strides, strides, &status);
+  secondstarts[0] = val2size;
+  dimensions[0] = val1size;
+  XdmfArrayInsertDataFromXdmfArray(returnArray, val1, secondstarts, starts, dimensions, dimensions, strides, strides, &status);
+  return returnArray;
+}
diff --git a/core/tests/C/CTestXdmfHDF5Controller.c b/core/tests/C/CTestXdmfHDF5Controller.c
new file mode 100644
index 0000000..e57ca38
--- /dev/null
+++ b/core/tests/C/CTestXdmfHDF5Controller.c
@@ -0,0 +1,194 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  void * array = XdmfArrayNew();
+
+  int status = 0;
+
+  int i = 0;
+
+  for (i = 0; i < 5; i++) {
+    XdmfArrayPushBack(array, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  char * valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 3 4", valueString),
+
+  assert(strcmp("0 1 2 3 4", valueString) == 0);
+
+  free(valueString);
+
+  unsigned int starts[1] = {0};
+  unsigned int strides[1] = {2};
+  unsigned int dimensions[1] = {5};
+  unsigned int dataspace[1] = {10};
+
+  unsigned int numDims = 1;
+
+  XDMFHDF5CONTROLLER * controller = XdmfHDF5ControllerNew("hdf5test.h5", "Data", XDMF_ARRAY_TYPE_INT32, starts, strides, dimensions, dataspace, numDims, &status);
+
+  valueString = XdmfHDF5ControllerGetFilePath(controller);
+
+  printf("%s ?= %s\n", "hdf5test.h5", valueString);
+
+  assert(strcmp("hdf5test.h5", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfHDF5ControllerGetDataSetPath(controller);
+
+  printf("dataset = %s\n", valueString);
+
+  assert(strcmp("Data", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfHDF5ControllerGetName(controller);
+
+  printf("%s ?= %s\n", "HDF", valueString);
+
+  assert(strcmp("HDF", valueString) == 0);
+
+  free(valueString);
+
+  unsigned int controllerSize = XdmfHDF5ControllerGetSize(controller);
+
+  printf("%d ?= %d\n", controllerSize, 5);
+
+  assert(controllerSize == 5);
+
+  unsigned int heldNumDims = XdmfHDF5ControllerGetNumberDimensions(controller);
+
+  printf("%d ?= %d\n", heldNumDims, 1);
+
+  assert(heldNumDims == 1);
+
+  int heldType = XdmfHDF5ControllerGetType(controller, &status);
+
+  printf("%d ?= %d\n", heldType, XDMF_ARRAY_TYPE_INT32);
+
+  assert(heldType == XDMF_ARRAY_TYPE_INT32);
+
+  unsigned int * internalStart = XdmfHDF5ControllerGetStart(controller);
+
+  printf("%d ?= %d\n", internalStart[0], 0);
+
+  assert(internalStart[0] == 0);
+
+  free(internalStart);
+
+  unsigned int * internalStride = XdmfHDF5ControllerGetStride(controller);
+
+  printf("%d ?= %d\n", internalStride[0], 2);
+
+  assert(internalStride[0] == 2);
+
+  free(internalStride);
+
+  unsigned int * internalDim = XdmfHDF5ControllerGetDimensions(controller);
+
+  printf("%d ?= %d\n", internalDim[0], 5);
+
+  assert(internalDim[0] == 5);
+
+  free(internalDim);
+
+  unsigned int * internalDataspace = XdmfHDF5ControllerGetDataspaceDimensions(controller);
+
+  printf("%d ?= %d\n", internalDataspace[0], 10);
+
+  assert(internalDataspace[0] == 10);
+
+  free(internalDataspace);
+
+  XdmfArrayInsertHeavyDataController(array, (XDMFHEAVYDATACONTROLLER *)controller, 0);
+
+  XDMFHDF5WRITER * heavyWriter = XdmfHDF5WriterNew("testhdf5.h5", 0);
+
+  XdmfHDF5WriterSetMode(heavyWriter, XDMF_HEAVY_WRITER_MODE_HYPERSLAB, &status);
+
+  XdmfArrayAccept(array, (XDMFVISITOR *)heavyWriter, &status);
+
+  void * secondarray = XdmfArrayNew();
+
+  for (i = 10; i < 15; i++) {
+    XdmfArrayPushBack(secondarray, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  valueString = XdmfArrayGetValuesString(secondarray);
+
+  printf("%s ?= %s\n", "10 11 12 13 14", valueString);
+
+  assert(strcmp("10 11 12 13 14", valueString) == 0);
+
+  free(valueString);
+
+  unsigned int secondstarts[1] = {1};
+  unsigned int secondstrides[1] = {2};
+  unsigned int seconddimensions[1] = {5};
+  unsigned int seconddataspace[1] = {10};
+
+  XDMFHDF5CONTROLLER * secondcontroller = XdmfHDF5ControllerNew("hdf5test.h5", "Data", XDMF_ARRAY_TYPE_INT32, secondstarts, secondstrides, seconddimensions, seconddataspace, numDims, &status);
+
+  XdmfArrayInsertHeavyDataController(secondarray, (XDMFHEAVYDATACONTROLLER *)secondcontroller, 0);
+
+  XdmfArrayAccept(secondarray, (XDMFVISITOR *)heavyWriter, &status);
+
+  void * readarray = XdmfArrayNew();
+
+  unsigned int readstarts[1] = {0};
+  unsigned int readstrides[1] = {1};
+  unsigned int readdimensions[1] = {10};
+  unsigned int readdataspace[1] = {10};
+
+  XDMFHDF5CONTROLLER * readcontroller = XdmfHDF5ControllerNew("hdf5test.h5", "Data", XDMF_ARRAY_TYPE_INT32, readstarts, readstrides, readdimensions, readdataspace, numDims, &status);
+
+  int testType = XdmfHDF5ControllerGetType(readcontroller, &status);
+
+  printf("%d ?= %d\n", testType, XDMF_ARRAY_TYPE_INT32);
+
+  assert(testType == XDMF_ARRAY_TYPE_INT32);
+
+  XdmfHDF5ControllerRead(readcontroller, readarray, &status);
+
+  valueString = XdmfArrayGetValuesString(readarray);
+
+  printf("Read Values = %s\n", valueString);
+
+  assert(strcmp("0 10 1 11 2 12 3 13 4 14", valueString) == 0);
+
+  free(valueString);
+
+  XdmfHDF5ControllerSetArrayOffset(readcontroller, 5);
+
+  unsigned int internalOffset = XdmfHDF5ControllerGetArrayOffset(readcontroller);
+
+  printf("%d ?= %d\n", internalOffset, 5);
+
+  assert(internalOffset == 5);
+
+  XdmfArrayInsertHeavyDataController(readarray, (XDMFHEAVYDATACONTROLLER *)readcontroller, 0);
+
+  XdmfArrayRead(readarray, &status);
+
+  valueString = XdmfArrayGetValuesString(readarray);
+
+  printf("%s ?= %s\n", "0 0 0 0 0 0 10 1 11 2 12 3 13 4 14", valueString);
+
+  assert(strcmp("0 0 0 0 0 0 10 1 11 2 12 3 13 4 14", valueString) == 0);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfInformation.c b/core/tests/C/CTestXdmfInformation.c
new file mode 100644
index 0000000..d86debb
--- /dev/null
+++ b/core/tests/C/CTestXdmfInformation.c
@@ -0,0 +1,71 @@
+#include "XdmfInformation.hpp"
+#include "XdmfArray.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  int status = 0;
+
+  XDMFINFORMATION * information = XdmfInformationNew("keyvalue", "valuevalue");
+
+  char * infoKey = XdmfInformationGetKey(information);
+
+  printf("The key equals: %s\n", infoKey);
+
+  char * infoValue = XdmfInformationGetValue(information);
+
+  printf("The value equals: %s\n", infoValue);
+
+  XdmfInformationSetKey(information, "newKey", &status);
+
+  XdmfInformationSetValue(information, "newValue", &status);
+
+  infoKey = XdmfInformationGetKey(information);
+
+  infoValue = XdmfInformationGetValue(information);
+
+  printf("The key equals: %s\n", infoKey);
+
+  printf("The value equals: %s\n", infoValue);
+
+  XDMFINFORMATION * childInfo = XdmfInformationNew("childKey", "childValue");
+
+  XdmfInformationInsertInformation(information, childInfo, 0);
+
+  XdmfInformationSetKey(childInfo, "newChildKey", &status);
+  XdmfInformationSetValue(childInfo, "newChildValue", &status);
+
+  XDMFINFORMATION * internalInfo = XdmfInformationGetInformation(information, 0);
+
+  char * childKey = XdmfInformationGetKey(internalInfo);
+
+  char * childValue = XdmfInformationGetValue(internalInfo);
+
+  printf("The Child's key equals: %s\nThe Child's Value equals: %s\n", childKey, childValue);
+
+  unsigned int numArrays = XdmfInformationGetNumberArrays(information);
+  unsigned int numInfo = XdmfInformationGetNumberInformations(information);
+
+  printf("The main information contains %d arrays and %d information\n", numArrays, numInfo);
+
+  // Doing this used to deallocate the Information
+  // After changing the way that shared pointers interact with objects
+  // there is no longer any deallocation
+  XdmfInformationRemoveInformation(information, 0);
+
+  childKey = XdmfInformationGetKey(internalInfo);
+
+  childValue = XdmfInformationGetValue(internalInfo);
+
+  printf("The Child's key equals: %s\nThe Child's Value equals: %s\n", childKey, childValue);
+
+  childKey = XdmfInformationGetKey(childInfo);
+
+  childValue = XdmfInformationGetValue(childInfo);
+
+  printf("The Child's key equals: %s\nThe Child's Value equals: %s\n", childKey, childValue);
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfSparseMatrix.c b/core/tests/C/CTestXdmfSparseMatrix.c
new file mode 100644
index 0000000..be27028
--- /dev/null
+++ b/core/tests/C/CTestXdmfSparseMatrix.c
@@ -0,0 +1,170 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfWriter.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  int status = 0;
+
+  void * matrix = XdmfSparseMatrixNew(3, 3);
+
+  XdmfSparseMatrixSetName(matrix, "testMatrix", &status);
+
+  char * valueString = XdmfSparseMatrixGetName(matrix);
+
+  printf("%s ?= %s\n", valueString, "testMatrix");
+
+  assert(strcmp(valueString, "testMatrix") == 0);
+
+  free(valueString);
+
+  valueString = XdmfSparseMatrixGetItemTag(matrix);
+
+  printf("%s ?= %s\n", valueString, "SparseMatrix");
+
+  assert(strcmp(valueString, "SparseMatrix") == 0);
+
+  void * rowPointer = XdmfSparseMatrixGetRowPointer(matrix, &status);
+
+  void * columnIndex = XdmfSparseMatrixGetColumnIndex(matrix, &status);
+
+  void * values = XdmfSparseMatrixGetValues(matrix, &status);
+
+  unsigned int insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  double insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -1.0;
+
+  XdmfArrayInsertValue(values, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  valueString = XdmfSparseMatrixGetValuesString(matrix, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  rowPointer = XdmfArrayNew();
+
+  columnIndex = XdmfArrayNew();
+
+  values = XdmfArrayNew();
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -1.0;
+
+  XdmfArrayInsertValue(values, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfSparseMatrixSetColumnIndex(matrix, columnIndex, 0, &status);
+
+  XdmfSparseMatrixSetRowPointer(matrix, rowPointer, 0, &status);
+
+  XdmfSparseMatrixSetValues(matrix, values, 0, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("matrixfile.xmf");
+
+  XdmfSparseMatrixAccept(matrix, (XDMFVISITOR *)writer, &status);
+
+  unsigned int numRows = XdmfSparseMatrixGetNumberRows(matrix);
+
+  unsigned int numCols = XdmfSparseMatrixGetNumberColumns(matrix);
+
+  printf("%d ?= %d\n", numRows, 3);
+
+  assert(numRows == 3);
+
+  printf("%d ?= %d\n", numCols, 3);
+
+  assert(numCols == 3);
+
+  valueString = XdmfSparseMatrixGetValuesString(matrix, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  unsigned int numInfo = XdmfSparseMatrixGetNumberInformations(matrix);
+
+  printf("%d ?= %d\n", numInfo, 0);
+
+  assert(numInfo == 0);
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfSubset.c b/core/tests/C/CTestXdmfSubset.c
new file mode 100644
index 0000000..2e1f451
--- /dev/null
+++ b/core/tests/C/CTestXdmfSubset.c
@@ -0,0 +1,174 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfWriter.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  void * array = XdmfArrayNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(array, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  char * valueString = XdmfArrayGetValuesString(array);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  unsigned int starts[1] = {0};
+  unsigned int strides[1] = {2};
+  unsigned int dimensions[1] = {5};
+
+  unsigned int numDims = 1;
+
+  XDMFSUBSET * subset = XdmfSubsetNew(array, starts, strides, dimensions, numDims, 0, &status);
+
+  void * internalArray = XdmfSubsetGetReferenceArray(subset);
+
+  valueString = XdmfArrayGetValuesString(internalArray);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  unsigned int internalNumDims = XdmfSubsetGetNumberDimensions(subset);
+
+  printf("%d ?= %d\n", internalNumDims, 1);
+
+  assert(internalNumDims == 1);
+
+  unsigned int * internalDims = XdmfSubsetGetDimensions(subset);
+
+  printf("%d ?= %d\n", internalDims[0], 5);
+
+  assert(internalDims[0] == 5);
+
+  free(internalDims);
+
+  unsigned int * internalStarts = XdmfSubsetGetStart(subset);
+
+  printf("%d ?= %d\n", internalStarts[0], 0);
+
+  assert(internalStarts[0] == 0);
+
+  free(internalStarts);
+
+  unsigned int * internalStrides = XdmfSubsetGetStride(subset);
+
+  printf("%d ?= %d\n", internalStrides[0], 2);
+
+  assert(internalStrides[0] == 2);
+
+  free(internalStrides);
+
+  void * readArray = XdmfSubsetRead(subset, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 2 4 6 8", valueString);
+
+  assert(strcmp("0 2 4 6 8", valueString) == 0);
+
+  free(valueString);
+
+  free(readArray);
+
+  unsigned int internalSize = XdmfSubsetGetSize(subset);
+
+  printf("%d ?= %d\n", internalSize, 5);
+
+  assert(internalSize == 5);
+
+  strides[0] = 1;
+
+  starts[0] = 3;
+
+  dimensions[0] = 4;
+
+  XdmfSubsetSetDimensions(subset, dimensions, 1, &status);
+
+  XdmfSubsetSetStart(subset, starts, 1, &status);
+
+  XdmfSubsetSetStride(subset, strides, 1, &status);
+
+  internalNumDims = XdmfSubsetGetNumberDimensions(subset);
+
+  printf("%d ?= %d\n", internalNumDims, 1);
+
+  assert(internalNumDims == 1);
+
+  internalDims = XdmfSubsetGetDimensions(subset);
+
+  printf("%d ?= %d\n", internalDims[0], 4);
+
+  assert(internalDims[0] == 4);
+
+  internalStarts = XdmfSubsetGetStart(subset);
+
+  printf("%d ?= %d\n", internalStarts[0], 3);
+
+  assert(internalStarts[0] == 3);
+
+  internalStrides = XdmfSubsetGetStride(subset);
+
+  printf("%d ?= %d\n", internalStrides[0], 1);
+
+  assert(internalStrides[0] == 1);
+
+  readArray = XdmfSubsetRead(subset, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "3 4 5 6", valueString);
+
+  assert(strcmp("3 4 5 6", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfSubsetGetConstructedType(subset);
+
+  printf("%s ?= %s\n", "", valueString);
+
+  assert(strcmp("", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfSubsetGetItemTag(subset);
+
+  printf("%s ?= %s\n", "Subset", valueString);
+
+  assert(strcmp("Subset", valueString) == 0);
+
+  free(valueString);
+
+  XdmfSubsetSetConstructedType(subset, "DataItem");
+
+  XdmfSubsetSetConstructedProperties(subset, readArray);
+
+  XDMFWRITER * writer = XdmfWriterNew("subsetfile.xmf");
+
+  XdmfSubsetAccept(subset, (XDMFVISITOR *)writer, &status);
+
+  unsigned int numInfo = XdmfSubsetGetNumberInformations(subset);
+
+  printf("%d ?= %d\n", numInfo, 0);
+
+  assert(numInfo == 0);
+
+  return 0;
+}
diff --git a/core/tests/C/CTestXdmfWriter.c b/core/tests/C/CTestXdmfWriter.c
new file mode 100644
index 0000000..dbd3f9a
--- /dev/null
+++ b/core/tests/C/CTestXdmfWriter.c
@@ -0,0 +1,21 @@
+#include "XdmfArray.hpp"
+#include "XdmfWriter.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+  int status;
+  XDMFWRITER * writer = XdmfWriterNew("testfile.xmf");
+//TODO HeavyDataWriter interaction
+
+  char * testFileName = XdmfWriterGetFilePath(writer, &status);
+  int testLimit = XdmfWriterGetLightDataLimit(writer, &status);
+  printf("light data limit = %d\n", testLimit);
+
+  return 0;
+}
diff --git a/core/tests/CMakeLists.txt b/core/tests/CMakeLists.txt
new file mode 100644
index 0000000..25d1572
--- /dev/null
+++ b/core/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_subdirectory(C)
+add_subdirectory(Cxx)
+
+if(XDMF_WRAP_PYTHON)
+  add_subdirectory(Python)
+endif(XDMF_WRAP_PYTHON)
+
+if(XDMF_WRAP_JAVA)
+  add_subdirectory(Java)
+endif(XDMF_WRAP_JAVA)
diff --git a/core/tests/Cxx/CMakeLists.txt b/core/tests/Cxx/CMakeLists.txt
new file mode 100644
index 0000000..a84851c
--- /dev/null
+++ b/core/tests/Cxx/CMakeLists.txt
@@ -0,0 +1,59 @@
+# Include our test macros
+include(AddTestsCxx)
+
+# Add any dependencies that the cxx core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_CXX_DEPENDENCIES("XdmfCore")
+
+# Add any ldpath directories that the cxx tests may need
+ADD_TEST_CXX_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_CXX_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directoreis that the Cxx tests may need
+ADD_TEST_CXX_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_CXX_PATH("${XDMF_BINARIES}")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_CXX(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+ADD_TEST_CXX(TestXdmfArray)
+ADD_TEST_CXX(TestXdmfArrayInsert)
+ADD_TEST_CXX(TestXdmfArrayMultidimensional)
+ADD_TEST_CXX(TestXdmfArrayMultiDimensionalInsert)
+ADD_TEST_CXX(TestXdmfArrayWriteRead)
+ADD_TEST_CXX(TestXdmfArrayWriteReadHyperSlabs)
+ADD_TEST_CXX(TestXdmfError)
+ADD_TEST_CXX(TestXdmfHDF5Controller)
+ADD_TEST_CXX(TestXdmfHDF5Writer)
+ADD_TEST_CXX(TestXdmfHDF5WriterTree)
+ADD_TEST_CXX(TestXdmfInformation)
+ADD_TEST_CXX(TestXdmfSparseMatrix)
+ADD_TEST_CXX(TestXdmfVersion)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_CXX(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_CXX(TestXdmfArray)
+CLEAN_TEST_CXX(TestXdmfArrayInsert)
+CLEAN_TEST_CXX(TestXdmfArrayMultidimensional)
+CLEAN_TEST_CXX(TestXdmfArrayMultiDimensionalInsert)
+CLEAN_TEST_CXX(TestXdmfArrayWriteRead
+  test.h5)
+CLEAN_TEST_CXX(TestXdmfArrayWriteRead
+  testHyperslab.h5)
+CLEAN_TEST_CXX(TestXdmfError)
+CLEAN_TEST_CXX(TestXdmfHDF5Controller)
+CLEAN_TEST_CXX(TestXdmfHDF5Writer
+  hdf5WriterTest.h5
+  hdf5CompressionTestDeflate.h5
+  hdf5CompressionTestComparison.h5)
+CLEAN_TEST_CXX(TestXdmfHDF5WriterTree
+  hdf5WriterTestTree.h5)
+CLEAN_TEST_CXX(TestXdmfInformation)
+CLEAN_TEST_CXX(TestXdmfSparseMatrix
+  TestXdmfSparseMatrix.xmf)
+CLEAN_TEST_CXX(TestXdmfVersion)
diff --git a/core/tests/Cxx/TestXdmfArray.cpp b/core/tests/Cxx/TestXdmfArray.cpp
new file mode 100644
index 0000000..c63a91b
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfArray.cpp
@@ -0,0 +1,476 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+
+  int values[] = {1, 2, 3, 4};
+
+  //
+  // COPIES
+  //
+
+  /**
+   * Array stride = 1, Values stride = 1
+   */
+  shared_ptr<XdmfArray> array = XdmfArray::New();
+  std::cout << array->getSize() << " ?= " << 0 << std::endl;
+  std::cout << array->getArrayType() << " ?= " << XdmfArrayType::Uninitialized() << std::endl;
+  std::cout << array->getValuesString() << " ?= " << "" << std::endl;
+  std::cout << array->getValuesInternal() << " ?= " << "NULL" << std::endl;
+  assert(array->getSize() == 0);
+  assert(array->getArrayType() == XdmfArrayType::Uninitialized());
+  assert(array->getValuesString() == "");
+  assert(array->getValuesInternal() == NULL);
+  std::vector<unsigned int> dimensions = array->getDimensions();
+  std::cout << dimensions.size() << " ?= "  << 1 << std::endl;
+  std::cout << dimensions[0] << " ?= "  << 0 << std::endl;
+  std::cout << array->getDimensionsString() << " ?= "  << "0" << std::endl;
+  assert(dimensions.size() == 1);
+  assert(dimensions[0] == 0);
+  assert(array->getDimensionsString().compare("0") == 0);
+  array->insert(0, &values[0], 4, 1, 1);
+  std::cout << array->getSize() << " ?= " << 4 << std::endl;
+  std::cout << array->getArrayType() << " ?= " << XdmfArrayType::Int32() << std::endl;
+  std::cout << array->getValuesString() << " ?= " << "1 2 3 4" << std::endl;
+  assert(array->getSize() == 4);
+  assert(array->getArrayType() == XdmfArrayType::Int32());
+  assert(array->getValuesString().compare("1 2 3 4") == 0);
+  const int * const arrayPointer = 
+    static_cast<int *>(array->getValuesInternal());
+  std::cout << arrayPointer[0] << " ?= " << 1 << std::endl;
+  std::cout << arrayPointer[1] << " ?= " << 2 << std::endl;
+  std::cout << arrayPointer[2] << " ?= " << 3 << std::endl;
+  std::cout << arrayPointer[3] << " ?= " << 4 << std::endl;
+  assert(arrayPointer[0] == 1);
+  assert(arrayPointer[1] == 2);
+  assert(arrayPointer[2] == 3);
+  assert(arrayPointer[3] == 4);
+  // Assert we copied values correctly
+  shared_ptr<std::vector<int> > storedValues =
+    array->getValuesInternal<int>();
+  std::cout << (*storedValues)[0] << " ?= " << 1 << std::endl;
+  std::cout << (*storedValues)[1] << " ?= " << 2 << std::endl;
+  std::cout << (*storedValues)[2] << " ?= " << 3 << std::endl;
+  std::cout << (*storedValues)[3] << " ?= " << 4 << std::endl;
+  assert((*storedValues)[0] == 1);
+  assert((*storedValues)[1] == 2);
+  assert((*storedValues)[2] == 3);
+  assert((*storedValues)[3] == 4);
+  // Assert we can copy values out correctly
+  std::vector<int> outValues(4);
+  array->getValues(0, &outValues[0], 4);
+  for(unsigned int i=0; i<outValues.size(); ++i) {
+    std::cout << outValues[i] << " ?= " << values[i] << std::endl;
+    assert(outValues[i] == values[i]);
+  }
+
+  /**
+   * Array stride = 2, Values stride = 1
+   */
+  shared_ptr<XdmfArray> array2 = XdmfArray::New();
+  array2->insert(0, &values[0], 2, 2, 1);
+  std::cout << array2->getSize() << " ?= " << 3 << std::endl;
+  std::cout << array2->getArrayType() << " ?= " << XdmfArrayType::Int32() << std::endl;
+  std::cout << array2->getValuesString() << " ?= " << "1 0 2" << std::endl;
+  assert(array2->getSize() == 3);
+  assert(array2->getArrayType() == XdmfArrayType::Int32());
+  assert(array2->getValuesString().compare("1 0 2") == 0);
+  storedValues = array2->getValuesInternal<int>();
+  std::cout << (*storedValues)[0] << " ?= " << 1 << std::endl;
+  std::cout << (*storedValues)[1] << " ?= " << 0 << std::endl;
+  std::cout << (*storedValues)[2] << " ?= " << 2 << std::endl;
+  assert((*storedValues)[0] == 1);
+  assert((*storedValues)[1] == 0);
+  assert((*storedValues)[2] == 2);
+
+  /**
+   * Array stride = 1, Values stride = 2
+   */
+  shared_ptr<XdmfArray> array3 = XdmfArray::New();
+  array3->insert(0, &values[0], 2, 1, 2);
+  std::cout << array3->getSize() << " ?= " << 2 << std::endl;
+  std::cout << array3->getArrayType() << " ?= " << XdmfArrayType::Int32() << std::endl;
+  std::cout << array3->getValuesString() << " ?= " << "1 3" << std::endl;
+  assert(array3->getSize() == 2);
+  assert(array3->getArrayType() == XdmfArrayType::Int32());
+  assert(array3->getValuesString().compare("1 3") == 0);
+  storedValues = array3->getValuesInternal<int>();
+  std::cout << (*storedValues)[0] << " ?= " << 1 << std::endl;
+  std::cout << (*storedValues)[1] << " ?= " << 3 << std::endl;
+  assert((*storedValues)[0] == 1);
+  assert((*storedValues)[1] == 3);
+
+  /**
+   * Array stride = 2, Values stride = 2
+   */
+  shared_ptr<XdmfArray> array4 = XdmfArray::New();
+  array4->insert(0, &values[0], 2, 2, 2);
+  std::cout << array4->getSize() << " ?= " << 3 << std::endl;
+  std::cout << array4->getValuesString() << " ?= " << "1 0 3" << std::endl;
+  assert(array4->getSize() == 3);
+  assert(array4->getValuesString().compare("1 0 3") == 0);
+  storedValues = array4->getValuesInternal<int>();
+  std::cout << (*storedValues)[0] << " ?= " << 1 << std::endl;
+  std::cout << (*storedValues)[1] << " ?= " << 0 << std::endl;
+  std::cout << (*storedValues)[2] << " ?= " << 3 << std::endl;
+  assert((*storedValues)[0] == 1);
+  assert((*storedValues)[1] == 0);
+  assert((*storedValues)[2] == 3);
+
+  /**
+   * Copy values from another XdmfArray
+   * Array stride = 1, Values stride = 1
+   */
+  shared_ptr<XdmfArray> array5 = XdmfArray::New();
+  array5->insert(0, array, 1, 3);
+  std::cout << array5->getSize() << " ?= " << 3 << std::endl;
+  std::cout << array5->getArrayType() << " ?= " << array->getArrayType() << std::endl;
+  assert(array5->getSize() == 3);
+  assert(array5->getArrayType() == array->getArrayType());
+  storedValues = array5->getValuesInternal<int>();
+  std::cout << array5->getSize() << " ?= " << "3" << std::endl;
+  std::cout << array->getSize() << " ?= " << "4" << std::endl;
+  std::cout << array5->getValuesString() << " ?= " << "2 3 4" << std::endl;
+  assert(array5->getSize() == 3);
+  assert(array->getSize() == 4);
+  assert(array5->getValuesString().compare("2 3 4") == 0);
+  array5->insert(1, array, 1, 3);
+  std::cout << array5->getValuesString() << " ?= " << "2 2 3 4" << std::endl;
+  assert(array5->getValuesString().compare("2 2 3 4") == 0);
+  array5->clear();
+  std::cout << array5->getSize() << " ?= " << "0" << std::endl;
+  assert(array5->getSize() == 0);
+  array5->insert(0, array, 1, 3, 2, 1);
+  std::cout << array5->getValuesString() << " ?= " << "2 0 3 0 4" << std::endl;
+  assert(array5->getValuesString().compare("2 0 3 0 4") == 0);
+  array5->clear();
+  array5->insert(0, array, 1, 2, 2, 2);
+  std::cout << array5->getValuesString() << " ?= " << "2 0 4" << std::endl;
+  assert(array5->getValuesString().compare("2 0 4") == 0);
+
+  /**
+   * Single Insertion
+   */
+  shared_ptr<XdmfArray> array10 = XdmfArray::New();
+  array10->insert<unsigned int>(0, 1);
+  std::cout << array10->getSize() << " ?= " << 1 << std::endl;
+  std::cout << array10->getValue<unsigned int>(0) << " ?= " << 1 << std::endl;
+  assert(array10->getSize() == 1);
+  assert(array10->getValue<unsigned int>(0) == 1);
+
+  //
+  // PUSHBACK
+  //
+  shared_ptr<XdmfArray> pushBackArray = XdmfArray::New();
+  std::cout << pushBackArray->getSize() << " ?= " << 0 << std::endl;
+  assert(pushBackArray->getSize() == 0);
+  pushBackArray->pushBack(10);
+  std::cout << pushBackArray->getSize() << " ?= " << 1 << std::endl;
+  assert(pushBackArray->getSize() == 1);
+
+  //
+  // SETS
+  //
+
+  /**
+   * Simple Set
+   */
+  array5->setValuesInternal(values, 2, 0);
+  std::cout << array5->getSize() << " ?= " << 2 << std::endl;
+  std::cout << array5->getArrayType() << " ?= " << XdmfArrayType::Int32() << std::endl;
+  std::cout << array5->getValuesString() << " ?= " << "1 2" << std::endl;
+  assert(array5->getSize() == 2);
+  assert(array5->getArrayType() == XdmfArrayType::Int32());
+  assert(array5->getValuesString().compare("1 2") == 0);
+  const int * const array5Pointer = 
+    static_cast<int *>(array5->getValuesInternal());
+  std::cout << array5Pointer[0] << " ?= " << 1 << std::endl;
+  std::cout << array5Pointer[1] << " ?= " << 2 << std::endl;
+  assert(array5Pointer[0] == 1);
+  assert(array5Pointer[1] == 2);
+  // Assert we can copy values out correctly
+  array->getValues(1, &outValues[0], 3);
+  std::cout << outValues[0] << " ?= " << values[1] << std::endl;
+  assert(outValues[0] == values[1]);
+
+  /**
+   * Copy after Set
+   */
+  array5->setValuesInternal(&values[1], 3, 0);
+  std::cout << array5->getSize() << " ?= " << 3 << std::endl;
+  std::cout << array5->getValuesString() << " ?= " << "2 3 4" << std::endl;
+  assert(array5->getSize() == 3);
+  assert(array5->getValuesString().compare("2 3 4") == 0);
+   int zero = 0;
+   array5->insert(3, &zero, 1, 1, 0);
+  std::cout << array5->getSize() << " ?= " << 4 << std::endl;
+  std::cout << array5->getValuesString() << " ?= " << "2 3 4 0" << std::endl;
+  assert(array5->getSize() == 4);
+  assert(array5->getValuesString().compare("2 3 4 0") == 0);
+
+  /**
+   * Set and Ownership transfer
+   */
+  double * doubleValues = new double[3];
+  doubleValues[0] = 0;
+  doubleValues[1] = 1.1;
+  doubleValues[2] = 10.1;
+  array5->setValuesInternal(doubleValues, 3, 1);
+  std::cout << array5->getSize() << " ?= " << 3 << std::endl;
+  std::cout << array5->getArrayType() << " ?= " << XdmfArrayType::Float64() << std::endl;
+  assert(array5->getSize() == 3);
+  assert(array5->getArrayType() == XdmfArrayType::Float64());
+
+  //
+  // SHARED ASSIGNMENTS
+  //
+
+  /**
+   * Shared vector assignment
+   */
+  shared_ptr<std::vector<char> > values2(new std::vector<char>());
+  values2->push_back(-2);
+  values2->push_back(-1);
+  values2->push_back(0);
+  values2->push_back(1);
+  values2->push_back(2);
+  shared_ptr<XdmfArray> array6 = XdmfArray::New();
+  array6->setValuesInternal(values2);
+  std::cout << array6->getSize() << " ?= " << 5 << std::endl;
+  std::cout << array6->getArrayType() << " ?= " << XdmfArrayType::Int8() << std::endl;
+  std::cout << array6->getValuesString() << " ?= " << "-2 -1 0 1 2" << std::endl;
+  assert(array6->getSize() == 5);
+  assert(array6->getArrayType() == XdmfArrayType::Int8());
+  assert(array6->getValuesString().compare("-2 -1 0 1 2") == 0);
+  // Assert we have the same values!
+  shared_ptr<std::vector<char> > storedValues2 =
+    array6->getValuesInternal<char>();
+  int i = 0;
+  for(std::vector<char>::const_iterator iter = storedValues2->begin();
+      iter != storedValues2->end();
+      ++iter, ++i) {
+    std::cout << *iter << " ?= " << values2->operator[](i) << std::endl;
+    assert(*iter == values2->operator[](i));
+  }
+  // Now modify original array
+  values2->push_back(8);
+  std::cout << array6->getSize() << " ?= " << 6 << std::endl;
+  std::cout << array6->getValuesString() << " ?= " << "-2 -1 0 1 2 8" << std::endl;
+  assert(array6->getSize() == 6);
+  assert(array6->getValuesString().compare("-2 -1 0 1 2 8") == 0);
+  // Assert we have the same values!
+  i = 0;
+  for(std::vector<char>::const_iterator iter = storedValues2->begin();
+      iter != storedValues2->end();
+      ++iter, ++i) {
+    std::cout << *iter << " ?= " << values2->operator[](i) << std::endl;
+    assert(*iter == values2->operator[](i));
+  }
+  // Assert we can't get an int vector out of our array.
+  shared_ptr<std::vector<int> > storedValues2Int =
+    array6->getValuesInternal<int>();
+  std::cout << storedValues2Int << " ?= " << "NULL" << std::endl;
+  assert(storedValues2Int == NULL);
+
+  //
+  // SWAPS
+  //
+
+  /**
+   * Swap values from a vector
+   */
+  std::vector<short> values3;
+  values3.push_back(-1);
+  values3.push_back(0);
+  values3.push_back(1);
+  shared_ptr<XdmfArray> array7 = XdmfArray::New();
+  array7->swap(values3);
+  std::cout << values3.size() << " ?= " << 0 << std::endl;
+  std::cout << array7->getSize() << " ?= " << 3 << std::endl;
+  std::cout << array7->getArrayType() << " ?= " << XdmfArrayType::Int16() << std::endl;
+  assert(values3.size() == 0);
+  assert(array7->getSize() == 3);
+  assert(array7->getArrayType() == XdmfArrayType::Int16());
+  shared_ptr<std::vector<short> > storedValues3 =
+    array7->getValuesInternal<short>();
+  std::cout << (*storedValues3)[0] << " ?= " << -1 << std::endl;
+  std::cout << (*storedValues3)[1] << " ?= " << 0 << std::endl;
+  std::cout << (*storedValues3)[2] << " ?= " << 1 << std::endl;
+  assert((*storedValues3)[0] == -1);
+  assert((*storedValues3)[1] == 0);
+  assert((*storedValues3)[2] == 1);
+
+  /**
+   * Swap values from a shared vector
+   */
+  array7->release();
+  array7->swap(values2);
+  std::cout << storedValues2->size() << " ?= " << 0 << std::endl;
+  std::cout << array7->getSize() << " ?= " << 6 << std::endl;
+  std::cout << array7->getArrayType() << " ?= " << XdmfArrayType::Int8() << std::endl;
+  assert(storedValues2->size() == 0);
+  assert(array7->getSize() == 6);
+  assert(array7->getArrayType() == XdmfArrayType::Int8());
+
+  /**
+   * Swap values from an XdmfArray (with copy)
+   */
+  array7->release();
+  array7->swap(array4);
+  std::cout << array4->getSize() << " ?= " << 0 << std::endl;
+  std::cout << array7->getSize() << " ?= " << 3 << std::endl;
+  assert(array4->getSize() == 0);
+  assert(array7->getSize() == 3);
+
+  /**
+   * Swap values from an XdmfArray (with pointer)
+   */
+  array5->setValuesInternal(&values[1], 3, 0);
+  std::cout << array5->getSize() << " ?= " << 3 << std::endl;
+  assert(array5->getSize() == 3);
+  array7->release();
+  array7->swap(array5);
+  std::cout << array5->getSize() << " ?= " << 0 << std::endl;
+  std::cout << array7->getSize() << " ?= " << 3 << std::endl;
+  assert(array5->getSize() == 0);
+  assert(array7->getSize() == 3);
+
+  //
+  // Various STL like functions
+  //
+
+  /**
+   * Resize
+   */
+  shared_ptr<XdmfArray> array8 = XdmfArray::New();
+  array8->insert(0, &values[0], 4, 1, 1);
+  array8->resize(5, 0);
+  std::cout << array8->getValuesString() << " ?= " << "1 2 3 4 0" << std::endl;
+  assert(array8->getValuesString().compare("1 2 3 4 0") == 0);
+  array8->resize(3, 0);
+  std::cout << array8->getValuesString() << " ?= " << "1 2 3" << std::endl;
+  assert(array8->getValuesString().compare("1 2 3") == 0);
+  array8->resize(8, 1.1);
+  std::cout << array8->getValuesString() << " ?= " << "1 2 3 1 1 1 1 1" << std::endl;
+  assert(array8->getValuesString().compare("1 2 3 1 1 1 1 1") == 0);
+
+  /**
+   * Erase
+   */
+  array8->erase(0);
+  std::cout << array8->getValuesString() << " ?= " << "2 3 1 1 1 1 1" << std::endl;
+  assert(array8->getValuesString().compare("2 3 1 1 1 1 1") == 0);
+
+  /**
+   * Reserve / Capacity
+   */
+  array8->reserve(50);
+  std::cout << array8->getCapacity() << " ?>= " << 50 << std::endl;
+  assert(array8->getCapacity() >= 50);
+
+  std::cout << array8->getName() << " ?= " << "" << std::endl;
+  assert(array8->getName().compare("") == 0);
+  array8->setName("BLAH");
+  std::cout << array8->getName() << " ?= " << "BLAH" << std::endl;
+  assert(array8->getName().compare("BLAH") == 0);
+
+  /**
+   * Dimensions
+   */
+  dimensions.resize(2);
+  dimensions[0] = 3;
+  dimensions[1] = 3;
+  shared_ptr<XdmfArray> array9 = XdmfArray::New();
+  array9->initialize(XdmfArrayType::Float64(),
+                     dimensions);
+  std::cout << array9->getDimensionsString() << " ?= " << "3 3" << std::endl;
+  std::cout << array9->getSize() << " ?= " << "9" << std::endl;
+  assert(array9->getDimensionsString() == "3 3");
+  assert(array9->getSize() == 9);
+  array9->insert<double>(9, 1.0);
+  std::cout << array9->getDimensionsString() << " ?= " << "10" << std::endl;
+  assert(array9->getDimensionsString() == "10");
+
+  //
+  // STRINGS
+  //
+  shared_ptr<XdmfArray> stringArray = XdmfArray::New();
+  stringArray->resize<std::string>(3, "");
+  std::string firstValue = stringArray->getValue<std::string>(0);
+  std::cout << firstValue << " ?= " << "" << std::endl;
+  assert(firstValue.compare("") == 0);
+  stringArray->insert<std::string>(0, "foo");
+  stringArray->insert<std::string>(1, "bar");
+  stringArray->insert<std::string>(2, "cat");
+  firstValue = stringArray->getValue<std::string>(0);
+  std::cout << firstValue << " ?= " << "foo" << std::endl;
+  assert(firstValue.compare("foo") == 0);
+  std::string allValues = stringArray->getValuesString();
+  std::cout << allValues << " ?= " << "foo bar cat" << std::endl;
+  assert(allValues.compare("foo bar cat") == 0);
+  stringArray->insert<int>(3, 1);
+  allValues = stringArray->getValuesString();
+  std::cout << allValues << " ?= " << "foo bar cat 1" << std::endl;
+  assert(allValues.compare("foo bar cat 1") == 0);
+  int num = stringArray->getValue<int>(3);
+  std::cout << num << " ?= " << 1 << std::endl;
+  assert(num == 1);
+
+  /**
+   * ArrayType compatibility
+   */
+  std::vector<shared_ptr<const XdmfArrayType> > typeVector;
+  typeVector.push_back(XdmfArrayType::Int8());
+  typeVector.push_back(XdmfArrayType::Int16());
+  typeVector.push_back(XdmfArrayType::Int32());
+  typeVector.push_back(XdmfArrayType::Int64());
+  typeVector.push_back(XdmfArrayType::UInt8());
+  typeVector.push_back(XdmfArrayType::UInt16());
+  typeVector.push_back(XdmfArrayType::UInt32());
+  typeVector.push_back(XdmfArrayType::Float32());
+  typeVector.push_back(XdmfArrayType::Float64());
+  typeVector.push_back(XdmfArrayType::String());
+
+  for (unsigned int i = 0; i < typeVector.size(); ++i) {
+    for (unsigned int j = 0; j < typeVector.size(); ++j) {
+      shared_ptr<XdmfArray> valTypeArray1 = XdmfArray::New();
+      shared_ptr<XdmfArray> valTypeArray2 = XdmfArray::New();
+      shared_ptr<const XdmfArrayType> valType1 = typeVector[i];
+      shared_ptr<const XdmfArrayType> valType2 = typeVector[j];
+      valTypeArray1->initialize(valType1);
+      valTypeArray2->initialize(valType2);
+      valTypeArray1->pushBack(-1.25);
+      valTypeArray2->pushBack(-1.25);
+      shared_ptr<XdmfArray> valIntersectArray = XdmfArray::New();
+      shared_ptr<const XdmfArrayType> valIntersectType = XdmfArrayType::comparePrecision(typeVector[i], typeVector[j]);
+      valIntersectArray->initialize(valIntersectType);
+      valIntersectArray->insert(0, valTypeArray1, 0, 1, 1);
+      valIntersectArray->insert(1, valTypeArray2, 0, 1, 1);
+      std::stringstream output1;
+      std::stringstream output2;
+      if (valType1 == XdmfArrayType::Int8() && valType2 == XdmfArrayType::String()) {
+        output1 << valTypeArray1->getValue<char>(0) << " " << valTypeArray2->getValuesString() << std::endl;
+      }
+      else if (valType1 == XdmfArrayType::UInt8() && valType2 == XdmfArrayType::String()) {
+        output1 << valTypeArray1->getValue<unsigned char>(0) << " " << valTypeArray2->getValuesString() << std::endl;
+      }
+      else if (valType2 == XdmfArrayType::Int8() && valType1 == XdmfArrayType::String()) {
+        output1 << valTypeArray1->getValuesString() << " " << valTypeArray2->getValue<char>(0) << std::endl;
+      }
+      else if (valType2 == XdmfArrayType::UInt8() && valType1 == XdmfArrayType::String()) {
+        output1 << valTypeArray1->getValuesString() << " " << valTypeArray2->getValue<unsigned char>(0) << std::endl;
+      }
+      else {
+        output1 << valTypeArray1->getValuesString() << " " << valTypeArray2->getValuesString() << std::endl;
+      }
+      output2 << valIntersectArray->getValuesString() << std::endl;
+      std::cout << output1.str() << "==" << output2.str();
+      assert(output1.str() == output2.str());
+    }
+  }
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfArrayInsert.cpp b/core/tests/Cxx/TestXdmfArrayInsert.cpp
new file mode 100644
index 0000000..53fba3c
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfArrayInsert.cpp
@@ -0,0 +1,79 @@
+#include "XdmfArray.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+
+  // Insert from another array
+  shared_ptr<XdmfArray> array1 = XdmfArray::New();
+  shared_ptr<XdmfArray> insertArray1 = XdmfArray::New();
+  shared_ptr<XdmfArray> insertArray2 = XdmfArray::New();
+  shared_ptr<XdmfArray> insertArray3 = XdmfArray::New();
+  shared_ptr<XdmfArray> insertArray4 = XdmfArray::New();
+
+  insertArray1->resize<int>(10, 1);
+  insertArray2->resize<int>(10, 2);
+  insertArray3->resize<int>(10, 3);
+  insertArray4->resize<int>(10, 4);
+
+  array1->insert(0, insertArray1, 0, 10, 4, 1);
+  array1->insert(1, insertArray2, 0, 10, 4, 1);
+  array1->insert(2, insertArray3, 0, 10, 4, 1);
+  array1->insert(3, insertArray4, 0, 10, 4, 1);
+
+  std::cout << array1->getValuesString() << " ?= "
+            << "1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 "
+            << "2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 "
+            << "3 4 1 2 3 4" << std::endl;
+
+  assert(array1->getValuesString().compare("1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 "
+                                           "2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 "
+                                           "3 4 1 2 3 4") == 0);
+
+  // Insert from vector
+  std::vector<int> insertArray5(10, 1);
+  std::vector<int> insertArray6(10, 2);
+  std::vector<int> insertArray7(10, 3);
+  std::vector<int> insertArray8(10, 4);
+
+  shared_ptr<XdmfArray> array2 = XdmfArray::New();
+
+  array2->insert(0, &(insertArray5[0]), 10, 4, 1);
+  array2->insert(1, &(insertArray6[0]), 10, 4, 1);
+  array2->insert(2, &(insertArray7[0]), 10, 4, 1);
+  array2->insert(3, &(insertArray8[0]), 10, 4, 1);
+
+  std::cout << array2->getValuesString() << " ?= "
+            << "1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 "
+            << "2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 "
+            << "3 4 1 2 3 4" << std::endl;
+
+  assert(array2->getValuesString().compare("1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 "
+                                           "2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 "
+                                           "3 4 1 2 3 4") == 0);
+
+  // Insert from vector string
+  std::vector<std::string> insertArray9(10, "1");
+  std::vector<std::string> insertArray10(10, "2");
+  std::vector<std::string> insertArray11(10, "3");
+  std::vector<std::string> insertArray12(10, "4");
+
+  shared_ptr<XdmfArray> array3 = XdmfArray::New();
+
+  array3->insert(0, &(insertArray9[0]), 10, 4, 1);
+  array3->insert(1, &(insertArray10[0]), 10, 4, 1);
+  array3->insert(2, &(insertArray11[0]), 10, 4, 1);
+  array3->insert(3, &(insertArray12[0]), 10, 4, 1);
+
+  std::cout << array3->getValuesString() << " ?= "
+            << "1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 "
+            << "2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 "
+            << "3 4 1 2 3 4" << std::endl;
+
+  assert(array3->getValuesString().compare("1 2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 "
+                                           "2 3 4 1 2 3 4 1 2 3 4 1 2 3 4 1 2 "
+                                           "3 4 1 2 3 4") == 0);
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfArrayMultiDimensionalInsert.cpp b/core/tests/Cxx/TestXdmfArrayMultiDimensionalInsert.cpp
new file mode 100644
index 0000000..6022209
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfArrayMultiDimensionalInsert.cpp
@@ -0,0 +1,52 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfWriter.hpp>
+
+int main(int, char **)
+{
+	
+	shared_ptr<XdmfArray> writtenArray = XdmfArray::New();
+	std::vector<unsigned int> dimensionVector;
+	dimensionVector.push_back(5);
+	dimensionVector.push_back(4);
+	writtenArray->initialize<int>(dimensionVector);
+	for (int i = 0; i < 20; i++)
+	{
+		writtenArray->insert(i, i + 1);
+	}
+
+	shared_ptr<XdmfArray> readArray = XdmfArray::New();
+	std::vector<unsigned int> readDimensionVector;
+	readDimensionVector.push_back(6);
+	readDimensionVector.push_back(4);
+	readArray->initialize<int>(readDimensionVector);
+
+	std::vector<unsigned int> writeStarts;
+	writeStarts.push_back(0);
+	writeStarts.push_back(0);
+	std::vector<unsigned int> writeStrides;
+	writeStrides.push_back(2);
+	writeStrides.push_back(2);
+	std::vector<unsigned int> writeDim;
+	writeDim.push_back(3);
+	writeDim.push_back(2);
+	std::vector<unsigned int> readStarts;
+	readStarts.push_back(0);
+	readStarts.push_back(0);
+	std::vector<unsigned int> readStrides;
+	readStrides.push_back(2);
+	readStrides.push_back(2);
+	std::vector<unsigned int> readDim;
+	readDim.push_back(3);
+	readDim.push_back(2);
+	
+	readArray->insert(readStarts, writtenArray, writeStarts, writeDim, readDim, readStrides, writeStrides);
+
+        std::cout << readArray->getValuesString() << " ?= " << "1 0 3 0 5 0 0 0 0 0 0 0 11 0 13 0 15 0 0 0 0 0 0 0" << std::endl;
+
+	assert(readArray->getValuesString().compare("1 0 3 0 5 0 0 0 0 0 0 0 11 0 13 0 15 0 0 0 0 0 0 0") == 0);
+
+	return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfArrayMultidimensional.cpp b/core/tests/Cxx/TestXdmfArrayMultidimensional.cpp
new file mode 100644
index 0000000..e27aef6
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfArrayMultidimensional.cpp
@@ -0,0 +1,94 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+
+  //
+  // Create 1D arrays
+  //
+  shared_ptr<XdmfArray> array = XdmfArray::New();
+  array->initialize(XdmfArrayType::UInt32(), 2);
+  std::cout << array->getArrayType() << " ?= " << XdmfArrayType::UInt32() << std::endl;
+  assert(array->getArrayType() == XdmfArrayType::UInt32());
+  std::cout << array->getSize() << " ?= " << 2 << std::endl;
+  assert(array->getSize() == 2);
+  std::vector<unsigned int> dimensions = array->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 1 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 2 << std::endl;
+  assert(dimensions.size() == 1);
+  assert(dimensions[0] == 2);
+  std::string dimensionsString = array->getDimensionsString();
+  std::cout << dimensionsString << " ?= " << "2" << std::endl;
+  assert(dimensionsString.compare("2") == 0);
+  array->resize<unsigned int>(3);
+  std::cout << array->getSize() << " ?= " << 3 << std::endl;
+  assert(array->getSize() == 3);
+  dimensions = array->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 1 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 3 << std::endl;
+  assert(dimensions.size() == 1);
+  assert(dimensions[0] == 3);
+  dimensionsString = array->getDimensionsString();
+  std::cout << dimensionsString << " ?= " << "3" << std::endl;
+  assert(dimensionsString.compare("3") == 0);
+  
+  //
+  // Create 2D arrays
+  //
+  shared_ptr<XdmfArray> array2 = XdmfArray::New();
+  std::vector<unsigned int> newDimensions(2, 2);
+  array2->initialize<unsigned short>(newDimensions);
+  std::cout << array2->getArrayType() << " ?= " << XdmfArrayType::UInt16() << std::endl;
+  std::cout << array2->getSize() << " ?= " << 4 << std::endl;
+  assert(array2->getArrayType() == XdmfArrayType::UInt16());
+  assert(array2->getSize() == 4);
+  dimensions = array2->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << dimensions[1] << " ?= " << 2 << std::endl;
+  assert(dimensions.size() == 2);
+  assert(dimensions[0] == 2 && dimensions[1] == 2);
+  dimensionsString = array2->getDimensionsString();
+  std::cout << dimensionsString << " ?= " << "2 2" << std::endl;
+  assert(dimensionsString.compare("2 2") == 0);
+  std::vector<unsigned int> newDimensions2(3,3);
+  array2->resize<unsigned short>(newDimensions2);
+  std::cout << array2->getSize() << " ?= " << 27 << std::endl;
+  assert(array2->getSize() == 27);
+  dimensions = array2->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 3 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 3 << std::endl;
+  std::cout << dimensions[1] << " ?= " << 3 << std::endl;
+  std::cout << dimensions[2] << " ?= " << 3 << std::endl;
+  assert(dimensions.size() == 3);
+  assert(dimensions[0] == 3 && dimensions[1] == 3 && dimensions[2] == 3);
+  dimensionsString = array2->getDimensionsString();
+  std::cout << dimensionsString << " ?= " << "3 3 3" << std::endl;
+  assert(dimensionsString.compare("3 3 3") == 0);
+
+  int values[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+  array2->insert(0, &values[0], 11);
+  std::cout << array2->getSize() << " ?= " << 27 << std::endl;
+  assert(array2->getSize() == 27);
+  dimensions = array2->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 3 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 3 << std::endl;
+  std::cout << dimensions[1] << " ?= " << 3 << std::endl;
+  std::cout << dimensions[2] << " ?= " << 3 << std::endl;
+  assert(dimensions.size() == 3);
+  assert(dimensions[0] == 3 && dimensions[1] == 3 && dimensions[2] == 3);
+
+  array2->pushBack(10);
+  std::cout << array2->getSize() << " ?= " << 28 << std::endl;
+  assert(array2->getSize() == 28);
+  dimensions = array2->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 1 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 28 << std::endl;
+  assert(dimensions.size() == 1);
+  assert(dimensions[0] == 28);
+  
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfArrayWriteRead.cpp b/core/tests/Cxx/TestXdmfArrayWriteRead.cpp
new file mode 100644
index 0000000..c16851e
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfArrayWriteRead.cpp
@@ -0,0 +1,100 @@
+#include "XdmfArray.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  int values[] = {1, 2, 3, 4};
+
+  shared_ptr<XdmfArray> array = XdmfArray::New();
+  array->insert(0, &values[0], 4, 1, 1);
+  std::cout << array->getSize() << " ?= " << 4 << std::endl;
+  assert(array->getSize() == 4);
+  std::cout << array->getValuesString() << " ?= " << "1 2 3 4" << std::endl;
+  assert(array->getValuesString().compare("1 2 3 4") == 0);
+
+  shared_ptr<XdmfHDF5Writer> writer = XdmfHDF5Writer::New("test.h5");
+  array->accept(writer);
+
+  std::cout << array->getSize() << " ?= " << 4 << std::endl;
+  assert(array->getSize() == 4);
+  std::cout << array->getValuesString() << " ?= " << "1 2 3 4" << std::endl;
+  assert(array->getValuesString().compare("1 2 3 4") == 0);
+
+  array->release();
+  std::cout << array->getValuesString() << " ?= " << "" << std::endl;
+  assert(array->getValuesString() == "");
+  std::cout << array->getSize() << " ?= " << 4 << std::endl;
+  assert(array->getSize() == 4);
+
+  array->read();
+  std::cout << array->getValuesString() << " ?= " << "1 2 3 4" << std::endl;
+  assert(array->getValuesString().compare("1 2 3 4") == 0);
+
+  shared_ptr<XdmfArray> stringArray = XdmfArray::New();
+  stringArray->pushBack<std::string>("foo");
+  stringArray->pushBack<std::string>("bar");
+  stringArray->pushBack<std::string>("cat");
+  stringArray->pushBack<std::string>("dog");
+  stringArray->pushBack<std::string>("blah");
+  std::cout << stringArray->getSize() << " ?= " << 5 << std::endl;
+  assert(stringArray->getSize() == 5);
+  std::cout << stringArray->getValuesString() << " ?= " << "foo bar cat dog blah" << std::endl;
+  assert(stringArray->getValuesString().compare("foo bar cat dog blah") == 0);
+
+  shared_ptr<XdmfHDF5Writer> stringWriter = 
+    XdmfHDF5Writer::New("testString.h5");
+  stringArray->accept(stringWriter);
+
+  stringArray->release();
+  stringArray->read();
+  std::cout << stringArray->getSize() << " ?= " << 5 << std::endl;
+  assert(stringArray->getSize() == 5);
+  std::cout << stringArray->getValuesString() << " ?= " << "foo bar cat dog blah" << std::endl;
+  assert(stringArray->getValuesString().compare("foo bar cat dog blah") == 0);
+  std::cout << stringArray->getValue<std::string>(0) << " ?= " << "foo" << std::endl;
+  assert(stringArray->getValue<std::string>(0).compare("foo") == 0);
+  
+  shared_ptr<XdmfArray> dimensionsArray = XdmfArray::New();
+  std::vector<unsigned int> dimensions(3);
+  dimensions[0] = 2;
+  dimensions[1] = 3;
+  dimensions[2] = 4;
+  dimensionsArray->resize<double>(dimensions);
+  double data[24] = {0.0, 1.0, 2.0, 3.0, 4.0,
+                     5.0, 6.0, 7.0, 8.0, 9.0,
+                     10.0, 11.0, 12.0, 13.0, 14.0,
+                     15.0, 16.0, 17.0, 18.0, 19.0,
+                     20.0, 21.0, 22.0, 23.0};
+  dimensionsArray->insert<double>(0, data, 24);
+  shared_ptr<XdmfHDF5Writer> dimensionsWriter = 
+    XdmfHDF5Writer::New("testDimensions.h5");
+  dimensionsWriter->setChunkSize(4);
+  dimensionsArray->accept(dimensionsWriter);
+
+  dimensionsArray->release();
+  dimensionsArray->read();
+  std::cout << dimensionsArray->getSize() << " ?= " << 24 << std::endl;
+  assert(dimensionsArray->getSize() == 24);
+  std::vector<unsigned int> readDimensions = dimensionsArray->getDimensions();
+  std::cout << readDimensions.size() << " ?= " << 3 << std::endl;
+  assert(readDimensions.size() == 3);
+  std::cout << readDimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[1] << " ?= " << 3 << std::endl;
+  std::cout << readDimensions[2] << " ?= " << 4 << std::endl;
+  assert(readDimensions[0] == 2);
+  assert(readDimensions[1] == 3);
+  assert(readDimensions[2] == 4);
+
+  shared_ptr<XdmfHDF5Writer> largeArrayWriter = 
+    XdmfHDF5Writer::New("testLargeArray.h5");
+  largeArrayWriter->setChunkSize(1500);
+  shared_ptr<XdmfArray> largeArray = XdmfArray::New();
+  std::vector<unsigned int> largeDimensions(2);
+  largeDimensions[0] = 1000;
+  largeDimensions[1] = 3;
+  largeArray->resize<double>(largeDimensions);
+  largeArray->accept(largeArrayWriter);
+
+}
diff --git a/core/tests/Cxx/TestXdmfArrayWriteReadHyperSlabs.cpp b/core/tests/Cxx/TestXdmfArrayWriteReadHyperSlabs.cpp
new file mode 100644
index 0000000..ea80fee
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfArrayWriteReadHyperSlabs.cpp
@@ -0,0 +1,68 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  int values1[] = {1, 2};
+  int values2[] = {3, 4};
+
+  shared_ptr<XdmfArray> array1 = XdmfArray::New();
+  array1->insert(0, &values1[0], 2, 1, 1);
+  std::cout << array1->getSize() << " ?= " << "2" << std::endl;
+  assert(array1->getSize() == 2);
+  std::cout << array1->getValuesString() << " ?= " << "1 2" << std::endl;
+  assert(array1->getValuesString().compare("1 2") == 0);
+
+  shared_ptr<XdmfArray> array2 = XdmfArray::New();
+  array2->insert(0, &values2[0], 2, 1, 1);
+  std::cout << array2->getSize() << " ?= " << "2" << std::endl;
+  assert(array2->getSize() == 2);
+  std::cout << array2->getValuesString() << " ?= " << "3 4" << std::endl;
+  assert(array2->getValuesString().compare("3 4") == 0);
+
+  //
+  // write array1 to first part of dataset
+  //
+  shared_ptr<XdmfHDF5Controller> controller1 = 
+    XdmfHDF5Controller::New("testHyperslab.h5",
+                            "data",
+                            XdmfArrayType::Int32(),
+                            std::vector<unsigned int>(1, 0),
+                            std::vector<unsigned int>(1, 1),
+                            std::vector<unsigned int>(1, 2),
+                            std::vector<unsigned int>(1, 4));
+  array1->setHeavyDataController(controller1);
+  shared_ptr<XdmfHDF5Writer> writer = XdmfHDF5Writer::New("testHyperslab.h5");
+  writer->setMode(XdmfHeavyDataWriter::Hyperslab);
+  array1->accept(writer);
+
+  //
+  // write array2 to second part of dataset
+  //
+  shared_ptr<XdmfHDF5Controller> controller2 = 
+    XdmfHDF5Controller::New("testHyperslab.h5",
+                            "data",
+                            XdmfArrayType::Int32(),
+                            std::vector<unsigned int>(1, 2),
+                            std::vector<unsigned int>(1, 1),
+                            std::vector<unsigned int>(1, 2),
+                            std::vector<unsigned int>(1, 4));
+  array2->setHeavyDataController(controller2);
+  array2->accept(writer);
+
+  //
+  // assert we can release and read same data we wrote
+  //
+  array1->release();
+  array1->read();
+  std::cout << array1->getValuesString() << " ?= " << "1 2" << std::endl;
+  assert(array1->getValuesString().compare("1 2") == 0);
+  array2->release();
+  array2->read();
+  std::cout << array2->getValuesString() << " ?= " << "3 4" << std::endl;
+  std::cout << array2->getValuesString() << std::endl;
+  assert(array2->getValuesString().compare("3 4") == 0);
+}
diff --git a/core/tests/Cxx/TestXdmfError.cpp b/core/tests/Cxx/TestXdmfError.cpp
new file mode 100644
index 0000000..683d3ed
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfError.cpp
@@ -0,0 +1,188 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfError.hpp>
+
+int main(int, char **)
+{
+	
+	shared_ptr<XdmfArray> writtenArray = XdmfArray::New();
+	std::vector<unsigned int> dimensionVector;
+	dimensionVector.push_back(20);
+//	dimensionVector.push_back(5);
+//	dimensionVector.push_back(4);
+	writtenArray->initialize<int>(dimensionVector);
+	for (int i = 0; i < 20; i++)
+	{
+		writtenArray->insert(i, i + 1);
+	}
+
+	shared_ptr<XdmfArray> readArray = XdmfArray::New();
+	std::vector<unsigned int> readDimensionVector;
+	readDimensionVector.push_back(6);
+	readDimensionVector.push_back(4);
+	readArray->initialize<int>(readDimensionVector);
+
+	std::vector<unsigned int> writeStarts;
+	writeStarts.push_back(0);
+	writeStarts.push_back(0);
+	std::vector<unsigned int> writeStrides;
+	writeStrides.push_back(2);
+	writeStrides.push_back(2);
+	std::vector<unsigned int> writeDim;
+	writeDim.push_back(3);
+	writeDim.push_back(2);
+	std::vector<unsigned int> readStarts;
+	readStarts.push_back(0);
+	readStarts.push_back(0);
+	std::vector<unsigned int> readStrides;
+	readStrides.push_back(2);
+	readStrides.push_back(2);
+	std::vector<unsigned int> readDim;
+	readDim.push_back(3);
+	readDim.push_back(2);
+
+	try
+	{	
+		readArray->insert(readStarts, writtenArray, writeStarts, writeDim, readDim, readStrides, writeStrides);
+	}
+	catch (XdmfError e)
+	{
+		//a print statement is redundant since the error message is sent to cout
+		//std::cout << "The error message is:\n" << e.what() << std::endl;
+	}
+
+	std::cout << "default error levels" << std::endl;
+
+	try
+	{
+		XdmfError::message(XdmfError::FATAL, "throwing fatal");
+	}
+	catch (XdmfError e)
+	{
+		std::cout << "fatal caught" << std::endl;
+	}
+
+        try
+        {
+		XdmfError::message(XdmfError::WARNING, "throwing warning");
+        }
+        catch (XdmfError e)
+        {
+		std::cout << "warning caught" << std::endl;
+        }
+
+        try
+        {
+		XdmfError::message(XdmfError::DEBUG, "throwing debug");
+        }
+        catch (XdmfError e)
+        {
+		std::cout << "debug caught" << std::endl;
+        }
+
+	std::cout << std::endl;
+
+	std::cout << "both levels set to FATAL" << std::endl;
+
+	XdmfError::setSuppressionLevel(XdmfError::FATAL);
+	XdmfError::setLevelLimit(XdmfError::FATAL);
+
+        try
+        {
+                XdmfError::message(XdmfError::FATAL, "throwing fatal");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "fatal caught" << std::endl;
+        }
+
+        try
+        {
+                XdmfError::message(XdmfError::WARNING, "throwing warning");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "warning caught" << std::endl;
+        }
+
+        try
+        {
+                XdmfError::message(XdmfError::DEBUG, "throwing debug");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "debug caught" << std::endl;
+        }
+
+	std::cout << std::endl;
+
+	std::cout << "both levels set to WARNING" << std::endl;
+
+	XdmfError::setSuppressionLevel(XdmfError::WARNING);
+	XdmfError::setLevelLimit(XdmfError::WARNING);
+
+        try
+        {
+                XdmfError::message(XdmfError::FATAL, "throwing fatal");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "fatal caught" << std::endl;
+        }
+
+        try
+        {
+                XdmfError::message(XdmfError::WARNING, "throwing warning");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "warning caught" << std::endl;
+        }
+
+        try
+        {
+                XdmfError::message(XdmfError::DEBUG, "throwing debug");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "debug caught" << std::endl;
+        }
+
+	std::cout << std::endl;
+
+	std::cout << "both levels set to DEBUG" << std::endl;
+
+	XdmfError::setSuppressionLevel(XdmfError::DEBUG);
+	XdmfError::setLevelLimit(XdmfError::DEBUG);
+
+        try
+        {
+                XdmfError::message(XdmfError::FATAL, "throwing fatal");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "fatal caught" << std::endl;
+        }
+
+        try
+        {
+                XdmfError::message(XdmfError::WARNING, "throwing warning");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "warning caught" << std::endl;
+        }
+
+        try
+        {
+                XdmfError::message(XdmfError::DEBUG, "throwing debug");
+        }
+        catch (XdmfError e)
+        {
+                std::cout << "debug caught" << std::endl;
+        }
+
+	return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfHDF5Controller.cpp b/core/tests/Cxx/TestXdmfHDF5Controller.cpp
new file mode 100644
index 0000000..2f66163
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfHDF5Controller.cpp
@@ -0,0 +1,27 @@
+#include <sstream>
+#include <iostream>
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfSystemUtils.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfHDF5Controller> controller =
+    XdmfHDF5Controller::New("output.h5",
+                            "/foo/data1",
+                            XdmfArrayType::Int8(),
+                            std::vector<unsigned int>(1, 0),
+                            std::vector<unsigned int>(1, 1),
+                            std::vector<unsigned int>(1, 10),
+                            std::vector<unsigned int>(1, 10));
+
+  std::cout << controller->getDataSetPath() << " ?= " << "/foo/data1" << std::endl;
+  std::cout << controller->getSize() << " ?= " << 10 << std::endl;
+  std::cout << controller->getType() << " ?= " << XdmfArrayType::Int8() << std::endl;
+
+  assert(controller->getDataSetPath().compare("/foo/data1") == 0);
+  assert(controller->getSize() == 10);
+  assert(controller->getType() == XdmfArrayType::Int8());
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfHDF5Writer.cpp b/core/tests/Cxx/TestXdmfHDF5Writer.cpp
new file mode 100644
index 0000000..a212774
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfHDF5Writer.cpp
@@ -0,0 +1,130 @@
+#include "XdmfArray.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfArray> array = XdmfArray::New();
+  array->pushBack(0);
+  array->pushBack(1);
+  array->pushBack(2);
+
+  //
+  // Default operation - Always write to separate datasets.
+  //
+
+  std::cout << array->getHeavyDataController() << " ?= " << "NULL"
+            << std::endl; 
+
+  assert(array->getHeavyDataController() == NULL);
+  shared_ptr<XdmfHDF5Writer> writer = XdmfHDF5Writer::New("hdf5WriterTest.h5");
+  array->accept(writer);
+  shared_ptr<XdmfHDF5Controller> firstController =
+    shared_dynamic_cast<XdmfHDF5Controller>(array->getHeavyDataController());
+  std::string firstPath = firstController->getDataSetPath();
+  array->accept(writer);
+  shared_ptr<XdmfHDF5Controller> secondController =
+    shared_dynamic_cast<XdmfHDF5Controller>(array->getHeavyDataController());
+  std::string secondPath = secondController->getDataSetPath();
+
+  std::cout << firstPath << " ?!= " << secondPath << std::endl;
+
+  assert(firstPath.compare(secondPath) != 0);
+
+  //
+  // Overwrite operation - Always write to the same datasets.
+  //
+  writer->setMode(XdmfHDF5Writer::Overwrite);
+  array->accept(writer);
+  shared_ptr<XdmfHDF5Controller> thirdController =
+    shared_dynamic_cast<XdmfHDF5Controller>(array->getHeavyDataController());
+  std::string thirdPath = thirdController->getDataSetPath();
+
+  std::cout << secondPath << " ?= " << thirdPath << std::endl;
+
+  assert(secondPath.compare(thirdPath) == 0);
+
+  array->pushBack(3);
+  array->accept(writer);
+  shared_ptr<XdmfHDF5Controller> fourthController =
+    shared_dynamic_cast<XdmfHDF5Controller>(array->getHeavyDataController());
+  std::string fourthPath = fourthController->getDataSetPath();
+
+  std::cout << thirdPath << " ?= " << fourthPath << std::endl;
+
+  assert(thirdPath.compare(fourthPath) == 0);
+
+  array->erase(0);
+  array->erase(0);
+  array->accept(writer);
+  shared_ptr<XdmfHDF5Controller> fifthController = 
+    shared_dynamic_cast<XdmfHDF5Controller>(array->getHeavyDataController());
+  std::string fifthPath = fifthController->getDataSetPath();
+
+  std::cout << fourthPath << " ?= " << fifthPath << std::endl;
+
+  assert(fourthPath.compare(fifthPath) == 0);
+
+  //
+  // Append operation - Append data to same dataset.
+  //
+  writer->setMode(XdmfHDF5Writer::Append);
+  // Append 4 times
+  array->accept(writer);
+  array->accept(writer);
+  array->accept(writer);
+  array->accept(writer);
+
+  std::cout << array->getSize() << " ?= " << 2 << std::endl;
+
+  assert(array->getSize() == 2);
+  array->read();
+
+  std::cout << array->getSize() << " ?= " << 10 << std::endl;
+
+  assert(array->getSize() == 10);
+  for(int i=0; i<5; ++i) {
+    std::cout << array->getValue<int>(i*2) << " ?= " << 2 << std::endl;
+    std::cout << array->getValue<int>(i*2 + 1) << " ?= " << 3 << std::endl;
+
+    assert(array->getValue<int>(i*2) == 2);
+    assert(array->getValue<int>(i*2 + 1) == 3);
+  }
+
+  //
+  // Using Deflate Compression
+  //
+  shared_ptr<XdmfHDF5Writer> compressedWriter = XdmfHDF5Writer::New("hdf5CompressionTestDeflate.h5");
+  compressedWriter->setMode(XdmfHDF5Writer::Default);
+  compressedWriter->setUseDeflate(true);
+  compressedWriter->setDeflateFactor(6);
+  shared_ptr<XdmfArray> compressedArray = XdmfArray::New();
+  for (unsigned int i = 0; i < 20000; ++i)
+  {
+    compressedArray->pushBack(i);
+  }
+
+  compressedArray->accept(compressedWriter);
+
+  compressedArray->release();
+
+  compressedArray->read();
+
+  for (unsigned int i = 0; i < 20000; ++i)
+  {
+    assert(compressedArray->getValue<unsigned int>(i) == i);
+  }
+
+  // For comparison
+  shared_ptr<XdmfHDF5Writer> compareWriter = XdmfHDF5Writer::New("hdf5CompressionTestComparison.h5");
+  shared_ptr<XdmfArray> compareArray = XdmfArray::New();
+  for (unsigned int i = 0; i < 20000; ++i)
+  {
+    compareArray->pushBack(i);
+  }
+
+  compareArray->accept(compareWriter);
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfHDF5WriterTree.cpp b/core/tests/Cxx/TestXdmfHDF5WriterTree.cpp
new file mode 100644
index 0000000..94b8a56
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfHDF5WriterTree.cpp
@@ -0,0 +1,75 @@
+#include "XdmfArray.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  
+  shared_ptr<XdmfInformation> information = XdmfInformation::New();
+  information->setKey("foo");
+  information->setValue("bar");
+  
+  shared_ptr<XdmfArray> array1 = XdmfArray::New();
+  array1->pushBack(0);
+  array1->pushBack(1);
+  array1->pushBack(2);
+
+  shared_ptr<XdmfArray> array2 = XdmfArray::New();
+  array2->pushBack(3);
+  array2->pushBack(4);
+  array2->pushBack(5);
+  
+  information->insert(array1);
+  information->insert(array2);
+  
+  shared_ptr<XdmfHDF5Writer> writer = 
+    XdmfHDF5Writer::New("hdf5WriterTestTree.h5");
+  information->accept(writer);
+
+  if (array1->getHeavyDataController())
+  {
+    std::cout << "array 1 does not have a heavy data controller" << std::endl;
+  }
+  else
+  {
+    std::cout << "array 1 has a heavy data controller" << std::endl;
+  }
+
+  if (array2->getHeavyDataController())
+  {
+    std::cout << "array 2 does not have a heavy data controller" << std::endl;
+  }
+  else
+  {
+    std::cout << "array 2 has a heavy data controller" << std::endl;
+  }
+
+  assert(array1->getHeavyDataController());
+  assert(array2->getHeavyDataController());
+  
+  array1->release();
+  array2->release();
+
+  array1->read();
+  array2->read();
+
+  for (unsigned int i = 0; i < 3; ++i)
+  {
+    std::cout << array1->getValue<int>(i) << " ?= " << i << std::endl;
+  }
+
+  for (unsigned int i = 0; i < 3; ++i)
+  {
+    std::cout << array2->getValue<int>(i) << " ?= " << i+3 << std::endl;
+  }
+
+  assert(array1->getValue<int>(0) == 0);
+  assert(array1->getValue<int>(1) == 1);
+  assert(array1->getValue<int>(2) == 2);
+  assert(array2->getValue<int>(0) == 3);
+  assert(array2->getValue<int>(1) == 4);
+  assert(array2->getValue<int>(2) == 5);
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfInformation.cpp b/core/tests/Cxx/TestXdmfInformation.cpp
new file mode 100644
index 0000000..032f1b8
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfInformation.cpp
@@ -0,0 +1,71 @@
+#include "XdmfInformation.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfInformation> information = XdmfInformation::New();
+
+  std::cout << information->getKey() << " ?= " << "" << std::endl;
+  std::cout << information->getValue() << " ?= " << "" << std::endl;
+
+  assert(information->getKey().compare("") == 0);
+  assert(information->getValue().compare("") == 0);
+  information->setKey("Key");
+  information->setValue("Value");
+
+  std::cout << information->getKey() << " ?= " << "Key" << std::endl;
+  std::cout << information->getValue() << " ?= " << "Value" << std::endl;
+
+  assert(information->getKey().compare("Key") == 0);
+  assert(information->getValue().compare("Value") == 0);
+
+  shared_ptr<XdmfInformation> information1 = XdmfInformation::New("Key1", 
+                                                                  "Value1");
+
+  std::cout << information1->getKey() << " ?= " << "Key1" << std::endl;
+  std::cout << information1->getValue() << " ?= " << "Value1" << std::endl;
+
+  assert(information1->getKey().compare("Key1") == 0);
+  assert(information1->getValue().compare("Value1") == 0);
+
+  std::cout << information->getNumberInformations() << " ?= " << 0 << std::endl;
+  std::cout << information->getInformation(0) << " ?= " << "NULL" 
+            << std::endl;
+  std::cout << information->getInformation("foo") << " ?= " << "NULL"
+            << std::endl;
+
+  assert(information->getNumberInformations() == 0);
+  assert(information->getInformation(0) == NULL);
+  assert(information->getInformation("foo") == NULL);
+  information->removeInformation(0);
+
+  std::cout << information->getNumberInformations() << " ?= " << 0 << std::endl;
+
+  assert(information->getNumberInformations() == 0);
+  information->insert(information1);
+
+  std::cout << information->getNumberInformations() << " ?= " << 1 << std::endl;
+
+  assert(information->getNumberInformations() == 1);
+
+  std::cout << information->getInformation(0) << " ?= " << information1 
+            << std::endl;
+  std::cout << information->getInformation(1) << " ?= " << "NULL" 
+            << std::endl;
+  std::cout << information->getInformation("Key1") << " ?= " << information1 
+            << std::endl;
+  std::cout << information->getInformation("foo") << " ?= " << "NULL"
+            << std::endl;
+
+  assert(information->getInformation(0) == information1);
+  assert(information->getInformation(1) == NULL);
+  assert(information->getInformation("Key1") == information1);
+  assert(information->getInformation("foo") == NULL);
+  information->removeInformation("Key1");
+
+  std::cout << information->getNumberInformations() << " ?= " << 0 << std::endl;
+
+  assert(information->getNumberInformations() == 0);
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfSparseMatrix.cpp b/core/tests/Cxx/TestXdmfSparseMatrix.cpp
new file mode 100644
index 0000000..b18914f
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfSparseMatrix.cpp
@@ -0,0 +1,34 @@
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfWriter.hpp"
+#include "stdio.h"
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfSparseMatrix> matrix = XdmfSparseMatrix::New(3, 3);
+
+  matrix->setName("foo");
+  shared_ptr<XdmfArray> rowPointer = matrix->getRowPointer();
+  shared_ptr<XdmfArray> columnIndex = matrix->getColumnIndex();
+  shared_ptr<XdmfArray> values = matrix->getValues();
+
+  rowPointer->insert<unsigned int>(0, 0);
+  rowPointer->insert<unsigned int>(1, 1);
+  rowPointer->insert<unsigned int>(2, 2);
+  rowPointer->insert<unsigned int>(3, 3);
+  columnIndex->pushBack<unsigned int>(1);
+  columnIndex->pushBack<unsigned int>(2);
+  columnIndex->pushBack<unsigned int>(0);
+  values->pushBack<double>(5.0);
+  values->pushBack<double>(6.0);
+  values->pushBack<double>(-1.0);
+
+  std::cout << "matrix contains" << "\n" << matrix->getValuesString() << std::endl;
+
+  assert(matrix->getValuesString().compare("0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("TestXdmfSparseMatrix.xmf");
+  matrix->accept(writer);
+
+  return 0;
+}
diff --git a/core/tests/Cxx/TestXdmfVersion.cpp b/core/tests/Cxx/TestXdmfVersion.cpp
new file mode 100644
index 0000000..f3c1e8e
--- /dev/null
+++ b/core/tests/Cxx/TestXdmfVersion.cpp
@@ -0,0 +1,8 @@
+#include <iostream>
+#include "XdmfVersion.hpp"
+
+int main() {
+  std::cout << XdmfVersion.getFull() << std::endl;
+  std::cout << XdmfVersion.getShort() << std::endl;
+  return 0;
+}
diff --git a/core/tests/Java/CMakeLists.txt b/core/tests/Java/CMakeLists.txt
new file mode 100644
index 0000000..f5d4295
--- /dev/null
+++ b/core/tests/Java/CMakeLists.txt
@@ -0,0 +1,36 @@
+INCLUDE(AddTestsJava)
+
+#Add any dependencies that the java core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_JAVA_DEPENDENCIES(Compiled_XdmfCore_Jar)
+
+# Add any classpath directories that the java tests may need
+ADD_TEST_JAVA_CLASSPATH("${XdmfCore_JAVA_JAR}")
+
+# Add any ldpath directories that the java tests may need
+ADD_TEST_JAVA_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_JAVA_LDPATH("${XDMF_LIBRARIES}")
+
+# Add any path directories that the java tests may need
+ADD_TEST_JAVA_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_JAVA_PATH("${XDMF_BINARIES}")
+
+# Add any java tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have extra arguments (ie: ADD_TEST_JAVA(testname inputfile))
+#	Read UseJavaTest.cmake for more information
+# ------------------------
+ADD_TEST_JAVA(TestXdmfEquals)
+ADD_TEST_JAVA(TestXdmfArray)
+
+# Add any java cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have multiple files (ie: CLEAN_TEST_JAVA(testname outputfile1 ...))
+#	Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_JAVA(TestXdmfEquals)
+CLEAN_TEST_JAVA(TestXdmfArray)
+
+# Add a custom target for all java tests 
+# Note: ${TARGETS} is set in ADD_TEST_JAVA
+CREATE_TARGET_TEST_JAVA()
diff --git a/core/tests/Java/TestXdmfArray.java b/core/tests/Java/TestXdmfArray.java
new file mode 100644
index 0000000..3dbad67
--- /dev/null
+++ b/core/tests/Java/TestXdmfArray.java
@@ -0,0 +1,32 @@
+import mil.army.arl.xdmf.*;
+
+public class TestXdmfArray {
+    static {
+        System.loadLibrary("XdmfCoreJava");
+    }
+
+    public static void main (String argv[]) {
+        System.out.println("Hello World");
+        
+        XdmfArray array = XdmfArray.New();
+        array.initializeAsFloat64();
+        array.pushBackAsFloat64(1.0);
+        array.pushBackAsFloat64(2.0);
+        array.pushBackAsFloat64(3.0);
+		if(array.getSize() != 3) {
+			throw new SecurityException("XdmfArray: pushBack failed");
+		}
+    
+        double[] da = {1.0,2.0,3.0};
+        XdmfArray array2 = XdmfArray.New();
+        array2.initializeAsFloat64();
+        array2.insertValuesAsFloat64(0, da);
+        System.out.println(array2.getSize());
+        if(array2.getSize() != 3) {
+            throw new SecurityException("XdmfArray: insert failed");
+        }
+
+        
+		
+    }
+}
diff --git a/core/tests/Java/TestXdmfEquals.java b/core/tests/Java/TestXdmfEquals.java
new file mode 100644
index 0000000..a5bd035
--- /dev/null
+++ b/core/tests/Java/TestXdmfEquals.java
@@ -0,0 +1,39 @@
+import mil.army.arl.xdmf.*;
+
+public class TestXdmfEquals {
+    static {
+        System.loadLibrary("XdmfCoreJava");
+    }
+
+    public static void main (String argv[]) {
+        System.out.println("Hello World");
+
+		XdmfArrayType type1a = XdmfArrayType.Int16();
+		XdmfArrayType type1b = XdmfArrayType.Int16();
+		XdmfArrayType type2 = XdmfArrayType.Int32();	
+		// Check IsEquals
+		if(!(type1a.IsEqual(type1b))) /*True*/ {
+			throw new SecurityException("Failed True Check");
+		}
+		if((type1a.IsEqual(type2))) /*False*/ {
+	    		throw new SecurityException("Failed False Check");	
+		}
+	
+		// Check equals
+		if(!(type1a.equals(type1b))) /*True*/ {
+			throw new SecurityException("Failed True Check (equals)");
+		}
+		if(type1a.equals(type2)) /*False*/ {
+			throw new SecurityException("Failed False Check (equals)");
+		}
+	
+	    	// Check ==
+		if(type1a == type1b) /*False*/ {
+			throw new SecurityException("Failed True Check (==)");
+		}
+		if(type1a == type2) /*False*/ {
+			throw new SecurityException("Failed False Check (==)");
+		}
+		
+    }
+}
diff --git a/core/tests/Python/CMakeLists.txt b/core/tests/Python/CMakeLists.txt
new file mode 100644
index 0000000..2485c5f
--- /dev/null
+++ b/core/tests/Python/CMakeLists.txt
@@ -0,0 +1,42 @@
+include(AddTestsPython)
+
+# Add any dependencies that the python tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_PYTHON_DEPENDENCIES("")
+
+# Add any pythonpath directories that the python tests may need
+ADD_TEST_PYTHON_PYTHONPATH("${CMAKE_BINARY_DIR}")
+
+# Add any ldpath directories that the python tests may need
+ADD_TEST_PYTHON_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_PYTHON_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directories that the python tests may need
+ADD_TEST_PYTHON_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_PYTHON_PATH("${HDF5_BINARY_DIRS}")
+ADD_TEST_PYTHON_PATH("${LIBXML2_BINARY_DIRS}")
+
+# Add any python tests here:
+# Note: we don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_PYTHON(testname inputfile))
+#       Read UsePythonTest.cmake for more information
+# ---------------------
+ADD_TEST_PYTHON(TestXdmfArray)
+ADD_TEST_PYTHON(TestXdmfArrayMultidimensional)
+ADD_TEST_PYTHON(TestXdmfEquals)
+ADD_TEST_PYTHON(TestXdmfError)
+ADD_TEST_PYTHON(TestXdmfVersion)
+
+# Add any python cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_PYTHON(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_PYTHON(TestXdmfArray)
+CLEAN_TEST_PYTHON(TestXdmfArrayMultidimensional)
+CLEAN_TEST_PYTHON(TestXdmfEquals)
+CLEAN_TEST_PYTHON(TestXdmfError)
+CLEAN_TEST_PYTHON(TestXdmfVersion)
+
+# Add a custom target for all python tests
+CREATE_TARGET_TEST_PYTHON()
diff --git a/core/tests/Python/TestXdmfArray.py b/core/tests/Python/TestXdmfArray.py
new file mode 100644
index 0000000..cdaf671
--- /dev/null
+++ b/core/tests/Python/TestXdmfArray.py
@@ -0,0 +1,107 @@
+from XdmfCore import *
+
+if __name__ == "__main__":
+
+    values1 = [0, 1, 2, 3]
+    array1 = XdmfArray.New()
+    array1.insertAsInt8(0, values1)
+    print array1.getValuesString()
+    print str(array1.getArrayType()) + " ?= " + str(XdmfArrayType.Int8())
+    assert array1.getArrayType() == XdmfArrayType.Int8()
+
+    array2 = XdmfArray.New()
+    array2.insertAsInt16(0, values1)
+    print array2.getValuesString()
+    print str(array2.getArrayType()) + " ?= " + str(XdmfArrayType.Int16())
+    assert array2.getArrayType() == XdmfArrayType.Int16()
+
+    array3 = XdmfArray.New()
+    array3.insertAsInt32(0, values1[2:4])
+    print array3.getValuesString()
+    print str(array3.getArrayType()) + " ?= " + str(XdmfArrayType.Int32())
+    assert array3.getArrayType() == XdmfArrayType.Int32()
+
+    # Stride
+    array4 = XdmfArray.New()
+    array4.insertAsInt64(0, values1[0:4:2])
+    print array4.getValuesString()
+    print str(array4.getArrayType()) + " ?= " + str(XdmfArrayType.Int64())
+    assert array4.getArrayType() == XdmfArrayType.Int64()
+
+    # Stride on List
+    array4a = XdmfArray.New()
+    array4a.insertAsInt64(0, values1, 2, 4, 2, 1);
+    print array4a.getValuesString()
+    print str(array4a.getArrayType()) + " ?= " + str(XdmfArrayType.Int64())
+    assert array4a.getArrayType() == XdmfArrayType.Int64()
+
+    # Reverse
+    array5 = XdmfArray.New()
+    array5.insertAsFloat32(0, values1[::-1])
+    print array5.getValuesString()
+    print str(array5.getArrayType()) + " ?= " + str(XdmfArrayType.Float32())
+    assert array5.getArrayType() == XdmfArrayType.Float32()
+
+    array6 = XdmfArray.New()
+    array6.insertAsFloat64(0, values1)
+    print array6.getValuesString()
+    print str(array6.getArrayType()) + " ?= " + str(XdmfArrayType.Float64())
+    assert array6.getArrayType() == XdmfArrayType.Float64()
+
+    array7 = XdmfArray.New()
+    array7.insertAsUInt8(0, values1)
+    print array7.getValuesString()
+    print str(array7.getArrayType()) + " ?= " + str(XdmfArrayType.UInt8())
+    assert array7.getArrayType() == XdmfArrayType.UInt8()
+
+    array8 = XdmfArray.New()
+    array8.insertAsUInt16(0, values1)
+    print array8.getValuesString()
+    print str(array8.getArrayType()) + " ?= " + str(XdmfArrayType.UInt16())
+    assert array8.getArrayType() == XdmfArrayType.UInt16()
+
+    array9 = XdmfArray.New()
+    array9.insertAsUInt32(0, values1)
+    print array9.getValuesString()
+    print str(array9.getArrayType()) + " ?= " + str(XdmfArrayType.UInt32())
+    assert array9.getArrayType() == XdmfArrayType.UInt32()
+
+    stringArray = XdmfArray.New()
+    stringArray.insertValueAsString(0, "foo")
+    strings = ["bar", "car", "cellar"]
+    print str(stringArray.getArrayType()) + " ?= " + str(XdmfArrayType.String())
+    assert stringArray.getArrayType() == XdmfArrayType.String()
+    stringArray.insertAsString(0, strings)
+    print str(stringArray.getSize()) + " ?= " + str(3)
+    print stringArray.getValueAsString(0) + " ?= " + "bar"
+    assert stringArray.getSize() == 3
+    assert stringArray.getValueAsString(0) == "bar"
+    stringArray.pushBackAsString("dog")
+    print str(stringArray.getSize()) + " ?= " + str(4)
+    print stringArray.getValueAsString(3) + " ?= " + "dog"
+    assert stringArray.getSize() == 4
+    assert stringArray.getValueAsString(3) == "dog"
+    stringArray.resizeAsString(5, "")
+    print str(stringArray.getSize()) + " ?= " + str(5)
+    print stringArray.getValueAsString(4) + " ?= " + ""
+    assert stringArray.getSize() == 5
+    assert stringArray.getValueAsString(4) == ""
+    print stringArray.getValuesString()
+
+    # Retrieving data from XdmfArray
+    sourceArray = XdmfArray.New()
+    for i in range(0,20):
+      sourceArray.pushBackAsInt32(i)
+    output = []
+    sourceArray.getValues(0, output, sourceArray.getSize())
+    print output
+    for i in range(0,20):
+      assert(output[i] == i)
+    output2 = []
+    sourceArray.getValues(0, output2, sourceArray.getSize()/2, 2, 2)
+    print output2
+    for i in range(0,len(output2)):
+      if (i % 2 == 0):
+        assert(output2[i] == i)
+      else:
+        assert(output2[i] == 0)
diff --git a/core/tests/Python/TestXdmfArrayMultidimensional.py b/core/tests/Python/TestXdmfArrayMultidimensional.py
new file mode 100644
index 0000000..c83266b
--- /dev/null
+++ b/core/tests/Python/TestXdmfArrayMultidimensional.py
@@ -0,0 +1,86 @@
+from XdmfCore import *
+
+if __name__ == "__main__":
+
+    #
+    # Create 1D arrays
+    #
+    array1 = XdmfArray.New()
+    array1.initialize(XdmfArrayType.UInt32(), 2)
+    print str(array1.getArrayType()) + " ?= " + str(XdmfArrayType.UInt32())
+    print str(array1.getSize()) + " ?= " + str(2)
+    assert array1.getArrayType() == XdmfArrayType.UInt32()
+    assert array1.getSize() == 2
+    dimensions = array1.getDimensions()
+    print str(dimensions.size()) + " ?= " + str(1)
+    print str(dimensions[0]) + " ?= " + str(2)
+    assert dimensions.size() == 1
+    assert dimensions[0] == 2
+    dimensionsString = array1.getDimensionsString()
+    print dimensionsString + " ?= 2"
+    assert dimensionsString == "2"
+    array1.resizeAsInt32(3)
+    print str(array1.getSize()) + " ?= " + str(3)
+    assert array1.getSize() == 3
+    dimensions = array1.getDimensions()
+    print str(dimensions.size()) + " ?= " + str(1)
+    print str(dimensions[0]) + " ?= " + str(3)
+    assert dimensions.size() == 1
+    assert dimensions[0] == 3
+
+    #
+    # Create 2D arrays
+    #
+    array2 = XdmfArray.New()
+    newDimensions = UInt32Vector(2, 2)
+    array2.initialize(XdmfArrayType.UInt16(), newDimensions)
+    print str(array2.getArrayType()) + " ?= " + str(XdmfArrayType.UInt16())
+    print str(array2.getSize()) + " ?= " + str(4)
+    assert array2.getArrayType() == XdmfArrayType.UInt16()
+    assert array2.getSize() == 4
+    dimensions = array2.getDimensions()
+    print str(dimensions.size()) + " ?= " + str(2)
+    print str(dimensions[0]) + " ?= " + str(2)
+    print str(dimensions[1]) + " ?= " + str(2)
+    assert dimensions.size() == 2
+    assert dimensions[0] == 2 and dimensions[1] == 2
+    dimensionsString = array2.getDimensionsString()
+    print dimensionsString + " ?= 2 2" 
+    assert dimensionsString == "2 2"
+
+    newDimensions = UInt32Vector(3, 3)
+    array2.resizeAsUInt16(newDimensions)
+    print str(array2.getSize()) + " ?= " + str(27)
+    assert array2.getSize() == 27
+    dimensions = array2.getDimensions()
+    print str(dimensions.size()) + " ?= " + str(3)
+    print str(dimensions[0]) + " ?= " + str(3)
+    print str(dimensions[1]) + " ?= " + str(3)
+    print str(dimensions[2]) + " ?= " + str(3)
+    assert dimensions.size() == 3
+    assert dimensions[0] == 3 and dimensions[1] == 3 and dimensions[2] == 3
+    dimensionsString = array2.getDimensionsString()
+    print dimensionsString + " ?= 3 3 3"
+    assert dimensionsString == "3 3 3"
+
+    values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+    array2.insertAsUInt16(0, values)
+    print str(array2.getSize()) + " ?= " + str(27)
+    assert array2.getSize() == 27
+    dimensions = array2.getDimensions()
+    print str(dimensions.size()) + " ?= " + str(3)
+    print str(dimensions[0]) + " ?= " + str(3)
+    print str(dimensions[1]) + " ?= " + str(3)
+    print str(dimensions[2]) + " ?= " + str(3)
+    assert dimensions.size() == 3
+    assert dimensions[0] == 3 and dimensions[1] == 3 and dimensions[2] == 3
+
+    array2.pushBackAsInt16(10)
+    print str(array2.getSize()) + " ?= " + str(28)
+    assert array2.getSize() == 28
+    dimensions = array2.getDimensions()
+    print str(dimensions.size()) + " ?= " + str(1)
+    print str(dimensions[0]) + " ?= " + str(28)
+    assert dimensions.size() == 1
+    assert dimensions[0] == 28
+
diff --git a/core/tests/Python/TestXdmfEquals.py b/core/tests/Python/TestXdmfEquals.py
new file mode 100644
index 0000000..61e3258
--- /dev/null
+++ b/core/tests/Python/TestXdmfEquals.py
@@ -0,0 +1,13 @@
+from XdmfCore import *
+
+if __name__ == "__main__":
+
+    type1 = XdmfArrayType.Int16()
+    type2 = XdmfArrayType.Int16()
+    type3 = XdmfArrayType.Int32()
+
+    print "IsEqual True"
+    assert type1 == type2
+    print "IsEqual False"
+    assert not type1 == type3
+
diff --git a/core/tests/Python/TestXdmfError.py b/core/tests/Python/TestXdmfError.py
new file mode 100644
index 0000000..c56d54d
--- /dev/null
+++ b/core/tests/Python/TestXdmfError.py
@@ -0,0 +1,47 @@
+from XdmfCore import *
+
+if __name__ == "__main__":
+
+	writtenArray = XdmfArray.New()
+	dimensionVector = UInt32Vector()
+	dimensionVector.push_back(20)
+	writtenArray.initializeAsInt32(dimensionVector)
+	for i in range(20):
+		writtenArray.pushBackAsInt32(i + 1)
+
+	readArray = XdmfArray.New()
+	readDimensionVector = UInt32Vector()
+	readDimensionVector.push_back(6)
+	readDimensionVector.push_back(4)
+	readArray.initializeAsInt32(readDimensionVector)
+
+	writeStarts = UInt32Vector()
+	writeStarts.push_back(0)
+	writeStarts.push_back(0)
+	writeStrides = UInt32Vector()
+	writeStrides.push_back(2)
+	writeStrides.push_back(2)
+	writeDim = UInt32Vector()
+	writeDim.push_back(3)
+	writeDim.push_back(2)
+	readStarts = UInt32Vector()
+	readStarts.push_back(0)
+	readStarts.push_back(0)
+	readStrides = UInt32Vector()
+	readStrides.push_back(2)
+	readStrides.push_back(2)
+	readDim = UInt32Vector()
+	readDim.push_back(3)
+	readDim.push_back(2)
+
+	try:
+		readArray.insert(readStarts, writtenArray, writeStarts, writeDim, readDim, readStrides, writeStrides)
+	except RuntimeError as e:
+		#this is simpler than it is in C++
+		print e.args[0]
+
+
+	try:
+		raise RuntimeError(XdmfError(XdmfError.FATAL, "testError"))
+        except RuntimeError as e:
+		print e.args[0].what()
diff --git a/core/tests/Python/TestXdmfVersion.py b/core/tests/Python/TestXdmfVersion.py
new file mode 100644
index 0000000..ed675ad
--- /dev/null
+++ b/core/tests/Python/TestXdmfVersion.py
@@ -0,0 +1,5 @@
+from XdmfCore import *
+
+if __name__ == "__main__":
+    print XdmfVersion.getFull()
+    print XdmfVersion.getShort()
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
new file mode 100644
index 0000000..b00657d
--- /dev/null
+++ b/doc/CMakeLists.txt
@@ -0,0 +1 @@
+include(UseDoxygen)
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
new file mode 100644
index 0000000..51ad8b9
--- /dev/null
+++ b/doc/Doxyfile.in
@@ -0,0 +1,1516 @@
+# Doxyfile 1.5.8
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "@PROJECT_NAME@"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER         = "@PROJECT_VERSION@"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = "@DOXYFILE_OUTPUT_DIR@"
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
+# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene,
+# Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it parses.
+# With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this tag.
+# The format is ext=language, where ext is a file extension, and language is one of
+# the parsers supported by doxygen: IDL, Java, Javascript, C#, C, C++, D, PHP,
+# Objective-C, Python, Fortran, VHDL, C, C++. For instance to make doxygen treat
+# .inc files as Fortran files (default is PHP), and .f files as C (default is Fortran),
+# use: inc=Fortran f=C
+
+EXTENSION_MAPPING      =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by
+# doxygen. The layout file controls the global structure of the generated output files
+# in an output format independent way. The create the layout file that represents
+# doxygen's defaults, run doxygen with the -l option. You can optionally specify a
+# file name after the option, if omitted DoxygenLayout.xml will be used as the name
+# of the layout file.
+
+LAYOUT_FILE            =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT                  = "@CMAKE_SOURCE_DIR@" \
+                         "@CMAKE_SOURCE_DIR@/core" \
+                         "@CMAKE_SOURCE_DIR@/core/loki" \
+                         "@CMAKE_SOURCE_DIR@/core/dsm" \
+                         "@CMAKE_BINARY_DIR@"
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.hpp *.h
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = _darcs
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = */tests/* *.git
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = Loki::* Unit Visitor
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH           = "@CMAKE_SOURCE_DIR@/examples"
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = YES
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH             = "@CMAKE_SOURCE_DIR@"
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = "@DOXYFILE_HTML_DIR@"
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OSX 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE               =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING     =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER
+# are set, an additional index file will be generated that can be used as input for
+# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated
+# HTML documentation.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE          =
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to add.
+# For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the custom filter to add.For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION           =
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to FRAME, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature. Other possible values
+# for this tag are: HIERARCHIES, which will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list;
+# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which
+# disables this behavior completely. For backwards compatibility with previous
+# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE
+# respectively.
+
+GENERATE_TREEVIEW      = NONE
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE       = 10
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX         = @DOXYFILE_LATEX@
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = "@DOXYFILE_LATEX_DIR@"
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = "@LATEX_COMPILER@"
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME     = "@MAKEINDEX_COMPILER@"
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = @DOXYFILE_PDFLATEX@
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA             =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD                =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH           = "@CMAKE_SOURCE_DIR@/core/loki" \
+                         "@CMAKE_SOURCE_DIR@/core"
+
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS  = *.h *.hpp
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED             = __cplusplus 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = @DOXYFILE_DOT@
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME           = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = "@DOXYGEN_DOT_PATH@"
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS           =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Options related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/examples/Cxx/DSMLoopTest.cpp b/examples/Cxx/DSMLoopTest.cpp
new file mode 100644
index 0000000..9a16970
--- /dev/null
+++ b/examples/Cxx/DSMLoopTest.cpp
@@ -0,0 +1,297 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+        testArray->initialize<int>(0);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "data";
+
+        // Change this to determine the number of cores used as servers
+        int numServersCores = 8;
+        // Change this to determine the size of the arrays generated when initializing
+        int writeArraySize = 4;
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        std::vector<unsigned int> readOutputCountVector;
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->initialize<int>(0);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController;
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+        for(int i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1);
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        //split out sub-comm for the worker cores
+        //server cores will not progress to this point until after the servers are done running
+
+        if (id < size - numServersCores)
+        {
+                // Split the comm even further
+
+                MPI_Comm readComm, writeComm;
+
+                MPI_Group readingCores, writingCores;
+
+                MPI_Comm_group(workerComm, &workers);
+                int * ServerIds = (int *)calloc(((size - numServersCores) / 2), sizeof(int));
+                unsigned int index = 0;
+                for(int i=0 ; i < (int)((size - numServersCores) / 2) ; ++i)
+                {
+                        ServerIds[index++] = i;
+                }
+
+                MPI_Group_excl(workers, index, ServerIds, &readingCores);
+                testval = MPI_Comm_create(workerComm, readingCores, &readComm);
+                MPI_Group_incl(workers, index, ServerIds, &writingCores);
+                testval = MPI_Comm_create(workerComm, writingCores, &writeComm);
+                cfree(ServerIds);
+
+                std::cout << "initializing" << std::endl;
+
+                // Initialize values
+                // Writer is first
+                if (id < (int)((size - numServersCores) / 2))
+                {
+                        for (unsigned int i = 1; i <= writeArraySize; ++i)
+                        {
+                                testArray->pushBack(i*(id+1));
+                        }
+                        writeStartVector.push_back(id*writeArraySize);
+                        writeStrideVector.push_back(1);
+                        writeCountVector.push_back(writeArraySize);
+                        writeDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        writeController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray->insert(writeController);
+
+                        readStartVector.push_back(0);
+                        readStrideVector.push_back(1);
+                        readCountVector.push_back(0);
+                        readDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+
+                        readController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+                        readArray->insert(readController);
+
+                        for (unsigned int i = 0; i<size-numServersCores; ++i)
+                        {
+                                MPI_Barrier(writeComm);
+                                if (i == id)
+                                {
+                                        for(unsigned int i=0; i<testArray->getSize(); ++i)
+                                        {
+                                                std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+                }
+                else
+                {
+                        // Reader is second
+                        readStartVector.push_back(0);
+                        readStrideVector.push_back(1);
+                        readCountVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        readDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+
+                        readController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        readArray->insert(readController);
+
+                        readOutputCountVector.push_back(0);
+
+                        readOutputController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                readStartVector,
+                                readStrideVector,
+                                readOutputCountVector,
+                                readDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        writeStartVector.push_back(0);
+                        writeStrideVector.push_back(1);
+                        writeCountVector.push_back(0);
+                        writeDataSizeVector.push_back(writeArraySize*(int)((size-numServersCores) / 2));
+                        writeController = XdmfHDF5ControllerDSM::New(
+                                newPath,
+                                newSetPath,
+                                XdmfArrayType::Int32(),
+                                writeStartVector,
+                                writeStrideVector,
+                                writeCountVector,
+                                writeDataSizeVector,
+                                exampleWriter->getServerBuffer());
+
+                        testArray->insert(writeController);
+                }
+
+                testArray->accept(exampleWriter);
+
+                MPI_Barrier(workerComm);
+
+                // This is the loop that manipulates the data
+                for (unsigned int iteration = 0; iteration < 10; ++iteration)
+                {
+                        std::cout << "loop iteration " << iteration << " on core " << id << std::endl;
+
+                        // Read in to the first set of cores
+                        if (id >= (int)((size - numServersCores) / 2))
+                        {
+                                // Controllers are accessed like this since the writer removes them and creates its own.
+                                shared_dynamic_cast<XdmfHDF5ControllerDSM>(readArray->getHeavyDataController(0))->setWorkerComm(readComm);
+                                printf("read on core %d\n", id);
+                                readArray->read();
+                                MPI_Barrier(readComm);
+
+                                if (id == (int)((size - numServersCores) / 2))
+                                {
+                                        for(unsigned int i=0; i<readArray->getSize(); ++i)
+                                        {
+                                                int tempVal = readArray->getValue<int>(i);
+                                                tempVal = tempVal * 2;
+                                                readArray->insert(i, tempVal);
+                                                // Pull the value from the array in order to ensure the change has happened
+                                                std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                                        }
+                                }
+                        }
+                        shared_dynamic_cast<XdmfHDF5ControllerDSM>(readArray->getHeavyDataController(0))->setWorkerComm(workerComm);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data 
+                                readArray->removeHeavyDataController(0);
+                                readArray->insert(readOutputController);
+                        }
+
+                        readArray->accept(exampleWriter);
+
+                        if (id > (int)((size - numServersCores) / 2))
+                        {
+                                // Only the first read core should write out data
+                                readArray->removeHeavyDataController(0);
+                                readArray->insert(readController);
+                        }
+
+                        MPI_Barrier(workerComm);
+
+                        std::cout << "on writing cores" << std::endl;
+
+                        if (id < (int)((size - numServersCores) / 2))
+                        {
+                                shared_dynamic_cast<XdmfHDF5ControllerDSM>(testArray->getHeavyDataController(0))->setWorkerComm(writeComm);
+                                testArray->read();
+                                MPI_Barrier(writeComm);
+                                for (unsigned int i = 0; i<size; ++i)
+                                {
+                                        MPI_Barrier(writeComm);
+                                        if (i == id)
+                                        {
+                                                for(unsigned int i=0; i<testArray->getSize(); ++i)
+                                                {
+                                                        int tempVal = testArray->getValue<int>(i);
+                                                        tempVal = tempVal * 3;
+                                                        testArray->insert(i, tempVal);
+                                                        // Pull the value from the array in order to ensure the change has happened
+                                                        std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                                                }
+                                        }
+                                }
+                        }
+                        writeController->setWorkerComm(workerComm);
+                        testArray->accept(exampleWriter);
+                }
+
+        }
+
+        
+
+
+        if (id == 0)
+        {
+                exampleWriter->stopDSM();
+        }
+
+        MPI_Barrier(comm);
+
+        //the dsmManager must be deleted or else there will be a segfault
+        exampleWriter->deleteManager();
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfAggregate.cpp b/examples/Cxx/ExampleXdmfAggregate.cpp
new file mode 100644
index 0000000..1a48664
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfAggregate.cpp
@@ -0,0 +1,53 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfSubset.hpp"
+#include <vector>
+#include <map>
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfAggregate> exampleAggregate = XdmfAggregate::New();
+
+        shared_ptr<XdmfArray> partArray = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 10; ++i)
+        {
+                partArray->pushBack(i);
+        }
+
+        exampleAggregate->insert(partArray);
+
+        shared_ptr<XdmfArray> partArray2 = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 10; ++i)
+        {
+                partArray2->pushBack(i);
+        }
+
+        exampleAggregate->insert(partArray2);
+
+        //#initialization end
+
+        //#getDimensions begin
+
+        std::vector<unsigned int> exampleDimensions = exampleAggregate->getDimensions();
+
+        //#getDimensions end
+
+        //#getSize begin
+
+        int exampleSize = exampleAggregate->getSize();
+
+        //#getSize end
+
+        //#read begin
+
+        shared_ptr<XdmfArray> aggregateResult = exampleAggregate->read();
+
+        //#read end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfArray.cpp b/examples/Cxx/ExampleXdmfArray.cpp
new file mode 100644
index 0000000..c00d367
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfArray.cpp
@@ -0,0 +1,468 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include <vector>
+#include <map>
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfArray> exampleArray = XdmfArray::New();
+
+        //#initialization end
+
+        //#setName begin
+
+        std::string newName = "New Name";
+        exampleArray->setName(newName);
+
+        //#setName end
+
+        //#sizedeclaration begin
+
+        int newSize = 10;
+        
+        //#sizedeclaration end
+
+        //#reserve begin
+
+        exampleArray->reserve(newSize);
+
+        //#reserve end
+
+        //#initializesingletemplate begin
+
+        shared_ptr<std::vector<int> > exampleVector = exampleArray->initialize<int>(newSize);
+
+        //#initializesingletemplate end
+
+        //#initializesingletype begin
+
+        exampleArray->initialize(XdmfArrayType::Int32(), newSize);
+
+        //#initializesingletype end
+
+        //#sizevectordeclaration begin
+
+        std::vector<unsigned int> newSizeVector;
+        newSizeVector.push_back(4);
+        newSizeVector.push_back(5);
+
+        //#sizevectordeclaration end
+
+        //#initializevectortemplate begin
+
+        shared_ptr<std::vector<int> > exampleVectorFromVector = exampleArray->initialize<int>(newSizeVector);
+
+        //#initializevectortemplate end
+
+        //#initializevectortype begin
+
+        exampleArray->initialize(XdmfArrayType::Int32(), newSize);
+
+        //#initializevectortype end
+
+        //#isInitialized begin
+
+        if (exampleArray->isInitialized())
+        {
+                //do whatever is to be done if the array is initialized
+        }
+
+        //#isInitialized end
+
+        //#read begin
+
+        if (!exampleArray->isInitialized())
+        {
+                exampleArray->read();
+        }
+
+        //#read end
+
+        //#datapointersetup begin
+
+        int initArray [10] = {0,1,2,3,4,5,6,7,8,9};
+
+        //#datapointersetup end
+
+        //#pointerinsert begin
+
+        exampleArray->insert(0, initArray, 10, 1, 1);
+        //exampleArray now contains {0,1,2,3,4,5,6,7,8,9}
+        exampleArray->insert(0, initArray, 5, 2, 1);
+        //exampleArray now contains {0,1,1,3,2,5,3,7,4,9}
+        exampleArray->insert(0, initArray, 5, 1, 2);
+        //exampleArray now contains {0,2,4,6,8,5,3,7,4,9}
+
+        //#pointerinsert end
+
+        //#arrayinsert begin
+
+        shared_ptr<XdmfArray> tempArray = XdmfArray::New();
+        tempArray->insert(0, exampleArray, 0, 10, 1, 1);
+        //tempArray now contains {0,1,2,3,4,5,6,7,8,9}
+        tempArray->insert(0, exampleArray, 0, 5, 2, 1);
+        //tempArray now contains {0,1,1,3,2,5,3,7,4,9}
+        tempArray->insert(0, exampleArray, 0, 5, 1, 2);
+        //tempArray now contains {0,2,4,6,8,5,3,7,4,9}
+
+        //#arrayinsert end
+
+        //#pointinsertvalues begin
+
+        double newValue = 3.5;
+
+        //#pointinsertvalues end
+
+        //#pushBack begin
+
+        exampleArray->pushBack(newValue);
+
+        //#pushBack end
+
+        //#pointinsert begin
+
+        int newIndex = 0;
+        exampleArray->insert(newIndex, newValue);
+        //the value of 3.5 is inserted at index 0
+
+        //#pointinsert end
+
+        //#setValuesInternalpointer begin
+
+        exampleArray->setValuesInternal(initArray, 10, 1);
+
+        //#setValuesInternalpointer end
+
+        //#initinternalvector begin
+
+        std::vector<int> initVector;
+        initVector.push_back(1);
+        initVector.push_back(2);
+        initVector.push_back(3);
+        initVector.push_back(4);
+        initVector.push_back(5);
+
+        //#initinternalvector end
+
+        //#setValuesInternalvector begin
+
+        exampleArray->setValuesInternal(initVector, 1);
+
+        //#setValuesInternalvector end
+
+        //#initsharedvector begin
+
+        shared_ptr<std::vector<int> > storeVector(&initVector);
+
+        //#initsharedvector end
+
+        //#setValuesInternalsharedvector begin
+
+        exampleArray->setValuesInternal(storeVector);
+
+        //#setValuesInternalsharedvector end
+
+        //#setarraybase begin
+
+        exampleArray->insert(0, initArray, 10, 1, 1);
+        //exampleArray now contains {0,1,2,3,4,5,6,7,8,9}
+
+        //#setarraybase end
+
+        //#swapvector begin
+
+        //The vector contains {1,2,3,4,5} and the XdmfArray contains {0,1,2,3,4,5,6,7,8,9}
+        bool swapSucceded = exampleArray->swap(initVector);
+        //The vector contains {0,1,2,3,4,5,6,7,8,9} and the XdmfArray contains {1,2,3,4,5}
+
+        //#swapvector end
+
+        //#swapsharedvector begin
+
+        //The vector contains {1,2,3,4,5} and the XdmfArray contains {0,1,2,3,4,5,6,7,8,9}
+        bool storeSwapSucceded = exampleArray->swap(storeVector);
+        //storeVector contains {0,1,2,3,4,5,6,7,8,9} and the XdmfArray contains {1,2,3,4,5}
+
+        //#swapsharedvector end
+
+        //#swaparray begin
+
+        shared_ptr<XdmfArray> swapArray = XdmfArray::New();
+        int initArray2 [5] = {1,2,3,4,5};
+        swapArray->insert(0, initArray2, 5, 1, 1);
+        //exampleArray contains {0,1,2,3,4,5,6,7,8,9} and swapArray contains {1,2,3,4,5}
+        exampleArray->swap(swapArray);
+        //Now exampleArray contains {1,2,3,4,5} and swapArray contains {0,1,2,3,4,5,6,7,8,9}
+
+        //#swaparray end
+
+        //#clear begin
+
+        exampleArray->clear();
+
+        //#clear end
+
+        //#getValues begin
+
+        int storeArray [10] = {0,1,2,3,4,5,6,7,8,9};
+        exampleArray->insert(0, storeArray, 10, 1, 1);
+        int readArray [10] = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+        exampleArray->getValues(0, readArray, 5, 1, 2);
+        //readArray now contains {0, 11, 1, 13, 2, 15, 3, 17, 4, 19}
+        exampleArray->getValues(0, readArray, 5, 2, 1);
+        //readArray now contains {0, 2, 4, 6, 8, 15, 3, 17, 4, 19}
+
+        //#getValues end
+
+        //#resizesingle begin
+
+        newSize = 20;
+        int baseValue = 1;
+        exampleArray->resize(newSize, baseValue);
+        //exampleArray now contains {0,1,2,3,4,5,6,7,8,9,1,1,1,1,1,1,1,1,1,1}
+        newSize = 5;
+        exampleArray->resize(newSize, baseValue);
+        //exampleArray now contains {0,1,2,3,4}
+
+        //#resizesingle end
+
+        //#resizevector begin
+
+        std::vector<unsigned int> newresizeVector;
+        newResizeVector.push_back(4);
+        newResizeVector.push_back(5);   
+
+        exampleArray->resize(newResizeVector, baseValue);
+        //exampleArray now contains {0,1,2,3,4,5,6,7,8,9,1,1,1,1,1,1,1,1,1,1}
+        newResizeVector[0] = 1;
+        exampleArray->resize(newResizeVector, baseValue);
+        //exampleArray now contains {0,1,2,3,4}
+
+        //#resizevector end
+
+        //#getCapacity begin
+
+        unsigned int exampleCapacity = exampleArray->getCapacity();
+
+        //#getCapacity end
+
+        //#getDimensions begin
+
+        std::vector<unsigned int> exampleDimensions = exampleArray->getDimensions();
+
+        //#getDimensions end
+
+        //#getDimensionsString begin
+
+        std::string exampleDimensionString = exampleArray->getDimensionsString();
+
+        //#getDimensionsString end
+
+        //#getArrayType begin
+
+        shared_ptr<const XdmfArrayType> exampleType = exampleArray->getArrayType();
+
+        //#getArrayType end
+
+        //#getName begin
+
+        std::string exampleName = exampleArray->getName();
+
+        //#getName end
+
+        //#getSize begin
+
+        unsigned int exampleSize = exampleArray->getSize();
+
+        //#getSize end
+
+        //#getHeavyDataController begin
+
+        shared_ptr<XdmfHeavyDataController> exampleController = exampleArray->getHeavyDataController();
+
+        //#getHeavyDataController end
+
+        //#setHeavyDataController begin
+
+        shared_ptr<XdmfArray> newArray = XdmfArray::New();
+        newArray->setHeavyDataController(exampleController);
+
+        //#setHeavyDataController end
+
+        //#readController begin
+
+        newArray->readController();
+
+        //#readController end
+
+        //#getHeavyDataControllerconst begin
+
+        shared_ptr<const XdmfHeavyDataController> exampleControllerConst = exampleArray->getHeavyDataController();
+
+        //#getHeavyDataControllerconst end
+
+        //#setHeavyDataControllerVector begin
+
+        shared_ptr<XdmfArray> sourceArray = XdmfArray::New();
+
+        sourceArray->pushBack((int)5);
+
+        shared_ptr<XdmfHDF5Writer> heavywriter = XdmfHDF5Writer::New("heavyfile.h5");
+
+        sourceArray->accept(heavywriter);
+
+        std::vector<shared_ptr<XdmfHeavyDataController> > transferVector;
+
+        for (unsigned int i = 0; i < sourceArray->getNumberHeavyDataControllers(); ++i)
+        {
+          transferVector.push_back(sourceArray->getHeavyDataController(i));
+        }
+
+        exampleArray->setHeavyDataController(transferVector);
+
+        //#setHeavyDataControllerVector end
+
+        //#getValueindex begin
+
+        //if exampleArray contains {0,1,2,3,4,5,6,7,8,9}
+        int exampleValue = exampleArray->getValue<int>(4);
+        //exampleValue now has the value of what was stored at index 4, which in this case is 4
+
+        //#getValueindex end
+
+        //#getValuesString begin
+
+        std::string exampleValueString = exampleArray->getValuesString();
+
+        //#getValuesString end
+
+        //#getValuesInternalvector begin
+
+        shared_ptr<std::vector<int> > exampleInternalVector = exampleArray->getValuesInternal<int>();
+
+        //#getValuesInternalvector end
+
+        //#getValuesInternalvoid begin
+
+        void * exampleInternalPointer = exampleArray->getValuesInternal();
+
+        //#getValuesInternalvoid end
+
+        //#getValuesInternalvoidconst begin
+
+        const void * exampleInternalPointerConst = exampleArray->getValuesInternal();
+
+        //#getValuesInternalvoidconst end
+
+        //#erase begin
+
+        //if exampleArray contains {0,1,2,3,4,5,6,7,8,9}
+        unsigned int erasedIndex = 4;
+        exampleArray->erase(erasedIndex);
+        //exampleArray now contains the following
+        // {0,1,2,3,5,6,7,8,9}
+
+        //#erase end
+
+        //#release begin
+
+        exampleArray->release();
+
+        //#release end
+
+        //#insertmultidim begin
+
+        shared_ptr<XdmfArray> writtenArray = XdmfArray::New();
+        std::vector<unsigned int> dimensionVector;
+        dimensionVector.push_back(5);
+        dimensionVector.push_back(4);
+        writtenArray->initialize<int>(dimensionVector);
+        for (int i = 0; i < 20; ++i)
+        {
+                writtenArray->insert(i, i + 1);
+        }
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        std::vector<unsigned int> readDimensionVector;
+        readDimensionVector.push_back(6);
+        readDimensionVector.push_back(4);
+        readArray->initialize<int>(readDimensionVector);
+
+        std::vector<unsigned int> writeStarts;
+        writeStarts.push_back(0);
+        writeStarts.push_back(0);
+        std::vector<unsigned int> writeStrides;
+        writeStrides.push_back(2);
+        writeStrides.push_back(2);
+        std::vector<unsigned int> writeDim;
+        writeDim.push_back(3);
+        writeDim.push_back(2);
+        std::vector<unsigned int> readStarts;
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        std::vector<unsigned int> readStrides;
+        readStrides.push_back(2);
+        readStrides.push_back(2);
+        std::vector<unsigned int> readDim;
+        readDim.push_back(3);
+        readDim.push_back(2);
+
+        readArray->insert(readStarts, writtenArray, writeStarts, writeDim, readDim, readStrides, writeStrides);
+
+        //#insertmultidim end
+
+        //#setReference begin
+
+        shared_ptr<XdmfArray> variableArray = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 10; ++i)
+        {
+                variableArray->pushBack(i);
+        }
+
+        std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+
+        variableMap["A"] = variableArray;
+
+        shared_ptr<XdmfFunction> arrayFunction = XdmfFunction::New("AVE(A)", variableMap);
+
+	// Using an XdmfFunction as an example but any array reference will work.
+
+        exampleArray->setReference(arrayFunction);
+
+        //#setReference end
+
+        //#getReference begin
+
+        shared_ptr<XdmfFunction> exampleFunction = shared_dynamic_cast<XdmfFunction>(exampleArray->getReference());
+
+        //#getReference end
+
+        //#readReference begin
+
+        exampleArray->readReference();
+
+        //#readReference end
+
+        //#setReadMode begin
+
+        exampleArray->setReadMode(XdmfArray::Reference);
+
+        //#setReadMode end
+
+        //#getReadMode begin
+
+        ReadMode isReference = exampleArray->getReadMode();
+
+        if (isReference == XdmfArray::Reference)
+        {
+                exampleArray->readReference();
+        }
+
+        //#getReadMode end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfArrayType.cpp b/examples/Cxx/ExampleXdmfArrayType.cpp
new file mode 100644
index 0000000..097f485
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfArrayType.cpp
@@ -0,0 +1,47 @@
+#include "XdmfDomain.hpp"
+
+int main(int, char **)
+{
+        //#getType begin
+
+        shared_ptr<XdmfArray> exampleArray = XdmfArray::New();
+
+        if (XdmfArrayType::Int8() == exampleArray->getArrayType())
+        {
+                //do whatever is to be done with in the case that the array type is Int8
+        }
+
+        //#getType end
+
+        //#getElementSize begin
+
+        unsigned int dataSize = XdmfArrayType::Int8()->getElementSize();
+
+        //#getElementSize end
+
+        //#getIsSigned begin
+
+        bool isSigned = XdmfArrayType::UInt8()->getIsSigned();
+
+        //#getIsSigned end
+
+        //#getIsFloat begin
+
+        bool isFloat = XdmfArrayType::UInt8()->getIsFloat();
+
+        //#getIsFloat end
+
+        //#getName begin
+
+        std::string dataName = XdmfArrayType::Int8()->getName();
+
+        //#getName end
+
+        //#comparePrecision begin
+
+        shared_ptr<const XdmfArrayType> resultType = XdmfArrayType::comparePrecision(XdmfArrayType::Int16(), XdmfArrayType::UInt8());
+
+        //#comparePrecision end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfAttribute.cpp b/examples/Cxx/ExampleXdmfAttribute.cpp
new file mode 100644
index 0000000..d151805
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfAttribute.cpp
@@ -0,0 +1,61 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+        shared_ptr<XdmfAttribute> exampleAttribute = XdmfAttribute::New();
+        //#initialization end
+
+        //Assuming that exampleAttribute is a shared pointer to an XdmfAttribute object
+
+        //#setCenter begin
+
+        exampleAttribute->setCenter(XdmfAttributeCenter::Node());
+
+        //#setCenter end
+
+        //#setName begin
+
+        std::string newName = "New Name";
+        exampleAttribute->setName(newName);
+
+        //#setName end
+
+        //#setType begin
+
+        exampleAttribute->setType(XdmfAttributeType::Scalar());
+
+        //#setType end
+
+        //#getCenter begin
+
+        shared_ptr<const XdmfAttributeCenter> exampleCenter = exampleAttribute->getCenter();
+
+        if (exampleCenter == XdmfAttributeCenter::Grid())
+        {
+                //do whatever is to be done if the center is grid
+        }
+
+        //#getCenter end
+
+        //#getName begin
+
+        std::string exampleName = exampleAttribute->getName();
+
+        //#getName end
+
+        //#getType begin
+
+        shared_ptr<const XdmfAttributeType> exampleType = exampleAttribute->getType();
+
+        if (exampleType == XdmfAttributeType:Scalar())
+        {
+                //do whatever is to be done if the attribute is a scalar
+        }
+
+        //#getType end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfBinaryController.cpp b/examples/Cxx/ExampleXdmfBinaryController.cpp
new file mode 100644
index 0000000..59de551
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfBinaryController.cpp
@@ -0,0 +1,76 @@
+#include "XdmfBinaryController.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "File path to binary file goes here";
+        unsigned int newSeek = 0;
+        XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readStarts;
+        //Three dimensions, all starting at index 0
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        std::vector<unsigned int> readStrides;
+        //Three dimensions, no skipping between reads
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        std::vector<unsigned int> readDataSize;
+        //Three dimensions, each with a maximum of 20 values
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        shared_ptr<XdmfBinaryController> exampleController = XdmfBinaryController::New(
+                newPath,
+                readType,
+                newSeek,
+                newEndian,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize);
+
+        //#initialization end
+
+        //#initializationsimplified begin
+
+        std::string newPath = "File path to binary file goes here";
+        unsigned int newSeek = 0;
+        XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        shared_ptr<XdmfBinaryController> exampleController = XdmfBinaryController::New(
+                newPath,
+                readType,
+                newSeek,
+                newEndian,
+                readCounts);
+
+        //#initializationsimplified end
+
+        //#getEndian begin
+
+        XdmfBinaryController::Endian readEndian = exampleController->getEndian();
+
+        //#getEndian end
+
+        //#getSeek begin
+
+        unsigned int readSeek = exampleController->getSeek();
+
+        //#getSeek end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfCoreItemFactory.cpp b/examples/Cxx/ExampleXdmfCoreItemFactory.cpp
new file mode 100644
index 0000000..ed0038e
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfCoreItemFactory.cpp
@@ -0,0 +1,22 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfItemFactory.hpp"
+
+int main(int, char **)
+{
+        //#createItem begin
+
+        //using XdmfItemFactory because XdmfCoreItemFactory is abstract
+        shared_ptr<XdmfItemFactory> exampleFactory = XdmfItemFactory::New();
+        std::map<std::string, std::string> newProperties;
+        std::vector<shared_ptr<XdmfItem> > newChildren;
+        shared_ptr<XdmfAttribute> exampleAttribute =
+                shared_dynamic_cast<XdmfAttribute>(exampleFactory->createItem(XdmfAttribute::ItemTag, newProperties, newChildren));
+        //Same usage as the individual constructors
+        //But the item has to be cast afterwards to the correct type.
+        //childItems and itemProperties are not added to the item when created this way
+        //the collections are used to determine type
+
+        //#createItem end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfCoreReader.cpp b/examples/Cxx/ExampleXdmfCoreReader.cpp
new file mode 100644
index 0000000..bb746fd
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfCoreReader.cpp
@@ -0,0 +1,53 @@
+#include "XdmfReader.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfItem.hpp"
+
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        //using XdmfReader since XdmfCoreReader is abstract
+        shared_ptr<XdmfReader> exampleReader = XdmfReader::New();
+
+        //#initialization end
+
+        //#parse begin
+
+        std::string readLight = "your light data here";
+        //Assuming that an XdmfArray is the root item generated by the light data provided
+        shared_ptr<XdmfArray> exampleArray = shared_dynamic_cast<XdmfArray>(reader->parse(readLight));
+
+        //#parse end
+
+        //#readpath begin
+
+        std::string readPath = "your file path here";
+
+        //#readpath end
+
+        //#readroot begin
+
+        //Assuming that an XdmfDomain is the root item at the file path provided
+        shared_ptr<XdmfDomain> exampleDomain = shared_dynamic_cast<XdmfDomain>(reader->read(readPath));
+
+        //#readroot end
+
+        //#readItems begin
+
+        std::vector<shared_ptr<XdmfItem> > exampleCollection = reader->readItems(readPath);
+        //Used in a similar manner as read, but in this case the read file has multiple items at the returned level
+
+        //#readItems end
+
+        //#readXPath begin
+
+        std::string readXPath = "your X path here";
+
+        std::vector<shared_ptr<XdmfItem> > exampleItems = reader->read(readPath, readXPath);
+
+        //#readXPath end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfCurvilinearGrid.cpp b/examples/Cxx/ExampleXdmfCurvilinearGrid.cpp
new file mode 100644
index 0000000..a4ec6e1
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfCurvilinearGrid.cpp
@@ -0,0 +1,96 @@
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfArray.hpp"
+
+int main(int, char **)
+{
+        int size = 2;
+
+        //Assuming that exampleGrid is a shared pointer to an XdmfCurvilinearGrid object
+
+        if (size == 2)
+        {
+
+        //#initializationdim2 start
+
+        unsigned int newPointsX = 5;
+        unsigned int newPointsY = 5;
+        shared_ptr<XdmfCurvilinearGrid> exampleGrid = XdmfCurvilinearGrid::New(newPointsX, newPointsY);
+
+        //#initializationdim2 end
+
+        }
+        else if (size = 3)
+        {
+
+        //#initializationdim3 start
+
+        unsigned int newPointsX = 5;
+        unsigned int newPointsY = 5;
+        unsigned int newPointsZ = 5;
+        shared_ptr<XdmfCurvilinearGrid> exampleGrid = XdmfCurvilinearGrid::New(newPointsX, newPointsY, newPointsZ);
+
+        //#initializationdim3 end
+
+        //#setDimensions begin
+
+        shared_ptr<XdmfArray> newPoints = XdmfArray::New();
+        newPoints->pushBack(10);
+        newPoints->pushBack(10);
+        newPoints->pushBack(10);
+        exampleGrid->setDimensions(newPoints);
+
+        //#setDimensions end
+
+        //#getDimensions begin
+
+        shared_ptr<XdmfArray> exampleDimensions = exampleGrid->getDimensions();
+
+        //#getDimensions end
+
+        //#getDimensionsconst begin
+
+        shared_ptr<const XdmfArray> exampleDimensions = exampleGrid->getDimensions();
+
+        //#getDimensionsconst end
+
+        //#setGeometry begin
+
+        shared_ptr<XdmfArray> newData = XdmfArray::New();
+        newData->pushBack(5);
+        newData->pushBack(5);
+        newData->pushBack(5);
+        shared_ptr<XdmfGeometry> newGeometry = XdmfGeometry::New();
+        newGeometry->setType(XdmfGeometryType::XYZ());
+        // Start index is 0, 3 values are passed, stride for both arrays is 1
+        newGeometry->insert(0, newData, 0, 3, 1, 1);
+        exampleGrid->setGeometry(newGeometry);
+
+        //#setGeometry end
+
+        //#getGeometry begin
+
+        shared_ptr<XdmfGeometry> exampleGeometry = exampleGrid->getGeometry();
+
+        //#getGeometry end
+
+        }
+        else // via array
+        {
+
+        //#initializationvector start
+
+        shared_ptr<XdmfArray> newPoints = XdmfArray::New();
+        newPoints->pushBack(5);
+        newPoints->pushBack(5);
+        newPoints->pushBack(5);
+        shared_ptr<XdmfCurvilinearGrid> exampleGrid = XdmfCurvilinearGrid::New(newPoints);
+
+        //#initializationvector end
+
+        }
+
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfDSM.cpp b/examples/Cxx/ExampleXdmfDSM.cpp
new file mode 100644
index 0000000..62bd185
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfDSM.cpp
@@ -0,0 +1,700 @@
+#include <mpi.h>
+#include <H5FDdsm.h>
+#include <H5FDdsmManager.h>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        //#initMPI begin
+
+        int size, id, providedThreading, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &providedThreading);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        //#initMPI end
+
+        if (id == 0)
+        {
+                if (providedThreading != MPI_THREAD_MULTIPLE)
+                {
+                        std::cout << "# MPI_THREAD_MULTIPLE not set, you may need to recompile your "
+                                << "MPI distribution with threads enabled" << std::endl;
+                }
+                else
+                {
+                        std::cout << "# MPI_THREAD_MULTIPLE is OK" << std::endl;
+                }
+        }
+
+        //#generateBuffer begin
+
+        // Create DSM
+        H5FDdsmManager * dsmManager = new H5FDdsmManager();
+        dsmManager->SetMpiComm(comm);
+        dsmManager->SetLocalBufferSizeMBytes(dsmSize / size);
+        dsmManager->SetIsStandAlone(H5FD_DSM_TRUE);
+        dsmManager->Create();
+
+        H5FD_dsm_set_manager(dsmManager);
+
+        H5FD_dsm_set_options(H5FD_DSM_LOCK_ASYNCHRONOUS);
+
+        //Generate DSM buffer
+        H5FDdsmBuffer * dsmBuffer = dsmManager->GetDsmBuffer();
+
+        //#generateBuffer end
+
+        // Get info from remote server
+        double remoteMB = dsmBuffer->GetTotalLength() / (1024.0 * 1024.0);
+        double numServers = dsmBuffer->GetEndServerId() + 1;
+        if (id == 0)
+        {
+                std::cout << "DSM server memory size is : "
+                        << (int)remoteMB << " MB" << std::endl;
+                std::cout << "DSM server process count  : "
+                        << (int)numServers << std::endl;
+                std::cout << "Memory allocated per core : " << (int)(dsmSize / size) << "MB" << std::endl;
+        }
+
+        std::cout << "setting up DSM writer" << std::endl;
+        // Create DSM Writer and write to DSM space.
+
+        //#initializewriterfrombuffer begin
+
+        // Virtual file path
+        std::string newPath = "dsm";
+        shared_ptr<XdmfHDF5WriterDSM> writer = XdmfHDF5WriterDSM::New(newPath, dsmBuffer);
+        writer->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        //#initializewriterfrombuffer end
+
+        //#createwritecontrollervectors begin
+
+        // Virtual set path
+        std::string newSetPath = "data";
+
+        // Holds the starting index for each dimension
+        std::vector<unsigned int> writeStartVector;
+        // Holds the distance between written values for each dimension
+        std::vector<unsigned int> writeStrideVector;
+        // Holds the total number of values for each dimension
+        std::vector<unsigned int> writeCountVector;
+        //holds the maximum DSM size for each dimension
+        std::vector<unsigned int> writeDataSizeVector;
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController;
+
+        //#createwritecontrollervectors end
+
+        std::vector<unsigned int> outputVector;
+
+        /*
+        //writes must happen from all cores
+        //write empty arrays from cores other than main
+        shared_ptr<XdmfArray> array = XdmfArray::New();
+        array->initialize<int>(0);//this is required to write
+        if (id == 0)
+        {
+                for (unsigned int i = 0; i < 4*size; ++i)
+                {
+                        array->pushBack(i);
+                }
+
+
+                writeStartVector.push_back(0);
+                writeCountVector.push_back(4*size);
+                writeDataSizeVector.push_back(4*size);
+                writeStrideVector.push_back(1);
+
+                readController = XdmfHDF5ControllerDSM::New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType::Int32(),
+                        writeStartVector,
+                        writeStrideVector,
+                        writeCountVector,
+                        writeDataSizeVector,
+                        dsmBuffer);
+                array->insert(readController);
+
+                for (unsigned int i = 0; i<size -1; ++i)
+                {
+                        MPI_Barrier(comm);
+                }
+
+                std::cout << "Core # " << id << std::endl;
+                std::cout << "Controller stats" << std::endl;
+                std::cout << "datasetpath = " << readController->getDataSetPath() << std::endl;
+                std::cout << "filepath = " << readController->getFilePath() << std::endl;
+                outputVector = readController->getDataspaceDimensions();
+                std::cout << "Data space dimensions" << std::endl;
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller Dimensions" << std::endl;
+                outputVector = readController->getDimensions();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller size" << readController->getSize() << std::endl;
+                std::cout << "Controller starts" << std::endl;
+                outputVector = readController->getStart();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller strides" << std::endl;
+                outputVector = readController->getStride();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                }
+
+                std::cout << "DSM writer set up" << std::endl;
+                array->accept(writer);//if this hangs it's because writes need to be called on all cores
+                std::cout << "DSM writer used" << id << std::endl;
+        }
+        else
+        {
+                writeStartVector.push_back(0);
+                writeCountVector.push_back(0);
+                writeDataSizeVector.push_back(4*size);
+                writeStrideVector.push_back(1);
+
+                readController = XdmfHDF5ControllerDSM::New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType::Int32(),
+                        writeStartVector,
+                        writeStrideVector,
+                        writeCountVector,
+                        writeDataSizeVector,
+                        dsmBuffer);
+                array->insert(readController);
+
+                for (unsigned int i =1; i<size; ++i)
+                {
+                         if (id == i)
+                        {
+                                std::cout << "Core # " << id << std::endl;
+                                std::cout << "Controller stats" << std::endl;
+                                std::cout << "datasetpath = " << readController->getDataSetPath() << std::endl;
+                                std::cout << "filepath = " << readController->getFilePath() << std::endl;
+                                outputVector = readController->getDataspaceDimensions();
+                                std::cout << "Data space dimensions" << std::endl;
+                                for (int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller Dimensions" << std::endl;
+                                outputVector = readController->getDimensions();
+                                for (int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller size" << readController->getSize() << std::endl;
+                                std::cout << "Controller starts" << std::endl;
+                                outputVector = readController->getStart();
+                                for (int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller strides" << std::endl;
+                                outputVector = readController->getStride();
+                                for (int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                                }
+                        }
+
+                        MPI_Barrier(comm);
+                }
+
+                std::cout << "DSM writer set up" << std::endl;
+                array->accept(writer);//if this hangs it's because writes need to be called on all cores
+                std::cout << "DSM writer used" << id << std::endl;
+        }*/
+
+        
+        //multicore write with arrays of varying sizes
+        // Create Array
+        // Array should be distributed among processes
+        shared_ptr<XdmfArray> array = XdmfArray::New();
+        array->initialize<int>(0);
+        for(unsigned int i = 0; i <= id; ++i)
+        {
+                array->pushBack(id);
+        }
+
+        //#initializereadcontroller begin
+
+        int startindex = 0;
+        for (unsigned int i = 0; i <= id; ++i)
+        {
+                startindex += i;
+        }
+
+        int datacount = 0;
+        for (unsigned int i = 0; i < size; ++i)
+        {
+                datacount = datacount + i + 1;
+        }
+
+        writeStartVector.push_back(startindex);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(array->getSize());
+        writeDataSizeVector.push_back(datacount);
+
+        readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                dsmBuffer);
+
+        //#initializereadController end
+
+        array->insert(readController);
+        for (unsigned int i = 0; i < size; ++i)
+        {
+                MPI_Barrier(comm);
+                if (id == i)
+                {
+                        std::cout << "Core # " << id << std::endl;
+                        std::cout << "Controller stats" << std::endl;
+                        std::cout << "datasetpath = " << readController->getDataSetPath() << std::endl;
+                        std::cout << "filepath = " << readController->getFilePath() << std::endl;
+                        outputVector = readController->getDataspaceDimensions();
+                        std::cout << "Data space dimensions" << std::endl;
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller Dimensions" << std::endl;
+                        outputVector = readController->getDimensions();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller size" << readController->getSize() << std::endl;
+                        std::cout << "Controller starts" << std::endl;
+                        outputVector = readController->getStart();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller strides" << std::endl;
+                        outputVector = readController->getStride();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                        }
+                }
+        }
+
+
+        std::cout << "DSM writer set up" << std::endl;
+        MPI_Barrier(comm);
+        array->accept(writer);
+        std::cout << "DSM writer used" << id << std::endl;
+        
+
+
+        /*
+        //for writing from multiple cores
+        // Create Array
+        // Array should be distributed among processes
+        shared_ptr<XdmfArray> array = XdmfArray::New();
+        array->initialize<int>(0);
+        for (unsigned int i = 1; i<=4; ++i)
+        {
+                array->pushBack(id*i);
+        }
+
+        std::cout << "from core #" << id << " generating these values: " << id << " " << id*2 << " " << id*3 << " " << id*4 << std::endl;
+
+        writeStartVector.push_back(array->getSize()*id);
+        writeCountVector.push_back(array->getSize());
+        writeDataSizeVector.push_back(array->getSize()*size);
+        writeStrideVector.push_back(1);
+
+        readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                dsmBuffer);
+        array->insert(readController);
+        for (unsigned int i = 0; i < size; ++i)
+        {
+                MPI_Barrier(comm);
+                if (id == i)
+                {
+                        std::cout << "Core # " << id << std::endl;
+                        std::cout << "Controller stats" << std::endl;
+                        std::cout << "datasetpath = " << readController->getDataSetPath() << std::endl;
+                        std::cout << "filepath = " << readController->getFilePath() << std::endl;
+                        outputVector = readController->getDataspaceDimensions();
+                        std::cout << "Data space dimensions" << std::endl;
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller Dimensions" << std::endl;
+                        outputVector = readController->getDimensions();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller size" << readController->getSize() << std::endl;
+                        std::cout << "Controller starts" << std::endl;
+                        outputVector = readController->getStart();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller strides" << std::endl;
+                        outputVector = readController->getStride();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                        }
+                }
+        }
+
+
+        std::cout << "DSM writer set up" << std::endl;
+        MPI_Barrier(comm);
+        array->accept(writer);
+        std::cout << "DSM writer used" << id << std::endl;*/
+
+        //ensure all writes are called
+        MPI_Barrier(comm);
+        std::cout << "core #" << id << "finished waiting" << std::endl;
+
+        //#createreadcontrollervectors begin
+
+        //holds the starting index for each dimension
+        std::vector<unsigned int> startVector;
+        //holds the distance between read values for each dimension
+        std::vector<unsigned int> strideVector;
+        //holds the total number of values for each dimension
+        std::vector<unsigned int> countVector;
+        //holds the maximum DSM size for each dimension
+        std::vector<unsigned int> datasizeVector;
+
+        //#createreadcontrollervectors end
+
+        /*
+        //single core read must be called across all cores
+        if (id == 0)
+        {
+                std::cout << "getting output" << std::endl;
+                // Read data
+                startVector.push_back(0);
+                strideVector.push_back(1);
+                countVector.push_back(4*size);
+                datasizeVector.push_back(4*size);
+                std::cout << "starting index" << startVector[0] << std::endl;
+                std::cout << "stride = " << strideVector[0] << std::endl;
+                std::cout << "number of values = " << countVector[0] << std::endl;
+                std::cout << "Size of block = " << datasizeVector[0] << std::endl;
+                readController = XdmfHDF5ControllerDSM::New(
+                        array->getHeavyDataController(0)->getFilePath(),
+                        array->getHeavyDataController(0)->getDataSetPath(),
+                        array->getHeavyDataController(0)->getType(),
+                        startVector,
+                        strideVector,
+                        countVector,
+                        datasizeVector,
+                        dsmBuffer);
+                std::cout << "done making reader" << std::endl;
+                shared_ptr<XdmfArray> readArray = XdmfArray::New();
+                readArray->initialize<int>(0);
+                readArray->insert(readController);
+
+                std::cout << "reader set" << std::endl;
+                readArray->read();//if it hangs here, read requires all cores to read at the same time
+                std::cout << "done reading" << std::endl;
+                std::cout << "printing output" << std::endl;
+
+                std::cout << "Core # " << id << std::endl;
+                std::cout << "Controller stats" << std::endl;
+                std::cout << "datasetpath = " << readArray->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                std::cout << "filepath = " << readArray->getHeavyDataController(0)->getFilePath() << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getDataspaceDimensions();
+                std::cout << "Data space dimensions" << std::endl;
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller Dimensions" << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getDimensions();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller size" << readArray->getHeavyDataController(0)->getSize() << std::endl;
+                std::cout << "Controller starts" << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getStart();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller strides" << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getStride();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                }
+
+                for(unsigned int i=0; i<readArray->getSize(); ++i)
+                {
+                        std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                }
+        }
+        else
+        {
+                std::cout << "getting output" << std::endl;
+                // Read data
+                startVector.push_back(0);
+                std::cout << "starting index" << startVector[0] << std::endl;
+                strideVector.push_back(1);
+                std::cout << "stride = " << strideVector[0] << std::endl;
+                countVector.push_back(0);
+                std::cout << "number of values = " << countVector[0] << std::endl;
+                datasizeVector.push_back(4*size);
+                std::cout << "Size of block = " << datasizeVector[0] << std::endl;
+                readController = XdmfHDF5ControllerDSM::New(
+                array->getHeavyDataController(0)->getFilePath(),
+                array->getHeavyDataController(0)->getDataSetPath(),
+                array->getHeavyDataController(0)->getType(),
+                startVector,
+                strideVector,
+                countVector,
+                datasizeVector,
+                dsmBuffer);
+                std::cout << "done making reader" << std::endl;
+                shared_ptr<XdmfArray> readArray = XdmfArray::New();
+                readArray->initialize<int>(0);
+                readArray->insert(readController);
+
+                std::cout << "reader set" << std::endl;
+                readArray->read();//if it hangs here, read requires all cores to read at the same time
+                std::cout << "done reading" << std::endl;
+                std::cout << "printing output" << std::endl;
+
+                std::cout << "Core # " << id << std::endl;
+                std::cout << "Controller stats" << std::endl;
+                std::cout << "datasetpath = " << readArray->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                std::cout << "filepath = " << readArray->getHeavyDataController(0)->getFilePath() << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getDataspaceDimensions();
+                std::cout << "Data space dimensions" << std::endl;
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller Dimensions" << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getDimensions();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller size" << readArray->getHeavyDataController(0)->getSize() << std::endl;
+                std::cout << "Controller starts" << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getStart();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                }
+                std::cout << "Controller strides" << std::endl;
+                outputVector = readArray->getHeavyDataController(0)->getStride();
+                for (int j=0; j<outputVector.size(); ++j)
+                {
+                        std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                }
+
+                for(unsigned int i=0; i<readArray->getSize(); ++i)
+                {
+                        std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                }
+        }*/
+
+
+        
+        //mutlicore read with varying sizes
+        std::cout << "getting output" << std::endl;
+        // Read data (Working on getting this to produce meaningful results.)
+        startVector.push_back(datacount - (startindex + array->getSize()));
+        std::cout << "starting index" << startVector[0] << std::endl;
+        strideVector.push_back(1);
+        std::cout << "stride = " << strideVector[0] << std::endl;
+        countVector.push_back(array->getSize());
+        std::cout << "number of values = " << countVector[0] << std::endl;
+        datasizeVector.push_back(datacount);
+        std::cout << "Size of block = " << datasizeVector[0] << std::endl;
+        readController = XdmfHDF5ControllerDSM::New(
+                array->getHeavyDataController(0)->getFilePath(),
+                array->getHeavyDataController(0)->getDataSetPath(),
+                array->getHeavyDataController(0)->getType(),
+                startVector,
+                strideVector,
+                countVector,
+                datasizeVector,
+                dsmBuffer);
+        std::cout << "done making reader" << std::endl;
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->reserve(array->getSize()*size);
+        readArray->insert(readController);
+
+        std::cout << "reader set" << std::endl;
+        readArray->read();
+        std::cout << "done reading" << std::endl;
+        std::cout << "printing output" << std::endl;
+
+        for (unsigned int i = 0; i<size; ++i)
+        {
+                MPI_Barrier(comm);
+                if (i == id)
+                {
+                        std::cout << "Core # " << id << std::endl;
+                        std::cout << "Controller stats" << std::endl;
+                        std::cout << "datasetpath = " << array->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                        std::cout << "datasetpath = " << array->getHeavyDataController(0)->getFilePath() << std::endl;
+                        outputVector = array->getHeavyDataController(0)->getDataspaceDimensions();
+                        std::cout << "Data space dimensions" << std::endl;
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller Dimensions" << std::endl;
+                        outputVector = array->getHeavyDataController(0)->getDimensions();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller size" << array->getHeavyDataController(0)->getSize() << std::endl;
+                        std::cout << "Controller starts" << std::endl;
+                        outputVector = readController->getStart();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller strides" << std::endl;
+                        outputVector = array->getHeavyDataController(0)->getStride();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                        }
+
+                        for(unsigned int i=0; i<readArray->getSize(); ++i)
+                        {
+                                std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                        }
+                }
+        }
+
+
+        /*
+        //For the multicore read
+        std::cout << "getting output" << std::endl;
+        // Read data (Working on getting this to produce meaningful results.)
+        startVector.push_back((size - id -1)*4);
+        std::cout << "starting index" << startVector[0] << std::endl;
+        strideVector.push_back(1);
+        std::cout << "stride = " << strideVector[0] << std::endl;
+        countVector.push_back(4);
+        std::cout << "number of values = " << countVector[0] << std::endl;
+        datasizeVector.push_back(4*size);
+        std::cout << "Size of block = " << datasizeVector[0] << std::endl;
+        readController = XdmfHDF5ControllerDSM::New(
+                array->getHeavyDataController(0)->getFilePath(),
+                array->getHeavyDataController(0)->getDataSetPath(),
+                array->getHeavyDataController(0)->getType(),
+                startVector,
+                strideVector,
+                countVector,
+                datasizeVector,
+                dsmBuffer);
+        std::cout << "done making reader" << std::endl;
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->reserve(array->getSize()*size);
+        readArray->insert(readController);
+
+        std::cout << "reader set" << std::endl;
+        readArray->read();
+        std::cout << "done reading" << std::endl;
+        std::cout << "printing output" << std::endl;
+
+        for (unsigned int i = 0; i<size; ++i)
+        {
+                MPI_Barrier(comm);
+                if (i == id)
+                {
+                        std::cout << "Core # " << id << std::endl;
+                        std::cout << "Controller stats" << std::endl;
+                        std::cout << "datasetpath = " << array->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                        std::cout << "filepath = " << array->getHeavyDataController(0)->getFilePath() << std::endl;
+                        outputVector = array->getHeavyDataController(0)->getDataspaceDimensions();
+                        std::cout << "Data space dimensions" << std::endl;
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller Dimensions" << std::endl;
+                        outputVector = array->getHeavyDataController(0)->getDimensions();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller size" << array->getHeavyDataController(0)->getSize() << std::endl;
+                        std::cout << "Controller starts" << std::endl;
+                        outputVector = readController->getStart();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller strides" << std::endl;
+                        outputVector = array->getHeavyDataController(0)->getStride();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                        }
+
+                        for(unsigned int i=0; i<readArray->getSize(); ++i)
+                        {
+                                std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                        }
+                }
+        }*/
+
+
+        MPI_Barrier(comm);
+
+        //#finalizeMPI
+        delete dsmManager;
+
+        MPI_Finalize();
+
+        //#finalizeMPI
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfDSMNoThread.cpp b/examples/Cxx/ExampleXdmfDSMNoThread.cpp
new file mode 100644
index 0000000..0dc8b15
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfDSMNoThread.cpp
@@ -0,0 +1,953 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+#include "XdmfError.hpp"
+
+int main(int argc, char *argv[])
+{
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        //#initMPI end
+
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+
+        for (unsigned int i = 1; i <= 4; ++i)
+        {
+                testArray->pushBack(i*(id+1));
+        }
+
+        //#initwritevector begin
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "data";
+
+        int numServersCores = 4;
+
+        std::vector<unsigned int> writeStartVector;
+        writeStartVector.push_back(id*4);
+        //writeStartVector.push_back(id);
+        std::vector<unsigned int> writeStrideVector;
+        writeStrideVector.push_back(1);
+        //writeStrideVector.push_back(size-3);
+        std::vector<unsigned int> writeCountVector;
+        writeCountVector.push_back(4);
+        std::vector<unsigned int> writeDataSizeVector;
+        writeDataSizeVector.push_back(4*(size-numServersCores));
+
+        //#initwritervector end
+
+        //#commsplit begin
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+        for(int i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        //#commsplit end
+
+        //#initwritergenerate begin
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1);
+
+        //#initwritergenerate end
+/*
+        //#initwriterpagedgenerate begin
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, 1024, 1.0, size-numServersCores, size-1);
+
+        //#initwriterpagedgenerate end
+*/
+/*
+        //#initcontrollergenerate begin
+
+        shared_ptr<XdmfHDF5ControllerDSM> exampleController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                comm,
+                dsmSize/numServersCores,
+                size-numServersCores,
+                size-1);
+
+        //#initcontrollergenerate end
+*/
+/*
+        //#initcontrollerpagedgenerate begin
+
+        shared_ptr<XdmfHDF5ControllerDSM> exampleController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                comm,
+                dsmSize/numServersCores,
+                1024,
+                1.0,
+                size-numServersCores,
+                size-1);
+
+        //#initcontrollerpagedgenerate end
+*/
+
+        // Split out sub-comm for the worker cores
+        // Server cores will not progress to this point until after the servers are done running
+
+        //#startworksection begin
+
+        if (id < size - numServersCores)
+        {
+
+                //#startworksection end
+
+                // This section is to demonstrate the functionality of the XdmfDSM classes
+
+                //#setServerModewriter begin
+
+                exampleWriter->setServerMode(true);
+
+                //#setServerModewriter end
+
+                //#getServerModewriter begin
+
+                bool exampleServerMode = exampleWriter->getServerMode();
+
+                //#getServerModewriter end
+
+                //#getWorkerCommwriter begin
+
+                MPI_Comm exampleWorkerComm = exampleWriter->getWorkerComm();
+
+                //#getWorkerCommwriter end
+
+                //#setWorkerCommwriter begin
+
+                exampleWriter->setWorkerComm(exampleWorkerComm);
+
+                //#setWorkerCommwriter end
+
+/*
+                //#getWorkerCommcontroller begin
+
+                MPI_Comm exampleWorkerComm = exampleController->getWorkerComm();
+
+                //#getWorkerCommcontroller end
+
+                //#setWorkerCommcontroller begin
+
+                exampleController->setWorkerComm(exampleWorkerComm);
+
+                //#setWorkerCommcontroller end
+
+                //#setServerModecontroller begin
+
+                exampleController->setServerMode(true);
+
+                //#setServerModecontroller end
+
+                //#getServerModecontroller begin
+
+                bool exampleControllerServerMode = exampleController->getServerMode();
+
+                //#getServerModecontroller end
+*/
+
+                //#initcontrollerwithbuffer begin
+
+                shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType::Int32(),
+                        writeStartVector,
+                        writeStrideVector,
+                        writeCountVector,
+                        writeDataSizeVector,
+                        exampleWriter->getServerBuffer());
+
+                //#initcontrollerwithbuffer end
+
+                //#initwriterwithbuffer begin
+
+                shared_ptr<XdmfHDF5WriterDSM> exampleWriter2 = XdmfHDF5WriterDSM::New(newPath, exampleWriter->getServerBuffer());
+
+                //#declarebuffer begin
+
+                XdmfDSMBuffer * exampleBuffer;
+
+                //#delcarebuffer end
+
+                //#getServerBufferwriter begin
+
+                exampleBuffer = exampleWriter->getServerBuffer();
+
+                //#getServerBufferwriter end
+
+                //#initwriterwithbuffer end
+
+                writeController->setServerMode(true);
+                bool exampleControllerServerMode = writeController->getServerMode();
+
+                //#GetLocalBufferSizeMBytes begin
+
+                int exampleBufferSize = exampleBuffer->GetLocalBufferSizeMBytes();
+
+                //#GetLocalBufferSizeMBytes end
+
+                //#SetLocalBufferSizeMBytes begin
+
+                exampleBuffer->SetLocalBufferSizeMBytes(exampleBufferSize);
+
+                //#SetLocalBufferSizeMBytes end
+
+                //#GetInterCommType begin
+
+                int exampleCommType = exampleBuffer->GetInterCommType();
+
+                //#GetInterCommType end
+
+                //#SetInterCommType begin
+
+                exampleBuffer->SetInterCommType(XDMF_DSM_COMM_MPI);
+
+                //#SetInterCommType end
+
+        /*
+                //#Create begin
+
+                exampleBuffer->Create(comm, size - numServerCores, size - 1);
+
+                //#Create end
+        */
+
+                //#setBufferwriter begin
+
+                exampleWriter->setBuffer(exampleBuffer);
+
+                //#setBufferwriter end
+
+/*
+                //#getServerBuffercontroller begin
+
+                exampleBuffer = exampleController->getServerBuffer();
+
+                //#getServerBuffercontroller end
+
+                //#setBuffercontroller begin
+
+                exampleController->setBuffer(exampleBuffer);
+
+                //#setBuffercontroller end
+*/
+
+                //#GetIsConnectedbuffer begin
+
+                bool exampleIsConnected = exampleBuffer->GetIsConnected();
+
+                //#GetIsConnectedbuffer end
+
+                //#SetIsConnectedbuffer begin
+
+                exampleBuffer->SetIsConnected(exampleIsConnected);
+
+                //#SetIsConnectedbuffer end
+
+                //#GetDataPointer begin
+
+                char * exampleDataPointer = exampleBuffer->GetDataPointer();
+
+                //#GetDataPointer end
+
+                //#GetDSMTypebuffer begin
+
+                int exampleDSMType = exampleBuffer->GetDsmType();
+
+                //#GetDsmTypebuffer end
+
+                //#SetDsmTypebuffer begin
+
+                exampleBuffer->SetDsmType(XDMF_DSM_TYPE_UNIFORM);
+
+                //#SetDsmTypebuffer end
+
+                //#GetIsServerbuffer begin
+
+                bool exampleBufferIsServer = exampleBuffer->GetIsServer();
+
+                //#GetIsServerbuffer end
+
+                //#SetIsServerbuffer begin
+
+                exampleBuffer->SetIsServer(exampleIsServer);
+
+                //#SetIsServerbuffer end
+
+                //#GetStartAddress begin
+
+                int exampleBufferStart = exampleBuffer->GetStartAddress();
+
+                //#GetStartAddress end
+
+                //#GetEndAddress begin
+
+                int exampleBufferEnd = exampleBuffer->GetEndAddress();
+
+                //#GetEndAddress end
+
+                //#GetStartServerId begin
+
+                int exampleServerStart = exampleBuffer->GetStartServerId();
+
+                //#GetStartServerId end
+
+                //#GetEndServerId begin
+
+                int exampleServerEnd = exampleBuffer->GetEndServerId();
+
+                //#GetEndServerId end
+
+                for (int i = 0; i<size - numServersCores; ++i)
+                {
+                        if (i == id)
+                        {
+                                std::cout << "starting id = " << exampleServerStart << " and ending id = " << exampleServerEnd << " from core " << id << std::endl;
+                        }
+                }
+
+                //#GetLength begin
+
+                long exampleBufferLength = exampleBuffer->GetLength();
+
+                //#GetLength end
+
+                //#UpdateLength begin
+
+                exampleBuffer->UpdateLength(exampleBufferLength);
+
+                //#UpdateLength end
+
+                //#GetTotalLength begin
+
+                long exampleTotalBufferLength = exampleBuffer->GetTotalLength();
+
+                //#GetTotalLength end
+
+                //#GetBlockLengthbuffer begin
+
+                long exampleBufferBlockLength = exampleBuffer->GetBlockLength();
+
+                //#GetBlockLengthbuffer end
+
+                //#SetBlockLengthbuffer begin
+
+                exampleBuffer->SetBlockLength(exampleBufferBlockLength);
+
+                //#SetBlockLengthbuffer end
+
+                /*
+                //#ConfigureUniform begin
+
+                exampleBuffer->ConfigureUniform(exampleBuffer->GetComm(), dsmSize/numServersCores, size - numServersCores, size - 1);
+
+                //#ConfigureUniform end
+                */
+
+                //#CommandHeader begin
+
+                if (id == 0)
+                {
+                        exampleBuffer->SendCommandHeader(XDMF_DSM_LOCK_ACQUIRE, 1, 0, 0, XDMF_DSM_INTRA_COMM);
+                }
+
+                if (id == 1)
+                {
+                        int probeComm;
+                        exampleBuffer->ProbeCommandHeader(&probeComm);
+
+                        if (probeComm == XDMF_DSM_INTER_COMM)
+                        {
+                                std::cout << "InterComm" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "IntraComm" << std::endl;
+                        }
+                        int length;
+                        int address;
+                        int opcode;
+                        int source;
+                        exampleBuffer->ReceiveCommandHeader(&opcode, &source, &length, &address, XDMF_DSM_INTRA_COMM, 0);
+                }
+
+                //#CommandHeader end
+
+                //#SendRecvData begin
+
+                if (id == 0)
+                {
+                        char * sentData = "datastring";
+                        exampleBuffer->SendData(1, sentData, 0, XDMF_DSM_PUT_DATA_TAG, 0, XDMF_DSM_INTER_COMM);
+                }
+
+                if (id == 1)
+                {
+                        int length;
+                        int address;
+                        char * recvData;
+                        exampleBuffer->ReceiveData(0, recvData, length, XDMF_DSM_PUT_DATA_TAG, address, XDMF_DSM_INTER_COMM);
+                }
+
+                //#SendRecvData end
+
+                //#SendRecvAcknowledgement begin
+
+                if (id == 0)
+                {
+                        int sentData = 1;
+                        exampleBuffer->SendAcknowledgment(1, sentData, XDMF_DSM_PUT_DATA_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                if (id == 1)
+                {
+                        int recvData;
+                        exampleBuffer->ReceiveAcknowledgment(0, recvData, XDMF_DSM_PUT_DATA_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                //#SendRecvAcknowledgement end
+
+                //#BroadcastComm begin
+
+                int broadcastComm = XDMF_DSM_INTER_COMM;
+                exampleBuffer->BroadcastComm(&broadcastComm, 0);
+
+                //#BroadcastComm end
+
+                //#BufferService begin
+
+                if (id == 0)
+                {
+                        int returnCode;
+                        int serviceOut = exampleBuffer->BufferService(&returnCode);
+                }
+                if (id == 1)
+                {
+                        exampleBuffer->SendCommandHeader(XDMF_DSM_OPCODE_DONE, 0, 0, 0, XDMF_DSM_INTER_COMM);
+                }
+
+                //#BufferService end
+
+                //#BufferServiceLoop begin
+
+                if (id == 0)
+                {
+                        int returnCode;
+                        exampleBuffer->BufferServiceLoop(&returnCode);
+                }
+                if (id == 1)
+                {
+                        exampleBuffer->SendCommandHeader(XDMF_DSM_OPCODE_DONE, 0, 0, 0, XDMF_DSM_INTER_COMM);
+                }
+
+                //#BufferServiceloop end
+
+                //#GetAddressRangeForId begin
+
+                int core0StartAddress = 0;
+                int core0EndAddress = 0;
+                exampleBuffer->GetAddressRangeForId(0, &core0StartAddress, &core0EndAddress);
+
+                //#GetAddressRangeForId end
+
+                //#AddressToId begin
+
+                int correspondingId = exampleBuffer->AddressToId(500);
+
+                //#AddressToId end
+
+                //#PutGet begin
+
+                int dsmData = 5;
+                if (sizeof(int)/sizeof(char) + core0StartAddress < core0EndAddress)
+                {
+                        exampleBuffer->Put(0, sizeof(int)/sizeof(char), &dsmData);
+                        exampleBuffer->Get(0, sizeof(int)/sizeof(char), &dsmData);
+                }
+                else
+                {
+                        // Error occured
+                        XdmfError::message(XdmfError::FATAL, "Address out of range");
+                }
+
+                //#PutGet end
+
+                //#PutGetPaged begin
+
+                int pagedData = 5;
+                // Request pages to write to
+                std::vector<unsigned int> storedPages;
+                unsigned int numPages = 0;
+                unsigned int startaddress = 0;
+                unsigned int endaddress = 0;
+                exampleBuffer->RequestPages("pagedDSM",
+                                            sizeof(int),
+                                            std::vector<unsigned int> storedPages,
+                                            numPages,
+                                            startaddress,
+                                            endaddress);
+
+                // Write to pages requested
+                exampleBuffer->Put(&(storedPages[0]), numPages, 0, sizeof(int), *pagedData);
+
+                // Read from pages requested
+                exampleBuffer->Get(&(storedPages[0]), numPages, 0, sizeof(int), *pagedData);
+
+                //#PutGetPaged end
+
+                //#PageInfo begin
+
+                std::vector<unsigned int> setPages;
+                setPages.push_back(1);
+                unsigned int numSetPages = 1;
+                unsigned int setStart = 0;
+                unsigned int setEnd = exampleBuffer->GetBlockSize();
+
+                exampleBuffer->RequestFileDescription("pagedFile",
+                                                      setPages,
+                                                      numSetPages,
+                                                      setStart,
+                                                      setEnd);
+
+                exampleBuffer->RegisterFile("pagedFile",
+                                            setPages,
+                                            numSetPages,
+                                            setStart,
+                                            setEnd);
+
+                //#PageInfo end
+
+                //#PageToId begin
+
+                int coreForPage = exampleBuffer->PageToId(storedPages[0]);
+
+                //#PageToId end
+
+                //#PageToAddress begin
+
+                int addressForPage = exampleBuffer->PageToAddress(storedPages[0]);
+
+                //#PageToAddress end
+
+                //#GetComm begin
+
+                XdmfDSMCommMPI * exampleDSMComm = exampleBuffer->GetComm();
+
+                //#GetComm end
+
+                //#SetComm begin
+
+                exampleBuffer->SetComm(exampleDSMComm);
+
+                //#SetComm end
+
+                //#GetId begin
+
+                int exampleIntraID = exampleDSMComm->GetId();
+
+                //#GetId end
+
+                //#GetIntraSize begin
+
+                int exampleIntraSize = exampleDSMComm->GetIntraSize();
+
+                //#GetIntraSize end
+
+                //#GetInterId begin
+
+                int exampleInterId = exampleDSMComm->GetInterId();
+
+                //#GetInterId end
+
+                //#GetInterSize begin
+
+                int exampleInterSize = exampleDSMComm->GetInterSize();
+
+                //#GetInterSize end
+
+                //#GetInterCommType begin
+
+                int exampleInterCommType = exampleDSMComm->GetInterCommType();
+
+                //#GetInterCommType end
+
+                //#initcomm begin
+
+                exampleDSMComm->Init();
+
+                //#initcomm end
+
+                //#GetIntraComm begin
+
+                MPI_Comm exampleIntraComm = exampleDSMComm->GetIntraComm();
+
+                //#GetIntraComm end
+
+                //#DupComm begin
+
+                exampleDSMComm->DupComm(workerComm);
+
+                //#DupComm end
+
+                //#DSMSendRecv start
+
+                int dsmTransferValue = 0;
+
+                if (id == 0)
+                {
+                  dsmTransferValue = 1;
+                  exampleDSMComm->Send(&dsmTransferValue,
+                                       sizeof(int),
+                                       1,
+                                       XDMF_DSM_INTRA_COMM,
+                                       XDMF_DSM_DEFAULT_TAG);
+                }
+                else if (id == 1)
+                {
+                  int * probedComm;
+                  exampleDSMComm->Probe(probedComm);
+                  exampleDSMComm->Receive(&dsmTransferValue,
+                                          sizeof(int),
+                                          0,
+                                          XDMF_DSM_INTRA_COMM,
+                                          *probedComm);
+                }
+
+                //#DSMSendRecv end
+
+                //#DSMBarrier begin
+
+                exampleDSMComm->Barrier(XDMF_DSM_INTRA_COMM);
+
+                //#DSMBarrier end
+
+                //#DSMBroadcast begin
+
+                int dsmBcastValue = 10;
+
+                exampleDSMComm->Broadcast(&dsmBcastValue,
+                                          sizeof(int),
+                                          0,
+                                          XDMF_DSM_INTRA_COMM);
+
+                //#DSMBroadcast end
+
+                //#DSMAllGather begin
+
+                int dsmGatherSend = exampleDSMComm->GetInterId();
+
+                int * dsmGatherRecv = new int[exampleDSMComm->GetIntraSize()]();
+
+                exampleDSMComm->AllGather(&dsmGatherSend,
+                                          sizeof(int),
+                                          dsmGatherRecv,
+                                          sizeof(int),
+                                          XDMF_DSM_INTRA_COMM);
+
+                //#DSMAllGather end
+
+        /*
+                bool connectingGroup;
+                char * portString;
+                if (id < 5)
+                {
+                        connectingGroup = true;
+                }
+                else
+                {
+                        connectingGroup = false;
+                }
+
+                if (!connectingGroup)
+                {
+                        exampleDSMComm->OpenPort();
+                        portString = exampleDSMComm->GetDsmPortName();
+                        // Send the port string to the connecting group
+                        exampleDSMComm->Accept();
+
+                        // When done with connection;
+                        exampleDSMComm->ClosePort();
+                }
+
+                if (connectingGroup)
+                {
+                        // Recieve string from Master group
+                        exampleDSMComm->SetDsmPortName(portString);
+                        exampleDSMComm->Connect();
+
+                        // When done with connection
+                        exampleDSMComm->Disconnect();
+                }
+
+                if (connectingGroup)
+                {
+                        // Recieve string from Master group
+                        exampleDSMComm->SetDsmPortName(portString);
+                        exampleBuffer->Connect();
+
+                        // When done with connection
+                        exampleBuffer->Disconnect();
+                }
+
+        */
+
+
+                // This is the end of the Demonstration
+
+                exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+                testArray->insert(writeController);
+
+                for (unsigned int i = 0; i<size-numServersCores; ++i)
+                {
+                        MPI_Barrier(workerComm);
+                        if (i == id)
+                        {
+                                std::cout << "Core # " << id << std::endl;
+                                std::cout << "Controller stats" << std::endl;
+                                std::cout << "datasetpath = " << testArray->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                                std::cout << "filepath = " << testArray->getHeavyDataController(0)->getFilePath() << std::endl;
+                                outputVector = testArray->getHeavyDataController(0)->getDataspaceDimensions();
+                                std::cout << "Data space dimensions" << std::endl;
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller Dimensions" << std::endl;
+                                outputVector = testArray->getHeavyDataController(0)->getDimensions();
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller size" << testArray->getHeavyDataController(0)->getSize() << std::endl;
+                                std::cout << "Controller starts" << std::endl;
+                                outputVector = testArray->getHeavyDataController(0)->getStart();
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller strides" << std::endl;
+                                outputVector = testArray->getHeavyDataController(0)->getStride();
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                                }
+                                for(unsigned int j=0; j<testArray->getSize(); ++j)
+                                {
+                                        std::cout << "core #" << id <<" testArray[" << j << "] = " << testArray->getValue<int>(j) << std::endl;
+                                }
+                        }
+                }
+                testArray->accept(exampleWriter);
+
+                std::vector<unsigned int> readStartVector;
+                readStartVector.push_back(4*(size - id - 1 - numServersCores));
+                std::vector<unsigned int> readStrideVector;
+                readStrideVector.push_back(1);
+                std::vector<unsigned int> readCountVector;
+                readCountVector.push_back(4);
+                std::vector<unsigned int> readDataSizeVector;
+                readDataSizeVector.push_back(4*(size-numServersCores));
+
+                shared_ptr<XdmfArray> readArray = XdmfArray::New();
+
+                readArray->initialize<int>(0);
+                readArray->reserve(testArray->getSize());
+
+                shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType::Int32(),
+                        readStartVector,
+                        readStrideVector,
+                        readCountVector,
+                        readDataSizeVector,
+                        exampleWriter->getServerBuffer());
+
+                readArray->insert(readController);
+
+                if (id == 0)
+                {
+                        std::cout << "\n\n\n";
+                }
+
+                std::cout << "testing read" << std::endl;
+                readArray->read();
+
+
+                for (unsigned int i = 0; i<size; ++i)
+                {
+                        MPI_Barrier(workerComm);
+                        if (i == id)
+                        {
+                                std::cout << "Core # " << id << std::endl;
+                                std::cout << "Controller stats" << std::endl;
+                                std::cout << "datasetpath = " << readArray->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                                std::cout << "filepath = " << readArray->getHeavyDataController(0)->getFilePath() << std::endl;
+                                outputVector = readArray->getHeavyDataController(0)->getDataspaceDimensions();
+                                std::cout << "Data space dimensions" << std::endl;
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller Dimensions" << std::endl;
+                                outputVector = readArray->getHeavyDataController(0)->getDimensions();
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller size" << readArray->getHeavyDataController(0)->getSize() << std::endl;
+                                std::cout << "Controller starts" << std::endl;
+                                outputVector = readArray->getHeavyDataController(0)->getStart();
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                                }
+                                std::cout << "Controller strides" << std::endl;
+                                outputVector = readArray->getHeavyDataController(0)->getStride();
+                                for (unsigned int j=0; j<outputVector.size(); ++j)
+                                {
+                                        std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                                }
+                                for(unsigned int j=0; j<readArray->getSize(); ++j)
+                                {
+                                        std::cout << "core #" << id <<" readArray[" << j << "] = " << readArray->getValue<int>(j) << std::endl;
+                                }
+                        }
+                }
+
+                MPI_Barrier(workerComm);
+
+                // End of Work Section
+
+                //#endworksection begin
+
+        }
+
+        //#endworksection end
+
+        exampleWriter->closeFile();
+
+        //#stopDSMwriter begin
+
+        if (id == 0)
+        {
+                exampleWriter->stopDSM();
+        }
+
+        //#stopDSMwriter end
+
+        /*
+        //#stopDSMcontroller begin
+
+        if (id == 0)
+        {
+                exampleController->stopDSM();
+        }
+
+        //#stopDSMcontroller end
+        */
+
+        /*
+        //#SendDone begin
+
+        if (id == 0)
+        {
+                XdmfDSMBuffer closeBuffer = exampleWriter->getServerBuffer();
+                closeBuffer->SendDone();
+        }
+
+        //#SendDone end
+        */
+
+        //#GetInterComm begin
+
+        XdmfDSMCommMPI * exampleDSMComm = exampleWriter->getServerBuffer()->GetComm();
+        MPI_Comm exampleInterComm = exampleDSMComm->GetInterComm();
+
+        //#GetInterComm end
+
+        //#DupInterComm begin
+
+        exampleDSMComm->DupInterComm(comm);
+
+        //#DupInterComm end
+
+        //#SendRecvInfo begin
+
+        if (id >= size - numServersCores)
+        {
+                exampleWriter->getServerBuffer()->SendInfo();
+        }
+        else
+        {
+                exampleWriter->getServerBuffer()->ReceiveInfo();
+        }
+
+        //#SendRecvInfo begin
+
+        /*
+        //#restartDSMwriter begin
+
+        exampleWriter->restartDSM();
+
+        //#restartDSMwriter end
+
+        //#restartDSMcontroller begin
+
+        exampleController->restartDSM();
+
+        //#restartDSMcontroller end
+        */
+
+        MPI_Barrier(comm);
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfDSMSelfcontained.cpp b/examples/Cxx/ExampleXdmfDSMSelfcontained.cpp
new file mode 100644
index 0000000..b8a0b41
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfDSMSelfcontained.cpp
@@ -0,0 +1,285 @@
+#include <mpi.h>
+#include <H5FDdsm.h>
+#include <H5FDdsmManager.h>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init_thread(&argc, &argv, MPI_THREAD_MULTIPLE, &providedThreading);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        //#initMPI end
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+
+        for (unsigned int i = 1; i <= 4; ++i)
+        {
+                testArray->pushBack(i*id);
+        }
+
+        //#writevectorinit begin
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "data";
+
+        std::vector<unsigned int> writeStartVector;
+        writeStartVector.push_back(id*4);
+        std::vector<unsigned int> writeStrideVector;
+        writeStrideVector.push_back(1);
+        std::vector<unsigned int> writeCountVector;
+        writeCountVector.push_back(4);
+        std::vector<unsigned int> writeDataSizeVector;
+        writeDataSizeVector.push_back(4*size);
+
+        //#writevectorinit end
+
+        /*
+        //#initwritergenerate begin
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/size);
+
+        //#initwritergenerate end
+        */
+
+        //#initcontrollergenerate begin
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                comm,
+                dsmSize/size);
+
+        //#initcontrollergenerate end
+
+        /*
+        //#initcontrollerwithbuffer begin
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getBuffer());
+
+        //#initcontrollerwithbuffer end
+
+        //#setManagercontroller begin
+
+        writeController->setManager(exampleWriter->getManager());
+
+        //#setManagercontroller end
+
+        //#setBuffercontroller begin
+
+        writeController->setBuffer(exampleWriter->getBuffer());
+        //In this context setting the buffer is redundant
+        //However, if multiple buffers exist, this can be used to change between them
+
+        //#setBuffercontroller end
+        */
+
+        //#initwriterwithbuffer begin
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, writeController->getBuffer());
+
+        //#initwriterwithbuffer end
+
+        //#setManagerwriter begin
+
+        exampleWriter->setManager(writeController->getManager());
+
+        //#setManagerwriter end
+
+        //#setBufferwriter begin
+
+        exampleWriter->setBuffer(writeController->getBuffer());
+        //In this context setting the buffer is redundant
+        //However, if multiple buffers exist, this can be used to change between them
+
+        //#setBufferwriter end
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        testArray->insert(writeController);
+
+        for (unsigned int i = 0; i<size; ++i)
+        {
+                MPI_Barrier(comm);
+                if (i == id)
+                {
+                        std::cout << "Core # " << id << std::endl;
+                        std::cout << "Controller stats" << std::endl;
+                        std::cout << "datasetpath = " << testArray->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                        std::cout << "filepath = " << testArray->getHeavyDataController(0)->getFilePath() << std::endl;
+                        outputVector = testArray->getHeavyDataController(0)->getDataspaceDimensions();
+                        std::cout << "Data space dimensions" << std::endl;
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller Dimensions" << std::endl;
+                        outputVector = testArray->getHeavyDataController(0)->getDimensions();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller size" << testArray->getHeavyDataController(0)->getSize() << std::endl;
+                        std::cout << "Controller starts" << std::endl;
+                        outputVector = testArray->getHeavyDataController(0)->getStart();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller strides" << std::endl;
+                        outputVector = testArray->getHeavyDataController(0)->getStride();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                        }
+                        for(unsigned int i=0; i<testArray->getSize(); ++i)
+                        {
+                                std::cout << "core #" << id <<" testArray[" << i << "] = " << testArray->getValue<int>(i) << std::endl;
+                        }
+                }
+        }
+
+        testArray->accept(exampleWriter);
+
+        std::vector<unsigned int> readStartVector;
+        readStartVector.push_back(4*(size - id - 1));
+        std::vector<unsigned int> readStrideVector;
+        readStrideVector.push_back(1);
+        std::vector<unsigned int> readCountVector;
+        readCountVector.push_back(4);
+        std::vector<unsigned int> readDataSizeVector;
+        readDataSizeVector.push_back(4*size);
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+
+        readArray->initialize<int>(0);
+        readArray->reserve(testArray->getSize());
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter->getBuffer());
+
+        readArray->insert(readController);
+
+        std::cout << "testing read" << std::endl;
+        readArray->read();
+        std::cout << "done testing read" << std::endl;
+        
+
+        for (unsigned int i = 0; i<size; ++i)
+        {
+                MPI_Barrier(comm);
+                if (i == id)
+                {
+                        std::cout << "Core # " << id << std::endl;
+                        std::cout << "Controller stats" << std::endl;
+                        std::cout << "datasetpath = " << readArray->getHeavyDataController(0)->getDataSetPath() << std::endl;
+                        std::cout << "filepath = " << readArray->getHeavyDataController(0)->getFilePath() << std::endl;
+                        outputVector = readArray->getHeavyDataController(0)->getDataspaceDimensions();
+                        std::cout << "Data space dimensions" << std::endl;
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller Dimensions" << std::endl;
+                        outputVector = readArray->getHeavyDataController(0)->getDimensions();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller size" << readArray->getHeavyDataController(0)->getSize() << std::endl;
+                        std::cout << "Controller starts" << std::endl;
+                        outputVector = readArray->getHeavyDataController(0)->getStart();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << std::endl;
+                        }
+                        std::cout << "Controller strides" << std::endl;
+                        outputVector = readArray->getHeavyDataController(0)->getStride();
+                        for (int j=0; j<outputVector.size(); ++j)
+                        {
+                                std::cout << "[" << j << "] =" << outputVector[j] << "\n" << std::endl;
+                        }
+                        for(unsigned int i=0; i<readArray->getSize(); ++i)
+                        {
+                                std::cout << "core #" << id <<" readArray[" << i << "] = " << readArray->getValue<int>(i) << std::endl;
+                        }
+                }
+        }
+
+
+        MPI_Barrier(comm);
+
+        /*
+        //#managerdeletionwriter begin
+
+        //the dsmManager must be deleted or else there will be a segfault
+
+        delete exampleWriter->getManager();
+
+        //#managerdeletionwriter end
+
+        //#deleteManagerwriter begin
+
+        //the dsmManager must be deleted or else there will be a segfault
+
+        examplewriter->deleteManager();
+
+        //#deleteManagerwriter end
+        */
+
+        //#managerdeletioncontroller begin
+
+        //the dsmManager must be deleted or else there will be a segfault
+
+        delete writeController->getManager();
+
+        //#managerdeletioncontroller end
+
+        /*don't call delete twice on the same manager or else an error will occur
+        //#deleteManagercontroller begin
+
+        //the dsmManager must be deleted or else there will be a segfault
+
+        writeController->deleteManager();
+
+        //#deleteManagercontroller end
+        */
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfDomain.cpp b/examples/Cxx/ExampleXdmfDomain.cpp
new file mode 100644
index 0000000..e176645
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfDomain.cpp
@@ -0,0 +1,12 @@
+#include "XdmfDomain.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfDomain> exampleDomain = XdmfDomain::New();
+
+        //#initialization end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfEdit.cpp b/examples/Cxx/ExampleXdmfEdit.cpp
new file mode 100644
index 0000000..826e7da
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfEdit.cpp
@@ -0,0 +1,826 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "string.h"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+        shared_ptr<XdmfReader> exampleReader = XdmfReader::New();
+
+        /*
+        This is assuming that the read item is an XdmfDomain object
+        */
+        shared_ptr<XdmfDomain> primaryDomain = shared_dynamic_cast<XdmfDomain>(exampleReader->read("testoutput.xmf"));
+        shared_ptr<XdmfInformation> outputInformation = primaryDomain->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("The Domain's tag is: %s\n", primaryDomain->getItemTag().c_str());
+
+        shared_ptr<XdmfGridCollection> gridHolder = primaryDomain->getGridCollection(0);
+
+        printf("The Grid Collection's tag is: %s\n", gridHolder->getItemTag().c_str());
+        printf("The Grid Collection's name is: %s\n", gridHolder->getName().c_str());
+        outputInformation = gridHolder->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+
+        std::map<std::string, std::string>::iterator outputwalker = gridHolder->getItemProperties().begin();
+        for (;outputwalker!=gridHolder->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+ 
+        if (gridHolder->getType() == XdmfGridCollectionType::Spatial())
+        {
+                printf("This is a spatial grid collection\n");
+        }
+        else
+        {
+                printf("This is not a spatial grid collection\n");
+        }
+
+
+        //loop controlling integers
+        int i = 0;
+        int j = 0;
+        int k = 0;
+        int m = 0;
+        int task;
+        int node;
+        int remote;
+        std::string blankstring = "";
+        char* outstring = strdup(blankstring.c_str());
+        shared_ptr<XdmfMap> readMap;
+        std::map<int, std::map<int, std::set<int> > > taskIDMap;
+        std::map<int, std::map<int, std::set<int> > >::iterator taskWalker;
+        std::map<int, std::set<int> > nodeIDMap;
+        std::map<int, std::set<int> >::iterator nodeWalker;
+        std::set<int> remoteIDset;
+        std::set<int>::iterator remoteWalker;
+
+        for (i=0; i<gridHolder->getNumberMaps(); i++)
+        {
+                readMap = gridHolder->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+
+        printf("Unstructured Grid\n");
+        shared_ptr<XdmfUnstructuredGrid> ungrid = gridHolder->getUnstructuredGrid(0);
+        printf("The Unstructured Grid's tag is: %s\n", ungrid->getItemTag().c_str());
+        printf("The Unstructured Grid's name is: %s\n", ungrid->getName().c_str());
+
+        outputwalker = ungrid->getItemProperties().begin();
+        for (;outputwalker!=ungrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+
+        printf("The Unstructured Grid's time is: %f\n", ungrid->getTime()->getValue());
+        i=0;
+        for (i=0; i<ungrid->getNumberMaps(); i++)
+        {
+                readMap = ungrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+
+        shared_ptr<XdmfSet> readSet;
+        shared_ptr<XdmfAttribute> readAttribute;
+        for (i=0; i < ungrid->getNumberSets(); i++)
+        {
+                readSet = ungrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node\n");
+                }
+                else
+                {
+                        printf("This set is not a node\n");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar\n");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node\n");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < ungrid->getNumberAttributes(); i++)
+        {
+                readAttribute = ungrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+
+        printf("Unstructured Topology\n");
+        shared_ptr<XdmfTopology> untopology = ungrid->getTopology();
+        if (!untopology->isInitialized())
+        {
+                untopology->read();
+        }
+        printf("The topology's tag: %s\n", untopology->getItemTag().c_str());
+        if (untopology->getType() == XdmfTopologyType::Hexahedron())
+        {
+                printf("This topology is a hexahedron\n");
+        }
+        else
+        {
+                printf("This topology is not a hexahedron\n");
+        }
+        printf("Contains %d elements\n", untopology->getNumberElements());
+        printf("Contains the values: %s\n", untopology->getValuesString().c_str());
+
+        printf("Unstructured Geometry\n");
+        shared_ptr<XdmfGeometry> ungeometry = ungrid->getGeometry();
+        if (!ungeometry->isInitialized())
+        {
+                ungeometry->read();
+        }
+        printf("The geometry's tag: %s\n", ungeometry->getItemTag().c_str());
+        if (ungeometry->getType() == XdmfGeometryType::XYZ())
+        {
+                printf("This geometry is XYZ\n");
+        }
+        else
+        {
+                printf("This geometry is not XYZ\n");
+        }
+        outputInformation = ungeometry->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("Contains %d points\n", ungeometry->getNumberPoints());
+        printf("Contains the values: %s\n", ungeometry->getValuesString().c_str());
+
+
+
+
+
+        printf("Curvilinear Grid\n");
+        shared_ptr<XdmfCurvilinearGrid> curvgrid = gridHolder->getCurvilinearGrid(0);
+        printf("The Curvilinear Grid's tag is: %s\n", curvgrid->getItemTag().c_str());
+        printf("The Curvilinear Grid's name is: %s\n", curvgrid->getName().c_str());
+        outputwalker = curvgrid->getItemProperties().begin();
+        for (;outputwalker!=curvgrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+        outputInformation = curvgrid->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("The Curvilinear Grid's time is: %f\n", curvgrid->getTime()->getValue());
+        for (i=0; i<curvgrid->getNumberMaps(); i++)
+        {
+                readMap = curvgrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+        for (i=0; i < curvgrid->getNumberSets(); i++)
+        {
+                readSet = curvgrid->getSet(i);
+                if (!readSet->isInitialized());
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node\n");
+                }
+                else
+                {
+                        printf("This set is not a node\n");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar\n");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node\n");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < curvgrid->getNumberAttributes(); i++)
+        {
+                readAttribute = curvgrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+
+        printf("Curvilinear Dimensions\n");
+        shared_ptr<XdmfArray> curvdimensions = curvgrid->getDimensions();
+        if (!curvdimensions->isInitialized())
+        {
+                curvdimensions->read();
+        }
+        printf("The dimensions' tag: %s\n", curvdimensions->getItemTag().c_str());
+        printf("Contains the values: %s\n", curvdimensions->getValuesString().c_str());
+
+        printf("Curvilinear Geometry\n");
+        shared_ptr<XdmfGeometry> curvgeometry = curvgrid->getGeometry();
+        if (!curvgeometry->isInitialized())
+        {
+                curvgeometry->read();
+        }
+        printf("The geometry's tag: %s\n", curvgeometry->getItemTag().c_str());
+        if (curvgeometry->getType() == XdmfGeometryType::XYZ())
+        {
+                printf("This geometry is XYZ\n");
+        }
+        else
+        {
+                printf("This geometry is not XYZ\n");
+        }
+        outputInformation = curvgeometry->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("Contains %d points\n", curvgeometry->getNumberPoints());
+        printf("Contains the values: %s\n", curvgeometry->getValuesString().c_str());
+
+
+        printf("Rectilinear Grid\n");
+        shared_ptr<XdmfRectilinearGrid> rectgrid = gridHolder->getRectilinearGrid(0);
+        printf("The Rectilinear Grid's tag is: %s\n", rectgrid->getItemTag().c_str());
+        printf("The Rectilinear Grid's name is: %s\n", rectgrid->getName().c_str());
+        printf("The Rectilinear Grid's time is: %f\n", rectgrid->getTime()->getValue());
+
+        outputwalker = rectgrid->getItemProperties().begin();
+        for (; outputwalker!=rectgrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+
+        for (i=0; i<rectgrid->getNumberMaps(); i++)
+        {
+                readMap = rectgrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+        for (i=0; i < rectgrid->getNumberSets(); i++)
+        {
+                readSet = rectgrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node\n");
+                }
+                else
+                {
+                        printf("This set is not a node\n");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar\n");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node\n");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < rectgrid->getNumberAttributes(); i++)
+        {
+                readAttribute = rectgrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+        printf("Rectilinear Dimensions\n");
+        shared_ptr<XdmfArray> rectdimensions = rectgrid->getDimensions();
+        if (!rectdimensions->isInitialized())
+        {
+                rectdimensions->read();
+        }
+        printf("The dimensions' tag: %s\n", rectdimensions->getItemTag().c_str());
+        printf("Contains the values: %s\n", rectdimensions->getValuesString().c_str());
+
+        printf("Rectilinear Coordinates\n");
+        std::vector<shared_ptr<XdmfArray> > rectcoordinates = rectgrid->getCoordinates();
+        printf("Contains the values: \n");
+        for (i=0;i<rectcoordinates.size();i++)
+        {
+                if (!rectcoordinates[i]->isInitialized())
+                {
+                        rectcoordinates[i]->read();
+                }
+                printf("%s\n", rectcoordinates[i]->getValuesString().c_str());
+        }
+
+
+
+        printf("Regular Grid\n");
+        shared_ptr<XdmfRegularGrid> reggrid = gridHolder->getRegularGrid(0);
+        printf("The Regular Grid's tag is: %s\n", reggrid->getItemTag().c_str());
+        printf("The Regular Grid's name is: %s\n", reggrid->getName().c_str());
+        outputwalker = reggrid->getItemProperties().begin();
+        for (;outputwalker!=reggrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+        printf("The Regular Grid's time is: %f\n", reggrid->getTime()->getValue());
+        for (i=0; i<reggrid->getNumberMaps(); i++)
+        {
+                readMap = reggrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+        for (i=0; i < reggrid->getNumberSets(); i++)
+        {
+                readSet = reggrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node");
+                }
+                else
+                {
+                        printf("This set is not a node");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < reggrid->getNumberAttributes(); i++)
+        {
+                readAttribute = reggrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+
+        printf("Regular Brick Size\n");
+        shared_ptr<XdmfArray> regbricksize = reggrid->getBrickSize();
+        if (!regbricksize->isInitialized())
+        {
+                regbricksize->read();
+        }
+        printf("The brick's tag: %s\n", regbricksize->getItemTag().c_str());
+        printf("Contains the values: %s\n", regbricksize->getValuesString().c_str());
+
+        printf("Regular Number of Points\n");
+        shared_ptr<XdmfArray> regnumpoints = reggrid->getDimensions();
+        if (!regnumpoints->isInitialized())
+        {
+                regnumpoints->read();
+        }
+        printf("The dimensions' tag: %s\n", regnumpoints->getItemTag().c_str());
+        printf("Contains the values: %s\n", regnumpoints->getValuesString().c_str());
+
+        printf("Regular Origin\n");
+        shared_ptr<XdmfArray> regorigin = reggrid->getOrigin();
+        if (!regorigin->isInitialized())
+        {
+                regorigin->read();
+        }
+        printf("The origin's tag: %s\n", regorigin->getItemTag().c_str());
+        printf("Contains the values: %s\n", regorigin->getValuesString().c_str());
+
+
+
+
+
+
+        primaryDomain->getInformation(0)->setKey("Edited");
+        primaryDomain->getInformation(0)->setValue("This file is the edited version");
+        printf("edited domain information\n");
+
+        shared_ptr<XdmfAttribute> unglobalIDs = ungrid->getAttribute(0);
+        int newIDs1 [] = {5,2,8,7,9,1};
+        unglobalIDs->insert(0, newIDs1, 6, 1, 1);
+        printf("edited unstructured attribute: %s\n", unglobalIDs->getValuesString());
+
+        shared_ptr<XdmfSet> unset = ungrid->getSet(0);
+        double newunsetdata [] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 0.23};
+        unset->insert(0, newunsetdata, 10, 1, 1);
+        printf("edited unstructured set: %s\n", unset->getValuesString());
+
+        untopology = ungrid->getTopology();
+        int untoposize = untopology->getSize();
+        int untopologydata [untoposize];
+        untopology->getValues(0, untopologydata, untopology->getSize(), 1, 1);
+        for (i=0; i < untopology->getSize(); i++)
+        {
+                untopologydata[i] = untopologydata[i] + 1;
+        }
+        untopology->insert(0, untopologydata, untopology->getSize(), 1, 1);
+        printf("edited unstructured topology: %s\n", untopology->getValuesString());
+
+        ungeometry = ungrid->getGeometry();
+        int ungeosize = ungeometry->getSize();
+        double ungeometrydata [ungeosize];
+        ungeometry->getValues(0, ungeometrydata, ungeometry->getSize(), 1, 1);
+        for (i=0; i<ungeometry->getSize();i++)
+        {
+                ungeometrydata[i] = ungeometrydata[i] + 1;
+        }
+        ungeometry->insert(0, ungeometrydata, ungeometry->getSize(), 1, 1);
+
+
+        shared_ptr<XdmfAttribute> curvglobalIDs = curvgrid->getAttribute(0);
+        int newIDs2 [] = {3, 6, 2, 8, 1, 7, 5};
+        curvglobalIDs->insert(0, newIDs2, 7, 1, 1);
+
+        curvgeometry = curvgrid->getGeometry();
+        int curvgeosize = curvgeometry->getSize();
+        double curvgeometrydata [curvgeosize];
+        curvgeometry->getValues(0, curvgeometrydata, curvgeometry->getSize(), 1, 1);
+        for (i = 0; i<curvgeometry->getSize(); i++)
+        {
+                curvgeometrydata[i] = curvgeometrydata[i] + 1;
+        }
+        curvgeometry->insert(0, curvgeometrydata, curvgeometry->getSize(), 1, 1);
+        for (i = 0; i < 3; i++)
+        {
+                curvgeometry->pushBack(curvgeometry->getSize());
+        }
+
+        curvdimensions = curvgrid->getDimensions();
+        int curvdimensionsize = curvdimensions->getSize();
+        int curvdimensiondata [curvdimensionsize];
+        curvdimensions->getValues(0, curvdimensiondata, curvdimensions->getSize(), 1, 1);
+        for (i = 0;  i< curvdimensions->getSize(); i++)
+        {
+                curvdimensiondata[i] = curvdimensiondata[i] + 1;
+        }
+        curvdimensions->insert(0, curvdimensiondata, curvdimensions->getSize(), 1, 1);
+
+
+        shared_ptr<XdmfAttribute> rectglobalIDs = rectgrid->getAttribute(0);
+        int newIDs3 [] = {6, 4, 3, 7, 9, 8};
+        rectglobalIDs->insert(0, newIDs3, 6, 1, 1);
+
+        rectdimensions = rectgrid->getDimensions();
+        int rectdimensionsize = rectdimensions->getSize();
+        int rectdimensiondata [rectdimensionsize];
+        rectdimensions->getValues(0, rectdimensiondata, rectdimensions->getSize(), 1, 1);
+        for (i = 0; i < rectdimensions->getSize(); i++)
+        {
+                rectdimensiondata[i] = rectdimensiondata[i] + 1;
+        }
+        rectdimensions->insert(0, rectdimensiondata, rectdimensions->getSize(), 1, 1);
+
+        std::vector<shared_ptr<XdmfArray> > rectcoordinatevector = rectgrid->getCoordinates();
+        shared_ptr<XdmfArray> coordinateaxis;
+        for (i=0;i<rectcoordinatevector.size(); i++)
+        {
+                coordinateaxis = rectcoordinatevector[i];
+                int coordinatesize = coordinateaxis->getSize();
+                int coordinatedata [coordinatesize];
+                coordinateaxis->getValues(0, coordinatedata, coordinateaxis->getSize(), 1, 1);
+                for (j = 0; j < coordinateaxis->getSize(); j++)
+                {
+                        coordinatedata[i] = coordinatedata[i] + 1;
+                }
+                coordinateaxis->insert(0, coordinatedata, coordinateaxis->getSize(), 1, 1);
+                coordinateaxis->pushBack(coordinateaxis->getSize());
+                rectcoordinatevector[i] = coordinateaxis;
+        }
+        rectgrid->setCoordinates(rectcoordinatevector);
+
+        shared_ptr<XdmfAttribute> regglobalIDs = reggrid->getAttribute(0);
+        int newIDs4 [] = {3, 5, 1, 2, 4, 8, 0};
+        regglobalIDs->insert(0, newIDs4, 7, 1, 1);
+
+        regbricksize = reggrid->getBrickSize();
+        int regbrickdatasize = regbricksize->getSize();
+        double brickdata [regbrickdatasize];
+        regbricksize->getValues(0, brickdata, regbricksize->getSize(), 1, 1);
+        for (i = 0; i < regbricksize->getSize(); i++)
+        {
+                brickdata[i] = brickdata[i] + 1;
+        }
+        regbricksize->insert(0, brickdata, regbricksize->getSize(), 1, 1);
+        reggrid->setBrickSize(regbricksize);
+
+        shared_ptr<XdmfArray> regdimensions = reggrid->getDimensions();
+        int regdimensionssize = regdimensions->getSize();
+        int regdimensiondata [regdimensionssize];
+        regdimensions->getValues(0, regdimensiondata, regdimensions->getSize(), 1, 1);
+        for (i = 0; i < regdimensions->getSize(); i++)
+        {
+                regdimensiondata[i] = regdimensiondata[i] + 1;
+        }
+        regdimensions->insert(0, regdimensiondata, regdimensions->getSize(), 1, 1);
+        reggrid->setDimensions(regdimensions);
+
+        regorigin = reggrid->getOrigin();
+        int regoriginsize = regorigin->getSize();
+        double regorigindata [regoriginsize];
+        regorigin->getValues(0, regorigindata, regorigin->getSize(), 1, 1);
+        for (i = 0; i < regorigin->getSize(); i++)
+        {
+                regorigindata[i] = regorigindata[i] + 1;
+        }
+        regorigin->insert(0, regorigindata, regorigin->getSize(), 1, 1);
+        reggrid->setOrigin(regorigin);
+
+        shared_ptr<XdmfHDF5Writer> exampleHeavyWriter = XdmfHDF5Writer::New("editedtestoutput.h5");
+        shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New("editedtestoutput.xmf", exampleHeavyWriter);
+        //exampleHeavyWriter->setFileSizeLimit(1);
+        primaryDomain->accept(exampleHeavyWriter);
+        exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Overwrite);
+        primaryDomain->accept(exampleWriter);
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfError.cpp b/examples/Cxx/ExampleXdmfError.cpp
new file mode 100644
index 0000000..40a657d
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfError.cpp
@@ -0,0 +1,75 @@
+#include "XdmfError.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        XdmfError testError = XdmfError(XdmfError:DEBUG, "This is a debug error");
+
+        //#initialization end
+
+        //#getLevel begin
+
+        XdmfError::Level testError.getLevel();
+
+        //#getLevel end
+
+        //#setLevel begin
+
+        testError.setLevel(XdmfError::WARNING);
+
+        //#setLevel end
+
+        //#what begin
+
+        char * errorOutput = testError.what();
+
+        //#what end
+
+        //#getLevelLimit begin
+
+        XdmfError::Level exampleLevel = XdmfError::getLevelLimit();
+
+        //#getLevelLimit end
+
+        //#setLevelLimit begin
+
+        XdmfError::setLevelLimit(XdmfError::FATAL);
+
+        //#setLevelLimit end
+
+        //#getSuppressionLevel begin
+
+        XdmfError::Level exampleSuppression = XdmfError::getSuppressionLevel();
+
+        //#getSuppressionLevel end
+
+        //#setSuppressionLevel begin
+
+        XdmfError::setSuppressionLevel(XdmfError::DEBUG);
+
+        //#setSuppressionLevel end
+
+        //#setBuffer begin
+
+        XdmfError::setBuffer(std::cout.rdbuf());
+        //the default buffer is cout
+
+        //#setBuffer end
+
+        //#message begin
+
+        try
+        {
+                XdmfError::message(XdmfError::FATAL, "this is an example error");
+        }
+        catch (XdmfError exampleError)
+        {
+                char * errorOutput = exampleError.what();
+        }
+
+        //#message end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfFunction.cpp b/examples/Cxx/ExampleXdmfFunction.cpp
new file mode 100644
index 0000000..97bca95
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfFunction.cpp
@@ -0,0 +1,522 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfFunction.hpp"
+#include <vector>
+#include <map>
+
+//#declarefunction begin
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values);
+
+//#declarefunction end
+
+//#declareoperation begin
+
+shared_ptr<XdmfArray> prepend(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+
+//#declareoperation end
+
+//#declareoperationclass begin
+
+class OperationHolder : public XdmfFunction::XdmfOperationInternal
+{
+        public:
+                static shared_ptr<OperationHolder> New()
+                {
+                        shared_ptr<OperationHolder> obj (new OperationHolder());
+                        return obj;
+                }
+
+                virtual shared_ptr<XdmfArray> execute(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+                {
+                        // returns whichever array has more values
+                        if (val1->getSize() >= val2->getSize())
+                        {
+                                return val1;
+                        }
+                        else
+                        {
+                                return val2;
+                        }
+                }
+
+        private:
+                OperationHolder()
+                {
+                }
+
+}
+
+//#declareoperationclass end
+
+//#declarefunctionclass begin
+
+class FunctionHolder : public XdmfFunction::XdmfFunctionInternal
+{
+        public:
+                static shared_ptr<FunctionHolder> New()
+                {
+                        shared_ptr<FunctionHolder> obj (new FunctionHolder());
+                        return obj;
+                }
+
+                virtual shared_ptr<XdmfArray> execute(std::vector<shared_ptr<XdmfArray> > valueVector)
+                {
+                        // Simply returns an array containing 0
+                        shared_ptr<XdmfArray> zeroArray = XdmfArray::New();
+                        zeroArray.pushBack<int>(0);
+                }
+
+        private:
+                FunctionHolder()
+                {
+                }
+}
+
+//#declarefunctionclass end
+
+//#programstart begin
+
+int main(int, char **)
+{
+
+        //#programstart end
+
+        //#getSupportedOperations begin
+
+        std::string exampleOperations = XdmfFunction::getSupportedOperations();
+
+        //#getSupportedOperations end
+
+        //#getSupportedFunctions begin
+
+        std::vector<std::string> exampleFunctions = XdmfFunction::getSupportedFunctions();
+
+        //#getSupportedFunctions end
+
+        //#getValidVariableChars begin
+
+        std::string exampleVariableChars = XdmfFunction::getValidVariableChars();
+
+        //#getValidVariableChars end
+
+        //#getValidDigitChars begin
+
+        std::string exampleDigitChars = XdmfFunction::getValidDigitChars();
+
+        //#getValidDigitChars end
+
+        //#getOperationPriority begin
+
+        int examplePriority = XdmfFunction::getOperationPriority('|');
+
+        //#getOperationPriority end
+
+        //#valueinit begin
+
+        shared_ptr<XdmfArray> valueArray1 = XdmfArray::New();
+        valueArray1->pushBack(1);
+        valueArray1->pushBack(2);
+        valueArray1->pushBack(3);
+        valueArray1->pushBack(4);
+        shared_ptr<XdmfArray> valueArray2 = XdmfArray::New();
+        valueArray2->pushBack(9);
+        valueArray2->pushBack(8);
+        valueArray2->pushBack(7);
+        valueArray2->pushBack(6);
+
+        std::vector<shared_ptr<XdmfArray> > valueVector;
+        valueVector.push_back(valueArray1);
+        valueVector.push_back(valueArray2);
+
+        shared_ptr<XdmfArray> answerArray;
+
+        //#valueinit end
+
+        //#sum begin
+
+        answerArray = XdmfFunction::sum(valueVector);
+
+        //#sum end
+
+        //#average begin
+
+        answerArray = XdmfFunction::average(valueVector);
+
+        //#average end
+
+        //#chunk begin
+
+        answerArray = XdmfFunction::chunk(valueArray1, valueArray2);
+
+        //#chunk end
+
+        //#interlace begin
+
+        answerArray = XdmfFunction::interlace(valueArray1, valueArray2);
+
+        //#interlace end
+
+        //#addOperation begin
+
+        int exampleNumOperations = XdmfFunction::addOperation('@', (shared_ptr<XdmfArray>(*)(shared_ptr<XdmfArray>, shared_ptr<XdmfArray>))prepend, 2);
+
+        //#addOperation end
+
+        //#addOperationclass begin
+
+        shared_ptr<OperationHolder> newOperation = OperationHolder::New();
+        int numOperations = XdmfFunction::addOperation('>', newOperation);
+
+        //#addOperationclass end
+
+        //#evaluateOperation begin
+
+        answerArray = XdmfFunction::evaluateOperation(valueArray1, valueArray2, '@');
+
+        //#evaluateOperation end
+
+        //#addFunction begin
+
+        int exampleNumFunctions = XdmfFunction::addFunction("MAX", (shared_ptr<XdmfArray>(*)(std::vector<shared_ptr<XdmfArray> >))maximum);
+
+        //#addFunction end
+
+        //#addFunctionclass begin
+
+        shared_ptr<FunctionHolder> newFunction = FunctionHolder::New();
+        int numFunctions = XdmfFunction::addFunction("ZERO", newFunction);
+
+        //#addFunctionclass end
+
+        //#evaluateFunction begin
+
+        answerArray = XdmfFunction::evaluateFunction(valueVector, "MAX");
+
+        //#evaluateFunction end
+
+        //#evaluateExpression begin
+
+        std::map<std::string, shared_ptr<XdmfArray> > valueMap;
+        valueMap["A"] = valueArray1;
+        valueMap["B"] = valueArray2;
+
+        std::string parsedExpression = "MAX(A,B)@(A#B)";
+        answerArray = XdmfFunction::evaluateExpression(parsedExpression, valueMap);
+
+        //#evaluateExpression end
+
+        //#initialization begin
+
+        shared_ptr<XdmfFunction> testFunction = XdmfFunction::New();
+
+        //#initalization end
+
+        //#initexpression begin
+
+        std::string functionExpression = "AVE(A)";
+        shared_ptr<XdmfArray> variableArray = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 10; ++i)
+        {
+                variableArray->pushBack(i);
+        }
+
+        std::map<std::string, shared_ptr<XdmfArray> > variableMap;
+        variableMap["A"] = variableArray;
+
+        shared_ptr<XdmfFunction> exampleFunction = XdmfFunction::New(functionExpression, variableMap);
+
+        //#initexpression end
+
+        //#setExpression begin
+
+        std::string newExpression = "SUM(A)";
+        exampleFunction->setExpression(newExpression);
+
+        //#setExpression end
+
+        //#getExpression begin
+
+        std::string exampleExpression = exampleFunction->getExpression();
+
+        //#getExpression end
+
+        //#insertVariable begin
+
+        shared_ptr<XdmfArray> secondVariableArray = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 10; ++i)
+        {
+                secondVariableArray->pushBack(i);
+        }
+
+        exampleFunction->insertVariable("B", secondVariableArray);
+
+        //#insertVariable end
+
+        //#getVariable begin
+
+        shared_ptr<XdmfArray> variableValue = exampleFunction->getVariable("B");
+
+        //#getVariable end
+
+        //#getVariableList begin
+
+        std::vector<std::string> exampleVarList = exampleFunction->getVariableList();
+
+        //#getVariableList end
+
+        //#removeVariable begin
+
+        exampleFunction->removeVariable("B");
+
+        //#removeVariable end
+
+        //#setConstructedType begin
+
+        shared_ptr<XdmfAttribute> typeAttribute = XdmfAttribute::New();
+
+        exampleFunction->setConstructedType(typeAttribute->getItemTag());
+
+        //#setConstructedType end
+
+        //#getConstructedType begin
+
+        std::string exampleType = exampleFunction->getConstructedType();
+
+        //#getConstructedType end
+
+        //#setConstructedProperties begin
+
+        shared_ptr<XdmfAttribute> propertyAttribute = XdmfAttribute::New();
+        exampleFunction->setConstructedProperties(propertyAttribute->getItemProperties());
+
+        //#setConstructedProperties end
+
+        //#getConstructedProperties begin
+
+        std::map<std::string, std::string> exampleProperties = exampleFunction->getConstructedProperties();
+
+        //#getConstructedProperties end
+
+        //#read begin
+
+        shared_ptr<XdmfArray> functionResult = exampleFunction->read();
+
+        //#read end
+
+        //#abs begin
+
+        shared_ptr<XdmfArray> toBeAbs = XdmfArray::New();
+        toBeAbs->pushBack<double>(-5.5);
+        std::vector<shared_ptr<XdmfArray> > absVector;
+        absVector.push_back(toBeAbs);
+        shared_ptr<XdmfArray> absResult = XdmfFunction::abs(absVector);
+        assert(absResult->getValuesString().compare("5.5") == 0);
+
+        //#abs end
+
+        //#arcsin begin
+
+        shared_ptr<XdmfArray> toBeArcsin = XdmfArray::New();
+        toBeArcsin->pushBack<double>(-0.5);
+        std::vector<shared_ptr<XdmfArray> > arcsinVector;
+        arcsinVector.push_back(toBeArcsin);
+        shared_ptr<XdmfArray> arcsinResult = XdmfFunction::arcsin(arcsinVector);
+        assert(arcsinResult->getValuesString().compare("-0.52359877559829893") == 0);
+
+        //#arcsin end
+
+        //#arccos begin
+
+        shared_ptr<XdmfArray> toBeArccos = XdmfArray::New();
+        toBeArccos->pushBack<double>(-0.5);
+        std::vector<shared_ptr<XdmfArray> > arccosVector;
+        arccosVector.push_back(toBeArccos);
+        shared_ptr<XdmfArray> arccosResult = XdmfFunction::arccos(arccosVector);
+        assert(arccosResult->getValuesString().compare("2.0943951023931957") == 0);
+
+        //#arccos end
+
+        //#cos begin
+
+        shared_ptr<XdmfArray> toBeCos = XdmfArray::New();
+        toBeCos->pushBack<double>(-0.5);
+        std::vector<shared_ptr<XdmfArray> > cosVector;
+        cosVector.push_back(toBeCos);
+        shared_ptr<XdmfArray> cosResult = XdmfFunction::cos(cosVector);
+        assert(cosResult->getValuesString().compare("0.87758256189037276") == 0);
+
+        //#cos end
+
+        //#sin begin
+
+        shared_ptr<XdmfArray> toBeSin = XdmfArray::New();
+        toBeSin->pushBack<double>(-0.5);
+        std::vector<shared_ptr<XdmfArray> > sinVector;
+        sinVector.push_back(toBeSin);
+        shared_ptr<XdmfArray> sinResult = XdmfFunction::sin(sinVector);
+        assert(sinResult->getValuesString().compare("-0.47942553860420301") == 0);
+
+        //#sin end
+
+        //#tan begin
+
+        shared_ptr<XdmfArray> toBeTan = XdmfArray::New();
+        toBeTan->pushBack<double>(-0.5);
+        std::vector<shared_ptr<XdmfArray> > tanVector;
+        tanVector.push_back(toBeTan);
+        shared_ptr<XdmfArray> tanResult = XdmfFunction::tan(tanVector);
+        assert(tanResult->getValuesString().compare("-0.54630248984379048") == 0);
+
+        //#tan end
+
+        //#sqrt begin
+
+        shared_ptr<XdmfArray> toBeSqrt = XdmfArray::New();
+        toBeSqrt->pushBack<double>(2);
+        std::vector<shared_ptr<XdmfArray> > sqrtVector;
+        sqrtVector.push_back(toBeSqrt);
+        shared_ptr<XdmfArray> sqrtResult = XdmfFunction::sqrt(sqrtVector);
+        assert(sqrtResult->getValuesString().compare("1.4142135623730951") == 0);
+
+        //#sqrt end
+
+        //#log begin
+
+        shared_ptr<XdmfArray> toBeLog = XdmfArray::New();
+        toBeLog->pushBack<double>(2);
+        shared_ptr<XdmfArray> logBase = XdmfArray::New();
+        logBase->pushBack<double>(4);
+        std::vector<shared_ptr<XdmfArray> > logVector;
+        logVector.push_back(toBeLog);
+        logVector.push_back(logBase);
+        shared_ptr<XdmfArray> logResult = XdmfFunction::log(logVector);
+        assert(logResult->getValuesString().compare("0.5") == 0);
+
+        //#log end
+
+        //#exp begin
+
+        shared_ptr<XdmfArray> powerBase = XdmfArray::New();
+        powerBase->pushBack<double>(-0.5);
+        shared_ptr<XdmfArray> powerFactor = XdmfArray::New();
+        powerFactor->pushBack<double>(2);
+        std::vector<shared_ptr<XdmfArray> > expVector;
+        expVector.push_back(powerBase);
+        expVector.push_back(powerFactor);
+        shared_ptr<XdmfArray> expResult = XdmfFunction::exponent(expVector);
+        assert(expResult->getValuesString().compare("0.25") == 0);
+
+        //#exp end
+
+        //#join begin
+
+        shared_ptr<XdmfArray> array1 = XdmfArray::New();
+        array1->pushBack<double>(-0.5);
+        shared_ptr<XdmfArray> array2 = XdmfArray::New();
+        array2->pushBack<double>(2);
+        std::vector<shared_ptr<XdmfArray> > joinVector;
+        joinVector.push_back(array1);
+        joinVector.push_back(array2);
+        shared_ptr<XdmfArray> joinResult = XdmfFunction::join(joinVector);
+        assert(joinResult->getValuesString().compare("-0.5 2") == 0);
+
+        //#join end
+
+        //#addition begin
+
+        shared_ptr<XdmfArray> addArray1 = XdmfArray::New();
+        addArray1->pushBack<double>(-0.5);
+        shared_ptr<XdmfArray> addArray2 = XdmfArray::New();
+        addArray2->pushBack<double>(2);
+        shared_ptr<XdmfArray> addResult = XdmfFunction::addition(addArray1, addArray2);
+        assert(addResult->getValuesString().compare("1.5") == 0);
+
+        //#addition end
+
+        //#division begin
+
+        shared_ptr<XdmfArray> divArray1 = XdmfArray::New();
+        divArray1->pushBack<double>(-0.5);
+        shared_ptr<XdmfArray> divArray2 = XdmfArray::New();
+        divArray2->pushBack<double>(2);
+        shared_ptr<XdmfArray> divResult = XdmfFunction::division(divArray1, divArray2);
+        assert(divResult->getValuesString().compare("-0.25") == 0);
+
+        //#division end
+
+        //#multiplication begin
+
+        shared_ptr<XdmfArray> mulArray1 = XdmfArray::New();
+        mulArray1->pushBack<double>(-0.5);
+        shared_ptr<XdmfArray> mulArray2 = XdmfArray::New();
+        mulArray2->pushBack<double>(2);
+        shared_ptr<XdmfArray> mulResult = XdmfFunction::multiplication(mulArray1, mulArray2);
+        assert(mulResult->getValuesString().compare("-1") == 0);
+
+        //#multiplication end
+
+        //#subtraction begin
+
+        shared_ptr<XdmfArray> subArray1 = XdmfArray::New();
+        subArray1->pushBack<double>(-0.5);
+        shared_ptr<XdmfArray> subArray2 = XdmfArray::New();
+        subArray2->pushBack<double>(2);
+        shared_ptr<XdmfArray> subResult = XdmfFunction::subtraction(subArray1, subArray2);
+        assert(subResult->getValuesString().compare("-2.5") == 0);
+
+        //#subtraction end
+
+        //#programend start
+
+        return 0;
+}
+
+//#programend end
+
+//#definefunction begin
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values)
+{
+        if (values[0]->getArrayType() == XdmfArrayType::String())
+        {
+                shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+                returnArray->pushBack(values[0]->getValue<std::string>(0));
+                return returnArray;
+        }
+        else
+        {
+                double maxVal = values[0]->getValue<double>(0);
+                for (int i = 0; i < values.size(); ++i)
+                {
+                        for (int j = 0; j < values[i]->getSize(); ++j)
+                        {
+                                if (maxVal < values[i]->getValue<double>(j))
+                                {
+                                        maxVal = values[i]->getValue<double>(j);
+                                }
+                        }
+                }
+                shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+                returnArray->pushBack(maxVal);
+                return returnArray;
+        }
+}
+
+//#definefunction end
+
+//#defineoperation begin
+
+shared_ptr<XdmfArray> prepend(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+        //joins into new array and returns it
+        shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+        returnArray->insert(0, val2, 0, val2->getSize(),  1, 1);
+        returnArray->insert(val2->getSize(), val1, 0, val1->getSize(), 1, 1);
+        return returnArray;
+}
+
+//#defineoperation end
diff --git a/examples/Cxx/ExampleXdmfGeometry.cpp b/examples/Cxx/ExampleXdmfGeometry.cpp
new file mode 100644
index 0000000..4733a2c
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfGeometry.cpp
@@ -0,0 +1,49 @@
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfGeometry> exampleGeometry = XdmfGeometry::New();
+
+        //#initialization end
+
+        //Assuming that exampleGeometry is a shared pointer to a XdmfGeometry object
+
+        //#setType begin
+
+        exampleGeometry->setType(XdmfGeometryType::XYZ());
+
+        //#setType end
+
+        //#getType begin
+
+        shared_ptr<const XdmfGeometryType> exampleType = exampleGeometry->getType();
+
+        //#getType end
+
+        //#getNumberPoints begin
+
+        unsigned int numPoints = exampleGeometry->getNumberPoints();
+
+        //#getNumberPoints end
+
+        //#setOrigin begin
+
+        double newXval = 5.0;
+        double newYval = 10.0;
+        double newZval = 5.5;
+
+        exampleGeometry->setOrigin(newXval, newYval, newZval);
+
+        //#setOrigin end
+
+        //#getOrigin begin
+
+        std::vector<double> exampleGeometry->getOrigin();
+
+        //#getOrigin end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfGeometryType.cpp b/examples/Cxx/ExampleXdmfGeometryType.cpp
new file mode 100644
index 0000000..a222782
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfGeometryType.cpp
@@ -0,0 +1,33 @@
+#include "XdmfDomain.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfGeometry> exampleGeometry = XdmfGeometry::New();
+
+        //#initialization end
+
+        //#getType begin
+
+        if (exampleGeometry->getType() == XdmfGeometry::XYZ())
+        {
+                //do whatever is to be done if the geometry is xyz
+        }
+
+        //#getType end
+
+        //#getDimensions begin
+
+        unsigned int exampleDimensions = XdmfGeometryType::XYZ()->getDimensions();
+
+        //#getDimensions end
+
+        //#getName begin
+
+        std::string exampleName = XdmfGeometryType::XYZ()->getName();
+
+        //#getName end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfGraph.cpp b/examples/Cxx/ExampleXdmfGraph.cpp
new file mode 100644
index 0000000..e6ee3f1
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfGraph.cpp
@@ -0,0 +1,12 @@
+#include "XdmfGraph.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfGraph> exampleGraph = XdmfGraph::New();
+
+        //#initialization end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfGrid.cpp b/examples/Cxx/ExampleXdmfGrid.cpp
new file mode 100644
index 0000000..e61a13d
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfGrid.cpp
@@ -0,0 +1,85 @@
+#include "XdmfDomain.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfUnstructuredGrid> exampleGrid = XdmfUnstructuredGrid::New();
+
+        //Using an unstructured grid since XdmfGrid is an abstract class
+
+        //#initialization end
+        
+        //#setName begin
+
+        std::string newName = "New Name";
+        exampleGrid->setName(newName);
+
+        //#setName end
+
+        //#setTime begin
+
+        shared_ptr<XdmfTime> newTime = XdmfTime::New(20.0);
+        exampleGrid->setTime(newTime);
+
+        //#setTime end
+
+        //#getTime begin
+
+        shared_ptr< XdmfTime> exampleTime = exampleGrid->getTime();
+
+        //#getTime end
+
+        //#getTimeconst begin
+
+        shared_ptr<const XdmfTime> exampleTimeConst = exampleGrid->getTime();
+
+        //#getTimeconst end
+
+        //#getName begin
+
+        std::string exampleName = exampleGrid->getName();
+
+        //#getName end
+
+        //#getGeometry begin
+
+        shared_ptr<const XdmfGeometry> exampleGeometry = exampleGrid->getGeometry();
+
+        //#getGeometry end
+
+        //#getTopology begin
+
+        shared_ptr<const XdmfTopology> exampleTopology = exampleGrid->getTopology();
+
+        //#getTopology end
+
+        //#setGridController begin
+
+        shared_ptr<XdmfGridController> newGridController = XdmfGridController::New("gridFile.xmf", "/Xdmf/Domain/Grid[1]");
+
+        exampleGrid->setGridController(gridController);
+
+        //#setGridController end
+
+        //#getGridController begin
+
+        shared_ptr<XdmfGridController> exampleGridController = exampleGrid->getGridController();
+
+        //#getGridController end
+
+        //#read begin
+
+        exampleGrid->read();
+
+        //#read end
+
+        //#release begin
+
+        exampleGrid->release();
+
+        //#release end
+
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfGridCollection.cpp b/examples/Cxx/ExampleXdmfGridCollection.cpp
new file mode 100644
index 0000000..fe349c9
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfGridCollection.cpp
@@ -0,0 +1,44 @@
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfInformation.hpp"
+
+int main(int, char **)
+{
+        //Assuming that exampleCollection is a shared pointer to an XdmfGridCollection object
+
+        //#initalization begin
+
+        shared_ptr<XdmfGridCollection> exampleCollection = XdmfGridCollection::New();
+
+        //#initialization end
+
+        //#setType begin
+
+        exampleCollection->setType(XdmfGridCollectionType::Temporal());
+
+        //#setType end
+
+        //#getType begin
+
+        shared_ptr<const XdmfGridCollectionType> exampleType = exampleCollection->getType();
+
+        if (exampleType == XdmfGridCollectionType::Temporal())
+        {
+                //do whatever is to be done if the grid collection is temporal
+        }
+
+        //#getType end
+
+        //#insert begin
+
+        shared_ptr<XdmfInformation> exampleInformation = XdmfInformation::New();
+        std::string newKey = "New Key";
+        std::string newValue = "New Value";
+        exampleInformation->setKey(newKey);
+        exampleInformation->setValue(newValue);
+        exampleCollection->insert(exampleInformation);
+
+        //#insert end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfHDF5Controller.cpp b/examples/Cxx/ExampleXdmfHDF5Controller.cpp
new file mode 100644
index 0000000..9ee0dd7
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfHDF5Controller.cpp
@@ -0,0 +1,84 @@
+#include "XdmfHDF5Controller.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "File path to hdf5 file goes here";
+        std::string newSetPath = "path to the set goes here";
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readStarts;
+        //Three dimensions, all starting at index 0
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        std::vector<unsigned int> readStrides;
+        //Three dimensions, no skipping between reads
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        std::vector<unsigned int> readDataSize;
+        //Three dimensions, each with a maximum of 20 values
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        shared_ptr<XdmfHDF5Controller> exampleController = XdmfHDF5Controller::New(
+                newPath,
+                newSetPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize);
+
+        //#initialization end
+
+        //#getDataSetPath begin
+
+        std::string exampleSetPath = exampleController->getDataSetPath();
+
+        //#getDataSetPath end
+
+        //#getDataspaceDimensions begin
+
+        std::vector<unsigned int> exampleDataspaceDimensions = exampleController->getDataspaceDimensions();
+
+        //#getDataspaceDimensions end
+
+        //#getStart begin
+
+        std::vector<unsigned int> exampleStart = exampleController->getStart();
+
+        //#getStart end
+
+        //#getStride begin
+
+        std::vector<unsigned int> exampleStride = exampleController->getStride();
+
+        //#getStride end
+
+        //#setMaxOpenedFiles begin
+
+        XdmfHDF5Controller::setMaxOpenedFiles(2);
+
+        //#setMaxOpenedFiles end
+
+        //#getMaxOpenedFiles begin
+
+        unsigned int maxNumOpened = XdmfHDF5Controller::getMaxOpenedFiles();
+
+        //#getMaxOpenedFiles end
+
+        //#closeFiles begin
+
+        XdmfHDF5Controller::closeFiles();
+
+        //#closeFiles end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfHDF5Writer.cpp b/examples/Cxx/ExampleXdmfHDF5Writer.cpp
new file mode 100644
index 0000000..b73966c
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfHDF5Writer.cpp
@@ -0,0 +1,57 @@
+#include "XdmfHDF5Writer.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "Your file path goes here";
+        bool replaceOrig = true;
+        shared_ptr<XdmfHDF5Writer> exampleWriter = XdmfHDF5Writer::New(newPath, replaceOrig);
+
+        //#initialization end
+
+        //#setChunkSize begin
+
+        int newChunk = 10;
+        //creates blocks in sets of 10 slots
+
+        exampleWriter->setChunkSize(newChunk);
+
+        //#setChunkSize end
+
+        //#getChunkSize begin
+
+        int exampleChunk = exampleWriter->getChunkSize();
+
+        //#getChunkSize end
+
+        //#setUseDeflate
+
+        bool useDeflate = true;
+
+        exampleWriter->setUseDeflate(useDeflate);
+
+        //#setUseDeflate
+
+        //#getUseDeflate
+
+        bool isUsingDeflate = exampleWriter->getUseDeflate();
+
+        //#getUseDeflate
+
+        //#setDeflateFactor
+
+        int newDeflateFactor = 6;
+
+        exampleWriter->setDeflateFactor(newDeflateFactor);
+
+        //#setDeflateFactor
+
+        //#getDeflateFactor
+
+        int currentDeflateFactor = exampleWriter->getDeflateFactor();
+
+        //#getDeflateFactor
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfHeavyDataController.cpp b/examples/Cxx/ExampleXdmfHeavyDataController.cpp
new file mode 100644
index 0000000..09ce96b
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfHeavyDataController.cpp
@@ -0,0 +1,110 @@
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "File path to hdf5 file goes here";
+        std::string newSetPath = "path to the set goes here";
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readStarts;
+        //Three dimensions, all starting at index 0
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        std::vector<unsigned int> readStrides;
+        //Three dimensions, no skipping between reads
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        std::vector<unsigned int> readDataSize;
+        //Three dimensions, 10 values in each
+        readDataSize.push_back(10);
+        readDataSize.push_back(10);
+        readDataSize.push_back(10);
+        shared_ptr<XdmfHDF5Controller> exampleController = XdmfHDF5Controller::New(
+                newPath,
+                newSetPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize);
+
+        //Using XdmfHDF5Controller since XdmfHeavyDataController is an abstract class
+
+        //#initialization end
+
+        //#getDimensions begin
+
+        std::vector<unsigned int>  exampleDimensions = exampleController->getDimensions();
+
+        //#getDimensions end
+
+        //#getFilePath begin
+
+        std::string exampleFilePath = exampleController->getFilePath();
+
+        //#getFilePath end
+
+        //#getDescriptor begin
+
+        std::string exampleDescriptor = exampleController->getDescriptor();
+
+        //#getDescriptor end
+
+        //#getName begin
+
+        std::string exampleName = exampleController->getName();
+
+        //#getName end
+
+        //#getSize begin
+
+        unsigned int exampleSize = exampleController->getSize();
+
+        //#getSize end
+
+        //#getDataspaceSize begin
+
+        unsigned int exampleDataspaceSize = exampleController->getDataspaceSize();
+
+        //#getDataspaceSize end
+
+        //#getType begin
+
+        shared_ptr<const XdmfArrayType> exampleType = exampleController->getType();
+
+        //#getType end
+
+        //#read begin
+
+        shared_ptr<XdmfArray> exampleArray = XdmfArray::New();
+        exampleController->read(exampleArray);
+        //exampleArray now holds the data that exampleController holds.
+
+        //#read end
+
+        //#setArrayOffset begin
+
+        unsigned int newArrayOffset = 5;//default is 0
+
+        exampleController->setArrayOffset(newArrayOffset);
+
+        //#setArrayOffset end
+
+        //#getArrayOffset begin
+
+        unsigned int exampleOffset = exampleController->getArrayOffset();
+
+        //#getArrayOffset end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfHeavyDataWriter.cpp b/examples/Cxx/ExampleXdmfHeavyDataWriter.cpp
new file mode 100644
index 0000000..3948b4f
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfHeavyDataWriter.cpp
@@ -0,0 +1,127 @@
+#include "XdmfDomain.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "Your file path goes here";
+        bool replaceOrig = true;
+        shared_ptr<XdmfHDF5Writer> exampleWriter = XdmfHDF5Writer::New(newPath, replaceOrig);
+
+        //using an XdmfHDF5Writer because XdmfHeavyWriter is abstract
+
+        //#initialization end
+
+        //#openFile begin
+
+        exampleWriter->openFile();
+
+        //#openFile end
+
+        //#closeFile begin
+
+        exampleWriter->closeFile();
+
+        //#closeFile end
+
+        //#getFilePath begin
+
+        std::string examplePath = exampleWriter->getFilePath();
+
+        //#getFilePath end
+
+        //#getMode begin
+
+        XdmfHeavyDataWriter::Mode exampleMode = XdmfHeavyDataWriter::Default;
+
+        if (exampleWriter->getMode() == exampleMode)
+        {
+                //Do whatever is to be done if the mode is default
+        }
+
+        //#getMode end
+
+        //#getReleaseData begin
+
+        bool testRelease = exampleWriter->getReleaseData();
+
+        //#getReleaseData end
+
+        //#setMode begin
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Default);
+
+        //#setMode end
+
+        //#setReleaseData begin
+
+        exampleWriter->setReleaseData(true);
+        //Sets the writer to release data after writing
+
+        //#setReleaseData end
+
+        //#setFileSizeLimit begin
+
+        int newFileSizeLimit = 10;
+        //limit of 10 MB
+
+        exampleWriter->setFileSizeLimit(newFileSizeLimit);
+
+        //#setFileSizeLimit end
+
+        //#getFileSizeLimit begin
+
+        int exampleLimit = exampleWriter->getFileSizeLimit();
+
+        //#getFileSizeLimit end
+
+        //#getFileOverhead begin
+
+        unsigned int exampleOverhead = exampleWriter->getFileOverhead();
+
+        //#getFileOverhead end
+
+        //#setAllowSetSplitting begin
+
+        bool newAllow = true;
+        //false is default
+
+        exampleWriter->setAllowSetSplitting(newAllow);
+
+        //#setAllowSetSplitting end
+
+        //#getAllowSetSplitting begin
+
+        bool exampleAllowSplitting = exampleWriter->getAllowSetSplitting();
+
+        //#getAllowSetSplitting end
+
+        //#setFileIndex begin
+
+        int newFileIndex = 0;
+        //0 resets to no appended index
+
+        exampleWriter->setFileIndex(newFileIndex);
+
+        //#setFileIndex end
+
+        //#getFileIndex begin
+
+        int exampleIndex = exampleWriter->getFileIndex();
+
+        //#getFileIndex end
+
+        //#visit begin
+
+        shared_ptr<XdmfArray> exampleArray = XdmfArray::New();
+        exampleArray->pushBack(1);
+        exampleArray->pushBack(2);
+        exampleArray->pushBack(3);
+        exampleArray->pushBack(4);
+        exampleArray->pushBack(5);
+        exampleWriter->visit(exampleArray, exampleWriter);
+
+        //#visit end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfInformation.cpp b/examples/Cxx/ExampleXdmfInformation.cpp
new file mode 100644
index 0000000..ec616b9
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfInformation.cpp
@@ -0,0 +1,51 @@
+#include "XdmfInformation.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfInformation> exampleInformation = XdmfInformation::New();
+        //Then the key and value must be set seperately
+
+        exampleInformation->setKey("Your Key String");
+        exampleInformation->setValue("Your Value String");
+
+        //#initialization end
+
+        //#initializationfull begin
+
+        shared_ptr<XdmfInformation> infoExample = XdmfInformation::New("Your Key String", "Your Value String");
+        //This code creates an information with the key "Your Key String" and the value "Your Value String"
+
+        //#initializationfull end
+
+        //#getKey begin
+
+        std::string storedKey = infoExample->getKey();
+        //"Your Key String" is now stored in the variable storedKey
+
+        //#getKey end
+
+        //#getValue begin
+
+        std::string storedValue = infoExample->getValue();
+        //"Your Value String" is now stored in the variable storedValue
+
+        //#getValue end
+
+        //#setKey begin
+
+        infoExample->setKey("Your New Key");
+        //"Your New Key" is now the key for infoExample
+
+        //#setKey end
+
+        //#setValue begin
+
+        infoExample->setValue("Your New Value");
+        //"Your New Value" is now the value for infoExample
+
+        //#setValue end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfItem.cpp b/examples/Cxx/ExampleXdmfItem.cpp
new file mode 100644
index 0000000..a3615de
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfItem.cpp
@@ -0,0 +1,60 @@
+#include "XdmfInformation.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfWriter.hpp"
+
+int main(int, char **)
+{
+        //Assume that exampleItem is a shared pointer to the ParentClass object
+        //Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class
+
+        shared_ptr<XdmfInformation> exampleItem = XdmfInformation::New("Parent", "This is a parent information");
+        shared_ptr<XdmfInformation> addChild = XdmfInformation::New("Child", "This is a child information");
+
+        exampleItem->insert(addChild);
+
+        unsigned int getIndex = 0;
+        shared_ptr<XdmfInformation> exampleChild = exampleItem->getInformation(getIndex);
+        shared_ptr<const XdmfInformation> exampleChildConst = exampleItem->getInformation(getIndex);
+
+        std::string findingInfo = "Find this";
+        shared_ptr<XdmfInformation> exampleStringChild = exampleItem->getInformation(findingInfo);
+        shared_ptr<const XdmfInformation> exampleStringChildConst = exampleItem->getInformation(findingInfo);
+
+        unsigned int exampleSize = exampleItem->getNumberInformations();
+
+        unsigned int removeIndex = 0;
+        exampleItem->removeInformation(removeIndex);
+
+        std::string removeInfo = "Remove this";
+        exampleItem->removeInformation(removeInfo);
+
+        //#initialization begin
+
+        //Using a shared pointer to an XdmfDomain object as an example
+
+        shared_ptr<XdmfDomain> exampleDomain = XdmfDomain::New();
+
+        //#initialization end
+
+        //#getItemTag begin
+
+        std::string exampleTag = exampleDomain->getItemTag();
+
+        //#getItemTag end
+
+        //#getItemProperties begin
+
+        std::map<std::string, std::string> propertyMap = exampleDomain->getItemProperties();
+
+        //#getItemProperties end
+
+        //#traverse begin
+
+        std::string writePath = "file path here";
+        shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New(writepath);
+        exampleDomain->traverse(exampleWriter);
+
+        //#traverse end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfItemFactory.cpp b/examples/Cxx/ExampleXdmfItemFactory.cpp
new file mode 100644
index 0000000..34ddca4
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfItemFactory.cpp
@@ -0,0 +1,12 @@
+#include "XdmfItemFactory.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfItemFactory> exampleFactory = XdmfItemFactory::New();
+
+        //#initialization end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfItemProperty.cpp b/examples/Cxx/ExampleXdmfItemProperty.cpp
new file mode 100644
index 0000000..990fa98
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfItemProperty.cpp
@@ -0,0 +1,14 @@
+#include "XdmfArrayType.hpp"
+
+int main(int, char **)
+{
+        //#getProperties begin
+
+        //Using XdmfArrayType::Int32() as an example
+        std::map<std::string, std::string> propertyMap;
+        XdmfArrayType::Int32()->getProperties(propertyMap);
+
+        //#getProperties end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfMap.cpp b/examples/Cxx/ExampleXdmfMap.cpp
new file mode 100644
index 0000000..219c0a2
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfMap.cpp
@@ -0,0 +1,228 @@
+#include "XdmfMap.hpp"
+#include "XdmfAttribute.h[["
+#include "XdmfHDF5Controller.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfMap> exampleMap = XdmfMap::New();
+
+        //#initialization end
+
+        //#initializationnode begin
+
+        std::vector<shared_ptr<XdmfAttribute> > holdGlobalNodes;
+        shared_ptr<XdmfAttribute> nodeAttribute = XdmfAttribute::New();
+        //The globalNodeIDs are placed into the attribute
+        //The index they are at in the attribute corresponds to their localNodeID
+        nodeAttribute->insert(0, 1);
+        nodeAttribute->insert(1, 5);
+        nodeAttribute->insert(2, 8);
+        nodeAttribute->insert(3, 9);
+        nodeAttribute->insert(4, 4);
+        holdGlobalNodes.push_back(nodeAttribute);
+        //The Attribute is then added to the vector
+        //The index that the Attribute has in the vector corresponds to a task id
+        //Using this method add all the required nodes
+        nodeAttribute = XdmfAttribute::New();
+        nodeAttribute->insert(0, 2);
+        nodeAttribute->insert(1, 6);
+        nodeAttribute->insert(2, 9);
+        nodeAttribute->insert(3, 0);
+        nodeAttribute->insert(4, 5);
+        holdGlobalNodes.push_back(nodeAttribute);
+        std::vector<shared_ptr<XdmfMap> > exampleMapVector = XdmfMap::New(holdGlobalNodes);
+        //returns a vector of maps that holds the equivalencies for the nodes provided
+        //for example if Attribute 1 had globalNodeID 3 at localNodeID 2
+        //and Attribute 3 had globalNodeID 3 at localNodeID 5
+        //then map 1 would have an entry of (3, 5, 2)
+        //and map 3 would have an entry of (1, 2, 5)
+        //The entries are formatted (remoteTaskID, remoteLocalNodeID, localNodeID)
+
+        //#initializationnode end
+
+        //#setMap begin
+
+        std::map<int, std::map<int, std::set<int> > > taskMap;
+        std::map<int, std::set<int> > nodeMap;
+        std::set<int> remoteIDset;
+        remoteIDset.insert(3);
+        remoteIDset.insert(6);
+        remoteIDset.insert(8);
+        nodeMap.insert(pair<int, std::set<int> >(2, remoteIDset));
+        remoteIDset.clear();
+        remoteIDset.insert(3);
+        nodeMap.insert(pair<int, std::set<int> >(3, remoteIDset));
+        remoteIDset.clear();
+        remoteIDset.insert(7);
+        remoteIDset.insert(9);
+        nodeMap.insert(pair<int, std::set<int> >(4, remoteIDset));
+        //First create a std::map<int, std::set<int> >
+        taskMap.insert(pair<int, std::map<int, std::set<int> > >(1, nodeMap));
+        //Then insert it into a std::map<int, std::map<int, std::set<int> > >
+        nodeMap.clear();
+        //Repeat as many times as necessary.
+        remoteIDset.clear();
+        remoteIDset.insert(3);
+        remoteIDset.insert(6);
+        remoteIDset.insert(8);
+        nodeMap.insert(pair<int, std::set<int> >(5, remoteIDset));
+        remoteIDset.clear();
+        remoteIDset.insert(3);
+        nodeMap.insert(pair<int, std::set<int> >(7, remoteIDset));
+        remoteIDset.clear();
+        remoteIDset.insert(7);
+        remoteIDset.insert(9);
+        nodeMap.insert(pair<int, std::set<int> >(9, remoteIDset));
+        taskMap.insert(pair<int, std::map<int, std::set<int> > >(2, nodeMap));
+        //then the result is set to the XdmfMap
+        exampleMap->setMap(taskMap);
+        //(1, 2, 3)
+        //(1, 2, 6)
+        //(1, 2, 8)
+        //(1, 3, 3)
+        //(1, 4, 7)
+        //(1, 4, 9)
+        //(2, 5, 3)
+        //(2, 5, 6)
+        //(2, 5, 8)
+        //(2, 7, 3)
+        //(2, 9, 7)
+        //(2, 9, 9)
+        //Are now in the XdmfMap
+
+        //#setMap end
+
+
+        //#inserttuple begin
+
+        unsigned int newRemoteTaskID = 4;
+        unsigned int newLocalNodeID = 7;
+        unsigned int newRemoteLocalNodeID = 3;
+        exampleMap->insert(newRemoteTaskID, newLocalNodeID, newRemoteLocalNodeID);
+        //This inserts an entry of (4, 7, 3) into the map
+
+        //#inserttuple end
+
+
+        //#setName begin
+
+        std::string newName = "New Name";
+        exampleMap->setName(newName);
+
+        //#setName end
+
+        //#getMap begin
+
+        //Assuming that exampleMap is a shared pointer to an XdmfMap object filled with the following tuples
+        //(1, 1, 9)
+        //(1, 2, 8)
+        //(2, 3, 7)
+        //(2, 4, 6)
+        //(3, 5, 5)
+        //(3, 6, 4)
+        std::map<int, std::map<int, std::set<int> > > taskIDMap = exampleMap->getMap();
+        //taskIDMap now contains the same tuples as exampleMap
+        std::map<int, std::map<int, std::set<int> > >::iterator taskWalker = taskIDMap.begin();
+        int taskIDValue = (*taskWalker).first;
+        //taskIDValue is now equal to 1, because that is the first taskID listed
+        std::map<int, std::set<int> > nodeIDMap = taskIDMap[1];
+        //nodeIDMap now contains the following tuples because it retrieved the tuples associated with taskID 1
+        //(1, 9)
+        //(2, 8)
+        std::map<int, std::set<int> >::iterator mapWalker = nodeIDMap.begin();
+        int localNodeValue = (*mapWalker).first;
+        //localNodeValue is now equal to 1, because it is the first entry in the first tuple in the set
+        std::set<int> remoteNodeSet = exampleMap[1];
+        //remoteNodeSet now contains all remoteLocalNodeIDs for taskID 1 and LocalNode 1
+        //in this case remoteNodeSet contains (9)
+        std::set<int>::iterator setWalker = remoteNodeSet.begin();
+        int remoteNodeValue = (*setWalker);
+        //remoteNodeValue now equals 9
+
+        //#getMap end
+
+
+        //#getRemoteNodeIds begin
+
+        //Assuming that exampleMap is a shared pointer to an XdmfMap object filled with the following tuples
+        //(1, 1, 9)
+        //(1, 2, 8)
+        //(2, 3, 7)
+        //(2, 4, 6)
+        //(3, 5, 5)
+        //(3, 6, 4)
+        std::map<int, std::set<int> > nodeIDMap = exampleMap->getRemoteNodeIds(1);
+        //nodeIDMap now contains the following tuples because it retrieved the tuples associated with taskID 1
+        //(1, 9)
+        //(2, 8)
+        std::map<int, std::set<int> >::iterator mapWalker = nodeIDMap.begin();
+        int localNodeValue = (*mapWalker).first;
+        //localNodeValue is now equal to 1, because it is the first entry in the first tuple in the set
+        std::set<int> remoteNodeSet = exampleMap[1];
+        //remoteNodeSet now contains all remoteLocalNodeIDs for taskID 1 and LocalNode 1
+        //in this case remoteNodeSet contains (9)
+        std::set<int>::iterator setWalker = remoteNodeSet.begin();
+        int remoteNodeValue = (*setWalker);
+        //remoteNodeValue now equals 9
+
+        //#getRemoteNodeIds end
+
+        //#getName begin
+
+        std::string exampleName = exampleMap->getName();
+
+        //#getName end
+
+        //#isInitialized begin
+
+        if (!exampleMap->isInitialized())
+        {
+                exampleMap->read();
+        }
+
+        //#isInitialized end
+
+        //#setHeavyDataControllers begin
+
+        std::string hdf5FilePath = "The HDF5 file path goes here";
+        std::string hdf5SetPath = "The HDF5 set path goes here";
+        int startIndex = 0; //start at the beginning
+        int readStride = 1; //read all values
+        int readNumber = 10; //read 10 values
+        int readDataSize = 10;//maximum data size
+        std::vector<int> startVector;
+        startVector.push_back(startIndex);
+        std::vector<int> strideVector;
+        strideVector.push_back(readStride);
+        std::vector<int> countVector;
+        countVector.push_back(readNumber);
+        std::vector<int> dataSizeVector;
+        dataSizeVector.push_back(readDataSize);
+        shared_ptr<XdmfHDF5Controller> newRemoteTaskController = XdmfHDF5Controller::New(
+                hdf5FilePath, hdf5SetPath, XdmfArrayType::Int32(),
+                startVector, strideVector, countVector, dataSizeVector);
+        hdf5FilePath = "The HDF5 file path for the local nodes goes here";
+        hdf5SetPath = "The HDF5 set path for the local nodes goes here";
+        shared_ptr<XdmfHDF5Controller> newLocalNodeController = XdmfHDF5Controller::New(
+                hdf5FilePath, hdf5SetPath, XdmfArrayType::Int32(),
+                startVector, strideVector, countVector, dataSizeVector);
+        hdf5FilePath = "The HDF5 file path for the remote local nodes goes here";
+        hdf5SetPath = "The HDF5 set path for the remote local nodes goes here";
+        shared_ptr<XdmfHDF5Controller> newRemoteLocalNodeController = XdmfHDF5Controller::New(
+                hdf5FilePath, hdf5SetPath, XdmfArrayType::Int32(),
+                startVector, strideVector, countVector, dataSizeVector);
+        shared_ptr<XdmfMap> exampleMap = XdmfMap::New();
+        exampleMap->setHeavyDataControllers(newRemoteTaskController, newLocalNodeController, newRemoteLocalNodeController);
+
+        //#setHeavyDataControllers end
+
+        //#release begin
+
+        exampleMap->release();
+
+        //#release end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfPlaceholder.cpp b/examples/Cxx/ExampleXdmfPlaceholder.cpp
new file mode 100644
index 0000000..a1fb250
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfPlaceholder.cpp
@@ -0,0 +1,40 @@
+#include "XdmfPlaceholder.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "Dummy File Path";
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readStarts;
+        //Three dimensions, all starting at index 0
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        std::vector<unsigned int> readStrides;
+        //Three dimensions, no skipping between reads
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        std::vector<unsigned int> readDataSize;
+        //Three dimensions, each with a maximum of 20 values
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        shared_ptr<XdmfPlaceholder> exampleController = XdmfPlaceholder::New(
+                newPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize);
+
+        //#initialization end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfRead.cpp b/examples/Cxx/ExampleXdmfRead.cpp
new file mode 100644
index 0000000..b2fec36
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfRead.cpp
@@ -0,0 +1,676 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "string.h"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+        printf("Program Started\n");
+        shared_ptr<XdmfReader> exampleReader = XdmfReader::New();
+
+        /*
+        This is assuming that the read item is an XdmfDomain object
+        */
+        shared_ptr<XdmfDomain> primaryDomain = shared_dynamic_cast<XdmfDomain>(exampleReader->read("testoutput.xmf"));
+        //shared_ptr<XdmfDomain> primaryDomain = shared_dynamic_cast<XdmfDomain>(exampleReader->read("editedtestoutput.xmf"));
+        shared_ptr<XdmfInformation> outputInformation = primaryDomain->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("The Domain's tag is: %s\n", primaryDomain->getItemTag().c_str());
+
+        shared_ptr<XdmfGridCollection> gridHolder = primaryDomain->getGridCollection(0);
+
+        printf("The Grid Collection's tag is: %s\n", gridHolder->getItemTag().c_str());
+        printf("The Grid Collection's name is: %s\n", gridHolder->getName().c_str());
+        outputInformation = gridHolder->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+
+        std::map<std::string, std::string>::iterator outputwalker = gridHolder->getItemProperties().begin();
+        for (;outputwalker!=gridHolder->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+ 
+        if (gridHolder->getType() == XdmfGridCollectionType::Spatial())
+        {
+                printf("This is a spatial grid collection\n");
+        }
+        else
+        {
+                printf("This is not a spatial grid collection\n");
+        }
+
+
+        //loop controlling integers
+        int i = 0;
+        int j = 0;
+        int k = 0;
+        int m = 0;
+        int task;
+        int node;
+        int remote;
+        std::string blankstring = "";
+        char* outstring = strdup(blankstring.c_str());
+        shared_ptr<XdmfMap> readMap;
+        std::map<int, std::map<int, std::set<int> > > taskIDMap;
+        std::map<int, std::map<int, std::set<int> > >::iterator taskWalker;
+        std::map<int, std::set<int> > nodeIDMap;
+        std::map<int, std::set<int> >::iterator nodeWalker;
+        std::set<int> remoteIDset;
+        std::set<int>::iterator remoteWalker;
+
+        for (i=0; i<gridHolder->getNumberMaps(); i++)
+        {
+                readMap = gridHolder->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+
+        printf("Unstructured Grid\n");
+        shared_ptr<XdmfUnstructuredGrid> ungrid = gridHolder->getUnstructuredGrid(0);
+        printf("The Unstructured Grid's tag is: %s\n", ungrid->getItemTag().c_str());
+        printf("The Unstructured Grid's name is: %s\n", ungrid->getName().c_str());
+
+        outputwalker = ungrid->getItemProperties().begin();
+        for (;outputwalker!=ungrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+
+        printf("The Unstructured Grid's time is: %f\n", ungrid->getTime()->getValue());
+        i=0;
+        for (i=0; i<ungrid->getNumberMaps(); i++)
+        {
+                readMap = ungrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+
+        shared_ptr<XdmfSet> readSet;
+        shared_ptr<XdmfAttribute> readAttribute;
+        for (i=0; i < ungrid->getNumberSets(); i++)
+        {
+                readSet = ungrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node\n");
+                }
+                else
+                {
+                        printf("This set is not a node\n");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar\n");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node\n");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < ungrid->getNumberAttributes(); i++)
+        {
+                readAttribute = ungrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+
+        printf("Unstructured Topology\n");
+        shared_ptr<XdmfTopology> untopology = ungrid->getTopology();
+        if (!untopology->isInitialized())
+        {
+                untopology->read();
+        }
+        printf("The topology's tag: %s\n", untopology->getItemTag().c_str());
+        if (untopology->getType() == XdmfTopologyType::Hexahedron())
+        {
+                printf("This topology is a hexahedron\n");
+        }
+        else
+        {
+                printf("This topology is not a hexahedron\n");
+        }
+        printf("Contains %d elements\n", untopology->getNumberElements());
+        printf("Contains the values: %s\n", untopology->getValuesString().c_str());
+
+        printf("Unstructured Geometry\n");
+        shared_ptr<XdmfGeometry> ungeometry = ungrid->getGeometry();
+        if (!ungeometry->isInitialized())
+        {
+                ungeometry->read();
+        }
+        printf("The geometry's tag: %s\n", ungeometry->getItemTag().c_str());
+        if (ungeometry->getType() == XdmfGeometryType::XYZ())
+        {
+                printf("This geometry is XYZ\n");
+        }
+        else
+        {
+                printf("This geometry is not XYZ\n");
+        }
+        outputInformation = ungeometry->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("Contains %d points\n", ungeometry->getNumberPoints());
+        printf("Contains the values: %s\n", ungeometry->getValuesString().c_str());
+
+
+
+
+
+        printf("Curvilinear Grid\n");
+        shared_ptr<XdmfCurvilinearGrid> curvgrid = gridHolder->getCurvilinearGrid(0);
+        printf("The Curvilinear Grid's tag is: %s\n", curvgrid->getItemTag().c_str());
+        printf("The Curvilinear Grid's name is: %s\n", curvgrid->getName().c_str());
+        outputwalker = curvgrid->getItemProperties().begin();
+        for (;outputwalker!=curvgrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+        outputInformation = curvgrid->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("The Curvilinear Grid's time is: %f\n", curvgrid->getTime()->getValue());
+        for (i=0; i<curvgrid->getNumberMaps(); i++)
+        {
+                readMap = curvgrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+        for (i=0; i < curvgrid->getNumberSets(); i++)
+        {
+                readSet = curvgrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node\n");
+                }
+                else
+                {
+                        printf("This set is not a node\n");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar\n");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node\n");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < curvgrid->getNumberAttributes(); i++)
+        {
+                readAttribute = curvgrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+
+        printf("Curvilinear Dimensions\n");
+        shared_ptr<XdmfArray> curvdimensions = curvgrid->getDimensions();
+        if (!curvdimensions->isInitialized())
+        {
+                curvdimensions->read();
+        }
+        printf("The dimensions' tag: %s\n", curvdimensions->getItemTag().c_str());
+        printf("Contains the values: %s\n", curvdimensions->getValuesString().c_str());
+
+        printf("Curvilinear Geometry\n");
+        shared_ptr<XdmfGeometry> curvgeometry = curvgrid->getGeometry();
+        if (!curvgeometry->isInitialized())
+        {
+                curvgeometry->read();
+        }
+        printf("The geometry's tag: %s\n", curvgeometry->getItemTag().c_str());
+        if (curvgeometry->getType() == XdmfGeometryType::XYZ())
+        {
+                printf("This geometry is XYZ\n");
+        }
+        else
+        {
+                printf("This geometry is not XYZ\n");
+        }
+        outputInformation = curvgeometry->getInformation(0);
+        printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+        printf("Contains %d points\n", curvgeometry->getNumberPoints());
+        printf("Contains the values: %s\n", curvgeometry->getValuesString().c_str());
+
+
+        printf("Rectilinear Grid\n");
+        shared_ptr<XdmfRectilinearGrid> rectgrid = gridHolder->getRectilinearGrid(0);
+        printf("The Rectilinear Grid's tag is: %s\n", rectgrid->getItemTag().c_str());
+        printf("The Rectilinear Grid's name is: %s\n", rectgrid->getName().c_str());
+        printf("The Rectilinear Grid's time is: %f\n", rectgrid->getTime()->getValue());
+
+        outputwalker = rectgrid->getItemProperties().begin();
+        for (; outputwalker!=rectgrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+
+        for (i=0; i<rectgrid->getNumberMaps(); i++)
+        {
+                readMap = rectgrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+        for (i=0; i < rectgrid->getNumberSets(); i++)
+        {
+                readSet = rectgrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node\n");
+                }
+                else
+                {
+                        printf("This set is not a node\n");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar\n");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node\n");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node\n");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < rectgrid->getNumberAttributes(); i++)
+        {
+                readAttribute = rectgrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+        printf("Rectilinear Dimensions\n");
+        shared_ptr<XdmfArray> rectdimensions = rectgrid->getDimensions();
+        if (!rectdimensions->isInitialized())
+        {
+                rectdimensions->read();
+        }
+        printf("The dimensions' tag: %s\n", rectdimensions->getItemTag().c_str());
+        printf("Contains the values: %s\n", rectdimensions->getValuesString().c_str());
+
+        printf("Rectilinear Coordinates\n");
+        std::vector<shared_ptr<XdmfArray> > rectcoordinates = rectgrid->getCoordinates();
+        printf("Contains the values: \n");
+        for (i=0;i<rectcoordinates.size();i++)
+        {
+                if (!rectcoordinates[i]->isInitialized())
+                {
+                        rectcoordinates[i]->read();
+                }
+                printf("%s\n", rectcoordinates[i]->getValuesString().c_str());
+        }
+
+        printf("Regular Grid\n");
+        shared_ptr<XdmfRegularGrid> reggrid = gridHolder->getRegularGrid(0);
+        printf("The Regular Grid's tag is: %s\n", reggrid->getItemTag().c_str());
+        printf("The Regular Grid's name is: %s\n", reggrid->getName().c_str());
+        outputwalker = reggrid->getItemProperties().begin();
+        for (;outputwalker!=reggrid->getItemProperties().end(); outputwalker++)
+        {
+                printf("%s: %s\n", (*outputwalker).first.c_str(), (*outputwalker).second.c_str());
+        }
+        printf("The Regular Grid's time is: %f\n", reggrid->getTime()->getValue());
+        for (i=0; i<reggrid->getNumberMaps(); i++)
+        {
+                readMap = reggrid->getMap(i);
+                if (!readMap->isInitialized())
+                {
+                        readMap->read();
+                }
+                printf("Map # %d\n", i);
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); taskWalker++)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); nodeWalker++)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end();remoteWalker++)
+                                {
+                                        remote = (*remoteWalker);
+                                        printf("taskID: %d\tlocalnodeID: %d\tremotenodeID: %d\n", task, node, remote);
+                                }
+                        }
+                }
+        }
+        for (i=0; i < reggrid->getNumberSets(); i++)
+        {
+                readSet = reggrid->getSet(i);
+                if (!readSet->isInitialized())
+                {
+                        readSet->read();
+                }
+                printf("Set # %d\n", i);
+                printf("%s\n", readSet->getName().c_str());
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        printf("This set is a node");
+                }
+                else
+                {
+                        printf("This set is not a node");
+                }
+                outputInformation = readSet->getInformation(0);
+                printf("Key: %s\nValue: %s\n", outputInformation->getKey().c_str(), outputInformation->getValue().c_str());
+                printf("%s\n", readSet->getValuesString().c_str());
+                for (j=0; j < readSet->getNumberAttributes(); j++)
+                {
+                        readAttribute = readSet->getAttribute(j);
+                        if (!readAttribute->isInitialized())
+                        {
+                                readAttribute->read();
+                        }
+                        printf("Set Attribute # %d\n", j);
+                        printf("%s\n", readAttribute->getName().c_str());
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                printf("This attribute is a scalar");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a scalar");
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                printf("This attribute is a node");
+                        }
+                        else
+                        {
+                                printf("This attribute is not a node");
+                        }
+                        printf("%s\n", readAttribute->getValuesString().c_str());
+                }
+        }
+        for (i = 0; i < reggrid->getNumberAttributes(); i++)
+        {
+                readAttribute = reggrid->getAttribute(i);
+                if (!readAttribute->isInitialized())
+                {
+                        readAttribute->read();
+                }
+                printf("Attribute # %d\n", i);
+                printf("%s\n", readAttribute->getName().c_str());
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        printf("This attribute is a scalar\n");
+                }
+                else
+                {
+                        printf("This attribute is not a scalar\n");
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        printf("This attribute is a node\n");
+                }
+                else
+                {
+                        printf("This attribute is not a node\n");
+                }
+                printf("%s\n", readAttribute->getValuesString().c_str());
+        }
+
+        printf("Regular Brick Size\n");
+        shared_ptr<XdmfArray> regbricksize = reggrid->getBrickSize();
+        if (!regbricksize->isInitialized())
+        {
+                regbricksize->read();
+        }
+        printf("The brick's tag: %s\n", regbricksize->getItemTag().c_str());
+        printf("Contains the values: %s\n", regbricksize->getValuesString().c_str());
+
+        printf("Regular Number of Points\n");
+        shared_ptr<XdmfArray> regnumpoints = reggrid->getDimensions();
+        printf("The dimensions' tag: %s\n", regnumpoints->getItemTag().c_str());
+        printf("Contains the values: %s\n", regnumpoints->getValuesString().c_str());
+
+        printf("Regular Origin\n");
+        shared_ptr<XdmfArray> regorigin = reggrid->getOrigin();
+        if (!regorigin->isInitialized())
+        {
+                regorigin->read();
+        }
+        printf("The origin's tag: %s\n", regorigin->getItemTag().c_str());
+        printf("Contains the values: %s\n", regorigin->getValuesString().c_str());
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfReader.cpp b/examples/Cxx/ExampleXdmfReader.cpp
new file mode 100644
index 0000000..98661f2
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfReader.cpp
@@ -0,0 +1,12 @@
+#include "XdmfDomain.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<Xdmfreader> exampleReader = XdmfReader::New();
+
+        //#initialization end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfRectilinearGrid.cpp b/examples/Cxx/ExampleXdmfRectilinearGrid.cpp
new file mode 100644
index 0000000..b615c74
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfRectilinearGrid.cpp
@@ -0,0 +1,121 @@
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfArray.hpp"
+
+int main(int, char **)
+{
+        int size = 2;
+
+        //Assuming that exampleGrid is a shared pointer to an XdmfRectilinearGrid
+
+        //#initvalues begin
+
+        shared_ptr<XdmfArray> pointsXArray = XdmfArray::New();
+        pointsXArray->pushBack(5);
+        pointsXArray->pushBack(6);
+        pointsXArray->pushBack(7);
+        pointsXArray->pushBack(8);
+        pointsXArray->pushBack(9);
+        pointsXArray->pushBack(10);
+        shared_ptr<XdmfArray> pointsYArray = XdmfArray::New();
+        pointsYArray->pushBack(3);
+        pointsYArray->pushBack(6);
+        pointsYArray->pushBack(4);
+        pointsYArray->pushBack(8);
+        pointsYArray->pushBack(7);
+        pointsYArray->pushBack(10);
+        shared_ptr<XdmfArray> pointsZArray = XdmfArray::New();
+        pointsZArray->pushBack(3);
+        pointsZArray->pushBack(9);
+        pointsZArray->pushBack(4);
+        pointsZArray->pushBack(5);
+        pointsZArray->pushBack(7);
+        pointsZArray->pushBack(2);
+
+        //#initvalues end
+
+        if (size==2)
+        {
+
+        //#initialization2 begin
+
+        shared_ptr<XdmfRectilinearGrid> exampleGrid = XdmfRectilinearGrid::New(pointsXArray, pointsYArray);
+
+        //#initialization2 end
+
+        //#getCoodinatessingle begin
+
+        shared_ptr<XdmfArray> readPointsX = exampleGrid->getCoordinates(0);
+        shared_ptr<XdmfArray> readPointsY = exampleGrid->getCoordinates(1);
+
+        //#getCoordinatessingle end
+
+        //#getCoordinatessingleconst begin
+
+        shared_ptr<const XdmfArray> readPointsXConst = exampleGrid->getCoordinates(0);
+        shared_ptr<const XdmfArray> readPointsYConst = exampleGrid->getCoordinates(1);
+
+        //#getCoordinatessingleconst end
+
+        }
+        else if (size==3)
+        {
+
+        //#initialization3 begin
+
+        shared_ptr<XdmfRectilinearGrid> exampleGrid = XdmfRectilinearGrid::New(pointsXArray, pointsYArray, pointsZArray);
+
+        //#initialization3 end
+
+        //#setCoordinatessingle begin
+
+        exampleGrid->setCoordinates(0, pointsXArray);
+
+        //#setCoordinatessingle end
+
+        }
+        else //mutable size
+        {
+
+        //#initializationvector begin
+
+        std::vector<shared_ptr<XdmfArray> > pointsCollector;
+        pointsCollector.push_back(pointsXArray);
+        pointsCollector.push_back(pointsYArray);
+        pointsCollector.push_back(pointsZArray);
+        shared_ptr<XdmfRectilinearGrid> exampleGrid = XdmfRectilinearGrid::New(pointsCollector);
+
+        //#initializationvector end
+
+        //#setCoordinatesvector begin
+
+        exampleGrid->setCoordinates(pointsCollector);
+
+        //#setCoordinatesvector end
+
+        //#getDimensions begin
+
+        shared_ptr<XdmfArray> exampleDimensions = exampleGrid->getDimensions();
+
+        //#getDimensions end
+
+        //#getDimensionsconst begin
+
+        shared_ptr<const XdmfArray> exampleDimensionsConst = exampleGrid->getDimensions();
+
+        //#getDimensionsconst end
+
+        //#getCoordinatesvector begin
+
+        std::vector<shared_ptr<XdmfArray> > exampleCoordinates = exampleGrid->getCoordinates();
+
+        //#getCoordinatesvector end
+
+        //#getCoordinatesvectorconst begin
+
+        const std::vector<shared_ptr<XdmfArray> > exampleCoordinatesConst = exampleGrid->getCoordinates();
+
+        //#getCoordinatesvectorconst end
+
+        }
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfRegularGrid.cpp b/examples/Cxx/ExampleXdmfRegularGrid.cpp
new file mode 100644
index 0000000..327b009
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfRegularGrid.cpp
@@ -0,0 +1,124 @@
+#include "XdmfArray.hpp"
+#include "XdmfRegularGrid.hpp"
+
+int main(int, char **)
+{
+        int size = 2;
+
+        //Assuming exampleGrid is a shared pointer to an XdmfRegularGrid object
+
+        //#initvalue begin
+
+        double newBrickX = 20.0;
+        unsigned int newPointsX = 5;
+        double newOriginX = 0;
+        double newBrickY = 20.0;
+        unsigned int newPointsY = 5;
+        double newOriginY = 0;
+        double newBrickZ = 20.0;
+        unsigned int newPointsZ = 5;
+        double newOriginZ = 0;
+
+        //#initvalue end
+
+        if (size==2)
+        {
+
+        //#initialization2 begin
+
+        shared_ptr<XdmfRegularGrid> exampleGrid = XdmfRegularGrid::New(
+                newBrickX, newBrickY, newPointsX, newPointsY, newOriginX, newOriginY);
+
+        //#initialization2 end
+
+        //#getBrickSize begin
+
+        shared_ptr<XdmfArray> exampleBrick = exampleGrid->getBrickSize();
+
+        //#getBrickSize end
+
+        //#getBrickSizeconst begin
+
+        shared_ptr<const XdmfArray> exampleBrickConst = exampleGrid->getBrickSize();
+
+        //#getBrickSizeconst end
+
+        //#getDimensions begin
+
+        shared_ptr<XdmfArray> exampleDimensions = exampleGrid->getDimensions();
+
+        //#getDimensions end
+
+        //#getDimensionsconst begin
+
+        shared_ptr<const XdmfArray> exampleDimensionsConst = exampleGrid->getDimensions();
+
+        //#getDimensionsconst end
+
+        //#getOrigin begin
+
+        shared_ptr<XdmfArray> exampleOrigin = exampleGrid->getOrigin();
+
+        //#getOrigin end
+
+        //#getOriginconst begin
+
+        shared_ptr<const XdmfArray> exampleOriginConst = exampleGrid->getOrigin();
+
+        //#getOriginconst end
+
+        }
+        else if (size==3)
+        {
+
+        //#initialization3 begin
+
+        shared_ptr<XdmfRegularGrid> exampleGrid = XdmfRegularGrid::New(
+                newBrickX, newBrickY, newBrickZ, newPointsX, newPointsY, newPointsZ, newOriginX, newOriginY, newOriginZ);
+
+        //#initialization3 end
+
+        }
+        else //mutable size
+        {
+
+        //#initializationvector begin
+
+        shared_ptr<XdmfArray> newBrickSize = XdmfArray::New();
+        newBrickSize->pushBack(20.0);
+        newBrickSize->pushBack(21.0);
+        newBrickSize->pushBack(22.0);
+        shared_ptr<XdmfArray> newNumPoints = XdmfArray::New();
+        newNumPoints->pushBack(5);
+        newNumPoints->pushBack(6);
+        newNumPoints->pushBack(7);
+        shared_ptr<XdmfArray> newGridOrigin = XdmfArray::New();
+        newGridOrigin->pushBack(0.0);
+        newGridOrigin->pushBack(1.0);
+        newGridOrigin->pushBack(2.0);
+        shared_ptr<XdmfRegularGrid> exampleGrid = XdmfRegularGrid::New(newBrickSize, newNumPoints, newGridOrigin);
+
+        //#initializationvector end
+
+        //#setBrickSize begin
+
+        exampleGrid->setBrickSize(newBrickSize);
+
+        //#setBrickSize end
+
+        //#setDimensions begin
+
+        exampleGrid->setDimensions(newNumPoints);
+
+        //#setDimensions end
+
+        //#setOrigin begin
+
+        exampleGrid->setOrigin(newGridOrigin);
+
+        //#setOrigin end
+
+        }
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfSet.cpp b/examples/Cxx/ExampleXdmfSet.cpp
new file mode 100644
index 0000000..0c206d3
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfSet.cpp
@@ -0,0 +1,43 @@
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+
+int main(int, char **)
+{
+        //#initialize begin
+
+        shared_ptr<XdmfSet> exampleSet = XdmfSet::New();
+
+        //#initialize end
+
+        //#setName begin
+
+        std::string newName = "New Name";
+        exampleSet->setName(newName);
+
+        //#setName end
+
+        //#setType begin
+
+        exampleSet->setType(XdmfSetType::Node());
+
+        //#setType end
+
+        //#getName begin
+
+        std::string exampleName = exampleSet->getName();
+
+        //#getName end
+
+        //#getType begin
+
+        shared_ptr<const XdmfSetType> exampleType = exampleSet->getType();
+
+        if (exampleType == XdmfSetType::Node())
+        {
+                //Do whatever is to be done if the set is a node
+        }
+
+        //#getType end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfSparseMatrix.cpp b/examples/Cxx/ExampleXdmfSparseMatrix.cpp
new file mode 100644
index 0000000..934d5e1
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfSparseMatrix.cpp
@@ -0,0 +1,98 @@
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfArray.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfSparseMatrix> exampleMatrix = XdmfSparseMatrix::New(3, 3);
+
+        //#initialization end
+
+        //#setName begin
+
+        exampleMatrix->setName("TestMatrix");
+
+        //#setName end
+
+        //#getName begin
+
+        std::string exampleName = exampleMatrix->getName();
+
+        //#getName end
+
+        //#setRowPointer begin
+
+        shared_ptr<XdmfArray> newRowPointer = XdmfArray::New();
+
+        newRowPointer->insert<unsigned int>(0, 1);
+        newRowPointer->insert<unsigned int>(1, 1);
+        newRowPointer->insert<unsigned int>(2, 2);
+        newRowPointer->insert<unsigned int>(3, 3);
+
+        exampleMatrix->setRowPointer(newRowPointer);
+
+        //#setRowPointer end
+
+        //#getRowPointer begin
+
+        shared_ptr<XdmfArray> exampleRowPointer = exampleMatrix->getRowPointer();
+
+        //#getRowPointer end
+
+        //#setColumnIndex begin
+
+        shared_ptr<XdmfArray> newColumnIndex = XdmfArray::New();
+
+        newColumnIndex->pushBack<unsigned int>(1);
+        newColumnIndex->pushBack<unsigned int>(2);
+        newColumnIndex->pushBack<unsigned int>(0);
+
+        exampleMatrix->setColumnIndex(newColumnIndex);
+
+        //#setColumnIndex end
+
+        //#getColumnIndex begin
+
+        shared_ptr<XdmfArray> exampleColumnIndex = exampleMatrix->getColumnIndex();
+
+        //#getColumnIndex end
+
+        //#getNumberRows begin
+
+        unsigned int exampleNumRows = exampleMatrix->getNumberRows();
+
+        //#getNumberRows end
+
+        //#getNumberColumns begin
+
+        unsigned int exampleNumCols = exampleMatrix->getNumberColumns();
+
+        //#getNumberColumns end
+
+        //#setValues begin
+
+        shared_ptr<XdmfArray> newValues = XdmfArray::New();
+
+        newValues->pushBack<double>(5.0);
+        newValues->pushBack<double>(6.0);
+        newValues->pushBack<double>(-1.0);
+
+        exampleMatrix->setValues(newValues);
+
+        //#setValues end
+
+        //#getValues begin
+
+        shared_ptr<XdmfArray> exampleValues = exampleMatrix->getValues();
+
+        //#getValues end
+
+        //#getValuesString begin
+
+        std::string exampleValueString = exampleMatrix->getValuesString();
+
+        //#getValuesString end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfSubset.cpp b/examples/Cxx/ExampleXdmfSubset.cpp
new file mode 100644
index 0000000..0b9ff7a
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfSubset.cpp
@@ -0,0 +1,120 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfSubset.hpp"
+#include <vector>
+#include <map>
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfArray> baseArray = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 10; ++i)
+        {
+                baseArray->pushBack(i);
+        }
+
+        std::vector<unsigned int> initStart;
+        initStart.push_back(0);
+        std::vector<unsigned int> initStride;
+        initStride.push_back(1);
+        std::vector<unsigned int> initDimension;
+        initDimension.push_back(10);
+
+        shared_ptr<XdmfSubset> exampleSubset = XdmfSubset::New(baseArray,
+                                                               initStart,
+                                                               initStride,
+                                                               initDimension);
+
+        //#initialization end
+
+        //#getStart begin
+
+        std::vector<unsigned int> exampleStart = exampleSubset->getStart();
+
+        //#getStart end
+
+        //#setStart begin
+
+        exampleSubset->setStart(exampleStart);
+
+        //#setStart end
+
+        //#getStride begin
+
+        std::vector<unsigned int> exampleStride = exampleSubset->getStride();
+
+        //#getStride end
+
+        //#setStride begin
+
+        exampleSubset->setStride(exampleStride);
+
+        //#setStride end
+
+        //#getDimensions begin
+
+        std::vector<unsigned int> exampleDimensions = exampleSubset->getDimensions();
+
+        //#getDimensions end
+
+        //#setDimensions begin
+
+        exampleSubset->setDimensions(exampleDimensions);
+
+        //#setDimensions end
+
+        //#getReferenceArray begin
+
+        shared_ptr<XdmfArray> exampleInternalArray = exampleSubset->getReferenceArray();
+
+        //#getReferenceArray end
+
+        //#setReferenceArray begin
+
+        exampleSubset->setReferenceArray(exampleInternalArray);
+
+        //#setReferenceArray end
+
+        //#getSize begin
+
+        int exampleSize = exampleSubset->getSize();
+
+        //#getSize end
+
+        //#setConstructedType begin
+
+        shared_ptr<XdmfAttribute> typeAttribute = XdmfAttribute::New();
+        exampleSubset->setConstructedType(typeAttribute->getItemTag());
+
+        //#setConstructedType end
+
+        //#getConstructedType begin
+
+        std::string exampleType = exampleSubset->getConstructedType();
+
+        //#getConstructedType end
+
+        //#setConstructedProperties begin
+
+        shared_ptr<XdmfAttribute> propertyAttribute = XdmfAttribute::New();
+        exampleSubset->setConstructedProperties(propertyAttribute->getItemProperties());
+
+        //#setConstructedProperties end
+
+        //#getConstructedProperties begin
+
+        std::map<std::string, std::string> exampleProperties = exampleSubset->getConstructedProperties();
+
+        //#getConstructedProperties end
+
+        //#read begin
+
+        shared_ptr<XdmfArray> subsetResult = exampleSubset->read();
+
+        //#read end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfSystemUtils.cpp b/examples/Cxx/ExampleXdmfSystemUtils.cpp
new file mode 100644
index 0000000..64edeae
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfSystemUtils.cpp
@@ -0,0 +1,13 @@
+#include "XdmfSystemUtils.hpp"
+
+int main(int, char **)
+{
+        //#getRealPath begin
+
+        std::string priorPath = "Path you want to convert";
+        std::string convertedPath = XdmfSystemUtils::getRealPath(priorPath);
+
+        //#getRealPath end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfTIFFController.cpp b/examples/Cxx/ExampleXdmfTIFFController.cpp
new file mode 100644
index 0000000..41df5f7
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfTIFFController.cpp
@@ -0,0 +1,56 @@
+#include "XdmfTIFFController.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string newPath = "File path to TIFF file goes here";
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readStarts;
+        //Three dimensions, all starting at index 0
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        readStarts.push_back(0);
+        std::vector<unsigned int> readStrides;
+        //Three dimensions, no skipping between reads
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        readStrides.push_back(1);
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        std::vector<unsigned int> readDataSize;
+        //Three dimensions, each with a maximum of 20 values
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        readDataSize.push_back(20);
+        shared_ptr<XdmfTIFFController> exampleController = XdmfTIFFController::New(
+                newPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize);
+
+        //#initialization end
+
+        //#initializationsimplified begin
+
+        std::string newPath = "File path to TIFF file goes here";
+        shared_ptr<const XdmfArrayType> readType = XdmfArrayType::Int32();
+        std::vector<unsigned int> readCounts;
+        //Three dimensions, reading 10 values from each
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        readCounts.push_back(10);
+        shared_ptr<XdmfTIFFController> exampleController = XdmfTIFFController::New(
+                newPath,
+                readType,
+                readCounts);
+
+        //#initializationsimplified end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfTime.cpp b/examples/Cxx/ExampleXdmfTime.cpp
new file mode 100644
index 0000000..8df8df9
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfTime.cpp
@@ -0,0 +1,29 @@
+#include "XdmfTime.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfTime> exampleTime = XdmfTime::New();
+        //The Default case sets the time to 0.0
+        //You can also specify a time when creating the XdmfTime object
+
+        double newTime = 5.0;
+        shared_ptr<XdmfTime> exampleTime2 = XdmfTime::New(newTime);
+
+        //#initialization end
+
+        //#getValue begin
+
+        double readTime = exampleTime->getValue();
+
+        //#getValue end
+
+        //#setValue begin
+
+        exampleTime->setValue(newTime);
+
+        //#setValue end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfTopology.cpp b/examples/Cxx/ExampleXdmfTopology.cpp
new file mode 100644
index 0000000..a7db116
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfTopology.cpp
@@ -0,0 +1,31 @@
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfTopology> exampleTopology = XdmfTopology::New();
+
+        //#initialization end
+
+        //#setType begin
+
+        exampleTopology->setType(XdmfTopologyType::Pyramid());
+
+        //#setType end
+
+        //#getType begin
+
+        shared_ptr<const XdmfTopologyType> exampleType = exampleTopology->getType();
+
+        //#getType end
+
+        //#getNumberElements begin
+
+        unsigned int numElements = exampleTopology->getNumberElements();
+
+        //#getNumberElements end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfTopologyType.cpp b/examples/Cxx/ExampleXdmfTopologyType.cpp
new file mode 100644
index 0000000..1c23008
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfTopologyType.cpp
@@ -0,0 +1,71 @@
+#include "XdmfTopologyType.hpp"
+#include "XdmfTopology.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        unsigned int exampleID = XdmfTopologyType::Triangle()->getID();
+        shared_ptr<XdmfTopology> createdTopology = XdmfTopology::New();
+        createdTopology->setType(XdmfTopologyType::New(exampleID));
+
+        //#initialization end
+
+        //#getCellType begin
+
+        XdmfTopologyType::CellType exampleType = XdmfTopologyType::Linear;
+        //Assuming that exampleTopology is a shared pointer to a filled XdmfTopology object
+        if (exampleType == exampleTopology->getCellType())
+        {
+                //Do whatever is to be done if the cell type is linear
+        }
+
+        //#getCellType end
+
+        //#getEdgesPerElement begin
+
+        unsigned int numEdges = XdmfTopologyType::Triangle()->getEdgesPerElement();
+
+        //#getEdgesPerElement end
+
+        //#getFacesPerElement begin
+
+        unsigned int numFaces = XdmfTopologyType::Triangle()->getFacesPerElement();
+
+        //#getFacesPerElement end
+
+        //#getID begin
+
+        unsigned int holdID = XdmfTopologyType::Triangle()->getID();
+
+        //#getID end
+
+        //#getName begin
+
+        std::string exampleName = XdmfTopologyType::Triangle()->getName();
+
+        //#getName end
+
+        //#getFaceType begin
+
+        shared_ptr<const XdmfTopologyType> exampleface = XdmfTopologyType::Tetrahedron()->getFaceType();
+
+        //#getFaceType end
+
+        //#getNodesPerElement begin
+
+        unsigned int numNodes = XdmfTopologyType::Triangle()->getNodesPerElement();
+
+        //#getNodesPerElement end
+
+        //#getType begin
+
+        if (createdTopology->getType() == XdmfTopologyType::Triangle())
+        {
+                //Do whatever is to be done if the type is Triangle
+        }
+
+        //#getType end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfUnstructuredGrid.cpp b/examples/Cxx/ExampleXdmfUnstructuredGrid.cpp
new file mode 100644
index 0000000..9d0c1c3
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfUnstructuredGrid.cpp
@@ -0,0 +1,74 @@
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfGeometry.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        shared_ptr<XdmfUnstructuredGrid> exampleGrid = XdmfUnstructuredGrid::New();
+
+        //#initialization end
+
+        //#initializationregular begin
+
+        double newBrickX = 0.0;
+        double newBrickY = 0.0;
+        unsigned int newPointsX = 5;
+        unsigned int newPointsY = 5;
+        double newOriginX = 20.0;
+        double newOriginY = 20.0;
+        shared_ptr<XdmfRegularGrid> baseGrid = XdmfRegularGrid::New(newBrickX, newBrickY, newPointsX, newPointsY, newOriginX, newOriginY);
+        shared_ptr<XdmfUnstructuredGrid> regGeneratedGrid = XdmfUnstructuredGrid::New(baseGrid);
+
+        //#initializationregular end
+
+        //#setGeometry begin
+
+        shared_ptr<XdmfGeometry> newGeometry = XdmfGeometry::New();
+        newGeometry->setType(XdmfGeometryType::XYZ());
+        newGeometry->pushBack(1);
+        newGeometry->pushBack(2);
+        newGeometry->pushBack(3);
+        newGeometry->pushBack(4);
+        newGeometry->pushBack(5);
+        newGeometry->pushBack(6);
+        newGeometry->pushBack(7);
+        newGeometry->pushBack(8);
+        newGeometry->pushBack(9);
+        exampleGrid->setGeometry(newGeometry);
+
+        //#setGeometry end
+
+        //#setTopology begin
+
+        shared_ptr<XdmfTopology> newTopology = XdmfTopology::New();
+        newTopology->setType(XdmfTopologyType::Triangle());
+        newTopology->pushBack(1);
+        newTopology->pushBack(2);
+        newTopology->pushBack(3);
+        newTopology->pushBack(4);
+        newTopology->pushBack(5);
+        newTopology->pushBack(6);
+        newTopology->pushBack(7);
+        newTopology->pushBack(8);
+        newTopology->pushBack(9);
+        exampleGrid->setTopology(newTopology);
+
+        //#setTopology end
+
+        //#getGeometry begin
+
+        shared_ptr<XdmfGeometry> exampleGeometry = exampleGrid->getGeometry();
+
+        //#getGeometry end
+
+        //#getTopology begin
+
+        shared_ptr<XdmfTopology> exampleTopology = exampleGrid->getTopology();
+
+        //#getTopology end
+
+        return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfWrite.cpp b/examples/Cxx/ExampleXdmfWrite.cpp
new file mode 100644
index 0000000..5cf4f02
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfWrite.cpp
@@ -0,0 +1,242 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+        shared_ptr<XdmfDomain> primaryDomain = XdmfDomain::New();
+        shared_ptr<XdmfInformation> domaininfo = XdmfInformation::New("Domain", "This is the primary data structure in Xdmf");
+        shared_ptr<XdmfInformation> domaininfoinfo = XdmfInformation::New("Information", "Information can have information");
+        domaininfo->insert(domaininfoinfo);
+        primaryDomain->insert(domaininfo);
+
+        shared_ptr<XdmfGridCollection> gridHolder = XdmfGridCollection::New();
+        gridHolder->setType(XdmfGridCollectionType::Spatial());
+        shared_ptr<XdmfInformation> holderInfo = XdmfInformation::New("Grid Collection 1", "This is the main grid collection");
+        gridHolder->insert(holderInfo);
+        gridHolder->setName("GridCollection Example");
+
+
+        shared_ptr<XdmfUnstructuredGrid> ungrid = XdmfUnstructuredGrid::New();
+        ungrid->setName("Unstructured Grid Example");
+        shared_ptr<XdmfTime> untime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> untimeinfo = XdmfInformation::New("Time", "This is the time for the Unstructured Grid");
+        untime->insert(untimeinfo);
+        ungrid->setTime(untime);
+        shared_ptr<XdmfAttribute> unglobalID = XdmfAttribute::New();
+        unglobalID->setType(XdmfAttributeType::GlobalId());
+        unglobalID->setCenter(XdmfAttributeCenter::Node());
+        unglobalID->setName("Global Node Equivalencies");
+        int task1globalnodes [] = {1, 4, 5, 7, 3, 6};
+        unglobalID->insert(0, task1globalnodes, 6, 1, 1 );
+        shared_ptr<XdmfInformation> unglobalIDinfo = XdmfInformation::New("Global Nodes", "This is the global nodes that accociate with the local nodes");
+        ungrid->insert(unglobalID);
+        shared_ptr<XdmfSet> unset = XdmfSet::New();
+        shared_ptr<XdmfInformation> unsetinfo = XdmfInformation::New("Data Set", "This is a set of arbitrary data");
+        unset->insert(unsetinfo);
+        unset->setName("Unstructured Grid's Set");
+        unset->setType(XdmfSetType::Node());
+        shared_ptr<XdmfAttribute> unsetattribute = XdmfAttribute::New();
+        unsetattribute->setType(XdmfAttributeType::Scalar());
+        unsetattribute->setCenter(XdmfAttributeCenter::Node());
+        unsetattribute->setName("The Set's attribute");
+        double unsetattribdata [] = {1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1};
+        unsetattribute->insert(0, unsetattribdata, 9, 1, 1);
+        unset->insert(unsetattribute);
+        double unsetdata [] = {5.1, 4.2, 3.3, 2.4, 1.5};
+        unset->insert(0, unsetdata, 5, 1, 1);
+        ungrid->insert(unset);
+        shared_ptr<XdmfGeometry> ungeometry = XdmfGeometry::New();
+        ungeometry->setType(XdmfGeometryType::XYZ());
+        ungeometry->setName("Unstructured Geometry");
+        double ungeopoints [] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1,
+                1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1,
+                0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1};
+        ungeometry->insert(0, ungeopoints, 36, 1, 1);
+        shared_ptr<XdmfInformation> ungeometryinfo = XdmfInformation::New("Geometry", "This is the geometry associated with the unstructured grid");
+        ungeometry->insert(ungeometryinfo);
+        ungrid->setGeometry(ungeometry);
+        shared_ptr<XdmfTopology> untopology = XdmfTopology::New();
+        untopology->setType(XdmfTopologyType::Hexahedron());
+        untopology->setName("Unstructured Topology");
+        int untopovalues [] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
+        untopology->insert(0, untopovalues, 16, 1, 1);
+        shared_ptr<XdmfInformation> untopologyinfo = XdmfInformation::New("Topology", "This is the topology associated with the unstructured grid");
+        ungrid->setTopology(untopology);
+
+
+        shared_ptr<XdmfArray> curvdimensions = XdmfArray::New();
+        curvdimensions->pushBack(12);
+        curvdimensions->pushBack(12);
+        curvdimensions->pushBack(12);
+        shared_ptr<XdmfCurvilinearGrid> curvgrid = XdmfCurvilinearGrid::New(curvdimensions);
+        curvgrid->setName("Curvilinear Grid Example");
+        shared_ptr<XdmfInformation> curvgridinfo = XdmfInformation::New("Curvilinear Grid", "This is an example curvilinear grid");
+        curvgrid->insert(curvgridinfo);
+        shared_ptr<XdmfTime>curvtime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> curvtimeinfo = XdmfInformation::New("Time", "The Time of the Curvilinear Grid");
+        curvtime->insert(curvtimeinfo);
+        curvgrid->setTime(curvtime);
+        shared_ptr<XdmfAttribute> curvglobalID = XdmfAttribute::New();
+        curvglobalID->setType(XdmfAttributeType::GlobalId());
+        curvglobalID->setCenter(XdmfAttributeCenter::Node());
+        curvglobalID->setName("Global Node Equivalencies");
+        int task2globalnodes [] = {7, 3, 8, 2, 5, 1};
+        curvglobalID->insert(0, task1globalnodes, 6, 1, 1);
+        shared_ptr<XdmfInformation> curvglobalIDinfo = XdmfInformation::New("Global Node Equivalencies", "These are the global nodes that accociate with the local nodes");
+        curvglobalID->insert(curvglobalIDinfo);
+        curvgrid->insert(curvglobalID);
+        shared_ptr<XdmfGeometry> curvgeometry = XdmfGeometry::New();
+        curvgeometry->setType(XdmfGeometryType::XYZ());
+        curvgeometry->setName("Curvilinear Geometry");
+        double curvgeopoints [] = {1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1, 2.1,
+                2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1, 4.1,
+                1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1};
+        curvgeometry->insert(0, curvgeopoints, 36, 1, 1);
+        shared_ptr<XdmfInformation> curvgeometryinfo = XdmfInformation::New("Geometry", "The geometry of the curvilinear grid");
+        curvgeometry->insert(curvgeometryinfo);
+        curvgrid->setGeometry(curvgeometry);
+
+
+        double rectXcoordinates [] = {1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1};
+        double rectYcoordinates [] = {2.1, 2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1};
+        double rectZcoordinates [] = {4.1, 1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1};
+        shared_ptr<XdmfArray> rectXarray = XdmfArray::New();
+        rectXarray->insert(0, rectXcoordinates, 12, 1, 1);
+        shared_ptr<XdmfArray> rectYarray = XdmfArray::New();
+        rectYarray->insert(0, rectYcoordinates, 12, 1, 1);
+        shared_ptr<XdmfArray> rectZarray = XdmfArray::New();
+        rectZarray->insert(0, rectZcoordinates, 12, 1, 1);
+        std::vector<shared_ptr<XdmfArray> > coordinatecontainer;
+        coordinatecontainer.push_back(rectXarray);
+        coordinatecontainer.push_back(rectYarray);
+        coordinatecontainer.push_back(rectZarray);
+        shared_ptr<XdmfRectilinearGrid> rectgrid = XdmfRectilinearGrid::New(coordinatecontainer);
+        rectgrid->setName("Rectilinear Grid Example");
+        shared_ptr<XdmfInformation> rectgridinfo = XdmfInformation::New("Rectilinear Grid", "This is an example of a rectilinear grid");
+        shared_ptr<XdmfAttribute> rectglobalID = XdmfAttribute::New();
+        rectglobalID->setType(XdmfAttributeType::GlobalId());
+        rectglobalID->setCenter(XdmfAttributeCenter::Node());
+        rectglobalID->setName("Global Node Equivalencies");
+        int task3globalnodes [] = {2, 7, 9, 0, 8, 6};
+        rectglobalID->insert(0, task3globalnodes, 6, 1, 1);
+        shared_ptr<XdmfInformation> rectglobalIDinfo = XdmfInformation::New("Global Node Equivalencies", "These are the global nodes that associate with the local nodes");
+        rectglobalID->insert(rectglobalIDinfo);
+        shared_ptr<XdmfTime> recttime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> recttimeinfo = XdmfInformation::New("Time", "The time of the rectiliniear grid");
+        recttime->insert(recttimeinfo);
+        rectgrid->setTime(recttime);
+        rectgrid->insert(rectglobalID);
+
+
+        shared_ptr<XdmfArray> regbrick = XdmfArray::New();
+        double regbrickvals [] = {10, 10, 10};
+        regbrick->insert(0, regbrickvals, 3, 1, 1);
+        shared_ptr<XdmfArray> regdimensions = XdmfArray::New();
+        int regdimensionvals [] = {5, 5, 5};
+        regdimensions->insert(0, regdimensionvals, 3, 1, 1);
+        shared_ptr<XdmfArray> regorigin = XdmfArray::New();
+        double regoriginvals [] = {0, 0, 0};
+        regorigin->insert(0, regoriginvals, 3, 1, 1);
+        shared_ptr<XdmfRegularGrid> reggrid = XdmfRegularGrid::New(regbrick, regdimensions, regorigin);
+        reggrid->setName("Regular Grid Example");
+        shared_ptr<XdmfInformation> reggridinfo = XdmfInformation::New("Regular Grid", "This is an example of a regular grid");
+        shared_ptr<XdmfTime> regtime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> regtimeinfo = XdmfInformation::New("Time", "This is the time for the regular grid");
+        regtime->insert(regtimeinfo);
+        reggrid->setTime(regtime);
+        shared_ptr<XdmfAttribute> regglobalID = XdmfAttribute::New();
+        regglobalID->setType(XdmfAttributeType::GlobalId());
+        regglobalID->setCenter(XdmfAttributeCenter::Node());
+        regglobalID->setName("Global Node Equivalencies");
+        int task4globalnodes [] = {3, 6, 1, 4, 2, 5, 9};
+        regglobalID->insert(0, task4globalnodes, 7, 1, 1);
+        shared_ptr<XdmfInformation> regglobalIDinfo = XdmfInformation::New("Global Node Equivalencies", "These are the global nodes that associate with the local nodes");
+        regglobalID->insert(regglobalIDinfo);
+        reggrid->insert(regglobalID);
+
+
+
+        std::vector<shared_ptr<XdmfAttribute> > nodeholder;
+        nodeholder.push_back(unglobalID);
+        nodeholder.push_back(curvglobalID);
+        nodeholder.push_back(rectglobalID);
+        nodeholder.push_back(regglobalID);
+        std::vector<shared_ptr<XdmfMap> > mapcollection = XdmfMap::New(nodeholder);
+
+        ungrid->insert(mapcollection[0]);
+        curvgrid->insert(mapcollection[1]);
+        rectgrid->insert(mapcollection[2]);
+        reggrid->insert(mapcollection[3]);
+
+        /*
+        the version of XdmfMap::New() used here returns a number of maps equal to the number of attributes it was provided with.
+        */
+        for (int i = 0; i<mapcollection.size(); ++i)
+        {
+                gridHolder->insert(mapcollection[i]);
+        }
+
+        gridHolder->insert(ungrid);
+        gridHolder->insert(curvgrid);
+        gridHolder->insert(rectgrid);
+        gridHolder->insert(reggrid);
+
+        shared_ptr<XdmfGridCollection> secondaryHolder = XdmfGridCollection::New();
+        secondaryHolder->setName("Secondary grid collection");
+        gridHolder->insert(secondaryHolder);
+        /*
+        grid collections can be placed inside other grid collections
+        */
+
+        primaryDomain->insert(gridHolder);
+        /*
+        grids can be inserted into the domain in the same way as the grid collection
+        */
+        primaryDomain->insert(ungrid);
+        primaryDomain->insert(curvgrid);
+        primaryDomain->insert(rectgrid);
+        primaryDomain->insert(reggrid);
+
+        shared_ptr<XdmfHDF5Writer> exampleHeavyWriter = XdmfHDF5Writer::New("testoutput.h5");
+        shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New("testoutput.xmf", exampleHeavyWriter);
+
+        exampleHeavyWriter->setFileSizeLimit(1);
+
+        primaryDomain->accept(exampleHeavyWriter);
+        exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Overwrite);//do this so that the data isn't in the hdf5 file twice.
+        primaryDomain->accept(exampleWriter);
+
+        exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+        for (int i = 0; i <= 408; ++i)
+        {//overflow occurs a little after the end of this loop
+                primaryDomain->accept(exampleHeavyWriter);
+        }
+        exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Default);
+        primaryDomain->accept(exampleHeavyWriter);
+        exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+        for (int i = 0; i<5; ++i)
+        {//this loop covers the overflow of the fileSizeLimit
+                primaryDomain->accept(exampleHeavyWriter);
+        }
+        primaryDomain->accept(exampleWriter);
+  return 0;
+}
diff --git a/examples/Cxx/ExampleXdmfWriter.cpp b/examples/Cxx/ExampleXdmfWriter.cpp
new file mode 100644
index 0000000..9c27d28
--- /dev/null
+++ b/examples/Cxx/ExampleXdmfWriter.cpp
@@ -0,0 +1,155 @@
+#include "XdmfDomain.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+
+int main(int, char **)
+{
+        //#initialization begin
+
+        std::string outFile = "output file name goes here";
+        shared_ptr<XdmfWriter> writerExample = XdmfWriter::New(outFile);
+
+        //#initialization end
+
+        //#heavyinitialization begin
+
+        std::string heavyFile = "heavy file name goes here";
+        bool replaceFile = true;
+        shared_ptr<XdmfHDF5Writer> exampleHeavyWriter = XdmfHDF5Writer::New(heavyFile, replaceFile);
+        shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New(outFile, exampleHeavyWriter);
+
+        //#heavyinitialization end
+
+        //#bufferinitialization begin
+
+        filebuf exampleBuffer;
+        exampleBuffer.open("file goes here", ios::out);
+        ostream exampleStream(&exampleBuffer);
+        shared_ptr<XdmfWriter> exampleBufferWriter = XdmfWriter::New(exampleStream, exampleHeavyWriter);
+
+        //#bufferinitialization end
+
+        //#getFilePath begin
+
+        std::string examplePath = exampleWriter->getFilePath();
+
+        //#getFilePath
+
+        //#getHeavyDataWriter begin
+
+        shared_ptr<XdmfHeavyDataWriter> exampleHeavyWriter = exampleWriter->getHeavyDataWriter();
+
+        //#getHeavyDataWriter end
+
+        //#getHeavyDataWriterconst begin
+
+        shared_ptr<const XdmfHeavyDataWriter> exampleHeavyWriterConst = exampleWriter->getHeavyDataWriter();
+
+        //#getHeavyDataWriterconst end
+
+        //#setHeavyDataWriter begin
+
+        exampleWriter->setHeavyDataWriter(exampleHeavyWriter);
+
+        //#setHeavyDataWriter end
+
+        //#getLightDataLimit begin
+
+        unsigned int exampleLimit = exampleWriter->getLightDataLimit();
+
+        //#getLightDataLimit end
+
+        //#getMode begin
+
+        XdmfWriter::Mode testMode = XdmfWriter::Default;
+        if (exampleWriter->getMode() == testMode)
+        {
+                //Do whatever is to be done if the mode is default
+        }
+
+        //#getMode end
+
+        //#getWriteXPaths begin
+
+        bool exampleTestPaths = exampleWriter->getWriteXPaths();
+
+        //#getWriteXPaths end
+
+        //#getRebuildXML begin
+
+        bool exampleRebuildStatus = exampleWriter->getRebuildXML();
+
+        //#getRebuildXML end
+
+        //#setRebuildXML begin
+
+        bool exampleNewRebuildStatus = true;
+        exampleWriter->getRebuildXML(exampleNewRebuildStatus);
+
+        //#setRebuildXML end
+
+        //#getXPathParse begin
+
+        bool exampleXPathParse = exampleWriter->getXPathParse();
+
+        //#getXPathParse end
+
+        //#setLightDataLimit begin
+
+        unsigned int newLimit = 20;
+        exampleWriter->setLightDataLimit(newLimit);
+        //The writer will now place any data with a number of values over 20 into heavy data
+
+        //#setLightDataLimit end
+
+        //#setMode begin
+
+        exampleWriter->setMode(XdmfWriter::Default);
+
+        //#setMode end
+
+        //#setWriteXPaths begin
+
+        exampleWriter->setWriteXPaths(true);
+
+        //#setWriteXPaths end
+
+        //#setXPathParse begin
+
+        exampleWriter->setXPathParse(true);
+
+        //#setXPathParse end
+
+        //#visitarray begin
+
+        //Using XdmfAttribute here, but any XdmfArray would work
+        shared_ptr<XdmfAttribute> exampleAttribute = XdmfAttribute::New();
+        exampleAttribute->setCenter(XdmfAttributeCenter::Node());
+        exampleAttribute->setType(XdmfAttributeType::Scalar());
+        exampleAttribute->pushBack(1);
+        exampleAttribute->pushBack(2);
+        exampleAttribute->pushBack(3);
+        exampleAttribute->pushBack(4);
+        exampleAttribute->pushBack(5);
+        exampleAttribute->pushBack(6);
+        std::string attributeFile = "output file name goes here";
+        shared_ptr<XdmfWriter> exampleArrayWriter = XdmfWriter::New(attributeFile);
+        exampleArrayWriter->visit(exampleAttribute, exampleWriter);
+
+        //#visitarray end
+
+        //#visititem begin
+
+        //Using XdmfDomain here, but any XdmfItem would work
+        shared_ptr<XdmfDomain> exampleDomain = XdmfDomain::New();
+        std::string domainFile = "output file name goes here";
+        shared_ptr<XdmfWriter> exampleDomainWriter = XdmfWriter::New(domainFile);
+        exampleDomainWriter->visit(exampleDomain, exampleWriter);
+
+        //#visititem end
+
+        return 0;
+}
diff --git a/examples/Cxx/XdmfAcceptTest.cpp b/examples/Cxx/XdmfAcceptTest.cpp
new file mode 100644
index 0000000..60a5bb9
--- /dev/null
+++ b/examples/Cxx/XdmfAcceptTest.cpp
@@ -0,0 +1,115 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+
+
+int main(int argc, char *argv[])
+{
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::string newPath = "dsm";
+        int numServersCores = size - 1;
+        int numConnections = 2;
+
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1);
+
+        exampleWriter->stopDSM();
+
+        double resizefactor = exampleWriter->getServerBuffer()->GetResizeFactor();
+
+        exampleWriter->getServerBuffer()->SetResizeFactor(resizefactor);
+
+        exampleWriter->restartDSM();
+
+        if (id == 0)
+        {
+                //#initMPI end
+
+                //#GetDsmFileName begin
+
+                std::string connectionFileName = exampleWriter->getServerBuffer()->GetComm()->GetDsmFileName();
+
+                //#GetDsmFileName end
+
+                //#SetDsmFileName begin
+
+                exampleWriter->getServerBuffer()->GetComm()->SetDsmFileName(connectionFileName);
+
+                //#SetDsmFileName end
+
+                //#OpenPort begin
+
+                exampleWriter->getServerBuffer()->GetComm()->OpenPort();
+
+                //#OpenPort end
+
+                //#SendAccept begin
+
+                exampleWriter->getServerBuffer()->SendAccept(numConnections);
+
+                //#SendAccept end
+
+                /*
+
+                //#manualAccept begin
+
+                // Notify the server cores to accept connections
+                for (int i = exampleWriter->getServerBuffer()->StartServerId; i <= exampleWriter->getServerBuffer()->EndServerId; ++i)
+                {
+                        if (i != exampleWriter->getServerBuffer()->Comm->GetId())
+                        {
+                                exampleWriter->getServerBuffer()->SendCommandHeader(XDMF_DSM_ACCEPT, i, 0, 0, XDMF_DSM_INTER_COMM);
+                                exampleWriter->getServerBuffer()->SendAcknowledgment(i, numConnections, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                        }
+                }
+                // Accept connections
+                exampleWriter->getServerBuffer()->Comm->Accept(numConnections);
+                // Distribute current DSM status
+                exampleWriter->getServerBuffer()->SendInfo();
+
+                //#manualAccept end
+
+                */
+
+                //#finishwork begin
+
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        //#finishwork end
+
+        //#ClosePort begin
+
+	if (id == 0)
+	{
+	        exampleWriter->getServerBuffer()->GetComm()->ClosePort();
+	}
+
+        //#ClosePort end
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+        return 0;
+}
diff --git a/examples/Cxx/XdmfConnectTest.cpp b/examples/Cxx/XdmfConnectTest.cpp
new file mode 100644
index 0000000..3d205dd
--- /dev/null
+++ b/examples/Cxx/XdmfConnectTest.cpp
@@ -0,0 +1,286 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+        //#initMPI begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "Data";
+
+        //#GetUseEnvFileName begin
+
+        bool fromEnv = XdmfDSMCommMPI::GetUseEnvFileName();
+
+        //#GetUseEnvFileName end
+
+        //#SetUseEnvFileName begin
+
+        XdmfDSMCommMPI::SetUseEnvFileName(fromEnv);
+
+        //#SetUseEnvFileName end
+
+        // Initializing objects
+
+        XdmfDSMCommMPI * testComm = new XdmfDSMCommMPI();
+        testComm->DupComm(comm);
+        testComm->Init();
+        XdmfDSMBuffer * testBuffer = new XdmfDSMBuffer();
+        testBuffer->SetIsServer(false);
+        testBuffer->SetComm(testComm);
+        testBuffer->SetIsConnected(true);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, testBuffer);
+
+        //#initMPI end
+
+        //#SetApplicationName begin
+
+        testComm->SetApplicationName("Connect 1");
+
+        //#SetApplicationName end
+
+        //#ReadDsmPortName begin
+
+        exampleWriter->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+        //#ReadDsmPortName end
+
+        //#GetDsmPortName begin
+
+        char * portName = exampleWriter->getServerBuffer()->GetComm()->GetDsmPortName();
+
+        //#GetDsmPortName end
+
+        //#SetDsmPortName begin
+
+        exampleWriter->getServerBuffer()->GetComm()->SetDsmPortName(portName);
+
+        //#SetDsmPortName end
+
+        //#Connect begin
+
+        exampleWriter->getServerBuffer()->Connect();
+
+        //#Connect end
+
+        //#GetApplicationName begin
+
+        std::string appName = testComm->GetApplicationName();
+
+        //#GetApplicationName end
+
+        //#GetDsmProcessStructure begin
+
+        std::vector<std::pair<std::string, unsigned int> > structure = testComm->GetDsmProcessStructure();
+
+        for (unsigned int i = 0; i < structure.size(); ++i)
+        {
+          if (structure.first.compare(appName) == 0)
+          {
+            // This program is the "i"th program in the DSM structure
+          }
+        }
+
+        //#GetDsmProcessStructure end
+
+        /*
+
+        //#manualConnect begin
+
+        try
+        {
+                status = exampleWriter->getServerBuffer()->GetComm()->Connect();
+        }
+        catch (XdmfError e)
+        {
+                // Connection failed
+                std::cout << e.what() << std::endl;
+                return 0;
+        }
+        if (status == MPI_SUCCESS)
+        {
+                exampleWriter->getServerBuffer()->SetIsConnected(true);
+                try
+                {
+                        exampleWriter->getServerBuffer()->ReceiveInfo();
+                }
+                catch (XdmfError e)
+                {
+                        //ReceiveInfo failed
+                        std::cout << e.what() << std::endl;
+                        return 0;
+                }
+        }
+
+        //#manualConnect end
+
+        */
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        shared_ptr<XdmfArray> writeArray = XdmfArray::New();
+
+        for (int i = 1; i <= 5; ++i)
+        {
+                writeArray->pushBack(i*(id+1));
+        }
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        // Done initializing
+
+        for (int i = 0; i < size; ++i)
+        {
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+                if (i == id)
+                {
+                        std::stringstream outputstream;
+                        outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                        for (unsigned int j = 0; j < writeArray->getSize(); ++j)
+                        {
+                                outputstream << "[" << j << "]" << writeArray->getValue<int>(j) << std::endl;
+                        }
+                        std::cout << outputstream.str();
+                }
+        }
+
+        for (unsigned int numloops = 0; numloops < 4; ++numloops)
+        {
+                if (writeArray->getNumberHeavyDataControllers() > 0)
+                {
+                        writeArray->removeHeavyDataController(0);
+                }
+                writeArray->insert(writeController);
+        
+
+                if (id == size - 1)
+                {
+                        std::cout << std::endl << std::endl;
+                }
+
+                writeArray->accept(exampleWriter);
+
+                if (id == size - 1)
+                {
+                        int sentData = 1;
+                        exampleWriter->getServerBuffer()->SendAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                        exampleWriter->getServerBuffer()->ReceiveAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+                writeArray->removeHeavyDataController(0);
+                writeArray->insert(readController);
+                writeArray->release();
+                writeArray->read();
+
+                for (int i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+                        if (i == id)
+                        {
+                                std::stringstream outputstream;
+                                outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                                for (unsigned int j = 0; j < writeArray->getSize(); ++j)
+                                {
+                                        int tempVal = writeArray->getValue<int>(j);
+                                        tempVal = tempVal * 2;
+                                        writeArray->insert(j, tempVal);
+                                        outputstream << "[" << j << "]" << writeArray->getValue<int>(j) << std::endl;
+                                }
+                                std::cout << outputstream.str();
+                        }
+                }
+        }
+
+        if (id == size - 1)
+        {
+                int sentData = 1;
+                exampleWriter->getServerBuffer()->SendAcknowledgment(exampleWriter->getServerBuffer()->GetComm()->GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetIntraComm());
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        //#Disconnectbuffer begin
+
+        exampleWriter->getServerBuffer()->Disconnect();
+
+        //#Disconnectbuffer end
+
+        //#Disconnectcomm begin
+
+        exampleWriter->getServerBuffer()->GetComm()->Disconnect();
+
+        //#Disconnectcomm end
+
+        //#finalizeMPI begin
+
+        MPI_Finalize();
+
+        //#finalizeMPI end
+
+        return 0;
+}
diff --git a/examples/Cxx/XdmfConnectTest2.cpp b/examples/Cxx/XdmfConnectTest2.cpp
new file mode 100644
index 0000000..6e0e59f
--- /dev/null
+++ b/examples/Cxx/XdmfConnectTest2.cpp
@@ -0,0 +1,199 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <iostream>
+#include <fstream>
+#include <string.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfHDF5WriterDSM.hpp>
+#include <XdmfHDF5ControllerDSM.hpp>
+#include <XdmfDSMBuffer.hpp>
+#include <XdmfDSMCommMPI.hpp>
+
+int main(int argc, char *argv[])
+{
+        //#initDSMWriterConnectRequired begin
+
+        int size, id, dsmSize;
+        dsmSize = 64;
+        MPI_Status status;
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "Data";
+
+        // Initializing objects
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm);
+
+        exampleWriter->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+        exampleWriter->getServerBuffer()->Connect();
+
+        //#initDSMWriterConnectRequired end
+
+        //#notify begin
+
+        int notify = 0;
+
+        if (size > 1) {
+          if (id == 0) {
+            notify = exampleWriter->waitOn(newPath, "notify");
+          }
+          else if (id == size - 1) {
+            // The user will want to ensure that the waiton command is called first
+            exampleWriter->waitRelease(newPath, "notify", 3);
+          }
+        }
+
+        //#notify end
+
+        //#buffernotify begin
+
+        int notify = 0;
+
+        if (size > 1) {
+          if (id == 0) {
+            notify = exampleWriter->getServerBuffer()->WaitOn(newPath, "notify");
+          }
+          else if (id == size - 1) {
+            // The user will want to ensure that the waiton command is called first
+            exampleWriter->getServerBuffer()->WaitRelease(newPath, "notify", 3);
+          }
+        }
+
+        //#buffernotify end
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+
+        readArray->initialize<int>(0);
+        readArray->reserve(5);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        shared_ptr<XdmfHDF5ControllerDSM> writeController = XdmfHDF5ControllerDSM::New(
+                newPath,
+                newSetPath,
+                XdmfArrayType::Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter->getServerBuffer());
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+        // Done initialization
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+        for (unsigned int numloops = 0; numloops < 4; ++numloops)
+        {
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        readController->getServerBuffer()->ReceiveAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+
+                MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+                if (readArray->getNumberHeavyDataControllers() > 0)
+                {
+                        readArray->removeHeavyDataController(0);
+                }
+                readArray->insert(readController);
+                readArray->read();
+
+                for (int i = 0; i < size; ++i)
+                {
+                        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+                        if (i == id)
+                        {
+                                std::stringstream outputstream;
+                                outputstream << "Array on core " << exampleWriter->getServerBuffer()->GetComm()->GetInterId() << " contains:" << std::endl;
+                                for (unsigned int j = 0; j < readArray->getSize(); ++j)
+                                {
+                                        int tempVal = readArray->getValue<int>(j);
+                                        tempVal = tempVal * 3;
+                                        readArray->insert(j, tempVal);
+                                        outputstream << "[" << j << "]" << readArray->getValue<int>(j) << std::endl;
+                                }
+                                std::cout << outputstream.str();
+                        }
+                }
+
+                MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+                if (id == 0)
+                {
+                        std::cout << std::endl << std::endl;
+                }
+
+                readArray->removeHeavyDataController(0);
+                readArray->insert(writeController);
+
+                readArray->accept(exampleWriter);
+
+                if (id == 0)
+                {
+                        int receiveData = 0;
+                        readController->getServerBuffer()->SendAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+                }
+        }
+
+        //this last acknowledgment is to end the loop.
+
+        if (id == 0)
+        {
+                int receiveData = 0;
+                readController->getServerBuffer()->ReceiveAcknowledgment(readController->getServerBuffer()->GetComm()->GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM);
+        }
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetIntraComm());
+
+        // Do work stuff here
+
+        if (id == 0)
+        {
+                readController->stopDSM();
+        }
+
+        MPI_Barrier(readController->getServerBuffer()->GetComm()->GetInterComm());
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/examples/Python/XdmfExampleAcceptTest.py b/examples/Python/XdmfExampleAcceptTest.py
new file mode 100644
index 0000000..5c528c4
--- /dev/null
+++ b/examples/Python/XdmfExampleAcceptTest.py
@@ -0,0 +1,85 @@
+from Xdmf import *
+from mpi4py.MPI import *
+
+if __name__ == "__main__":
+        #//initMPI begin
+
+        dsmSize = 64
+        comm = COMM_WORLD
+
+        id = comm.Get_rank()
+        size = comm.Get_size()
+
+        newPath = "dsm";
+        numServersCores = size - 1;
+        numConnections = 2
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1);
+
+        exampleWriter.stopDSM()
+
+        resizefactor = exampleWriter.getServerBuffer().GetResizeFactor()
+
+        exampleWriter.getServerBuffer().SetResizeFactor(resizefactor)
+
+        exampleWriter.restartDSM()
+
+        if id == 0:
+                #//initMPI end
+
+                #//GetDsmFileName begin
+
+                connectionFileName = exampleWriter.getServerBuffer().GetComm().GetDsmFileName()
+
+                #//GetDsmFileName end
+
+                #//SetDsmFileName begin
+
+                exampleWriter.getServerBuffer().GetComm().SetDsmFileName(connectionFileName)
+
+                #//SetDsmFileName end
+
+                #//OpenPort begin
+
+                exampleWriter.getServerBuffer().GetComm().OpenPort()
+
+                #//OpenPort end
+
+                #//SendAccept begin
+
+                exampleWriter.getServerBuffer().SendAccept(numConnections)
+
+                #//SendAccept end
+
+                '''
+
+                #//manualAccept begin
+
+                # Notify the server cores to accept connections
+                for i in range(exampleWriter.getServerBuffer().StartServerId, exampleWriter.getServerBuffer().EndServerId+1):
+                        if i != exampleWriter.getServerBuffer().Comm.GetId():
+                                exampleWriter.getServerBuffer().SendCommandHeader(XDMF_DSM_ACCEPT, i, 0, 0, XDMF_DSM_INTER_COMM)
+                                exampleWriter.getServerBuffer().SendAcknowledgment(i, numConnections, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+                # Accept connections
+                exampleWriter.getServerBuffer().Comm.Accept(numConnections)
+                # Distribute current DSM status
+                exampleWriter.getServerBuffer().SendInfo()
+
+                #//manualAccept end
+
+                '''
+
+                #//finishwork begin
+
+                exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+        exampleWriter.getServerBuffer().GetComm().GetInterComm().Barrier()
+
+        #//finishwork end
+
+        #//ClosePort begin
+
+	if id == 0:
+	        exampleWriter.getServerBuffer().GetComm().ClosePort()
+
+        #//ClosePort end
diff --git a/examples/Python/XdmfExampleAggregate.py b/examples/Python/XdmfExampleAggregate.py
new file mode 100644
index 0000000..78f0af7
--- /dev/null
+++ b/examples/Python/XdmfExampleAggregate.py
@@ -0,0 +1,40 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleAggregate = XdmfAggregate.New()
+
+        partArray = XdmfArray.New()
+
+        for i in range(0, 10):
+                partArray.pushBack(i)
+
+        exampleAggregate.insert(partArray)
+
+        partArray2 = XdmfArray.New()
+
+        for i in range(0, 10):
+                partArray2.pushBack(i)
+
+        exampleAggregate.insert(partArray2)
+
+        #//initialization end
+
+        #//getDimensions begin
+
+        exampleDimensions = exampleAggregate.getDimensions()
+
+        #//getDimensions end
+
+        #//getSize begin
+
+        exampleSize = exampleAggregate.getSize()
+
+        #//getSize end
+
+        #//read begin
+
+        aggregateResult = exampleAggregate.read()
+
+        #//read end
diff --git a/examples/Python/XdmfExampleArray.py b/examples/Python/XdmfExampleArray.py
new file mode 100644
index 0000000..73268b3
--- /dev/null
+++ b/examples/Python/XdmfExampleArray.py
@@ -0,0 +1,364 @@
+from Xdmf import *
+from numpy import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleArray = XdmfArray.New()
+
+        #//initialization end
+
+        #//setName begin
+
+        newName = "New Name"
+        exampleArray.setName(newName)
+
+        #//setName end
+
+        #//reserve begin
+
+        newSize = 10
+        exampleArray.reserve(newSize)
+
+        #//reserve end
+
+        #//initializesingle begin
+
+        newSize = 10
+        exampleArray.initialize(XdmfArrayType.Int32(), newSize)
+
+        #//initializesingle end
+
+        #//initializevector begin
+
+        newSizeVector = UInt32Vector()
+        newSizeVector.push_back(5)
+        newSizeVector.push_back(5)
+        newSizeVector.push_back(5)
+        exampleArray.initialize(XdmfArrayType.Int32(), newSizeVector)
+
+        #//initializevector end
+
+        #//getArrayType begin
+
+        exampleType = exampleArray.getArrayType()
+
+        #//getArrayType end
+
+        #//getCapacity begin
+
+        exampleCapacity = exampleArray.getCapacity()
+
+        #//getCapacity end
+
+        #//getDimensions begin
+
+        exampleDimensions = exampleArray.getDimensions()
+
+        #//getDimensions end
+
+        #//getDimensionsString begin
+
+        exampleDimensionString = exampleArray.getDimensionsString()
+
+        #//getDimensionsString end
+
+        #//getName begin
+
+        exampleName = exampleArray.getName()
+
+        #//getName end
+
+        #//getSize begin
+
+        exampleSize = exampleArray.getSize()
+
+        #//getSize end
+
+        #//insertarray begin
+
+        initArray = [0,1,2,3,4,5,6,7,8,9]
+        storeArray = XdmfArray.New()
+        exampleArray.insertAsInt32(0, initArray)
+        storeArray.insert(0, exampleArray, 0, 10, 1, 1)
+        #storeArray now contains {0,1,2,3,4,5,6,7,8,9}
+        storeArray.insert(0, exampleArray, 0, 5, 2, 1)
+        #storeArray now contains {0,1,1,3,2,5,3,7,4,9}
+        storeArray.insert(0, exampleArray, 0, 5, 1, 2)
+        #storeArray now contains {0,2,4,6,8,5,3,7,4,9}
+
+        #//insertarray end
+
+        #//insertlist begin
+
+        initArray = [0,1,2,3,4,5,6,7,8,9]
+        exampleArray.insertAsInt32(0, initArray)
+        #exampleArray now contains {0,1,2,3,4,5,6,7,8,9}
+        exampleArray.insertAsInt32(0, initArray[0:5:2])
+        #exampleArray now contains {0,2,4,6,8,5,3,7,4,9}
+        exampleArray.insertAsInt32(0, initArray[::-1])
+        #exampleArray now contains {9,8,7,6,5,4,3,2,1,0}
+
+        #Python uses a different function for each data type
+        #This example uses insertAsInt32 to insert ints
+        #insertAsFloat64 can also be used to insert doubles
+        #This function takes a start index and a list
+        #Sublists are inserted using Python's sublist notation
+
+        #//insertlist end
+
+        #//getNumpyArray begin
+
+        outputArray = exampleArray.getNumpyArray()
+
+        #//getNumpyArray end
+
+        #//arraydefaultvalues begin
+
+        initArray = [0,1,2,3,4,5,6,7,8,9]
+        exampleArray.insertAsInt32(0, initArray)
+
+        #//arraydefaultvalues end
+
+        #//resizesingle begin
+
+        newSize = 20
+        baseValue = 1
+        exampleArray.resizeAsInt32(newSize, baseValue)
+        #exampleArray now contains {0,1,2,3,4,5,6,7,8,9,1,1,1,1,1,1,1,1,1,1}
+        newSize = 5
+        exampleArray.resizeAsInt32(newSize, baseValue)
+        #exampleArray now contains {0,1,2,3,4}
+        #This example uses resizeAsInt32 because the baseValue inserted is to be an integer
+        #All other supported data types have similarly named function calls
+        #For example to insert a double resizeAsFloat64 is called
+
+        #//resizesingle end
+
+        #//resizevector begin
+
+        newSizeArray = UInt32Vector()
+        newSizeArray.push_back(4)
+        newSizeArray.push_back(5)
+        baseValue = 1
+        exampleArray.resizeAsInt32(newSizeArray, baseValue)
+        #exampleArray now contains {0,1,2,3,4,5,6,7,8,9,1,1,1,1,1,1,1,1,1,1}
+        newSizeArray[0] = 1
+        exampleArray.resizeAsInt32(newSizeArray, baseValue)
+        #exampleArray now contains {0,1,2,3,4}
+        #This example uses resizeAsInt32 because the baseValue inserted is to be an integer
+        #All other supported data types have similarly named function calls
+        #For example to insert a double resizeAsFloat64 is called
+
+        #//resizevector end
+
+        #//getValueindex begin
+
+        #If exampleArray contains  [0, 1, 2, 3, 4, 5, 6, 7]
+        exampleValue = exampleArray.getValueAsInt32(4)
+        #exampleValue now equals 4
+        #The data type of the returned value can be changed by changing the function name
+        #getValueAsInt32 returns an int value while getValueAsFloat64 returns a double value
+        #Variations of this function exist for all supported data types
+
+        #//getValueindex end
+
+        #//getValuesparse begin
+
+        exampleValueString = exampleArray.getValuesString()
+        valueArray = [float(piece) for piece in exampleArray.getValuesString().split()]
+        #This is one method of getting the contained values of the array
+
+        #//getValuesparse end
+
+        #//isInitialized begin
+
+        if not(exampleArray.isInitialized()):
+                exampleArray.read()
+
+        #//isInitialized end
+
+        #//getValuesInternal begin
+
+        exampleValues = exampleArray.getValuesInternal()
+        #alternatively getBuffer gives a buffer object
+        exampleValues = exampleArray.getBuffer()
+        #due to the way python handles void pointers, this function is only useful for getting a pointer to pass
+        #if the retrieval of the internal values of the array is required, another function should be used
+
+        #//getValuesInternal end
+
+        #//swap begin
+
+        swapArray = XdmfArray.New()
+        initArray2 = [1,2,3,4,5]
+        swapArray.insertAsInt32(0, initArray2)
+        #exampleArray contains {0,1,2,3,4,5,6,7,8,9} and swapArray contains {1,2,3,4,5}
+        exampleArray.swap(swapArray)
+        #Now exampleArray contains {1,2,3,4,5} and swapArray contains {0,1,2,3,4,5,6,7,8,9}
+
+        #//swap end
+
+        #//pushBack begin
+
+        newValue = 5
+        exampleArray.pushBackAsInt32(newValue)
+        #For Python pushBack has multiple functions to cover different data types
+        #This case used an int so the function was pushBackAsInt32
+        #Another example would be to use pushBackAsFloat64 for double values
+
+        #//pushBack end
+
+        #//pointinsert begin
+
+        newIndex = 0
+        newValue = 3.5
+        exampleArray.insertAsFloat64(newIndex, [newValue])
+        #this example uses insertAsFloat64 to insert a double value
+        #versions for all other data types exist
+        #for example insertAsInt32 inserts as an int
+
+        #//pointinsert end
+
+        #//erase begin
+
+        #If exampleArray contains  [0, 1, 2, 3, 4, 5, 6, 7]
+        erasedIndex = 4
+        exampleArray.erase(erasedIndex)
+        #exampleArray now contains the following
+        #[0, 1, 2, 3, 5, 6, 7]
+
+        #//erase end
+
+        #//clear begin
+
+        exampleArray.clear()
+
+        #//clear end
+
+        #//getHeavyDataController begin
+
+        exampleController = exampleArray.getHeavyDataController()
+
+        #//getHeavyDataController end
+
+        #//setHeavyDataController begin
+
+        newArray = XdmfArray.New()
+        newArray.setHeavyDataController(exampleController)
+
+        #//setHeavyDataController end
+
+        #//setHeavyDataControllerVector begin
+
+        sourceArray = XdmfArray.New()
+
+        sourceArray.pushBackAsInt32(5)
+
+        heavywriter = XdmfHDF5Writer.New("heavyfile.h5")
+
+        sourceArray.accept(heavywriter)
+
+        transferVector = HeavyControllerVector()
+
+        for i in range(0, sourceArray.getNumberHeavyDataControllers()):
+          transferVector.push_back(sourceArray.getHeavyDataController(i))
+
+        exampleArray.setHeavyDataController(transferVector)
+
+        #//setHeavyDataControllerVector end
+
+        #//readController begin
+
+        newArray->readController()
+
+        #//readController end
+
+        #//release begin
+
+        exampleArray.release()
+
+        #//release end
+
+        #//insertmultidim begin
+
+        writtenArray = XdmfArray.New()
+        dimensionVector = UInt32Vector()
+        dimensionVector.push_back(5)
+        dimensionVector.push_back(4)
+        writtenArray.initializeAsInt32(dimensionVector)
+        for i in range (0, 20):
+                writtenArray.insertAsInt32(i, i + 1)
+        readArray = XdmfArray.New()
+        readDimensionVector = UInt32Vector()
+        readDimensionVector.push_back(6)
+        readDimensionVector.push_back(4)
+        readArray.initializeAsInt32(readDimensionVector)
+
+        writeStarts = UInt32Vector()
+        writeStarts.push_back(0)
+        writeStarts.push_back(0)
+        writeStrides = UInt32Vector()
+        writeStrides.push_back(2)
+        writeStrides.push_back(2)
+        writeDim = UInt32Vector()
+        writeDim.push_back(3)
+        writeDim.push_back(2)
+        readStarts = UInt32Vector()
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStrides = UInt32Vector()
+        readStrides.push_back(2)
+        readStrides.push_back(2)
+        readDim = UInt32Vector()
+        readDim.push_back(3)
+        readDim.push_back(2)
+
+        readArray.insert(readStarts, writtenArray, writeStarts, writeDim, readDim, readStrides, writeStrides)
+
+        #//insertmultidim end
+
+        #//setReference begin
+
+        variableArray = XdmfArray.New()
+
+        for i in range(0, 10):
+                variableArray.pushBack(i)
+
+        variableMap = ArrayMap()
+
+        variableMap["A"] = variableArray
+
+        arrayFunction = XdmfFunction.New("AVE(A)", variableMap)
+
+        exampleArray.setReference(arrayFunction)
+
+        #//setReference end
+
+        #//getReference begin
+
+        exampleReference = exampleArray.getReference()
+
+        #//getReference end
+
+        #//readReference begin
+
+        exampleArray.readReference()
+
+        #//readReference end
+
+        #//setReadMode begin
+
+        exampleArray.setReadMode(XdmfArray.Reference)
+
+        #//setReadMode end
+
+        #//getReadMode begin
+
+        isReference = exampleArray.getReadMode()
+
+        if isReference == XdmfArray.Reference:
+                exampleArray.readReference()
+
+        #//getReadMode end
diff --git a/examples/Python/XdmfExampleArrayType.py b/examples/Python/XdmfExampleArrayType.py
new file mode 100644
index 0000000..b60b3d6
--- /dev/null
+++ b/examples/Python/XdmfExampleArrayType.py
@@ -0,0 +1,43 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//getElementSize begin
+
+        dataSize = XdmfArrayType.Int8().getElementSize()
+
+        #//getElementSize end
+
+        #//getName begin
+
+        dataName = XdmfArrayType.Int8().getName()
+
+        #//getName end
+
+        #//getIsSigned begin
+
+        isSigned = XdmfArrayType.UInt8().getIsSigned()
+
+        #//getIsSigned end
+
+        #//getIsFloat begin
+
+        isFloat = XdmfArrayType.UInt8().getIsFloat()
+
+        #//getIsFloat end
+
+        #//getType begin
+
+        exampleArray = XdmfArray.New()
+
+        exampleType = exampleArray.getType()
+
+        if exampleType == XdmfArrayType.Int8():
+                #do whatever is to be done if the type is Int8
+
+        #//getType end
+
+        #//comparePrecision begin
+
+        resultType = XdmfArrayType.comparePrecision(XdmfArrayType.Int16(), XdmfArrayType.UInt8())
+
+        #//comparePrecision end
diff --git a/examples/Python/XdmfExampleAttribute.py b/examples/Python/XdmfExampleAttribute.py
new file mode 100644
index 0000000..e6b8ce0
--- /dev/null
+++ b/examples/Python/XdmfExampleAttribute.py
@@ -0,0 +1,52 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+        exampleAttribute = XdmfAttribute.New()
+        #//initialization end
+
+        #Assuming that exampleAttribute is a shared pointer to an XdmfAttribute object
+
+        #//setCenter begin
+
+        exampleAttribute.setCenter(XdmfAttributeCenter.Node())
+
+        #//setCenter end
+
+        #//setName begin
+
+        newName = "New Name"
+        exampleAttribute.setName(newName)
+
+        #//setNAme end
+
+        #//setType begin
+
+        exampleAttribute.setType(XdmfAttributeType.Scalar())
+
+        #//setType end
+
+        #//getCenter begin
+
+        exampleCenter = exampleAttribute.getCenter()
+
+        if exampleCenter == XdmfAttributeCenter.Grid():
+                #do whatever is to be done if the center is a grid
+
+        #//getCenter end
+
+        #//getName begin
+
+        exampleName = exampleAttribute.getName()
+
+        #//getName end
+
+        #//getType begin
+
+        exampleType = exampleAttribute.getType()
+
+        if exampleType == XdmfAttributeType.Scalar():
+                #do whatever is to be done if the Type is a Scalar
+
+        #//getType end
diff --git a/examples/Python/XdmfExampleBinaryController.py b/examples/Python/XdmfExampleBinaryController.py
new file mode 100644
index 0000000..33ef077
--- /dev/null
+++ b/examples/Python/XdmfExampleBinaryController.py
@@ -0,0 +1,72 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "File path to binary file goes here"
+        newSeek = 0
+        newEndian = XdmfBinaryController.NATIVE
+        readType = XdmfArrayType.Int32()
+        readStarts = UInt32Vector()
+        #Three dimensions, all starting at index 0
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStrides = UInt32Vector()
+        #Three dimensions, no skipping between reads
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readDataSize = UInt32Vector()
+        #three dimensins, each with 20 maximum values
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        exampleController = XdmfBinaryController.New(
+                newPath,
+                readType,
+                newSeek,
+                newEndian,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize)
+
+        #//initialization end
+
+        #//initializationsimplified begin
+
+        newPath = "File path to binary file goes here"
+        newSeek = 0
+        newEndian = XdmfBinaryController.NATIVE
+        readType = XdmfArrayType.Int32()
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        exampleController = XdmfBinaryController.New(
+                newPath,
+                readType,
+                newSeek,
+                newEndian,
+                readCounts)
+
+        #//initializationsimplified end
+
+        #//getEndian begin
+
+        readEndian = exampleController.getEndian()
+
+        #//getEndian end
+
+        #//getSeek begin
+
+        readSeek = exampleController.getSeek()
+
+        #//getSeek end
diff --git a/examples/Python/XdmfExampleConnectTest.py b/examples/Python/XdmfExampleConnectTest.py
new file mode 100644
index 0000000..57ba2ee
--- /dev/null
+++ b/examples/Python/XdmfExampleConnectTest.py
@@ -0,0 +1,222 @@
+from Xdmf import *
+from mpi4py.MPI import *
+
+if __name__ == "__main__":
+        #//initMPI begin
+
+        dsmSize = 64
+        comm = COMM_WORLD
+
+        id = comm.Get_rank()
+        size = comm.Get_size()
+
+        newPath = "dsm"
+        newSetPath = "Data"
+
+        #//GetUseEnvFileName begin
+
+        fromEnv = XdmfDSMCommMPI.GetUseEnvFileName()
+
+        #//GetUseEnvFileName end
+
+        #//SetUseEnvFileName begin
+
+        XdmfDSMCommMPI.SetUseEnvFileName(fromEnv)
+
+        #//SetUseEnvFileName end
+
+        # Initializing objects
+
+        testComm = XdmfDSMCommMPI()
+        testComm.DupComm(comm)
+        testComm.Init()
+        testBuffer = XdmfDSMBuffer()
+        testBuffer.SetIsServer(False)
+        testBuffer.SetComm(testComm)
+        testBuffer.SetIsConnected(True)
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, testBuffer)
+
+        #//initMPI end
+
+        #//SetApplicationName begin
+
+        testComm.SetApplicationName("Connect 1")
+
+        #//SetApplicationName end
+
+        #//ReadDsmPortName begin
+
+        exampleWriter.getServerBuffer().GetComm().ReadDsmPortName()
+
+        #//ReadDsmPortName end
+
+        #//GetDsmPortName begin
+
+        portName = exampleWriter.getServerBuffer().GetComm().GetDsmPortName()
+
+        #//GetDsmPortName end
+
+        #//SetDsmPortName begin
+
+        exampleWriter.getServerBuffer().GetComm().SetDsmPortName(portName)
+
+        #//SetDsmPortName end
+
+        #//Connect begin
+
+        exampleWriter.getServerManager().Connect()
+
+        #//Connect end
+
+        #//GetApplicationName begin
+
+        appName = testComm.GetApplicationName()
+
+        #//GetApplicationName end
+
+        #//GetDsmProcessStructure begin
+
+        structure = testComm.GetDsmProcessStructure()
+
+        for i in range(structure.size()):
+          if structure.first.compare(appName) == 0:
+            # This program is the "i"th program in the DSM structure
+
+        #//GetDsmProcessStructure end
+
+        '''
+
+        #//manualConnect begin
+
+        try:
+                status = exampleWriter.getServerBuffer().GetComm().Connect()
+                if status == MPI_SUCCESS:
+                exampleWriter.getServerBuffer().SetIsConnected(true)
+                try:
+                        exampleWriter.getServerBuffer().ReceiveInfo()
+                except RuntimeError as e:
+                        # ReceiveInfo failed
+                        print e.args[0]
+        except RuntimeError as e:
+                # Connection failed
+                print e.args[0]
+
+        #//manualConnect end
+
+        '''
+
+        exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+        writeArray = XdmfArray.New()
+
+        for i in range(1, 6):
+                writeArray.pushBackAsInt32(i*(id+1))
+
+        writeStartVector = UInt32Vector()
+        writeStrideVector = UInt32Vector()
+        writeCountVector = UInt32Vector()
+        writeDataSizeVector = UInt32Vector()
+
+        writeStartVector.push_back(id*5)
+        writeStrideVector.push_back(1)
+        writeCountVector.push_back(5)
+        writeDataSizeVector.push_back(5*size)
+
+        writeController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter.getServerBuffer());
+
+        readStartVector = UInt32Vector()
+        readStrideVector = UInt32Vector()
+        readCountVector = UInt32Vector()
+        readDataSizeVector = UInt32Vector()
+
+        readStartVector.push_back(5*id);
+        readStrideVector.push_back(1);
+        readCountVector.push_back(5);
+        readDataSizeVector.push_back(5*size);
+
+        readController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter.getServerBuffer());
+
+        exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab);
+
+        # Done initializing
+
+        for i in range(0, size):
+                exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                if i == id:
+                        outputstream = "Array on core " + str(exampleWriter.getServerBuffer().GetComm().GetInterId()) + " contains:\n"
+                        for j in range(0, writeArray.getSize()):
+                                outputstream  = outputstream + "[" + str(j) + "]" + str(writeArray.getValueAsInt32(j)) + "\n"
+                        print outputstream
+
+        loopamount = 4
+
+        for numloops in range(0, loopamount):
+                if writeArray.getNumberHeavyDataControllers() > 0:
+                        writeArray.removeHeavyDataController(0);
+                writeArray.insert(writeController)
+
+
+                if id == size - 1:
+                        print "\n\n"
+
+                writeArray.accept(exampleWriter)
+
+                if id == size - 1:
+                        sentData = 1
+                        exampleWriter.getServerBuffer().SendAcknowledgment(exampleWriter.getServerBuffer().GetComm().GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+                        exampleWriter.getServerBuffer().ReceiveAcknowledgment(exampleWriter.getServerBuffer().GetComm().GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+                exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+                writeArray.removeHeavyDataController(0)
+                writeArray.insert(readController)
+                writeArray.release()
+                writeArray.read()
+
+                for i in range (0, size):
+                        exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                        if i == id:
+                                outputstream = "Array on core " + str(exampleWriter.getServerBuffer().GetComm().GetInterId()) + " contains:\n"
+                                for j in range(0, writeArray.getSize()):
+                                        tempVal = writeArray.getValueAsInt32(j)
+                                        tempVal = tempVal * 2
+                                        writeArray.insertAsInt32(j, [tempVal])
+                                        outputstream = outputstream + "[" + str(j) + "]" + str(writeArray.getValueAsInt32(j)) + "\n"
+                                print outputstream
+
+        if id == size - 1:
+                sentData = 1
+                exampleWriter.getServerBuffer().SendAcknowledgment(exampleWriter.getServerBuffer().GetComm().GetInterId() + 1, sentData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+        exampleWriter.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+        exampleWriter.getServerBuffer().GetComm().GetInterComm().Barrier()
+
+        #//Disconnectmanager begin
+
+        exampleWriter.getServerManager().Disconnect()
+
+        #//Disconnectmanager end
+
+        #//Disconnectcomm begin
+
+        exampleWriter.getServerBuffer().GetComm().Disconnect()
+
+        #//Disconnectcomm end
diff --git a/examples/Python/XdmfExampleConnectTest2.py b/examples/Python/XdmfExampleConnectTest2.py
new file mode 100644
index 0000000..9bce646
--- /dev/null
+++ b/examples/Python/XdmfExampleConnectTest2.py
@@ -0,0 +1,166 @@
+from Xdmf import *
+from mpi4py.MPI import *
+
+if __name__ == "__main__":
+        #//initDSMWriterConnectRequired begin
+
+        dsmSize = 64
+        comm = COMM_WORLD
+
+        id = comm.Get_rank()
+        size = comm.Get_size()
+
+        newPath = "dsm"
+        newSetPath = "Data"
+
+        # Initializing objects
+
+        testComm = XdmfDSMCommMPI()
+        testComm.DupComm(comm)
+        testComm.Init()
+        testBuffer = XdmfDSMBuffer()
+        testBuffer.SetIsServer(False)
+        testBuffer.SetComm(testComm)
+        testBuffer.SetIsConnected(True)
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm);
+
+        exampleWriter.getServerBuffer().GetComm().ReadDsmPortName();
+
+        exampleWriter.getServerBuffer().Connect();
+
+        #//initDSMWriterConnectRequired end
+
+        #//notify begin
+
+        notify = 0
+
+        if size > 1: 
+          if id == 0:
+            notify = exampleWriter.waitOn(newPath, "notify")
+          elif id == size - 1:
+            # The user will want to ensure that the wait command is called first
+            exampleWriter.waitRelease(newPath, "notify", 3)
+
+        #//notify end
+
+        #//buffernotify begin
+
+        notify = 0
+
+        if size > 1:
+          if id == 0:
+            notify = exampleWriter.getServerBuffer().WaitOn(newPath, "notify")
+          elif id == size - 1:
+            # The user will want to ensure that the wait command is called first
+            exampleWriter.getServerBuffer().WaitRelease(newPath, "notify", 3)
+
+        #//buffernotify end
+
+        readStartVector = UInt32Vector()
+        readStrideVector = UInt32Vector()
+        readCountVector = UInt32Vector()
+        readDataSizeVector = UInt32Vector()
+
+        readStartVector.push_back(5*id)
+        readStrideVector.push_back(1)
+        readCountVector.push_back(5)
+        readDataSizeVector.push_back(5*size)
+
+        readArray = XdmfArray.New()
+
+        readArray.initializeAsInt32(0)
+        readArray.reserve(5)
+
+        readController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                readStartVector,
+                readStrideVector,
+                readCountVector,
+                readDataSizeVector,
+                exampleWriter.getServerBuffer());
+
+        writeStartVector = UInt32Vector();
+        writeStrideVector = UInt32Vector();
+        writeCountVector = UInt32Vector();
+        writeDataSizeVector = UInt32Vector();
+
+        writeStartVector.push_back(id*5);
+        writeStrideVector.push_back(1);
+        writeCountVector.push_back(5);
+        writeDataSizeVector.push_back(5*size);
+
+        writeController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                exampleWriter.getServerBuffer());
+
+        exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab);
+
+        # Done initialization
+
+        readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+        loopamount = 4
+
+        print str(range(0, loopamount)) + "'s type = " + str(type(range(0, loopamount)))
+
+        for numloops in range(0, loopamount):
+                if id == 0:
+                        receiveData = 0
+                        readController.getServerBuffer().ReceiveAcknowledgment(readController.getServerBuffer().GetComm().GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+                readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+                if readArray.getNumberHeavyDataControllers() > 0:
+                        readArray.removeHeavyDataController(0)
+                readArray.insert(readController)
+                readArray.read()
+
+                for i in range(0, size):
+                        readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                        if i == id:
+                                outputstream = " "
+                                outputstream = outputstream + "Array on core " + str(exampleWriter.getServerBuffer().GetComm().GetInterId()) + " contains:\n"
+                                for j in range(0, readArray.getSize()):
+                                        tempVal = readArray.getValueAsInt32(j)
+                                        tempVal = tempVal * 3
+                                        readArray.insertAsInt32(j, [tempVal])
+                                        outputstream = outputstream + "[" + str(j) + "]" + str(readArray.getValueAsInt32(j))+ "\n"
+                                print outputstream
+
+                readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+                if id == 0:
+                        print "\n\n"
+
+                readArray.removeHeavyDataController(0)
+                readArray.insert(writeController)
+
+                readArray.accept(exampleWriter)
+
+                if id == 0:
+                        receiveData = 0
+                        readController.getServerBuffer().SendAcknowledgment(readController.getServerBuffer().GetComm().GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+
+        # This last acknowledgment is to end the loop.
+
+        if id == 0:
+                receiveData = 0;
+                readController.getServerBuffer().ReceiveAcknowledgment(readController.getServerBuffer().GetComm().GetInterId() - 1, receiveData, XDMF_DSM_EXCHANGE_TAG, XDMF_DSM_INTER_COMM)
+
+        readController.getServerBuffer().GetComm().GetIntraComm().Barrier()
+
+        if id == 0:
+                readController.stopDSM()
+
+        readController.getServerBuffer().GetComm().GetInterComm().Barrier()
+
+        readController.getServerManager().Disconnect()
diff --git a/examples/Python/XdmfExampleCoreItemFactory.py b/examples/Python/XdmfExampleCoreItemFactory.py
new file mode 100644
index 0000000..2e42444
--- /dev/null
+++ b/examples/Python/XdmfExampleCoreItemFactory.py
@@ -0,0 +1,15 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//createItem begin
+
+        #using XdmfItemFactory because XdmfCoreItemFactory is abstract
+        exampleFactory = XdmfItemFactory.New()
+        newProperties = StringMap()
+        newChildren = ItemVector()
+        exampleItem = exampleFactory.createItem(XdmfAttribute.ItemTag, newProperties, newChildren)
+        #Same usage as the individual constructors
+        #childItems and itemProperties are not added to the item when created this way
+        #the collections are used to determine type
+
+        #//createItem end
diff --git a/examples/Python/XdmfExampleCoreReader.py b/examples/Python/XdmfExampleCoreReader.py
new file mode 100644
index 0000000..97641fe
--- /dev/null
+++ b/examples/Python/XdmfExampleCoreReader.py
@@ -0,0 +1,41 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        #using XdmfReader since XdmfCoreReader is abstract
+        exampleReader = XdmfReader.New()
+
+        #//initialization end
+
+        #//parse begin
+
+        readLight = "<dataitem>1 1 1 1 1 1 3 5 7 4 2</dataitem>"
+        exampleItem = exampleReader.parse(readLight)
+
+        #//parse end
+
+        #//readpath begin
+
+        readPath = "your file path here";
+
+        #//readpath end
+
+        #//readroot begin
+
+        exampleItem = exampleReader.read(readPath)
+
+        #//readroot end
+
+        #//readItems begin
+
+        exampleCollection = exampleReader.readItems(readPath)
+
+        #//readItems end
+
+        #//readXPath begin
+
+        readXPath = "your X path here"
+        exampleItems = exampleReader.read(readPath, readXPath)
+
+        #//readXPath end
diff --git a/examples/Python/XdmfExampleCurvilinearGrid.py b/examples/Python/XdmfExampleCurvilinearGrid.py
new file mode 100644
index 0000000..8235bf5
--- /dev/null
+++ b/examples/Python/XdmfExampleCurvilinearGrid.py
@@ -0,0 +1,70 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #Assuming that exampleGrid is a shared pointer to an XdmfCurvilinearGrid object
+
+        #//initialization begin
+
+        newPointsX = 5
+        newPointsY = 5
+        newPointsZ = 5
+
+        #//initialization end
+
+        #//constructor2 begin
+
+        exampleGrid = XdmfCurvilinearGrid.New(newPointsX, newPointsY)
+
+        #//constructor2 end
+
+        #//constructor3 begin
+
+        exampleGrid = XdmfCurvilinearGrid.New(newPointsX, newPointsY, newPointsZ)
+
+        #//constructor3 end
+
+        #//constructorvector begin
+
+        newPoints = XdmfArray.New()
+        newPoints.pushBackAsInt32(5)
+        newPoints.pushBackAsInt32(5)
+        newPoints.pushBackAsInt32(5)
+        exampleGrid = XdmfCurvilinearGrid.New(newPoints)
+
+        #//constructorvector end
+
+        #//setGeometry begin
+
+        newPoints = XdmfArray.New()
+        newPoints.pushBackAsInt32(5)
+        newPoints.pushBackAsInt32(5)
+        newPoints.pushBackAsInt32(5)
+        newGeometry = XdmfGeometry.New()
+        newGeometry.setType(XdmfGeometryType.XYZ())
+        # Start index is 0, 3 values are passed, stride for both arrays is 1
+        newGeometry.insert(0, newPoints, 0, 3, 1, 1)
+        exampleGrid.setGeometry(newGeometry)
+
+        #//setGeometry end
+
+        #//setDimensions begin
+
+        newPoints = XdmfArray.New()
+        newPoints.pushBackAsInt32(5)
+        newPoints.pushBackAsInt32(5)
+        newPoints.pushBackAsInt32(5)
+        exampleGrid.setDimensions(newPoints)
+
+        #//setDimensions end
+
+        #//getGeometry begin
+
+        exampleGeometry = exampleGrid.getGeometry()
+
+        #//getGeometry end
+
+        #//getDimensions begin
+
+        exampleDimensions = exampleGrid.getDimensions()
+
+        #//getDimensions end
diff --git a/examples/Python/XdmfExampleDSMNoThread.py b/examples/Python/XdmfExampleDSMNoThread.py
new file mode 100644
index 0000000..a3fed1f
--- /dev/null
+++ b/examples/Python/XdmfExampleDSMNoThread.py
@@ -0,0 +1,705 @@
+from Xdmf import *
+from mpi4py.MPI import *
+
+if __name__ == "__main__":
+        #//initMPI begin
+
+        #The total size of the DSM being created
+        dsmSize = 64
+        comm = COMM_WORLD
+
+        id = comm.Get_rank()
+        size = comm.Get_size()
+
+        #//initMPI end
+
+        testArray = XdmfArray.New()
+        testArray.initializeAsInt32(0)
+
+        for i in range(1,5):
+                testArray.pushBackAsInt32(i*(id+1))
+
+        #//initwritevector begin
+
+        newPath = "dsm"
+        newSetPath = "data"
+
+        numServersCores = 4
+
+        writeStartVector = UInt32Vector()
+        writeStartVector.push_back(id*4)
+        #writeStartVector.push_back(id);
+        writeStrideVector = UInt32Vector()
+        writeStrideVector.push_back(1)
+        #writeStrideVector.push_back(size-3);
+        writeCountVector = UInt32Vector()
+        writeCountVector.push_back(4)
+        writeDataSizeVector = UInt32Vector()
+        writeDataSizeVector.push_back(4*(size-numServersCores))
+
+        #//initwritevector end
+
+        #//splitcomm begin
+
+        ServerIds = []
+
+        for i in range(size-numServersCores, size):
+                ServerIds.append(i)
+
+        workers = comm.Get_group().Excl(ServerIds)
+
+        workerComm = comm.Create(workers)
+
+        #//splitcomm end
+
+        #//initwritergenerate begin
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, dsmSize/numServersCores, size-numServersCores, size-1)
+
+        #//initwritergenerate end
+
+        '''
+        #//initwriterpagedgenerate begin
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, dsmSize/numServersCores, 1024, 1.0, size-numServersCores, size-1)
+
+        #//initwriterpagedgenerate end
+        '''
+
+        '''
+        #//initcontrollergenerate begin
+
+        exampleController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                comm,
+                dsmSize/numServersCores,
+                size-numServersCores,
+                size-1)
+
+        #//initcontrollergenerate end
+        '''
+
+        '''
+        #//initcontrollerpagedgenerate begin
+
+
+        exampleController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStartVector,
+                writeStrideVector,
+                writeCountVector,
+                writeDataSizeVector,
+                comm,
+                dsmSize/numServersCores,
+                1024,
+                1.0,
+                size-numServersCores,
+                size-1)
+
+        #//initcontrollerpagedgenerate end
+        '''
+
+        # Split out sub-comm for the worker cores
+        # Server cores will not progress to this point until after the servers are done running
+
+        #//startworksection begin
+
+        if (id < size - numServersCores):
+
+                #//startworksection end
+
+                # This section is to demonstrate the functionality of the XdmfDSM classes
+
+                #//setServerModewriter begin
+
+                exampleWriter.setServerMode(True)
+
+                #//setServerModewriter end
+
+                #//getServerModewriter begin
+
+                exampleServerMode = exampleWriter.getServerMode()
+
+                #//getServerModewriter end
+
+                #//getWorkerCommwriter begin
+
+                exampleWorkerComm = exampleWriter.getWorkerComm()
+
+                #//getWorkerCommwriter end
+
+                #//setWorkerCommwriter begin
+
+                exampleWriter.setWorkerComm(exampleWorkerComm)
+
+                #//setWorkerCommwriter end
+
+                '''
+                #//getWorkerCommcontroller begin
+
+                exampleWorkerComm = exampleController.getWorkerComm()
+
+                #//getWorkerCommcontroller end
+
+                #//setWorkerCommcontroller begin
+
+                exampleController.setWorkerComm(exampleWorkerComm)
+
+                #//setWorkerCommcontroller end
+
+                #//setServerModecontroller begin
+
+                exampleController.setServerMode(True)
+
+                #//setServerModecontroller end
+
+                #//getServerModecontroller begin
+
+                exampleControllerServerMode = exampleController.getServerMode()
+
+                #//getServerModecontroller end
+                '''
+
+                #//initcontrollerfrombuffer begin
+
+                writeController = XdmfHDF5ControllerDSM.New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType.Int32(),
+                        writeStartVector,
+                        writeStrideVector,
+                        writeCountVector,
+                        writeDataSizeVector,
+                        exampleWriter.getServerBuffer());
+
+                #//initcontrollerfrombuffer end
+
+                #//initwriterfrombuffer begin
+
+                exampleWriter2 = XdmfHDF5WriterDSM.New(newPath, exampleWriter.getServerBuffer());
+
+                #//initwriterfrombuffer end
+
+                writeController.setServerMode(True)
+                exampleControllerServerMode = writeController.getServerMode()
+
+                #//getServerBufferwriter begin
+
+                exampleBuffer = exampleWriter.getServerBuffer()
+
+                #//getServerBufferwriter end
+
+                #//GetlocalBufferSizeMBytes begin
+
+                exampleBufferSize = exampleBuffer.GetLocalBufferSizeMBytes()
+
+                #//GetLocalBufferSizeMBytes end
+
+                #//SetLocalBufferSizeMBytes begin
+
+                exampleBuffer.SetLocalBufferSizeMBytes(exampleBufferSize)
+
+                #//SetLocalBufferSizeMBytes end
+
+                #//GetInterCommType begin
+
+                exampleCommType = exampleBuffer.GetInterCommType()
+
+                #//GetInterCommType end
+
+                #//SetinterCommType begin
+
+                exampleBuffer.SetInterCommType(XDMF_DSM_COMM_MPI)
+
+                #//SetInterCommType end
+
+                '''
+                #//Create begin
+
+                exampleBuffer.Create(size - numServerCores, size - 1)
+
+                #//Create end
+                '''
+
+                #//setBufferwriter begin
+
+                exampleWriter.setBuffer(exampleBuffer)
+
+                #//setBufferwriter end
+
+                '''
+                #//getServerBuffercontroller begin
+
+                exampleBuffer = exampleController.getServerBuffer()
+
+                #//getServerBuffercontroller end
+
+                #//setBuffercontroller begin
+
+                exampleController.setBuffer(exampleBuffer)
+
+                #//setBuffercontroller end
+                '''
+
+                #//GetIsConnectedbuffer begin
+
+                exampleIsConnected = exampleBuffer.GetIsConnected()
+
+                #//GetIsConnectedbuffer end
+
+                #//SetIsConnectedbuffer begin
+
+                exampleBuffer.SetIsConnected(exampleIsConnected)
+
+                #//SetIsConnectedbuffer end
+
+                #//GetDataPointer begin
+
+                exampleDataPointer = exampleBuffer.GetDataPointer()
+
+                #//GetDataPointer end
+
+                #//GetDsmTypebuffer begin
+
+                exampleDSMType = exampleBuffer.GetDsmType()
+
+                #//GetDsmTypebuffer end
+
+                #//SetDsmTypebuffer begin
+
+                exampleBuffer.SetDsmType(XDMF_DSM_TYPE_UNIFORM)
+
+                #//SetDsmTypebuffer end
+
+                #//GetIsServerbuffer begin
+
+                exampleBufferIsServer = exampleBuffer.GetIsServer()
+
+                #//GetIsServerbuffer end
+
+                #//SetIsServerbuffer begin
+
+                exampleBuffer.SetIsServer(exampleIsServer)
+
+                #//SetIsServerbuffer end
+
+                #//GetStartAddress begin
+
+                exampleBufferStart = exampleBuffer.GetStartAddress()
+
+                #//GetStartAddress end
+
+                #//GetEndAddress begin
+
+                exampleBufferEnd = exampleBuffer.GetEndAddress()
+
+                #//GetEndAddress end
+
+                #//GetStartServerId begin
+
+                exampleServerStart = exampleBuffer.GetStartServerId()
+
+                #//GetStartServerId end
+
+                #//GetEndServerid begin
+
+                exampleServerEnd = exampleBuffer.GetEndServerId()
+
+                #//GetEndServerId end
+
+                #//GetLength begin
+
+                exampleBufferLength = exampleBuffer.GetLength()
+
+                #//GetLength end
+
+                #//UpdateLength begin
+
+                exampleBuffer.UpdateLength(exampleBufferLength)
+
+                #//UpdateLength end
+
+                #//GetTotalLength begin
+
+                exampleTotalBufferLength = exampleBuffer.GetTotalLength()
+
+                #//GetTotalLength end
+
+                #//GetBlockLengthbuffer begin
+
+                exampleBufferBlockLength = exampleBuffer.GetBlockLength()
+
+                #//GetBlockLengthbuffer end
+
+                #//SetBlockLengthbuffer begin
+
+                exampleBuffer.SetBlockLength(exampleBufferBlockLength)
+
+                #//SetBlockLengthbuffer end
+
+                '''
+                #//ConfigureUniform begin
+
+                exampleBuffer.ConfigureUniform(exampleBuffer.GetComm(), dsmSize/numServersCores, size - numServersCores, size - 1)
+
+                #//ConfigureUniform end
+                '''
+                sendingCore = -1
+
+                #//SendCommandHeader begin
+
+                if (id == sendingCore):
+                        exampleBuffer.SendCommandHeader(XDMF_DSM_OPCODE_DONE, 1, 0, 0, XDMF_DSM_INTER_COMM)
+
+                #//SendCommandHeader end
+
+                #//SendData begin
+
+                if (id == sendingCore):
+                        sentData = "datastring"
+                        exampleBuffer.SendData(1, sentData, 0, XDMF_DSM_PUT_DATA_TAG, 0, XDMF_DSM_INTER_COMM)
+
+                #//SendData end
+
+                #//SendAcknowledgment begin
+
+                if (id == 1):
+                        sentData = 1
+                        exampleBuffer.SendAcknowledgment(0, sentData, XDMF_DSM_PUT_DATA_TAG, XDMF_DSM_INTER_COMM)
+
+                #//SendAcknowledgment end
+
+                #//ReceiveAcknowledgement begin
+
+                if (id == 0):
+                        recvData = 0
+                        exampleBuffer.ReceiveAcknowledgment(1, recvData, XDMF_DSM_PUT_DATA_TAG, XDMF_DSM_INTER_COMM)
+
+                #//ReceiveAcknowledgement end
+
+
+
+                ServerIds = []
+
+                for i in range(0, (size - numServersCores) / 2):
+                        ServerIds.append(i)
+
+                readingCores = workerComm.Get_group().Excl(ServerIds)
+
+                readComm = workerComm.Create(readingCores)
+
+                writingCores = workerComm.Get_group().Incl(ServerIds)
+
+                writeComm = workerComm.Create(writingCores)
+
+                exampleBuffer.GetComm().DupComm(workerComm)
+
+                #//BufferService begin
+
+                if (id == 0):
+                        serviceOut = exampleBuffer.BufferService()
+
+                if (id == 1):
+                        exampleBuffer.SendCommandHeader(XDMF_DSM_OPCODE_DONE, 0, 0, 0, XDMF_DSM_INTER_COMM)
+
+                #//BufferService end
+
+                #//BufferServiceLoop begin
+
+                if (id == 0):
+                        exampleBuffer.BufferServiceLoop()
+
+                if (id == 1):
+                        exampleBuffer.SendCommandHeader(XDMF_DSM_OPCODE_DONE, 0, 0, 0, XDMF_DSM_INTER_COMM)
+
+                #//BufferServiceLoop end
+
+                #//AddressToId begin
+
+                correspondingId = exampleBuffer.AddressToId(500)
+
+                #//AddressToId end
+
+                #//GetComm begin
+
+                exampleDSMComm = exampleBuffer.GetComm()
+
+                #//GetComm end
+
+                #//SetComm begin
+
+                exampleBuffer.SetComm(exampleDSMComm)
+
+                #//SetComm end
+
+                #//GetId begin
+
+                exampleIntraID = exampleDSMComm.GetId()
+
+                #//GetId end
+
+                #//GetIntraSize begin
+
+                exampleIntraSize = exampleDSMComm.GetIntraSize()
+
+                #//GetIntraSize end
+
+                #//GetInterId begin
+
+                exampleInterID = exampleDSMComm.GetInterId()
+
+                #//GetInterId end
+
+                #//GetInterSize begin
+
+                exampleInterSize = exampleDSMComm.GetInterSize()
+
+                #//GetInterSize end
+
+                #//GetInterCommType begin
+
+                exampleInterCommType = exampleDSMComm.GetInterCommType()
+
+                #//GetInterCommType end
+
+                #//initcomm begin
+
+                exampleDSMComm.Init()
+
+                #//initcomm end
+
+                #//GetIntraComm begin
+
+                exampleIntraComm = exampleDSMComm.GetIntraComm()
+
+                #//GetIntraComm end
+
+                #//DupComm begin
+
+                exampleDSMComm.DupComm(exampleIntraComm.Dup())
+
+                #//DupComm end
+
+                #//DSMBarrier begin
+
+                exampleDSMComm.Barrier(XDMF_DSM_INTRA_COMM)
+
+                #//DSMBarrier end
+
+
+                print type(exampleDSMComm.GetDsmPortName())
+                testName = "test"
+                exampleDSMComm.SetDsmPortName(testName)
+                print exampleDSMComm.GetDsmPortName()
+
+                '''
+
+                connectingGroup = True
+                if (id < 5):
+                        connectingGroup = True;
+                else:
+                        connectingGroup = False;
+
+                portString = ""
+
+                if (!connectingGroup):
+                        exampleDSMComm.OpenPort()
+                        portString = exampleDSMComm.GetDsmPortName()
+                        // Send the port string to the connecting group
+                        exampleDSMComm.Accept()
+                        // When done with connection
+                        exampleDSMComm.ClosePort()
+
+                if (connectingGroup):
+                        // Recieve string from Master group
+                        exampleDSMComm.SetDsmPortName(portString)
+                        exampleDSMComm.Connect()
+                        // When done with connection
+                        exampleDSMComm.Disconnect()
+
+                if (connectingGroup):
+                        // Recieve string from Master group
+                        exampleDSMComm.SetDsmPortName(portString);
+                        exampleManager.Connect();
+                        // When done with connection
+                        exampleManager.Disconnect();
+
+                '''
+
+                # This is the end of the Demonstration
+
+                exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab)
+
+                testArray.insert(writeController)
+
+                for i in range(0, size-numServersCores):
+                        workerComm.Barrier()
+                        if (i == id):
+                                print "Core # " + str(id)
+                                print "Controller stats" 
+                                print "datasetpath = " + testArray.getHeavyDataController(0).getDataSetPath() 
+                                print "filepath = " + testArray.getHeavyDataController(0).getFilePath()
+                                outputVector = testArray.getHeavyDataController(0).getDataspaceDimensions()
+                                print "Data space dimensions" 
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller Dimensions"
+                                outputVector = testArray.getHeavyDataController(0).getDimensions()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller size"  + str(testArray.getHeavyDataController(0).getSize())
+                                print "Controller starts"
+                                outputVector = testArray.getHeavyDataController(0).getStart()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller strides"
+                                outputVector = testArray.getHeavyDataController(0).getStride()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                for j in range(0, testArray.getSize()):
+                                        print "core #" + str(id) + " testArray[" + str(j) + "] = " + str(testArray.getValueAsInt32(j))
+                testArray.accept(exampleWriter)
+
+                readStartVector = UInt32Vector()
+                readStartVector.push_back(4*(size - id - 1 - numServersCores))
+                readStrideVector = UInt32Vector()
+                readStrideVector.push_back(1)
+                readCountVector = UInt32Vector()
+                readCountVector.push_back(4)
+                readDataSizeVector = UInt32Vector()
+                readDataSizeVector.push_back(4*(size-numServersCores))
+
+                readArray = XdmfArray.New()
+
+                readArray.initializeAsInt32(0)
+                readArray.reserve(testArray.getSize())
+
+                readController = XdmfHDF5ControllerDSM.New(
+                        newPath,
+                        newSetPath,
+                        XdmfArrayType.Int32(),
+                        readStartVector,
+                        readStrideVector,
+                        readCountVector,
+                        readDataSizeVector,
+                        exampleWriter.getServerBuffer())
+
+                readArray.insert(readController)
+
+                if (id == 0):
+                        print "\n\n\n"
+
+                print "testing read"
+                readArray.read()
+
+
+                for i in range (0, size):
+                        workerComm.Barrier()
+                        if (i == id):
+                                print "Core # " + str(id)
+                                print "Controller stats"
+                                print "datasetpath = " + readArray.getHeavyDataController(0).getDataSetPath()
+                                print "filepath = " + readArray.getHeavyDataController(0).getFilePath()
+                                outputVector = readArray.getHeavyDataController(0).getDataspaceDimensions()
+                                print "Data space dimensions"
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller Dimensions"
+                                outputVector = readArray.getHeavyDataController(0).getDimensions()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller size" + str(readArray.getHeavyDataController(0).getSize())
+                                print "Controller starts"
+                                outputVector = readArray.getHeavyDataController(0).getStart()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                print "Controller strides"
+                                outputVector = readArray.getHeavyDataController(0).getStride()
+                                for j in range(0, outputVector.size()):
+                                        print "[" + str(j) + "] =" + str(outputVector[j])
+                                for j in range (0, readArray.getSize()):
+                                        print "core #" + str(id) + " readArray[" + str(j) + "] = " + str(readArray.getValueAsInt32(j))
+
+                workerComm.Barrier()
+
+                # End of Work Section
+
+        #//stopDSMwriter begin
+
+        if (id == 0):
+                exampleWriter.stopDSM()
+
+        #//stopDSMwriter end
+
+        '''
+        #//stopDSMcontroller begin
+
+
+        if (id == 0):
+                exampleController.stopDSM()
+
+        #//stopDSMcontroller end
+
+        #//sendDone begin
+
+        if (id == 0):
+                closeBuffer = exampleWriter.getServerBuffer()
+                closeBuffer.SendDone()
+
+        #//sendDone end
+
+        '''
+        #//GetInterComm begin
+
+        exampleDSMComm = exampleWriter.getServerBuffer().GetComm()
+
+        exampleInterComm = exampleDSMComm.GetInterComm()
+
+        #//GetInterComm end
+
+        #//DupInterComm begin
+
+        exampleDSMComm.DupInterComm(exampleInterComm.Dup())
+
+        #//DupInterComm end
+
+        #//SendRecvInfo begin
+
+        if (id >= size - numServersCores):
+                exampleWriter.getServerBuffer().SendInfo()
+        else:
+                exampleWriter.getServerBuffer().ReceiveInfo()
+
+        #//SendRecvInfo end
+
+        '''
+        #//restartDSMwriter begin
+
+        exampleWriter.restartDSM()
+
+        #//restartDSMwriter end
+
+        #//restartDSMcontroller begin
+
+        exampleController.restartDSM()
+
+        #//restartDSMcontroller end
+        '''
+
+        #//finalizeMPI
+
+        exampleWriter.deleteManager()
+
+        #//finalizeMPI
+
+        '''
+        exampleController.deleteManager()
+        '''
diff --git a/examples/Python/XdmfExampleDSMStandalone.py b/examples/Python/XdmfExampleDSMStandalone.py
new file mode 100644
index 0000000..51171de
--- /dev/null
+++ b/examples/Python/XdmfExampleDSMStandalone.py
@@ -0,0 +1,283 @@
+from Xdmf import *
+from mpi4py.MPI import * #the act of importing this automatically calls Init
+
+if __name__ == "__main__":
+        #//initMPI begin
+
+        comm = COMM_WORLD
+
+        dsmSize = 64
+
+        id = comm.Get_rank()
+        size = comm.Get_size()
+
+        coreSize = int(dsmSize/size)
+
+        #//initMPI end
+
+        exampleArray = XdmfArray.New()
+        exampleArray.initializeAsInt32(0)
+
+        #Writing form all cores
+
+        #//writevectorinit begin
+
+        newPath = "dsm"
+        newSetPath = "data"
+
+        writeStarts = UInt32Vector()
+        writeCounts = UInt32Vector()
+        writeStrides = UInt32Vector()
+        writeDataSize = UInt32Vector()
+
+        writeStarts.push_back(id*4)
+        writeCounts.push_back(4)
+        writeStrides.push_back(1)
+        writeDataSize.push_back(size*4)
+
+        #//writevectorinit end
+
+        for i in range (1, 5):
+                exampleArray.pushBackAsInt32(i*id)
+
+
+        #writing from one core
+        #if id == 0:
+        #       for i in range (1, (size*4)+1):
+        #               exampleArray.pushBackAsInt32(i)
+        #       writeStarts.push_back(0)
+        #       writeCounts.push_back(size*4)
+        #       writeStrides.push_back(1)
+        #       writeDataSize.push_back(size*4)
+        #else:
+        #       writeStarts.push_back(0)
+        #       writeCounts.push_back(0)
+        #       writeStrides.push_back(1)
+        #       writeDataSize.push_back(size*4)
+
+        #writing with arrays of different sizes
+        #startposition = 0
+        #for i in range(0, id):
+        #       startposition = startposition + i + 1
+        #totaldata = 0
+        #for i in range(0, size):
+        #       totaldata = totaldata + i + 1
+        #for i in range(0, id+1):
+        #       exampleArray.pushBackAsInt32(id)
+        #writeStarts.push_back(startposition)
+        #writeCounts.push_back(id+1)
+        #writeStrides.push_back(1)
+        #writeDataSize.push_back(totaldata)
+
+        #//initwritergenerate begin
+
+        #Python has to do it this way because H5FD isn't wrapped to Python
+        #If this is used the manager must be deleted before the program ends.
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, comm, coreSize)
+
+        #//initwritergenerate end
+
+        #//initcontrollerwithbuffer begin
+
+        writeController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStarts,
+                writeStrides,
+                writeCounts,
+                writeDataSize,
+                exampleWriter.getBuffer())
+
+        #//initcontrollerwithbuffer end
+
+        #//setManagercontroller begin
+
+        writeController.setManager(exampleWriter.getManager())
+
+        #//setManagercontroller end
+
+        #//setBuffercontroller begin
+
+        writeController.setBuffer(exampleWriter.getBuffer())
+
+        #//setBuffercontroller end
+
+        exampleWriter.deleteManager()
+
+        #//initcontrollergenerate begin
+
+        #Python has to do it this way because H5FD isn't wrapped to Python
+        #If this is used the manager must be deleted before the program ends.
+        writeController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                writeStarts,
+                writeStrides,
+                writeCounts,
+                writeDataSize,
+                comm,
+                coreSize)
+
+        #//initcontrollergenerate end
+
+        #//initwriterwithbuffer begin
+
+        exampleWriter = XdmfHDF5WriterDSM.New(newPath, writeController.getBuffer())
+
+        #//initwriterwithbuffer end
+
+        #//setManagerwriter begin
+
+        exampleWriter.setManager(writeController.getManager())
+
+        #//setManagerwriter end
+
+        #//setBufferwriter begin
+
+        exampleWriter.setBuffer(writeController.getBuffer())
+
+        #//setBufferwriter end
+
+        exampleWriter.setMode(XdmfHeavyDataWriter.Hyperslab);
+
+        exampleArray.insert(writeController);
+
+        for i in range (0, size):
+                comm.Barrier()
+                if i == id:
+                        print "Core # " + str(id)
+                        print "Controller Stats"
+                        print "datasetpath = " + exampleArray.getHeavyDataController(0).getDataSetPath()
+                        print "filepath = " + exampleArray.getHeavyDataController(0).getFilePath()
+                        print "Dataspace Dimensions"
+                        outputVector = exampleArray.getHeavyDataController(0).getDataspaceDimensions()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        print "Controller Dimensions"
+                        outputVector = exampleArray.getHeavyDataController(0).getDimensions()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        print "Controller Size = " + str(exampleArray.getHeavyDataController(0).getSize())
+                        print "Controller Starts"
+                        outputVector = exampleArray.getHeavyDataController(0).getStart()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        print "Controller strides"
+                        outputVector = exampleArray.getHeavyDataController(0).getStride()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        for j in range (0, exampleArray.getSize()):
+                                print "Core #" + str(id) +" exampleArray[" + str(j) + "] = " + str(exampleArray.getValueAsInt32(j))
+
+        exampleArray.accept(exampleWriter)
+
+        readStarts = UInt32Vector()
+        readCounts = UInt32Vector()
+        readStrides = UInt32Vector()
+        readDataSize = UInt32Vector()
+
+        #read equal size arrays for all cores
+        readStarts.push_back((size - id - 1) * 4)
+        readCounts.push_back(4)
+        readStrides.push_back(1)
+        readDataSize.push_back(size*4)
+
+        #read to one core
+        #if (id == 0):
+        #       readStarts.push_back(0)
+        #       readCounts.push_back(4*size)
+        #       readStrides.push_back(1)
+        #       readDataSize.push_back(size*4)
+        #else:
+        #       readStarts.push_back(0)
+        #       readCounts.push_back(0)
+        #       readStrides.push_back(1)
+        #       readDataSize.push_back(size*4)
+
+        #for arrays of different sizes
+        #readStarts.push_back(totaldata - startposition - 1 - id)
+        #readCounts.push_back(id+1)
+        #readStrides.push_back(1)
+        #readDataSize.push_back(totaldata)
+
+        readArray = XdmfArray.New()
+
+        readArray.initializeAsInt32(0)
+        readArray.reserve(exampleArray.getSize())
+
+        readController = XdmfHDF5ControllerDSM.New(
+                newPath,
+                newSetPath,
+                XdmfArrayType.Int32(),
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize,
+                exampleWriter.getBuffer())
+
+        readArray.insert(readController)
+
+        print "testing read"
+        readArray.read()
+        print "done testing read"
+
+        for i in range (0, size):
+                comm.Barrier()
+                if i == id:
+                        print "Core # " + str(id)
+                        print "Controller Stats"
+                        print "datasetpath = " + readArray.getHeavyDataController(0).getDataSetPath()
+                        print "filepath = " + readArray.getHeavyDataController(0).getFilePath()
+                        print "Dataspace Dimensions"
+                        outputVector = readArray.getHeavyDataController(0).getDataspaceDimensions()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        print "Controller Dimensions"
+                        outputVector = readArray.getHeavyDataController(0).getDimensions()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        print "Controller Size = " + str(readArray.getHeavyDataController(0).getSize())
+                        print "Controller Starts"
+                        outputVector = readArray.getHeavyDataController(0).getStart()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        print "Controller strides"
+                        outputVector = readArray.getHeavyDataController(0).getStride()
+                        j=0
+                        for item in outputVector:
+                                print "[" + str(j) + "] = " + str(item)
+                                j = j + 1
+                        for j in range (0, readArray.getSize()):
+                                print "Core #" + str(id) +" exampleArray[" + str(j) + "] = " + str(readArray.getValueAsInt32(j))
+
+        #//deleteManagerwriter begin
+
+        exampleWriter.deleteManager()
+
+        #//deleteManagerwriter end
+
+        '''
+        #//deleteManagercontroller
+
+        writeController.deleteManager()
+
+        #//deleteManagercontroller
+        '''
+
+        #finalize is automatically called on program exit
diff --git a/examples/Python/XdmfExampleDomain.py b/examples/Python/XdmfExampleDomain.py
new file mode 100644
index 0000000..8cfa4ae
--- /dev/null
+++ b/examples/Python/XdmfExampleDomain.py
@@ -0,0 +1,9 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleDomain = XdmfDomain.New()
+
+        #//initialization end
diff --git a/examples/Python/XdmfExampleEdit.py b/examples/Python/XdmfExampleEdit.py
new file mode 100644
index 0000000..b25e600
--- /dev/null
+++ b/examples/Python/XdmfExampleEdit.py
@@ -0,0 +1,568 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        exampleReader = XdmfReader.New()
+
+        '''
+        This is assuming that the read item is an XdmfDomain object
+        '''
+        primaryDomain = exampleReader.read("testoutput.xmf")
+        outputInformation = primaryDomain.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "The Domain's tag is: " + primaryDomain.getItemTag()
+
+        gridHolder = primaryDomain.getGridCollection(0)
+
+        print "The Grid Collection's tag is: " + gridHolder.getItemTag()
+        print "The Grid Collection's name is: " + gridHolder.getName()
+        outputInformation = gridHolder.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+
+        for property in gridHolder.getItemProperties():
+                print property + ": " + gridHolder.getItemProperties()[property]
+
+        if gridHolder.getType() == XdmfGridCollectionType.Spatial():
+                print "This is a spatial grid collection"
+        else:
+                print "This is not a spatial grid collection"
+
+        i=0
+        outstring = ""
+        while i < gridHolder.getNumberMaps():
+                readMap = gridHolder.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                outstring = outstring + "Map # " + str(i) + "\n"
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        print outstring
+
+        print "Unstructured Grid"
+        ungrid = gridHolder.getUnstructuredGrid(0)
+        print "The Unstructured Grid's tag is: " + ungrid.getItemTag()
+        print "The Unstructured Grid's name is: " + ungrid.getName()
+        for property in ungrid.getItemProperties():
+                print property + ": " + ungrid.getItemProperties()[property]
+        print "The Unstructured Grid's time is: " + str(ungrid.getTime().getValue())
+        i=0
+        outstring = ""
+        while i < ungrid.getNumberMaps():
+                readMap = ungrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < ungrid.getNumberSets():
+                readSet = ungrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                outputInformation = readSet.getInformation(0)
+                print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attrubte is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i=i+1
+        i=0
+        while i < ungrid.getNumberAttributes():
+                readAttribute = ungrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attrubte is not a node"
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Unstructured Topology"
+        untopology = ungrid.getTopology()
+        if not untopology.isInitialized():
+                untopology.read()
+        print "The topology's tag: " + untopology.getItemTag()
+        if untopology.getType() == XdmfTopologyType.Hexahedron():
+                print "This topology is a hexahedron"
+        else:
+                print "This topology is not a hexahedron"
+        print "Contains " + str(untopology.getNumberElements()) + " elements"
+        print "Contains the values: " + untopology.getValuesString()
+
+        print "Unstructured Geometry"
+        ungeometry = ungrid.getGeometry()
+        if not ungeometry.isInitialized():
+                ungeometry.read()
+        print "The geometry's tag: " +ungeometry.getItemTag()
+        if ungeometry.getType() == XdmfGeometryType.XYZ():
+                print "This geometry is XYZ"
+        else:
+                print "This geometry is not XYZ"
+        outputInformation = ungeometry.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "Contains " + str(ungeometry.getNumberPoints()) + " points"
+        print "Contains the values: " + ungeometry.getValuesString()
+
+
+        print "Curvilinear Grid"
+        curvgrid = gridHolder.getCurvilinearGrid(0)
+        print "The Curvilinear Grid's tag is: " + curvgrid.getItemTag()
+        print "The Curvilinear Grid's name is: " + curvgrid.getName()
+        for property in curvgrid.getItemProperties():
+                print property + ": " + curvgrid.getItemProperties()[property]
+        outputInformation = curvgrid.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "The Curvilinear Grid's time is: " + str(curvgrid.getTime().getValue())
+        outputInformation = curvgrid.getTime().getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        i=0
+        outstring = ""
+        while i < curvgrid.getNumberMaps():
+                readMap = curvgrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < curvgrid.getNumberSets():
+                readSet = curvgrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attrubte is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i=i+1
+        i=0
+        while i < curvgrid.getNumberAttributes():
+                readAttribute = curvgrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attrubte is not a node"
+                outputInformation = readAttribute.getInformation(0)
+                print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Curvilinear Dimensions"
+        curvdimensions = curvgrid.getDimensions()
+        if not curvdimensions.isInitialized():
+                curvdimensions.read()
+        print "The dimensions' tag: " + curvdimensions.getItemTag()
+        print "Contains the values: " + curvdimensions.getValuesString()
+
+        print "Curvilinear Geometry"
+        curvgeometry = curvgrid.getGeometry()
+        if not curvgeometry.isInitialized():
+                curvgeometry.read()
+        print "The geometry's tag: " + curvgeometry.getItemTag()
+        if curvgeometry.getType() == XdmfGeometryType.XYZ():
+                print "This geometry is XYZ"
+        else:
+                print "This geometry is not XYZ"
+        outputInformation = curvgeometry.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "Contains " + str(curvgeometry.getNumberPoints()) + " points"
+        print "Contains the values: " + curvgeometry.getValuesString()
+
+
+        print "Rectilinear Grid"
+        rectgrid = gridHolder.getRectilinearGrid(0)
+        print "The Rectilinear Grid's tag is: " + rectgrid.getItemTag()
+        print "The Rectilinear Grid's name is: " + rectgrid.getName()
+        for property in rectgrid.getItemProperties():
+                print property + ": " + rectgrid.getItemProperties()[property]
+        print "The Rectilinear Grid's time is: " + str(rectgrid.getTime().getValue())
+        i=0
+        outstring = ""
+        while i < rectgrid.getNumberMaps():
+                readMap = rectgrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < rectgrid.getNumberSets():
+                readSet = rectgrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attrubte is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i=i+1
+        i=0
+        while i < rectgrid.getNumberAttributes():
+                readAttribute = rectgrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attrubte is not a node"
+                outputInformation = readAttribute.getInformation(0)
+                print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Rectilinear Dimensions"
+        rectdimensions = rectgrid.getDimensions()
+        if not rectdimensions.isInitialized():
+                rectdimensions.read()
+        print "The dimensions' tag: " + rectdimensions.getItemTag()
+        print "Contains the values: " + rectdimensions.getValuesString()
+
+        print "Rectilinear Coordinates"
+        rectcoordinates = rectgrid.getCoordinates()
+        print "Contains the values: "
+        for coordinateaxes in rectcoordinates:
+                if not coordinateaxes.isInitialized():
+                        coordinateaxes.read()
+                print coordinateaxes.getValuesString()
+
+        print "Regular Grid"
+        reggrid = gridHolder.getRegularGrid(0)
+        print "The Regular Grid's tag is: " + reggrid.getItemTag()
+        print "The Regular Grid's name is: " + reggrid.getName()
+        for property in reggrid.getItemProperties():
+                print property + ": " + reggrid.getItemProperties()[property]
+        print "The Regular Grid's time is: " + str(reggrid.getTime().getValue())
+        i=0
+        outstring = ""
+        while i < reggrid.getNumberMaps():
+                readMap = reggrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < reggrid.getNumberSets():
+                readSet = reggrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attrubte is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i=i+1
+        i=0
+        while i < reggrid.getNumberAttributes():
+                readAttribute = reggrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attrubte is not a node"
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Regular Brick Size"
+        regbricksize = reggrid.getBrickSize()
+        if not regbricksize.isInitialized():
+                regbricksize.read()
+        print "The brick's tag: " + regbricksize.getItemTag()
+        print "Contains the values: " + regbricksize.getValuesString()
+
+        print "Regular Number of Points"
+        regnumpoints = reggrid.getDimensions()
+        if not regnumpoints.isInitialized():
+                regnumpoints.read()
+        print "The dimensions' tag: " + regnumpoints.getItemTag()
+        print "Contains the values: " + regnumpoints.getValuesString()
+
+        print "Regular Origin"
+        regorigin = reggrid.getOrigin()
+        if not regorigin.isInitialized():
+                regorigin.read()
+        print "The origin's tag: " + regorigin.getItemTag()
+        print "Contains the values: " + regorigin.getValuesString()
+
+
+
+        primaryDomain.getInformation(0).setKey("Edited")
+        primaryDomain.getInformation(0).setValue("This file is the edited version")
+
+        unglobalIDs = ungrid.getAttribute(0)
+        newIDs1 = [5,2,8,7,9,1]
+        unglobalIDs.insertAsInt32(0, newIDs1)
+
+        unset = ungrid.getSet(0)
+        newunsetdata = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 0.23]
+        unset.insertAsFloat64(0, newunsetdata)
+
+        untopology = ungrid.getTopology()
+        untopologydata = [int(val) for val in untopology.getValuesString().split()]
+        i=0
+        while i<len(untopologydata):
+                untopologydata[i] = untopologydata[i] + 1
+                i = i + 1
+        untopology.insertAsInt32(0, untopologydata)
+
+        ungeometry = ungrid.getGeometry()
+        ungeometrydata = [float(val) for val in ungeometry.getValuesString().split()]
+        i=0
+        while i<len(ungeometrydata):
+                ungeometrydata[i] = ungeometrydata[i] + 1
+                i = i + 1
+        ungeometry.insertAsFloat64(0, ungeometrydata)
+
+
+        curvglobalIDs = curvgrid.getAttribute(0)
+        newIDs2 = [3, 6, 2, 8, 1, 7, 5]
+        curvglobalIDs.insertAsInt32(0, newIDs2)
+
+        curvgeometry = curvgrid.getGeometry()
+        curvgeometrydata = [float(val) for val in curvgeometry.getValuesString().split()]
+        i=0
+        while i<len(curvgeometrydata):
+                curvgeometrydata[i] = curvgeometrydata[i] + 1
+                i = i + 1
+        i=0
+        while i<3:
+                curvgeometrydata.append(len(curvgeometrydata))
+                i = i + 1
+        curvgeometry.insertAsFloat64(0, curvgeometrydata)
+
+        curvdimensions = curvgrid.getDimensions()
+        curvdimensiondata = [int(val) for val in curvdimensions.getValuesString().split()]
+        i=0
+        while i< len(curvdimensiondata):
+                curvdimensiondata[i] = curvdimensiondata[i] + 1
+                i = i + 1
+        curvdimensions.insertAsInt32(0, curvdimensiondata)
+
+
+        rectglobalIDs = rectgrid.getAttribute(0)
+        newIDs3 = [6, 4, 3, 7, 9, 8]
+        rectglobalIDs.insertAsInt32(0, newIDs3)
+
+        rectdimensions = rectgrid.getDimensions()
+        rectdimensiondata = [int(val) for val in rectdimensions.getValuesString().split()]
+        i=0
+        while i < len(rectdimensiondata):
+                rectdimensiondata[i] = rectdimensiondata[i] + 1
+                i = i + 1
+        rectdimensions.insertAsInt32(0, rectdimensiondata)
+
+        rectcoordinates = rectgrid.getCoordinates()
+        for coordinateaxes in rectcoordinates:
+                coordinatedata = [float(val) for val in coordinateaxes.getValuesString().split()]
+                i=0
+                while i < len(coordinatedata):
+                        coordinatedata[i] = coordinatedata[i] + 1
+                        i = i + 1
+                coordinatedata.append(len(coordinatedata))
+                coordinateaxes.insertAsFloat64(0, coordinatedata)
+
+        regglobalIDs = reggrid.getAttribute(0)
+        newIDs4 = [3, 5, 1, 2, 4, 8, 0]
+        regglobalIDs.insertAsInt32(0, newIDs4)
+
+        regbricksize = reggrid.getBrickSize()
+        brickdata = [float(val) for val in regbricksize.getValuesString().split()]
+        i=0
+        while i < len(brickdata):
+                brickdata[i] = brickdata[i] + 1
+                i = i + 1
+        regbricksize.insertAsFloat64(0, brickdata)
+        reggrid.setBrickSize(regbricksize)
+
+        regdimensions = reggrid.getDimensions()
+        regdimensiondata = [int(val) for val in regdimensions.getValuesString().split()]
+        i=0
+        while i < len(regdimensiondata):
+                regdimensiondata[i] = regdimensiondata[i] + 1
+                i = i + 1
+        regdimensions.insertAsInt32(0, regdimensiondata)
+        reggrid.setDimensions(regdimensions)
+
+        regorigin = reggrid.getOrigin()
+        regorigindata = [float(val) for val in regorigin.getValuesString().split()]
+        i=0
+        while i < len(regorigindata):
+                regorigindata[i] = regorigindata[i] + 1
+                i = i + 1
+        regorigin.insertAsFloat64(0, regorigindata)
+        reggrid.setOrigin(regorigin)
+
+
+
+        exampleWriter = XdmfWriter.New("editedtestoutput.xmf")
+        primaryDomain.accept(exampleWriter)
diff --git a/examples/Python/XdmfExampleError.py b/examples/Python/XdmfExampleError.py
new file mode 100644
index 0000000..f8e6903
--- /dev/null
+++ b/examples/Python/XdmfExampleError.py
@@ -0,0 +1,72 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//getLevelLimit begin
+
+        exampleLevel = XdmfError.getLevelLimit()
+        #these are considered integers in Python
+
+        #//getLevelLimit end
+
+        #//setLevelLimit begin
+
+        XdmfError.setLevelLimit(XdmfError.FATAL)
+
+        #//setLevelLimit end
+
+        #//getSuppressionLevel begin
+
+        exampleSuppression = XdmfError.getSuppressionLevel()
+
+        #//getSuppressionLevel end
+
+        #//setSuppressionLevel begin
+
+        XdmfError.setSuppressionLevel(XdmfError.DEBUG)
+
+        #//setSuppressionLevel end
+
+        #//message begin
+
+        try:
+                XdmfError::message(XdmfError::FATAL, "this is an example error")
+        except RuntimeError as exampleError:
+                print exampleError
+
+        #//message end
+
+        #//what begin
+
+        try:
+                raise RuntimeError(XdmfError(XdmfError.FATAL, "testError"))
+        except RuntimeError as exampleError:
+                errorString = e.args[0].what()
+
+        #//what end
+
+        #//getLevel begin
+
+        try:
+                raise RuntimeError(XdmfError(XdmfError.FATAL, "testError"))
+        except RuntimeError as exampleError:
+                errorLevel = e.args[0].getLevel()
+
+        #//getLevel end
+
+        #//setLevel begin
+
+        try:
+                raise RuntimeError(XdmfError(XdmfError.FATAL, "testError"))
+        except RuntimeError as exampleError:
+                e.args[0].setLevel(XdmfError.FATAL)
+
+        #//setLevel end
+
+        #//initialization begin
+
+        try:
+                raise RuntimeError(XdmfError(XdmfError.FATAL, "testError"))
+        except RuntimeError as exampleError:
+                print exampleError
+
+        #//initialization end
diff --git a/examples/Python/XdmfExampleFunction.py b/examples/Python/XdmfExampleFunction.py
new file mode 100644
index 0000000..9f5dc45
--- /dev/null
+++ b/examples/Python/XdmfExampleFunction.py
@@ -0,0 +1,410 @@
+from Xdmf import *
+from numpy import *
+
+#//definefunction begin
+
+def maximum(values):
+        # Need to cast to the right data type
+        values = ArrayVector(values)
+        if values[0].getArrayType() == XdmfArrayType.String():
+                returnArray = XdmfArray.New()
+                returnArray.pushBackAsString(values[0].getValueAsString(0))
+                return returnArray;
+        else:
+                maxVal = values[0].getValueAsFloat64(0)
+                for i in range (0, values.size()):
+                        for j in range (0, values[i].getSize()):
+                                if maxVal < values[i].getValueAsFloat64(j):
+                                        maxVal = values[i].getValueAsFloat64(j)
+                returnArray = XdmfArray.New()
+                returnArray.pushBackAsFloat64(maxVal)
+                return returnArray
+
+#//definefunction end
+
+#//defineoperation begin
+
+def prepend(val1, val2):
+        # Need to cast to the right data type
+        # Had to write a custom casting method to integrate it properly
+        val1 = XdmfArray.XdmfArrayPtr(val1)
+        val2 = XdmfArray.XdmfArrayPtr(val2)
+        returnArray = XdmfArray.New()
+        returnArray.insert(0, val2, 0, val2.getSize())
+        returnArray.insert(val2.getSize(), val1, 0, val1.getSize())
+        return returnArray
+
+#//defineoperation end
+
+#//programstart begin
+
+if __name__ == "__main__":
+
+        #//programstart end
+
+        #//getSupportedOperations begin
+
+        exampleOperations = XdmfFunction.getSupportedOperations()
+
+        #//getSupportedOperations end
+
+        #//getSupportedFunctions begin
+
+        exampleFunctions = XdmfFunction.getSupportedFunctions()
+
+        #//getSupportedFunctions end
+
+        #//getValidVariableChars begin
+
+        exampleVariableChars = XdmfFunction.getValidVariableChars()
+
+        #//getValidVariableChars end
+
+        #//getValidDigitChars begin
+
+        exampleDigitChars = XdmfFunction.getValidDigitChars()
+
+        #//getValidDigitChars end
+
+        #//getOperationPriority begin
+
+        examplePriority = XdmfFunction.getOperationPriority('|')
+
+        #//getOperationPriority end
+
+        #//valueinit begin
+
+        valueArray1 = XdmfArray.New()
+        valueArray1.pushBackAsInt32(1)
+        valueArray1.pushBackAsInt32(2)
+        valueArray1.pushBackAsInt32(3)
+        valueArray1.pushBackAsInt32(4)
+        valueArray2 = XdmfArray.New()
+        valueArray2.pushBackAsInt32(9)
+        valueArray2.pushBackAsInt32(8)
+        valueArray2.pushBackAsInt32(7)
+        valueArray2.pushBackAsInt32(6)
+
+        valueVector = ArrayVector()
+        valueVector.push_back(valueArray1)
+        valueVector.push_back(valueArray2)
+
+        #//valueinit end
+
+        #//sum begin
+
+        answerArray = XdmfFunction.sum(valueVector)
+
+        #//sum end
+
+        #//average begin
+
+        answerArray = XdmfFunction.average(valueVector)
+
+        #//average end
+
+        #//chunk begin
+
+        answerArray = XdmfFunction.chunk(valueArray1, valueArray2)
+
+        #//chunk end
+
+        #//interlace begin
+
+        answerArray = XdmfFunction.interlace(valueArray1, valueArray2)
+
+        #//interlace end
+
+        #//addOperation begin
+
+        exampleNumOperations = XdmfFunction.addOperation('@', prepend, 2)
+
+        #//addOperation end
+
+        #//evaluateOperation begin
+
+        answerArray = XdmfFunction.evaluateOperation(valueArray1, valueArray2, '@')
+
+        #//evaluateOperation end
+
+        #//addFunction begin
+
+        exampleNumFunctions = XdmfFunction.addFunction("MAX", maximum)
+
+        #//addFunction end
+
+        #//evaluateFunction begin
+
+        answerArray = XdmfFunction.evaluateFunction(valueVector, "MAX")
+
+        #//evaluateFunction end
+
+        #//evaluateExpression begin
+
+        valueMap = ArrayMap()
+        valueMap["A"] = valueArray1
+        valueMap["B"] = valueArray2
+
+        parsedExpression = "MAX(A,B)@(A#B)"
+        answerArray = XdmfFunction.evaluateExpression(parsedExpression, valueMap)
+
+        #//evaluateExpression end
+
+        #//initialization begin
+
+        testFunction = XdmfFunction.New()
+
+        #//initalization end
+
+        #//initexpression begin
+
+        functionExpression = "AVE(A)"
+        variableArray = XdmfArray.New()
+
+        for i in range(0, 10):
+                variableArray.pushBackAsInt32(i)
+
+        variableMap = ArrayMap()
+        variableMap["A"] = variableArray;
+
+        exampleFunction = XdmfFunction.New(functionExpression, variableMap)
+
+        #//initexpression end
+
+        #//setExpression begin
+
+        newExpression = "SUM(A)"
+        exampleFunction.setExpression(newExpression)
+
+        #//setExpression end
+
+        #//getExpression begin
+
+        exampleExpression = exampleFunction.getExpression()
+
+        #//getExpression end
+
+        #//insertVariable begin
+
+        secondVariableArray = XdmfArray.New()
+
+        for i in range(0, 10):
+                secondVariableArray.pushBack(i)
+
+        exampleFunction.insertVariable("B", secondVariableArray)
+
+        #//insertVariable end
+
+        #//getVariable begin
+
+        variableValue = exampleFunction->getVariable("B")
+
+        #//getVariable end
+
+        #//getVariableList begin
+
+        exampleVarList = exampleFunction.getVariableList()
+
+        #//getVariableList end
+
+        #//removeVariable begin
+
+        exampleFunction.removeVariable("B")
+
+        #//removeVariable end
+
+        #//setConstructedType begin
+
+        typeAttribute = XdmfAttribute.New()
+
+        exampleFunction.setConstructedType(typeAttribute.getItemTag())
+
+        #//setConstructedType end
+
+        #//getConstructedType begin
+
+        std::string exampleType = exampleFunction->getConstructedType();
+
+        #//getConstructedType end
+
+        #//setConstructedProperties begin
+
+        propertyAttribute = XdmfAttributeNew()
+        exampleFunction.setConstructedProperties(propertyAttribute.getItemProperties())
+
+        #//setConstructedProperties end
+
+        #//getConstructedProperties begin
+
+        exampleProperties = exampleFunction.getConstructedProperties()
+
+        #//getConstructedProperties end
+
+        #//read begin
+
+        functionResult = exampleFunction.read()
+
+        #//read end
+
+        #//abs begin
+
+        toBeAbs = XdmfArray.New()
+        toBeAbs.pushBackAsFloat64(-5.5)
+        absVector = ArrayVector()
+        absVector.push_back(toBeAbs)
+        absResult = XdmfFunction.abs(absVector)
+        assert absResult.getValuesString() == "5.5"
+
+        #//abs end
+
+        #//arcsin begin
+
+        toBeArcsin = XdmfArray.New()
+        toBeArcsin.pushBackAsFloat64(-0.5)
+        arcsinVector = ArrayVector()
+        arcsinVector.push_back(toBeArcsin)
+        arcsinResult = XdmfFunction.arcsin(arcsinVector)
+        assert arcsinResult.getValuesString() == "-0.52359877559829893"
+
+        #//arcsin end
+
+        #//arccos begin
+
+        toBeArccos = XdmfArray.New()
+        toBeArccos.pushBackAsFloat64(-0.5)
+        arccosVector = ArrayVector()
+        arccosVector.push_back(toBeArccos)
+        arccosResult = XdmfFunction.arccos(arccosVector)
+        assert arccosResult.getValuesString() == "2.0943951023931957"
+
+        #//arccos end
+
+        #//cos begin
+
+        toBeCos = XdmfArray.New()
+        toBeCos.pushBackAsFloat64(-0.5)
+        cosVector = ArrayVector()
+        cosVector.push_back(toBeCos)
+        cosResult = XdmfFunction.cos(cosVector)
+        assert cosResult.getValuesString() == "0.87758256189037276"
+
+        #//cos end
+
+        #//sin begin
+
+        toBeSin = XdmfArray.New()
+        toBeSin.pushBackAsFloat64(-0.5)
+        sinVector = ArrayVector()
+        sinVector.push_back(toBeSin)
+        sinResult = XdmfFunction.sin(sinVector)
+        assert sinResult.getValuesString() == "-0.47942553860420301"
+
+        #//sin end
+
+        #//tan begin
+
+        toBeTan = XdmfArray.New()
+        toBeTan.pushBackAsFloat64(-0.5)
+        tanVector = ArrayVector()
+        tanVector.push_back(toBeTan)
+        tanResult = XdmfFunction.tan(tanVector)
+        assert tanResult.getValuesString() == "-0.54630248984379048"
+
+        #//tan end
+
+        #//sqrt begin
+
+        toBeSqrt = XdmfArray.New()
+        toBeSqrt.pushBackAsFloat64(2)
+        sqrtVector = ArrayVector()
+        sqrtVector.push_back(toBeSqrt)
+        sqrtResult = XdmfFunction.sqrt(sqrtVector)
+        assert sqrtResult.getValuesString() == "1.4142135623730951"
+
+        #//sqrt end
+
+        #//log begin
+
+        toBeLog = XdmfArray.New()
+        toBeLog.pushBackAsFloat64(2)
+        logBase = XdmfArray.New()
+        logBase.pushBackAsFloat64(4)
+        logVector = ArrayVector()
+        logVector.push_back(toBeLog)
+        logVector.push_back(logBase)
+        logResult = XdmfFunction.log(logVector)
+        assert logResult.getValuesString() == "0.5"
+
+        #//log end
+
+        #//exp begin
+
+        powerBase = XdmfArray.New()
+        powerBase.pushBackAsFloat64(-0.5)
+        powerFactor = XdmfArray.New()
+        powerFactor.pushBackAsFloat64(2)
+        expVector = ArrayVector()
+        expVector.push_back(powerBase)
+        expVector.push_back(powerFactor)
+        expResult = XdmfFunction.exponent(expVector)
+        assert expResult.getValuesString() == "0.25"
+
+        #//exp end
+
+        #//join begin
+
+        array1 = XdmfArray.New()
+        array1.pushBackAsFloat64(-0.5)
+        array2 = XdmfArray.New()
+        array2.pushBackAsFloat64(2)
+        joinVector = ArrayVector()
+        joinVector.push_back(array1)
+        joinVector.push_back(array2)
+        joinResult = XdmfFunction.join(joinVector)
+        assert joinResult.getValuesString() == "-0.5 2"
+
+        #//join end
+
+        #//addition begin
+
+        addArray1 = XdmfArray.New()
+        addArray1.pushBackAsFloat64(-0.5)
+        addArray2 = XdmfArray.New()
+        addArray2.pushBackAsFloat64(2)
+        addResult = XdmfFunction.addition(addArray1, addArray2)
+        assert addResult.getValuesString() == "1.5"
+
+        #//addition end
+
+        #//division begin
+
+        divArray1 = XdmfArray.New()
+        divArray1.pushBackAsFloat64(-0.5)
+        divArray2 = XdmfArray.New()
+        divArray2.pushBackAsFloat64(2)
+        divResult = XdmfFunction.division(divArray1, divArray2)
+        assert divResult.getValuesString() == "-0.25"
+
+        #//division end
+
+        #//multiplication begin
+
+        mulArray1 = XdmfArray.New()
+        mulArray1.pushBackAsFloat64(-0.5)
+        mulArray2 = XdmfArray.New()
+        mulArray2.pushBackAsFloat64(2)
+        mulResult = XdmfFunction.multiplication(mulArray1, mulArray2)
+        assert mulResult.getValuesString() == "-1"
+
+        #//multiplication end
+
+        #//subtraction begin
+
+        subArray1 = XdmfArray.New()
+        subArray1.pushBackAsFloat64(-0.5)
+        subArray2 = XdmfArray.New()
+        subArray2.pushBackAsFloat64(2)
+        subResult = XdmfFunction.subtraction(subArray1, subArray2)
+        assert subResult.getValuesString() == "-2.5"
+
+        #//subtraction end
diff --git a/examples/Python/XdmfExampleGeometry.py b/examples/Python/XdmfExampleGeometry.py
new file mode 100644
index 0000000..b5e41a0
--- /dev/null
+++ b/examples/Python/XdmfExampleGeometry.py
@@ -0,0 +1,29 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleGeometry = XdmfGeometry.New()
+
+        #//initialization end
+
+        #Assuming that exampleGeometry is a shared pointer to a XdmfGeometry object
+
+        #//setType begin
+
+        exampleGeometry.setType(XdmfGeometryType.XYZ())
+
+        #//setType end
+
+        #//getType begin
+
+        exampleType = exampleGeometry.getType()
+
+        #//getType end
+
+        #//getNumberPoints begin
+
+        numPoints = exampleGeometry.getNumberPoints()
+
+        #//getNumberPoints end
diff --git a/examples/Python/XdmfExampleGeometryType.py b/examples/Python/XdmfExampleGeometryType.py
new file mode 100644
index 0000000..71a8972
--- /dev/null
+++ b/examples/Python/XdmfExampleGeometryType.py
@@ -0,0 +1,26 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//getDimensions begin
+
+        exampleDimensions = XdmfGeometryType.XYZ().getDimensions()
+
+        #//getDimensions end
+
+        #//getName begin
+
+        exampleName = XdmfGeometryType.XYZ().getName()
+
+        #//getName end
+
+        #//getType begin
+
+        exampleGeometry = XdmfGeometry.New()
+
+        exampleType = exampleGeometry.getType()
+
+        if exampleType == XdmfGeometryType.XYZ():
+                #do whatever is to be done if the geometry is XYZ
+
+        #//getType end
diff --git a/examples/Python/XdmfExampleGraph.py b/examples/Python/XdmfExampleGraph.py
new file mode 100644
index 0000000..7feb3cc
--- /dev/null
+++ b/examples/Python/XdmfExampleGraph.py
@@ -0,0 +1,9 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleGraph = XdmfGraph.New()
+
+        #//initialization end
diff --git a/examples/Python/XdmfExampleGrid.py b/examples/Python/XdmfExampleGrid.py
new file mode 100644
index 0000000..efe62b3
--- /dev/null
+++ b/examples/Python/XdmfExampleGrid.py
@@ -0,0 +1,75 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleGrid = XdmfUnstructuredGrid.New()
+
+        #Using an unstructured grid since XdmfGrid is an abstract class
+
+        #//initialization end
+
+        #//setName begin
+
+        newName = "New Name"
+        exampleGrid.setName(newName)
+
+        #//setName end
+
+        #//setTime begin
+
+        newTime = XdmfTime.New(20.0)
+        exampleGrid.setTime(newTime)
+
+        #//setTIme end
+
+        #//getTime begin
+
+        exampleTime = exampleGrid.getTime()
+
+        #//getTime end
+
+        #//getName begin
+
+        exampleName = exampleGrid.getName()
+
+        #//getName end
+
+        #//getGeometry begin
+
+        exampleGeometry = exampleGrid.getGeometry()
+
+        #//getGeometry end
+
+        #//getTopology begin
+
+        exampleTopology = exampleGrid.getTopology()
+
+        #//getTopology end
+
+        #//setGridController begin
+
+        newGridController = XdmfGridController.New("gridFile.xmf", "/Xdmf/Domain/Grid[1]")
+
+        exampleGrid.setGridController(gridController)
+
+        #//setGridController end
+
+        #//getGridController begin
+
+        exampleGridController = exampleGrid.getGridController()
+
+        #//getGridController end
+
+        #//read begin
+
+        exampleGrid.read()
+
+        #//read end
+
+        #//release begin
+
+        exampleGrid.release()
+
+        #//release end
+
diff --git a/examples/Python/XdmfExampleGridCollection.py b/examples/Python/XdmfExampleGridCollection.py
new file mode 100644
index 0000000..9370c66
--- /dev/null
+++ b/examples/Python/XdmfExampleGridCollection.py
@@ -0,0 +1,36 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #Assuming that exampleCollection is a shared pointer to an XdmfGridCollection object
+
+        #//initialization begin
+
+        exampleCollection = XdmfGridCollection.New()
+
+        #//initialization end
+
+        #//setType begin
+
+        exampleCollection.setType(XdmfGridCollectionType.Temporal())
+
+        #//setType end
+
+        #//getType begin
+
+        exampleType = exampleCollection.getType()
+
+        if exampleType == XdmfGridCollectionType.Temporal():
+                #do whatever is to be done if the grid collection is temporal
+
+        #//getType end
+
+        #//insert begin
+
+        exampleInformation = XdmfInformation.New()
+        newKey = "New Key"
+        newValue = "New Value"
+        exampleInformation.setKey(newKey)
+        exampleInformation.setValue(newValue)
+        exampleCollection.insert(exampleInformation)
+
+        #//insert end
diff --git a/examples/Python/XdmfExampleHDF5Controller.py b/examples/Python/XdmfExampleHDF5Controller.py
new file mode 100644
index 0000000..31a14b6
--- /dev/null
+++ b/examples/Python/XdmfExampleHDF5Controller.py
@@ -0,0 +1,81 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "File path to hdf5 file goes here"
+        newSetPath = "path to the set goes here"
+        readType = XdmfArrayType.Int32()
+        readStarts = UInt32Vector()
+        #Three dimensions, all starting at index 0
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStrides = UInt32Vector()
+        #Three dimensions, no skipping between reads
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readDataSize = UInt32Vector()
+        #three dimensins, each with 20 maximum values
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        exampleController = XdmfHDF5Controller.New(
+                newPath,
+                newSetPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize)
+
+        #//initialization end
+
+        #//getDataSetPath begin
+
+        examplePath = exampleController.getDataSetPath()
+
+        #//getDataSetPath end
+
+        #//getDataspaceDimensions begin
+
+        exampleDataspaceDimensions = exampleController.getDataspaceDimensions()
+
+        #//getDataspaceDimensions end
+
+        #//getStart begin
+
+        exampleStart = exampleController.getStart()
+
+        #//getStart end
+
+        #//getStride begin
+
+        exampleStride = exampleController.getStride()
+
+        #//getStride end
+
+        #//setMaxOpenedFiles begin
+
+        XdmfHDF5Controller.setMaxOpenedFiles(2)
+
+        #//setMaxOpenedFiles end
+
+        #//getMaxOpenedFiles begin
+
+        maxNumOpened = XdmfHDF5Controller.getMaxOpenedFiles()
+
+        #//getMaxOpenedFiles end
+
+        #//closeFiles begin
+
+        XdmfHDF5Controller.closeFiles()
+
+        #//closeFiles end
+
diff --git a/examples/Python/XdmfExampleHDF5Writer.py b/examples/Python/XdmfExampleHDF5Writer.py
new file mode 100644
index 0000000..aae1e48
--- /dev/null
+++ b/examples/Python/XdmfExampleHDF5Writer.py
@@ -0,0 +1,53 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "Your file path goes here"
+        replaceOrig = True
+        exampleWriter = XdmfHDF5Writer.New(newPath, replaceOrig)
+
+        #//initialization end
+
+        #//setChunkSize begin
+
+        newChunk = 10
+        #creates blocks in sets of 10 slots
+
+        exampleWriter.setChunkSize(newChunk)
+
+        #//setChunkSize end
+
+        #//getChunkSize begin
+
+        exampleChunk = exampleWriter.getChunkSize()
+
+        #//getChunkSize end
+
+        #//setUseDeflate
+
+        useDeflate = True
+
+        exampleWriter.setUseDeflate(useDeflate)
+
+        #//setUseDeflate
+
+        #//getUseDeflate
+
+        isUsingDeflate = exampleWriter.getUseDeflate()
+
+        #//getUseDeflate
+
+        #//setDeflateFactor
+
+        newDeflateFactor = 6
+
+        exampleWriter.setDeflateFactor(newDeflateFactor)
+
+        #//setDeflateFactor
+
+        #//getDeflateFactor
+
+        currentDeflateFactor = exampleWriter.getDeflateFactor()
+
+        #//getDeflateFactor
diff --git a/examples/Python/XdmfExampleHeavyDataController.py b/examples/Python/XdmfExampleHeavyDataController.py
new file mode 100644
index 0000000..cc749e0
--- /dev/null
+++ b/examples/Python/XdmfExampleHeavyDataController.py
@@ -0,0 +1,104 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "File path to hdf5 file goes here"
+        newSetPath = "path to the set goes here"
+        readType = XdmfArrayType.Int32()
+        readStarts = UInt32Vector()
+        #Three dimensions, all starting at index 0
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStrides = UInt32Vector()
+        #Three dimensions, no skipping between reads
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readDataSize = UInt32Vector()
+        #Three dimensions, 10 values in each
+        readDataSize.push_back(10)
+        readDataSize.push_back(10)
+        readDataSize.push_back(10)
+        exampleController = XdmfHDF5Controller.New(
+                newPath,
+                newSetPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize)
+
+        #Using an XdmfHDF5Controller since XdmfHeavyDataController is an abstract class
+
+        #//initialization end
+
+        #//getDimensions begin
+
+        exampleDimensions = exampleController.getDimensions()
+
+        #//getDimensions end
+
+        #//getFilePath begin
+
+        examplePath = exampleController.getFilePath()
+
+        #//getFilePath end
+
+        #//getDescriptor begin
+
+        exampleDescriptor = exampleController.getDescriptor()
+
+        #//getDescriptor end
+
+        #//getName begin
+
+        exampleName = exampleController.getName()
+
+        #//getName end
+
+        #//getSize begin
+
+        exampleSize = exampleController.getSize()
+
+        #//getSize end
+
+        #//getDataspaceSize begin
+
+        exampleDataspaceSize = exampleController.getDataspaceSize()
+
+        #//getDataspaceSize end
+
+        #//getType begin
+
+        exampleType = exampleController.getType()
+
+        #//getType end
+
+        #//read begin
+
+        exampleArray = XdmfArray.New()
+        exampleController.read(exampleArray)
+        #exampleArray now holds the data that exampleController holds.
+
+        #//read end
+
+        #//setArrayOffset begin
+
+        newArrayOffset = 5#default is 0
+
+        exampleController.setArrayOffset(newArrayOffset)
+
+        #//setArrayOffset end
+
+        #//getArrayOffset begin
+
+        exampleOffset = exampleController.getArrayOffset()
+
+        #//getArrayOffset end
diff --git a/examples/Python/XdmfExampleHeavyDataWriter.py b/examples/Python/XdmfExampleHeavyDataWriter.py
new file mode 100644
index 0000000..376d2d2
--- /dev/null
+++ b/examples/Python/XdmfExampleHeavyDataWriter.py
@@ -0,0 +1,117 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "Your file path goes here"
+        replaceOrig = True
+        exampleWriter = XdmfHDF5Writer.New(newPath, replaceOrig)
+
+        #//initialization end
+
+        #//openFile begin
+
+        exampleWriter.openFile()
+
+        #//openFile end
+
+        #//closeFile begin
+
+        exampleWriter.closeFile()
+
+        #//closeFile end
+
+        #//getFilePath begin
+
+        examplePath = exampleWriter.getFilePath()
+
+        #//getFilePath end
+
+        #//getMode begin
+
+        exampleMode = XdmfHeavyDataWriter.Default
+        if exampleWriter.getMode() == exampleMode:
+                #Do whatever is to be done if the mode is default
+
+        #//getMode end
+
+        #//getReleaseData begin
+
+        testRelease = exampleWriter.getReleaseData()
+
+        #//getReleaseData end
+
+        #//setFileSizeLimit begin
+
+        newFileSizeLimit = 10
+
+        exampleWriter.setFileSizeLimit(newFileSizeLimit)
+
+        #//setFileSizeLimit end
+
+        #//getFileSizeLimit begin
+
+        exampleLimit = exampleWriter.getFileSizeLimit()
+
+        #//getFileSizeLimit end
+
+        #//getFileOverhead begin
+
+        exampleOverhead = exampleWriter.getFileOverhead()
+
+        #//getFileOverhead end
+
+        #//setAllowSetSplitting begin
+
+        newAllow = True
+        #false is default
+
+        exampleWriter.setAllowSetSplitting(newAllow)
+
+        #//setAllowSetSplitting end
+
+        #//getAllowSetSplitting begin
+
+        exampleAllowSplitting = exampleWriter.getAllowSetSplitting()
+
+        #//getAllowSetSplitting end
+
+        #//setFileIndex begin
+
+        newFileIndex = 0
+        #0 resets to no appended index
+
+        exampleWriter.setFileIndex(newFileIndex)
+
+        #//setFileIndex end
+
+        #//getFileIndex begin
+
+        exampleIndex = exampleWriter.getFileIndex()
+
+        #//getFileIndex end
+
+        #//setMode begin
+
+        exampleWriter.setMode(XdmfHeavyDataWriter.Default)
+
+        #//setMode end
+
+        #//setReleaseData begin
+
+        exampleWriter.setReleaseData(True)
+        #Sets the writer to release data after writing
+
+        #//setReleaseData end
+
+        #//visit begin
+
+        exampleArray = XdmfArray.New()
+        exampleArray.pushBackAsInt32(1)
+        exampleArray.pushBackAsInt32(2)
+        exampleArray.pushBackAsInt32(3)
+        exampleArray.pushBackAsInt32(4)
+        exampleArray.pushBackAsInt32(5)
+        exampleWriter.visit(exampleArray, exampleWriter)
+
+        #//visit end
diff --git a/examples/Python/XdmfExampleInformation.py b/examples/Python/XdmfExampleInformation.py
new file mode 100644
index 0000000..653ff90
--- /dev/null
+++ b/examples/Python/XdmfExampleInformation.py
@@ -0,0 +1,46 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        infoExample = XdmfInformation.New()
+        #Then the key and value must be set seperately
+        infoExample.setKey("Your Key String")
+        infoExample.setValue("Your Value String")
+
+        #//initialization end
+
+        #//initializationfull begin
+
+        infoExample = XdmfInformation.New("Your Key String", "Your Value String")
+        #This code creates an information with the key "Your Key String" and the value "Your Value String"
+
+        #//initializationfull end
+
+        #//getKey begin
+
+        storedKey = infoExample.getKey()
+        #"Your Key String" is now stored in the variable storedKey
+
+        #//getKey end
+
+        #//getValue begin
+
+        storedValue = infoExample.getValue()
+        #"Your Value String" is now stored in the variable storedValue
+
+        #//getValue end
+
+        #//setKey begin
+
+        infoExample.setKey("Your New Key")
+        #"Your New Key" is now the key for infoExample
+
+        #//setKey end
+
+        #//setValue begin
+
+        infoExample.setValue("Your New Value")
+        #"Your New Value" is now the value for infoExample
+
+        #//setValue end
diff --git a/examples/Python/XdmfExampleItem.py b/examples/Python/XdmfExampleItem.py
new file mode 100644
index 0000000..8f877c6
--- /dev/null
+++ b/examples/Python/XdmfExampleItem.py
@@ -0,0 +1,52 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #Assume that exampleItem is a shared pointer to the ParentClass object
+        #Using an XdmfInformation as an example because all XdmfItems have XdmfInformation as a child class
+
+        exampleItem = XdmfInformation.New("Parent", "This is a parent information")
+        addChild = XdmfInformation.New("Child", "This is a child information")
+
+        exampleItem.insert(addChild)
+
+        getIndex = 0
+        exampleChild = exampleItem.getInformation(getIndex)
+
+        findingInfo = "Find this"
+        exampleStringChild = exampleItem.getInformation(findingInfo)
+
+        exampleSize = exampleItem.getNumberInformations()
+
+        removeIndex = 0
+        exampleItem.removeInformation(removeIndex)
+
+        removeInfo = "Remove this"
+        exampleItem.removeInformation(removeInfo)
+
+        #//initialization begin
+
+        #Using a shared pointer to an XdmfDomain object as an example
+
+        exampleDomain = XdmfDomain.New()
+
+        #//initialization end
+
+        #//getItemTag begin
+
+        exampleTag = exampleDomain.getItemTag()
+
+        #//getItemTag end
+
+        #//getItemProperties begin
+
+        propertyMap = exampleDomain.getItemProperties()
+
+        #//getItemProperties end
+
+        #//traverse begin
+
+        writePath = "file path here"
+        exampleWriter = XdmfWriter.New(writepath)
+        exampleDomain.traverse(exampleWriter)
+
+        #//traverse end
diff --git a/examples/Python/XdmfExampleItemFactory.py b/examples/Python/XdmfExampleItemFactory.py
new file mode 100644
index 0000000..3bc9e3d
--- /dev/null
+++ b/examples/Python/XdmfExampleItemFactory.py
@@ -0,0 +1,9 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleFactory = XdmfItemFactory.New()
+
+        #//initialization end
diff --git a/examples/Python/XdmfExampleItemProperty.py b/examples/Python/XdmfExampleItemProperty.py
new file mode 100644
index 0000000..41e1a14
--- /dev/null
+++ b/examples/Python/XdmfExampleItemProperty.py
@@ -0,0 +1,11 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//getProperties begin
+
+        #Using XdmfArrayType.Int32() as an example
+        propertyMap = StringMap()
+        XdmfArrayType.Int32().getProperties(propertyMap)
+
+        #//getProperties end
diff --git a/examples/Python/XdmfExampleMap.py b/examples/Python/XdmfExampleMap.py
new file mode 100644
index 0000000..e59a743
--- /dev/null
+++ b/examples/Python/XdmfExampleMap.py
@@ -0,0 +1,205 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleMap = XdmfMap.New()
+
+        #//initialization end
+
+        #//initializationnode begin
+
+        #create attributes for each task id
+        #the index of the node id in the attribute is the local node id
+        map1Attribute = XdmfAttribute.New()
+        map1Attribute.setName("Test Attribute")
+        map1Attribute.setType(XdmfAttributeType.Scalar())
+        map1Attribute.setCenter(XdmfAttributeCenter.Node())
+        map1Vals = [1,2,3,4,5,7,9]
+        map1Attribute.insertAsInt32(0, map1Vals)
+
+        map2Attribute = XdmfAttribute.New()
+        map2Attribute.setName("Test Attribute")
+        map2Attribute.setType(XdmfAttributeType.Scalar())
+        map2Attribute.setCenter(XdmfAttributeCenter.Node())
+        map2Vals = [9,8,7,4,3]
+        map2Attribute.insertAsInt32(0, map2Vals)
+
+        #insert the attributes into a vector
+        #the id of the attribute in the vector is equal to the task id
+        testVector = AttributeVector()
+        testVector.push_back(map1Attribute)
+        testVector.push_back(map2Attribute)
+
+        exampleMapVector = XdmfMap.New(testVector)
+        #returns a vector of maps that holds the equivalencies for the nodes provided
+        #for example if Attribute 1 had globalNodeID 3 at localNodeID 2
+        #and Attribute 3 had globalNodeID 3 at localNodeID 5
+        #then map 1 would have an entry of (3, 5, 2)
+        #and map 3 would have an entry of (1, 2, 5)
+        #The entries are formatted (remoteTaskID, remoteLocalNodeID, localNodeID)
+
+        #//initializationnode end
+
+        #//inserttuple begin
+
+        newRemoteTaskID = 4
+        newLocalNodeID = 7
+        newRemoteLocalNodeID = 3
+        exampleMap.insert(newRemoteTaskID, newLocalNodeID, newRemoteLocalNodeID)
+        #This inserts an entry of (4, 7, 3) into the map
+
+        #//inserttuple end
+
+        #//setMap begin
+
+        newTaskMap = XdmfMapMap()
+        newNodeIdMap = XdmfMapNodeIdMap()
+        newNodeIdMap[2] = (3, 6, 8)
+        newNodeIdMap[3] = (3,)
+        newNodeIdMap[4] = (7,9)
+        #newNodeIdMap now contains the following
+        #(2, 3)
+        #(2, 6)
+        #(2, 8)
+        #(3, 3)
+        #(4, 7)
+        #(4, 9)
+        secondNodeIdMap = XdmfMapNodeIdMap()
+        secondNodeIdMap[5] = (3, 6, 8)
+        secondNodeIdMap[7] = (3,)
+        secondNodeIdMap[9] = (7,9)
+        #secondNodeIdMap now contains the following
+        #(5, 3)
+        #(5, 6)
+        #(5, 8)
+        #(7, 3)
+        #(9, 7)
+        #(9, 9)
+        newTaskMap[1] = newNodeIdMap
+        newTaskMap[2] = secondNodeIdMap
+        exampleMap = XdmfMap.New()
+        exampleMap.setMap(newTaskMap)
+        #(1, 2, 3)
+        #(1, 2, 6)
+        #(1, 2, 8)
+        #(1, 3, 3)
+        #(1, 4, 7)
+        #(1, 4, 9)
+        #(2, 5, 3)
+        #(2, 5, 6)
+        #(2, 5, 8)
+        #(2, 7, 3)
+        #(2, 9, 7)
+        #(2, 9, 9)
+        #Is now stored in exampleMap
+
+        #//setMap end
+
+        #//setName begin
+
+        newName = "New Name"
+        exampleMap.setName(newName)
+
+        #//setName end
+
+        #//getName begin
+
+        exampleName = exampleMap.getName()
+
+        #//getName end
+
+        #//getMap begin
+
+        #Assuming that exampleMap is a shared pointer to an XdmfMap object filled with the following tuples
+        #(1, 1, 9)
+        #(1, 2, 8)
+        #(2, 3, 7)
+        #(2, 4, 6)
+        #(3, 5, 5)
+        #(3, 6, 4)
+        taskIDMap = exampleMap.getMap()
+        i = 0
+        for val in taskIDMap:
+                print val
+                i = i + 1
+                if i == taskIDMap.size():
+                        break
+        #This prints out all the task IDs
+        #unless the break is called on the last iteration the program will fail because of an issue with SWIG
+        nodeIDMap = taskIDMap[1]
+        #nodeIDMap now contains the following tuples because it retrieved the tuples associated with taskID 1
+        #(1, 9)
+        #(2, 8)
+        i = 0
+        for val in nodeIDMap:
+                print val
+                i = i + 1
+                if i == nodeIDMap.size():
+                        break
+        #This prints out all the local node IDs
+        #unless the break is called on the last iteration the program will fail because of an issue with SWIG
+        for val in nodeIDMap[1]:
+                print val
+        #prints out all the remote node values associated with taskID 1 and localNode 1
+
+        #//getMap end
+
+        #//getRemoteNodeIds begin
+
+        nodeIDMap = exampleMap.getRemoteNodeIds(1)
+        #nodeIDMap now contains the following tuples because it retrieved the tuples associated with taskID 1
+        #(1, 9)
+        #(2, 8)
+        i = 0
+        for val in nodeIDMap:
+                print val
+                i = i + 1
+                if i == nodeIDMap.size():
+                        break
+        #This prints out all the local node IDs
+        #unless the break is called on the last iteration the program will fail because of an issue with SWIG
+        for val in nodeIDMap[1]:
+                print val
+        #prints out all the remote node values associated with taskID 1 and localNode 1
+
+        #//getRemoteNodeIds end
+
+        #//isInitialized begin
+
+        if not(exampleMap.isInitialized()):
+                exampleMap.read()
+
+        #//isInitialized end
+
+        #//release begin
+
+        exampleMap.release()
+
+        #//release end
+
+        #//setHeavyDataControllers begin
+
+        hdf5FilePath = "The HDF5 file path goes here"
+        hdf5SetPath = "The HDF5 set path goes here"
+        startIndex = 0#start at the beginning
+        readStride = 1#read all values
+        readNumber = 10#read 10 values
+        newRemoteTaskController = XdmfHDF5Controller.New(
+                hdf5FilePath, hdf5SetPath, XdmfArrayType.Int32(),
+                startIndex, readStride, readNumber)
+        hdf5FilePath = "The HDF5 file path for the local nodes goes here"
+        hdf5SetPath = "The HDF5 set path for the local nodes goes here"
+        newLocalNodeController = XdmfHDF5Controller.New(
+                hdf5FilePath, hdf5SetPath, XdmfArrayType.Int32(),
+                startIndex, readStride, readNumber)
+        hdf5FilePath = "The HDF5 file path for the remote local nodes goes here"
+        hdf5SetPath = "The HDF5 set path for the remote local nodes goes here"
+        newRemoteLocalNodeController = XdmfHDF5Controller.New(
+                hdf5FilePath, hdf5SetPath, XdmfArrayType.Int32(),
+                startIndex, readStride, readNumber)
+        exampleMap = XdmfMap.New()
+        exampleMap.setHeavyDataControllers(newRemoteTaskController, newLocalNodeController, newRemoteLocalNodeController)
+
+        #//setHeavyDataControllers end
diff --git a/examples/Python/XdmfExamplePlaceholder.py b/examples/Python/XdmfExamplePlaceholder.py
new file mode 100644
index 0000000..0a9d1c1
--- /dev/null
+++ b/examples/Python/XdmfExamplePlaceholder.py
@@ -0,0 +1,36 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "Dummy File Path"
+        readType = XdmfArrayType.Int32()
+        readStarts = UInt32Vector()
+        #Three dimensions, all starting at index 0
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStrides = UInt32Vector()
+        #Three dimensions, no skipping between reads
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readDataSize = UInt32Vector()
+        #three dimensins, each with 20 maximum values
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        exampleController = XdmfPlaceholder.New(
+                newPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize)
+
+        #//initialization end
diff --git a/examples/Python/XdmfExampleRead.py b/examples/Python/XdmfExampleRead.py
new file mode 100644
index 0000000..5aef9af
--- /dev/null
+++ b/examples/Python/XdmfExampleRead.py
@@ -0,0 +1,461 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        exampleReader = XdmfReader.New()
+
+        '''
+        This is assuming that the read item is an XdmfDomain object
+        '''
+        primaryDomain = exampleReader.read("testoutput.xmf")
+        outputInformation = primaryDomain.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "The Domain's tag is: " + primaryDomain.getItemTag()
+
+        gridHolder = primaryDomain.getGridCollection(0)
+
+        print "The Grid Collection's tag is: " + gridHolder.getItemTag()
+        print "The Grid Collection's name is: " + gridHolder.getName()
+        outputInformation = gridHolder.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+
+        for property in gridHolder.getItemProperties():
+                print property + ": " + gridHolder.getItemProperties()[property]
+
+        if gridHolder.getType() == XdmfGridCollectionType.Spatial():
+                print "This is a spatial grid collection"
+        else:
+                print "This is not a spatial grid collection"
+
+        i = 0
+        outstring = ""
+        while i < gridHolder.getNumberMaps():
+                readMap = gridHolder.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                outstring = outstring + "Map # " + str(i) + "\n"
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        print outstring
+
+        print "Unstructured Grid"
+        ungrid = gridHolder.getUnstructuredGrid(0)
+        print "The Unstructured Grid's tag is: " + ungrid.getItemTag()
+        print "The Unstructured Grid's name is: " + ungrid.getName()
+        for property in ungrid.getItemProperties():
+                print property + ": " + ungrid.getItemProperties()[property]
+        print "The Unstructured Grid's time is: " + str(ungrid.getTime().getValue())
+        i = 0
+        outstring = ""
+        while i < ungrid.getNumberMaps():
+                readMap = ungrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < ungrid.getNumberSets():
+                readSet = ungrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                outputInformation = readSet.getInformation(0)
+                print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        if not readAttribute.isInitialized():
+                                readAttribute.read()
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attribute is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i = i + 1
+        i = 0
+        while i < ungrid.getNumberAttributes():
+                readAttribute = ungrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attribute is not a node"
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Unstructured Topology"
+        untopology = ungrid.getTopology()
+        if not untopology.isInitialized():
+                untopology.read()
+        print "The topology's tag: " + untopology.getItemTag()
+        if untopology.getType() == XdmfTopologyType.Hexahedron():
+                print "This topology is a hexahedron"
+        else:
+                print "This topology is not a hexahedron"
+        print "Contains " + str(untopology.getNumberElements()) + " elements"
+        print "Contains the values: " + untopology.getValuesString()
+
+        print "Unstructured Geometry"
+        ungeometry = ungrid.getGeometry()
+        if not ungeometry.isInitialized():
+                ungeometry.read()
+        print "The geometry's tag: " +ungeometry.getItemTag()
+        if ungeometry.getType() == XdmfGeometryType.XYZ():
+                print "This geometry is XYZ"
+        else:
+                print "This geometry is not XYZ"
+        outputInformation = ungeometry.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "Contains " + str(ungeometry.getNumberPoints()) + " points"
+        print "Contains the values: " + ungeometry.getValuesString()
+
+
+        print "Curvilinear Grid"
+        curvgrid = gridHolder.getCurvilinearGrid(0)
+        print "The Curvilinear Grid's tag is: " + curvgrid.getItemTag()
+        print "The Curvilinear Grid's name is: " + curvgrid.getName()
+        for property in curvgrid.getItemProperties():
+                print property + ": " + curvgrid.getItemProperties()[property]
+        outputInformation = curvgrid.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "The Curvilinear Grid's time is: " + str(curvgrid.getTime().getValue())
+        i = 0
+        outstring = ""
+        while i < curvgrid.getNumberMaps():
+                readMap = curvgrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < curvgrid.getNumberSets():
+                readSet = curvgrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        if not readAttribute.isInitialized():
+                                readAttribute.read()
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attribute is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i = i + 1
+        i = 0
+        while i < curvgrid.getNumberAttributes():
+                readAttribute = curvgrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attribute is not a node"
+                outputInformation = readAttribute.getInformation(0)
+                print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Curvilinear Dimensions"
+        curvdimensions = curvgrid.getDimensions()
+        if not curvdimensions.isInitialized():
+                curvdimensions.read()
+        print "The dimensions' tag: " + curvdimensions.getItemTag()
+        print "Contains the values: " + curvdimensions.getValuesString()
+
+        print "Curvilinear Geometry"
+        curvgeometry = curvgrid.getGeometry()
+        if not curvgeometry.isInitialized():
+                curvgeometry.read()
+        print "The geometry's tag: " + curvgeometry.getItemTag()
+        if curvgeometry.getType() == XdmfGeometryType.XYZ():
+                print "This geometry is XYZ"
+        else:
+                print "This geometry is not XYZ"
+        outputInformation = curvgeometry.getInformation(0)
+        print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+        print "Contains " + str(curvgeometry.getNumberPoints()) + " points"
+        print "Contains the values: " + curvgeometry.getValuesString()
+
+
+        print "Rectilinear Grid"
+        rectgrid = gridHolder.getRectilinearGrid(0)
+        print "The Rectilinear Grid's tag is: " + rectgrid.getItemTag()
+        print "The Rectilinear Grid's name is: " + rectgrid.getName()
+        for property in rectgrid.getItemProperties():
+                print property + ": " + rectgrid.getItemProperties()[property]
+        print "The Rectilinear Grid's time is: " + str(rectgrid.getTime().getValue())
+        i = 0
+        outstring = ""
+        while i < rectgrid.getNumberMaps():
+                readMap = rectgrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < rectgrid.getNumberSets():
+                readSet = rectgrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        if not readAttribute.isInitialized():
+                                readAttribute.read()
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attribute is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i = i + 1
+        i = 0
+        while i < rectgrid.getNumberAttributes():
+                readAttribute = rectgrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attribute is not a node"
+                outputInformation = readAttribute.getInformation(0)
+                print "Key: " + outputInformation.getKey() + "\nValue: " + outputInformation.getValue()
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Rectilinear Dimensions"
+        rectdimensions = rectgrid.getDimensions()
+        if not rectdimensions.isInitialized():
+                rectdimensions.read()
+        print "The dimensions' tag: " + rectdimensions.getItemTag()
+        print "Contains the values: " + rectdimensions.getValuesString()
+
+        print "Rectilinear Coordinates"
+        rectcoordinates = rectgrid.getCoordinates()
+        print "Contains the values: "
+        for coordinateaxes in rectcoordinates:
+                if not coordinateaxes.isInitialized():
+                        coordinateaxes.read()
+                print coordinateaxes.getValuesString()
+
+        print "Regular Grid"
+        reggrid = gridHolder.getRegularGrid(0)
+        print "The Regular Grid's tag is: " + reggrid.getItemTag()
+        print "The Regular Grid's name is: " + reggrid.getName()
+        for property in reggrid.getItemProperties():
+                print property + ": " + reggrid.getItemProperties()[property]
+        print "The Regular Grid's time is: " + str(reggrid.getTime().getValue())
+        i = 0
+        outstring = ""
+        while i < reggrid.getNumberMaps():
+                readMap = reggrid.getMap(i)
+                if not readMap.isInitialized():
+                        readMap.read()
+                print "Map # " + str(i)
+                taskIDMap = readMap.getMap()
+                j = 0
+                for task in taskIDMap:
+                        nodeIDmap = taskIDMap[task]
+                        k = 0
+                        for node in nodeIDmap:
+                                remoteIDmap = nodeIDmap[node]
+                                for remote in remoteIDmap:
+                                        outstring = outstring + "taskID: " + str(task) + "\tlocalnodeID: " + str(node) +"\tremotenodeID: " + str(remote) + "\n"
+                                k = k + 1
+                                if k == nodeIDmap.size():
+                                        break
+                        j = j + 1
+                        if j == taskIDMap.size():
+                                break
+                i = i + 1
+        i = 0
+        print outstring
+        while i < reggrid.getNumberSets():
+                readSet = reggrid.getSet(i)
+                if not readSet.isInitialized():
+                        readSet.read()
+                print "Set # " + str(i)
+                print readSet.getName()
+                if readSet.getType() == XdmfSetType.Node():
+                        print "This set is a node"
+                else:
+                        print "This set is not a node"
+                print readSet.getValuesString()
+                j=0
+                while j < readSet.getNumberAttributes():
+                        readAttribute = readSet.getAttribute(j)
+                        if not readAttribute.isInitialized():
+                                readAttribute.read()
+                        print "Set Attribute # " + str(j)
+                        print readAttribute.getName()
+                        if readAttribute.getType() == XdmfAttributeType.Scalar():
+                                print "This attribute is a scalar"
+                        else:
+                                print "This attribute is not a scalar"
+                        if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                                print "This attribute is a node"
+                        else:
+                                print "This attribute is not a node"
+                        print readAttribute.getValuesString()
+                        j = j + 1
+                i = i + 1
+        i = 0
+        while i < reggrid.getNumberAttributes():
+                readAttribute = reggrid.getAttribute(i)
+                if not readAttribute.isInitialized():
+                        readAttribute.read()
+                print "Attribute # " + str(i)
+                print readAttribute.getName()
+                if readAttribute.getType() == XdmfAttributeType.Scalar():
+                        print "This attribute is a scalar"
+                else:
+                        print "This attribute is not a scalar"
+                if readAttribute.getCenter() == XdmfAttributeCenter.Node():
+                        print "This attribute is a node"
+                else:
+                        print "This attribute is not a node"
+                print readAttribute.getValuesString()
+                i = i + 1
+
+        print "Regular Brick Size"
+        regbricksize = reggrid.getBrickSize()
+        if not regbricksize.isInitialized():
+                regbricksize.read()
+        print "The brick's tag: " + regbricksize.getItemTag()
+        print "Contains the values: " + regbricksize.getValuesString()
+
+        print "Regular Number of Points"
+        regnumpoints = reggrid.getDimensions()
+        if not regnumpoints.isInitialized():
+                regnumpoints.read()
+        print "The dimensions' tag: " + regnumpoints.getItemTag()
+        print "Contains the values: " + regnumpoints.getValuesString()
+
+        print "Regular Origin"
+        regorigin = reggrid.getOrigin()
+        if not regorigin.isInitialized():
+                regorigin.read()
+        print "The origin's tag: " + regorigin.getItemTag()
+        print "Contains the values: " + regorigin.getValuesString()
diff --git a/examples/Python/XdmfExampleReader.py b/examples/Python/XdmfExampleReader.py
new file mode 100644
index 0000000..7a40912
--- /dev/null
+++ b/examples/Python/XdmfExampleReader.py
@@ -0,0 +1,9 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        #//initialization begin
+
+        exampleReader = XdmfReader.New()
+
+        #//initialization end
diff --git a/examples/Python/XdmfExampleRectilinearGrid.py b/examples/Python/XdmfExampleRectilinearGrid.py
new file mode 100644
index 0000000..343067d
--- /dev/null
+++ b/examples/Python/XdmfExampleRectilinearGrid.py
@@ -0,0 +1,83 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #Assuming that exampleGrid is a shared pointer to an XdmfRectilinearGrid
+
+        #//initvalues
+
+        pointsXArray = XdmfArray.New()
+        pointsXArray.pushBackAsInt32(5)
+        pointsXArray.pushBackAsInt32(6)
+        pointsXArray.pushBackAsInt32(7)
+        pointsXArray.pushBackAsInt32(8)
+        pointsXArray.pushBackAsInt32(9)
+        pointsXArray.pushBackAsInt32(10)
+        pointsYArray = XdmfArray.New()
+        pointsYArray.pushBackAsInt32(3)
+        pointsYArray.pushBackAsInt32(6)
+        pointsYArray.pushBackAsInt32(4)
+        pointsYArray.pushBackAsInt32(8)
+        pointsYArray.pushBackAsInt32(7)
+        pointsYArray.pushBackAsInt32(10)
+        pointsZArray = XdmfArray.New()
+        pointsZArray.pushBackAsInt32(3)
+        pointsZArray.pushBackAsInt32(9)
+        pointsZArray.pushBackAsInt32(4)
+        pointsZArray.pushBackAsInt32(5)
+        pointsZArray.pushBackAsInt32(7)
+        pointsZArray.pushBackAsInt32(2)
+
+        #//initvalues
+
+        #//initialization2
+
+        exampleGrid = XdmfRectilinearGrid.New(pointsXArray, pointsYArray)
+
+        #//initialization2
+
+        #//initialization3
+
+        exampleGrid = XdmfRectilinearGrid.New(pointsXArray, pointsYArray, pointsZArray)
+
+        #//initialization3
+
+        #//setCoordinatessingle
+
+        exampleGrid.setCoordinates(0, pointsXArray)
+
+        #//setCoordinatessingle
+
+        #//initializevector
+
+        pointsCollector = ArrayVector()
+        pointsCollector.push_back(pointsXArray)
+        pointsCollector.push_back(pointsYArray)
+        pointsCollector.push_back(pointsZArray)
+        exampleGrid = XdmfRectilinearGrid.New(pointsCollector)
+
+        #//initializevector
+
+        #//getCoordinatessingle
+
+        readPointsX = exampleGrid.getCoordinates(0)
+        readPointsY = exampleGrid.getCoordinates(1)
+
+        #//getCoordinatessingle
+
+        #//getCoordinatesvector
+
+        exampleCoordinates = exampleGrid.getCoordinates()
+
+        #//getCoordinatesvector
+
+        #//getDimensions
+
+        exampleDimensions = exampleGrid.getDimensions()
+
+        #//getDimensions
+
+        #//setCoordinatesvector
+
+        exampleGrid.setCoordinates(pointsCollector)
+
+        #//setCoordinatesvector
diff --git a/examples/Python/XdmfExampleRegularGrid.py b/examples/Python/XdmfExampleRegularGrid.py
new file mode 100644
index 0000000..ae8c05b
--- /dev/null
+++ b/examples/Python/XdmfExampleRegularGrid.py
@@ -0,0 +1,87 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #Assuming exampleGrid is a shared pointer to an XdmfRegularGrid object
+
+        #//initvalues begin
+
+        newBrickX = 20.0
+        newPointsX = 5
+        newOriginX = 0.0
+        newBrickY = 20.0
+        newPointsY = 5
+        newOriginY = 0.0
+        newBrickZ = 20.0
+        newPointsZ = 5
+        newOriginZ = 0.0
+
+        #//initvalues end
+
+        #//initialization2 begin
+
+        exampleGrid = XdmfRegularGrid.New(
+                newBrickX, newBrickY, newPointsX, newPointsY, newOriginX, newOriginY)
+
+        #//initialization2 end
+
+        #//initialization3 begin
+
+        exampleGrid = XdmfRegularGrid.New(
+                newBrickX, newBrickY, newBrickZ, newPointsX, newPointsY, newPointsZ, newOriginX, newOriginY, newOriginZ)
+
+        #//initialization3 end
+
+        #//getBrickSize begin
+
+        exampleBrick = exampleGrid.getBrickSize()
+
+        #//getBrickSize end
+
+        #//getDimensions begin
+
+        exampleDimensions = exampleGrid.getDimensions()
+
+        #//getDimensions end
+
+        #//getOrigin begin
+
+        exampleOrigin = exampleGrid.getOrigin()
+
+        #//getOrigin end
+
+        #//initializationvector begin
+
+        newBrickSize = XdmfArray.New()
+        newBrickSize.pushBackAsFloat64(20.0)
+        newBrickSize.pushBackAsFloat64(21.0)
+        newBrickSize.pushBackAsFloat64(22.0)
+        newNumPoints = XdmfArray.New()
+        newNumPoints.pushBackAsUInt32(5)
+        newNumPoints.pushBackAsUInt32(6)
+        newNumPoints.pushBackAsUInt32(7)
+        newGridOrigin = XdmfArray.New()
+        newGridOrigin.pushBackAsFloat64(0.0)
+        newGridOrigin.pushBackAsFloat64(1.0)
+        newGridOrigin.pushBackAsFloat64(2.0)
+
+        exampleGrid = XdmfRegularGrid.New(newBrickSize, newNumPoints, newGridOrigin)
+
+        #//initializationvector end
+
+        #//setBrickSize begin
+
+        exampleGrid.setBrickSize(newBrickSize)
+
+        #//setBrickSize end
+
+        #//setDimensions begin
+
+        exampleGrid.setDimensions(newNumPoints)
+
+        #//setDimensions end
+
+        #//setOrigin begin
+
+        exampleGrid.setOrigin(newGridOrigin)
+
+        #//setOrigin end
diff --git a/examples/Python/XdmfExampleSet.py b/examples/Python/XdmfExampleSet.py
new file mode 100644
index 0000000..54ed57a
--- /dev/null
+++ b/examples/Python/XdmfExampleSet.py
@@ -0,0 +1,36 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleSet = XdmfSet.New()
+
+        #//initialization end
+
+        #//setName begin
+
+        std::string newName = "New Name";
+        exampleSet->setName(newName);
+
+        #//setName end
+
+        #//setType begin
+
+        exampleSet->setType(XdmfSetType::Node());
+
+        #//setType end
+
+        #//getName begin
+
+        exampleName = exampleSet.getName()
+
+        #//getName end
+
+        #//getType begin
+
+        exampleType = exampleSet.getType()
+
+        if exampleType == XdmfSetType.Node():
+                #do whatever is to be done if the set is a node
+
+        #//getType end
diff --git a/examples/Python/XdmfExampleSparseMatrix.py b/examples/Python/XdmfExampleSparseMatrix.py
new file mode 100644
index 0000000..f9b6889
--- /dev/null
+++ b/examples/Python/XdmfExampleSparseMatrix.py
@@ -0,0 +1,93 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleMatrix = XdmfSparseMatrix.New(3, 3)
+
+        #//initialization end
+
+        #//setName begin
+
+        exampleMatrix.setName("TestMatrix")
+
+        #//setName end
+
+        #//getName begin
+
+        exampleName = exampleMatrix.getName()
+
+        #//getName end
+
+        #//setRowPointer begin
+
+        newRowPointer = XdmfArray.New()
+
+        newRowPointer.insertAsUInt32(0, 1)
+        newRowPointer.insertAsUInt32(1, 1)
+        newRowPointer.insertAsUInt32(2, 2)
+        newRowPointer.insertAsUInt32(3, 3)
+
+        exampleMatrix.setRowPointer(newRowPointer)
+
+        #//setRowPointer end
+
+        #//getRowPointer begin
+
+        exampleRowPointer = exampleMatrix.getRowPointer()
+
+        #//getRowPointer end
+
+        #//setColumnIndex begin
+
+        newColumnIndex = XdmfArray.New()
+
+        newColumnIndex.pushBackAsUInt32(1)
+        newColumnIndex.pushBackAsUInt32(2)
+        newColumnIndex.pushBackAsUInt32(0)
+
+        exampleMatrix.setColumnIndex(newColumnIndex)
+
+        #//setColumnIndex end
+
+        #//getColumnIndex begin
+
+        exampleColumnIndex = exampleMatrix.getColumnIndex()
+
+        #//getColumnIndex end
+
+        #//getNumberRows begin
+
+        exampleNumRows = exampleMatrix.getNumberRows()
+
+        #//getNumberRows end
+
+        #//getNumberColumns begin
+
+        exampleNumCols = exampleMatrix.getNumberColumns()
+
+        #//getNumberColumns end
+
+        #//setValues begin
+
+        newValues = XdmfArray.New()
+
+        newValues.pushBackAsFloat64(5.0)
+        newValues.pushBackAsFloat64(6.0)
+        newValues.pushBackAsFloat64(-1.0)
+
+        exampleMatrix.setValues(newValues)
+
+        #//setValues end
+
+        #//getValues begin
+
+        exampleValues = exampleMatrix.getValues()
+
+        #//getValues end
+
+        #//getValuesString begin
+
+        exampleValueString = exampleMatrix.getValuesString()
+
+        #//getValuesString end
diff --git a/examples/Python/XdmfExampleSubset.py b/examples/Python/XdmfExampleSubset.py
new file mode 100644
index 0000000..435c07b
--- /dev/null
+++ b/examples/Python/XdmfExampleSubset.py
@@ -0,0 +1,109 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        baseArray = XdmfArray.New()
+
+        for i in range(0, 10):
+                baseArray.pushBack(i)
+
+        initStart = UInt32Vector()
+        initStart.push_back(0)
+        initStride = UInt32Vector()
+        initStride.push_back(1)
+        initDimension = UInt32Vector()
+        initDimension.push_back(10)
+
+        exampleSubset = XdmfSubset.New(baseArray,
+                                       initStart,
+                                       initStride,
+                                       initDimension)
+
+        #//initialization end
+
+        #//getStart begin
+
+        exampleStart = exampleSubset.getStart()
+
+        #//getStart end
+
+        #//setStart begin
+
+        exampleSubset.setStart(exampleStart)
+
+        #//setStart end
+
+        #//getStride begin
+
+        exampleStride = exampleSubset.getStride()
+
+        #getStride end
+
+        #//setStride begin
+
+        exampleSubset.setStride(exampleStride)
+
+        #//setStride end
+
+        #//getDimensions begin
+
+        exampleDimensions = exampleSubset.getDimensions()
+
+        #//getDimensions end
+
+        #//setDimensions begin
+
+        exampleSubset.setDimensions(exampleDimensions)
+
+        #//setDimensions end
+
+        #//getReferenceArray begin
+
+        exampleInternalArray = exampleSubset.getReferenceArray()
+
+        #//getReferenceArray end
+
+        #//setReferenceArray begin
+
+        exampleSubset.setReferenceArray(exampleInternalArray)
+
+        #//setReferenceArray end
+
+        #//getSize begin
+
+        exampleSize = exampleSubset.getSize()
+
+        #//getSize end
+
+        #//setConstructedType begin
+
+        typeAttribute = XdmfAttribute.New()
+        exampleSubset.setConstructedType(typeAttribute.getItemTag())
+
+        #//setConstructedType end
+
+        #//getConstructedType begin
+
+        exampleType = exampleSubset.getConstructedType()
+
+        #//getConstructedType end
+
+        #//setConstructedProperties begin
+
+        propertyAttribute = XdmfAttribute.New()
+        exampleSubset.setConstructedProperties(propertyAttribute.getItemProperties())
+
+        #//setConstructedProperties end
+
+        #//getConstructedProperties begin
+
+        exampleProperties = exampleSubset.getConstructedProperties()
+
+        #//getConstructedProperties end
+
+        #//read begin
+
+        subsetResult = exampleSubset.read()
+
+        #//read end
diff --git a/examples/Python/XdmfExampleSystemUtils.py b/examples/Python/XdmfExampleSystemUtils.py
new file mode 100644
index 0000000..4430aef
--- /dev/null
+++ b/examples/Python/XdmfExampleSystemUtils.py
@@ -0,0 +1,9 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//getRealPath begin
+
+        priorPath = "Path you want to convert"
+        convertedPath = XdmfSystemUtils.getRealPath(priorPath)
+
+        #//getRealPath end
diff --git a/examples/Python/XdmfExampleTIFFController.py b/examples/Python/XdmfExampleTIFFController.py
new file mode 100644
index 0000000..5b602c8
--- /dev/null
+++ b/examples/Python/XdmfExampleTIFFController.py
@@ -0,0 +1,52 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        newPath = "File path to TIFF file goes here"
+        readType = XdmfArrayType.Int32()
+        readStarts = UInt32Vector()
+        #Three dimensions, all starting at index 0
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStarts.push_back(0)
+        readStrides = UInt32Vector()
+        #Three dimensions, no skipping between reads
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readStrides.push_back(1)
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readDataSize = UInt32Vector()
+        #three dimensins, each with 20 maximum values
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        readDataSize.push_back(20)
+        exampleController = XdmfTIFFController.New(
+                newPath,
+                readType,
+                readStarts,
+                readStrides,
+                readCounts,
+                readDataSize)
+
+        #//initialization end
+
+        #//initializationsimplified begin
+
+        newPath = "File path to TIFF file goes here"
+        readType = XdmfArrayType.Int32()
+        readCounts = UInt32Vector()
+        #Three dimensions, reading 10 values from each
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        readCounts.push_back(10)
+        exampleController = XdmfTIFFController.New(
+                newPath,
+                readType,
+                readCounts)
+
+        #//initializationsimplified end
diff --git a/examples/Python/XdmfExampleTime.py b/examples/Python/XdmfExampleTime.py
new file mode 100644
index 0000000..f24f2a2
--- /dev/null
+++ b/examples/Python/XdmfExampleTime.py
@@ -0,0 +1,25 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleTime = XdmfTime.New()
+        #The Default case sets the time to 0.0
+        #You can also specify a time when creating the XdmfTime object
+
+        newTime = 5.0
+        exampleTime2 = XdmfTime.New(newTime)
+
+        #//initialization end
+
+        #//setValue begin
+
+        exampleTime.setValue(newTime)
+
+        #//setValue end
+
+        #//getValue begin
+
+        readTime = exampleTime.getValue()
+
+        #//getValue end
diff --git a/examples/Python/XdmfExampleTopology.py b/examples/Python/XdmfExampleTopology.py
new file mode 100644
index 0000000..a52e0b0
--- /dev/null
+++ b/examples/Python/XdmfExampleTopology.py
@@ -0,0 +1,26 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleTopology = XdmfTopology.New()
+
+        #//initialization end
+
+        #//setType begin
+
+        exampleTopology.setType(XdmfTopologyType.Pyramid())
+
+        #//setType end
+
+        #//getType begin
+
+        exampleType = exampleTopology.getType()
+
+        #//getType end
+
+        #//getNumberElements begin
+
+        numElements = exampleTopology.getNumberElements()
+
+        #//getNumberElements end
diff --git a/examples/Python/XdmfExampleTopologyType.py b/examples/Python/XdmfExampleTopologyType.py
new file mode 100644
index 0000000..d178856
--- /dev/null
+++ b/examples/Python/XdmfExampleTopologyType.py
@@ -0,0 +1,59 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleID = XdmfTopologyType.Triangle().getID()
+        createdTopology = XdmfTopology.New()
+        createdTopology.setType(XdmfTopologyType.New(exampleID))
+
+        #//initialization end
+
+        #//getCellType begin
+
+        exampleType = XdmfTopologyType.Linear
+        if exampleType == exampleTopology.getCellType:
+                '''
+                Do whatever is to be done if the cell type is linear
+                '''
+
+        #//getCellType end
+
+        #//getEdgesPerElement begin
+
+        numEdges = XdmfTopologyType.Triangle().getEdgesPerElement()
+
+        #//getEdgesPerElement end
+
+        #//getFacesPerElement begin
+
+        numFaces = XdmfTopologyType.Triangle().getFacesPerElement()
+
+        #//getFacesPerElement end
+
+        #//getId begin
+
+        holdID = XdmfTopologyType::Triangle().getID()
+
+        #//getId end
+
+        #//getName begin
+
+        exampleName = XdmfTopologyType.Triangle().getName()
+
+        #//getName end
+
+        #//getNodesPerElement begin
+
+        numNodes = XdmfTopologyType.Triangle().getNodesPerElement()
+
+        #//getNodesPerElement end
+
+        #//getType begin
+
+        testType = createdTopology.getType()
+
+        if testType == XdmfTopologyType.Triangle:
+                #do whatever is to be done if the type is a triangle
+
+        #//getType end
diff --git a/examples/Python/XdmfExampleUnstructuredGrid.py b/examples/Python/XdmfExampleUnstructuredGrid.py
new file mode 100644
index 0000000..a5643a7
--- /dev/null
+++ b/examples/Python/XdmfExampleUnstructuredGrid.py
@@ -0,0 +1,67 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        exampleGrid = XdmfUnstructuredGrid.New()
+
+        #//initialization end
+
+        #//initializationregular begin
+
+        newBrickX = 0.0
+        newBrickY = 0.0
+        newPointsX = 5
+        newPointsY = 5
+        newOriginX = 20.0
+        newOriginY = 20.0
+        baseGrid = XdmfRegularGrid.New(newBrickX, newBrickY, newPointsX, newPointsY, newOriginX, newOriginY)
+        regGeneratedGrid = XdmfUnstructuredGrid.New(baseGrid)
+
+        #//initializationregular end
+
+        #//setGeometry begin
+
+        newGeometry = XdmfGeometry.New()
+        newGeometry.setType(XdmfGeometryType.XYZ())
+        newGeometry.pushBackAsInt32(1)
+        newGeometry.pushBackAsInt32(2)
+        newGeometry.pushBackAsInt32(3)
+        newGeometry.pushBackAsInt32(4)
+        newGeometry.pushBackAsInt32(5)
+        newGeometry.pushBackAsInt32(6)
+        newGeometry.pushBackAsInt32(7)
+        newGeometry.pushBackAsInt32(8)
+        newGeometry.pushBackAsInt32(9)
+        exampleGrid.setGeometry(newGeometry)
+
+        #//setGeometry end
+
+        #//setTopology begin
+
+        newTopology = XdmfTopology.New()
+        newTopology.setType(XdmfTopologyType.Triangle())
+        newTopology.pushBackAsInt32(1)
+        newTopology.pushBackAsInt32(2)
+        newTopology.pushBackAsInt32(3)
+        newTopology.pushBackAsInt32(4)
+        newTopology.pushBackAsInt32(5)
+        newTopology.pushBackAsInt32(6)
+        newTopology.pushBackAsInt32(7)
+        newTopology.pushBackAsInt32(8)
+        newTopology.pushBackAsInt32(9)
+        exampleGrid.setTopology(newTopology)
+
+        #//setTopology end
+
+        #//getGeometry begin
+
+        exampleGeometry = exampleGrid.getGeometry()
+
+        #//getGeometry end
+
+        #//getTopology begin
+
+        exampleTopology = exampleGrid.getTopology()
+
+        #//getTopology end
diff --git a/examples/Python/XdmfExampleWrite.py b/examples/Python/XdmfExampleWrite.py
new file mode 100644
index 0000000..e92fc80
--- /dev/null
+++ b/examples/Python/XdmfExampleWrite.py
@@ -0,0 +1,196 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        primaryDomain = XdmfDomain.New()
+        domaininfo = XdmfInformation.New("Domain", "This is the primary data structure in Xdmf")
+        domaininfoinfo = XdmfInformation.New("Information", "Information can have information")
+        domaininfo.insert(domaininfoinfo)
+        primaryDomain.insert(domaininfo)
+
+        gridHolder = XdmfGridCollection.New()
+        gridHolder.setType(XdmfGridCollectionType.Spatial())
+        holderInfo = XdmfInformation.New("Grid Collection 1", "This is the main grid collection")
+        gridHolder.insert(holderInfo)
+        gridHolder.setName("GridCollection Example")
+
+
+        ungrid = XdmfUnstructuredGrid.New()
+        ungrid.setName("Unstructured Grid Example")
+        untime = XdmfTime.New(5.0)
+        untimeinfo = XdmfInformation.New("Time", "This is the time for the Unstructured Grid")
+        untime.insert(untimeinfo)
+        ungrid.setTime(untime)
+        unglobalID = XdmfAttribute.New()
+        unglobalID.setType(XdmfAttributeType.GlobalId())
+        unglobalID.setCenter(XdmfAttributeCenter.Node())
+        unglobalID.setName("Global Node Equivalencies")
+        task1globalnodes = [1, 4, 5, 7, 3, 6]
+        unglobalID.insertAsInt32(0, task1globalnodes)
+        unglobalIDinfo = XdmfInformation.New("Global Nodes", "This is the global nodes that accociate with the local nodes")
+        ungrid.insert(unglobalID)
+        unset = XdmfSet.New()
+        unsetinfo = XdmfInformation.New("Data Set", "This is a set of arbitrary data")
+        unset.insert(unsetinfo)
+        unset.setName("Unstructured Grid's Set")
+        unset.setType(XdmfSetType.Node())
+        unsetattribute = XdmfAttribute.New()
+        unsetattribute.setType(XdmfAttributeType.Scalar())
+        unsetattribute.setCenter(XdmfAttributeCenter.Node())
+        unsetattribute.setName("The Set's attribute")
+        unsetattribdata = [1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1]
+        unsetattribute.insertAsFloat64(0, unsetattribdata)
+        unset.insert(unsetattribute)
+        unsetdata = [5.1, 4.2, 3.3, 2.4, 1.5]
+        unset.insertAsFloat64(0, unsetdata)
+        ungrid.insert(unset)
+        ungeometry = XdmfGeometry.New()
+        ungeometry.setType(XdmfGeometryType.XYZ())
+        ungeometry.setName("Unstructured Geometry")
+        ungeopoints = [0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1,
+                1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1,
+                0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1]
+        ungeometry.insertAsFloat64(0, ungeopoints)
+        ungeometryinfo = XdmfInformation.New("Geometry", "This is the geometry associated with the unstructured grid")
+        ungeometry.insert(ungeometryinfo)
+        ungrid.setGeometry(ungeometry)
+        untopology = XdmfTopology.New()
+        untopology.setType(XdmfTopologyType.Hexahedron())
+        untopology.setName("Unstructured Topology")
+        untopovalues = [0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10]
+        untopology.insertAsInt32(0, untopovalues)
+        untopologyinfo = XdmfInformation.New("Topology", "This is the topology associated with the unstructured grid")
+        ungrid.setTopology(untopology)
+
+
+        curvdimensions = XdmfArray.New()
+        curvdimensions.pushBackAsInt32(12)
+        curvdimensions.pushBackAsInt32(12)
+        curvdimensions.pushBackAsInt32(12)
+        curvgrid = XdmfCurvilinearGrid.New(curvdimensions)
+        curvgrid.setName("Curvilinear Grid Example")
+        curvgridinfo = XdmfInformation.New("Curvilinear Grid", "This is an example curvilinear grid")
+        curvgrid.insert(curvgridinfo)
+        curvtime = XdmfTime.New(5.0)
+        curvtimeinfo = XdmfInformation.New("Time", "The Time of the Curvilinear Grid")
+        curvtime.insert(curvtimeinfo)
+        curvgrid.setTime(curvtime)
+        curvglobalID = XdmfAttribute.New()
+        curvglobalID.setType(XdmfAttributeType.GlobalId())
+        curvglobalID.setCenter(XdmfAttributeCenter.Node())
+        curvglobalID.setName("Global Node Equivalencies")
+        task2globalnodes = [7, 3, 8, 2, 5, 1]
+        curvglobalID.insertAsInt32(0, task1globalnodes)
+        curvglobalIDinfo = XdmfInformation.New("Global Node Equivalencies", "These are the global nodes that accociate with the local nodes")
+        curvglobalID.insert(curvglobalIDinfo)
+        curvgrid.insert(curvglobalID)
+        curvgeometry = XdmfGeometry.New()
+        curvgeometry.setType(XdmfGeometryType.XYZ())
+        curvgeometry.setName("Curvilinear Geometry")
+        curvgeopoints = [1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1, 2.1,
+                2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1, 4.1,
+                1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1]
+        curvgeometry.insertAsFloat64(0, curvgeopoints)
+        curvgeometryinfo = XdmfInformation.New("Geometry", "The geometry of the curvilinear grid")
+        curvgeometry.insert(curvgeometryinfo)
+        curvgrid.setGeometry(curvgeometry)
+
+
+        rectXcoordinates = [1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1]
+        rectYcoordinates = [2.1, 2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1]
+        rectZcoordinates = [4.1, 1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1]
+        rectXarray = XdmfArray.New()
+        rectXarray.insertAsFloat64(0, rectXcoordinates)
+        rectYarray = XdmfArray.New()
+        rectYarray.insertAsFloat64(0, rectYcoordinates)
+        rectZarray = XdmfArray.New()
+        rectZarray.insertAsFloat64(0, rectZcoordinates)
+        coordinatecontainer = ArrayVector()
+        coordinatecontainer.push_back(rectXarray)
+        coordinatecontainer.push_back(rectYarray)
+        coordinatecontainer.push_back(rectZarray)
+        rectgrid = XdmfRectilinearGrid.New(coordinatecontainer)
+        rectgrid.setName("Rectilinear Grid Example")
+        rectgridinfo = XdmfInformation.New("Rectilinear Grid", "This is an example of a rectilinear grid")
+        rectglobalID = XdmfAttribute.New()
+        rectglobalID.setType(XdmfAttributeType.GlobalId())
+        rectglobalID.setCenter(XdmfAttributeCenter.Node())
+        rectglobalID.setName("Global Node Equivalencies")
+        task3globalnodes = [2, 7, 9, 0, 8, 6]
+        rectglobalID.insertAsInt32(0, task3globalnodes)
+        rectglobalIDinfo = XdmfInformation.New("Global Node Equivalencies", "These are the global nodes that associate with the local nodes")
+        rectglobalID.insert(rectglobalIDinfo)
+        recttime = XdmfTime.New(5.0)
+        recttimeinfo = XdmfInformation.New("Time", "The time of the rectiliniear grid")
+        recttime.insert(recttimeinfo)
+        rectgrid.setTime(recttime)
+        rectgrid.insert(rectglobalID)
+
+        regbrick = XdmfArray.New()
+        regbrickvals = [10, 10, 10]
+        regbrick.insertAsFloat64(0, regbrickvals)
+        regdimensions = XdmfArray.New()
+        regdimensionvals = [5, 5, 5]
+        regdimensions.insertAsInt32(0, regdimensionvals)
+        regorigin = XdmfArray.New()
+        regoriginvals = [0, 0, 0]
+        regorigin.insertAsFloat64(0, regoriginvals)
+        reggrid = XdmfRegularGrid.New(regbrick, regdimensions, regorigin)
+        reggrid.setName("Regular Grid Example")
+        reggridinfo = XdmfInformation.New("Regular Grid", "This is an example of a regular grid")
+        regtime = XdmfTime.New(5.0)
+        regtimeinfo = XdmfInformation.New("Time", "This is the time for the regular grid")
+        reggrid.setTime(regtime)
+        regglobalID = XdmfAttribute.New()
+        regglobalID.setType(XdmfAttributeType.GlobalId())
+        regglobalID.setCenter(XdmfAttributeCenter.Node())
+        regglobalID.setName("Global Node Equivalencies")
+        task4globalnodes = [3, 6, 1, 4, 2, 5, 9]
+        regglobalID.insertAsInt32(0, task4globalnodes)
+        regglobalIDinfo = XdmfInformation.New("Global Node Equivalencies", "These are the global nodes that associate with the local nodes")
+        reggrid.insert(regglobalID)
+
+        nodeholder = AttributeVector()
+        nodeholder.push_back(unglobalID)
+        nodeholder.push_back(curvglobalID)
+        nodeholder.push_back(rectglobalID)
+        nodeholder.push_back(regglobalID)
+        mapcollection = XdmfMap.New(nodeholder)
+
+        ungrid.insert(mapcollection[0])
+        curvgrid.insert(mapcollection[1])
+        rectgrid.insert(mapcollection[2])
+        reggrid.insert(mapcollection[3])
+
+        '''
+        the version of XdmfMap.New used here returns a number of maps equal to the number of attributes it was provided with.
+        '''
+        for insertedmap in mapcollection:
+                gridHolder.insert(insertedmap)
+
+        gridHolder.insert(ungrid)
+        gridHolder.insert(curvgrid)
+        gridHolder.insert(rectgrid)
+        gridHolder.insert(reggrid)
+
+        secondaryHolder = XdmfGridCollection.New()
+        secondaryHolder.setName("Secondary grid collection")
+        gridHolder.insert(secondaryHolder)
+        '''
+        grid collections can be placed inside other grid collections
+        '''
+
+        primaryDomain.insert(gridHolder)
+        '''
+        grids can be inserted into the domain in the same way as the grid collection
+        '''
+        primaryDomain.insert(ungrid)
+        primaryDomain.insert(curvgrid)
+        primaryDomain.insert(rectgrid)
+        primaryDomain.insert(reggrid)
+
+        exampleHeavyWriter = XdmfHDF5Writer.New("testoutput.h5")
+        exampleWriter = XdmfWriter.New("testoutput.xmf", exampleHeavyWriter)
+
+        primaryDomain.accept(exampleHeavyWriter)
+        exampleHeavyWriter.setMode(XdmfHeavyDataWriter.Overwrite)
+        primaryDomain.accept(exampleWriter)
diff --git a/examples/Python/XdmfExampleWriter.py b/examples/Python/XdmfExampleWriter.py
new file mode 100644
index 0000000..3c1e642
--- /dev/null
+++ b/examples/Python/XdmfExampleWriter.py
@@ -0,0 +1,131 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+        #//initialization begin
+
+        outFile = "output file name goes here"
+        exampleWriter = XdmfWriter.New(outFile)
+
+        #//initialization end
+
+        #//heavyinitialization begin
+
+        outFile = "output file name goes here"
+        heavyFile = "heavy file name goes here"
+        replaceFile = True
+        exampleHeavyWriter = XdmfHDF5Writer.New(heavyFile, replaceFile)
+        exampleWriter = XdmfWriter.New(outFile, exampleHeavyWriter)
+
+        #//heavyinitialization end
+
+        #//getFilePath begin
+
+        examplePath = exampleWriter.getFilePath()
+
+        #//getFilePath end
+
+        #//getHeavyDataWriter begin
+
+        exampleHeavyWriter = exampleWriter.getHeavyDataWriter()
+
+        #//getHeavyDataWriter end
+
+        #//setHeavyDataWriter begin
+
+        exampleWriter.setHeavyDataWriter(exampleHeavyWriter)
+
+        #//setHeavyDataWriter end
+
+        #//getLightDataLimit begin
+
+        exampleLimit = exampleWriter.getLightDataLimit()
+
+        #//getLightDataLimit end
+
+        #//getMode begin
+
+        testMode = XdmfWriter.Default
+        if exampleWriter.getMode() == testMode:
+                #Do whatever is to be done if the mode is default
+
+        #//getMode end
+
+
+        #//getRebuildXML begin
+
+        exampleRebuildStatus = exampleWriter.getRebuildXML()
+
+        #//getRebuildXML end
+
+        #//setRebuildXML begin
+
+        exampleNewRebuildStatus = True
+        exampleWriter.getRebuildXML(exampleNewRebuildStatus)
+
+        #//setRebuildXML end
+
+        #//getWriteXPaths begin
+
+        exampleTestPaths = exampleWriter.getWriteXPaths()
+
+        #//getWriteXPaths end
+
+        #//getXPathParse begin
+
+        exampleXPathParse = exampleWriter.getXPathParse()
+
+        #//getXPathParse end
+
+        #//setLightDataLimit begin
+
+        newLimit = 20;
+        exampleWriter.setLightDataLimit(newLimit)
+        #The writer will now place any data with a number of values over 20 into heavy data
+
+        #//setLightDataLimit end
+
+        #//setMode begin
+
+        exampleWriter.setMode(XdmfWriter.Default)
+
+        #//setMode end
+
+        #//setWriteXPaths begin
+
+        exampleWriter.setWriteXPaths(True)
+
+        #//setWriteXPaths end
+
+        #//setXPathParse begin
+
+        exampleWriter.setXPathParse(True)
+
+        #//setXPathParse end
+
+        #//visitarray begin
+
+        #Using XdmfAttribute here, but any XdmfArray would work
+        exampleAttribute = XdmfAttribute.New()
+        exampleAttribute.setCenter(XdmfAttributeCenter.Node())
+        exampleAttribute.setType(XdmfAttributeType.Scalar())
+        exampleAttribute.pushBackAsInt32(1)
+        exampleAttribute.pushBackAsInt32(2)
+        exampleAttribute.pushBackAsInt32(3)
+        exampleAttribute.pushBackAsInt32(4)
+        exampleAttribute.pushBackAsInt32(5)
+        exampleAttribute.pushBackAsInt32(6)
+        outFile = "output file name goes here"
+        exampleWriter = XdmfWriter.New(outFile)
+        exampleWriter.visit(exampleAttribute, exampleWriter)
+
+        #//visitarray end
+
+        #//visititem begin
+
+        #Using XdmfDomain here, but any XdmfItem would work
+        exampleDomain = XdmfDomain.New()
+        outFile = "output file name goes here"
+        exampleWriter = XdmfWriter.New(outFile)
+        exampleWriter.visit(exampleDomain, exampleWriter)
+
+        #//visititem end
diff --git a/tests/C/CMakeLists.txt b/tests/C/CMakeLists.txt
new file mode 100644
index 0000000..0113b97
--- /dev/null
+++ b/tests/C/CMakeLists.txt
@@ -0,0 +1,102 @@
+# Include our test macros
+include(AddTestsC)
+
+# Add any dependencies that the cxx core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_C_DEPENDENCIES("Xdmf")
+
+# Add any ldpath directories that the cxx tests may need
+ADD_TEST_C_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directoreis that the Cxx tests may need
+ADD_TEST_C_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_PATH("${XDMF_BINARIES}")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_C(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+ADD_TEST_C(CTestXdmfWriter)
+ADD_TEST_C(CTestXdmfAggregate)
+ADD_TEST_C(CTestXdmfAttribute)
+ADD_TEST_C(CTestXdmfBinaryController)
+ADD_TEST_C(CTestXdmfDomain)
+if (TIFF_FOUND)
+  ADD_TEST_C(CTestXdmfTIFFReadWriteCompressed)
+endif ()
+ADD_TEST_C(CTestXdmfTopology)
+ADD_TEST_C(CTestXdmfGeometry)
+ADD_TEST_C(CTestXdmfGraph)
+ADD_TEST_C(CTestXdmfGridCollection)
+ADD_TEST_C(CTestXdmfGridController)
+ADD_TEST_C(CTestXdmfCurvilinearGrid)
+ADD_TEST_C(CTestXdmfRectilinearGrid)
+ADD_TEST_C(CTestXdmfRegularGrid)
+ADD_TEST_C(CTestXdmfUnstructuredGrid)
+ADD_TEST_C(CTestXdmfMap)
+ADD_TEST_C(CTestXdmfSet)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_C(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_C(CTestXdmfWriter
+  testfile.xmf
+  testfile.h5
+  secondtestfile.xmf
+  secondtestfile.h5
+  subsetfile.xmf
+  subsetfile.h5
+  functionfile.xmf
+  functionfile.h5)
+CLEAN_TEST_C(CTestXdmfAggregate,
+  aggregate.xmf
+  aggregate.h5)
+CLEAN_TEST_C(CTestXdmfAttribute
+  attributefile.xmf
+  attributefile.h5)
+CLEAN_TEST_C(CTestXdmfBinaryController
+  binary.bin)
+CLEAN_TEST_C(CTestXdmfDomain
+  domainfile.xmf
+  domainfile.h5)
+if (TIFF_FOUND)
+  CLEAN_TEST_C(CTestXdmfTIFFReadWriteCompressed
+    compressedstripoutput.tif)
+endif ()
+CLEAN_TEST_C(CTestXdmfTopology
+  topofile.xmf
+  topofile.h5)
+CLEAN_TEST_C(CTestXdmfGeometry
+  geofile.xmf
+  geofile.h5)
+CLEAN_TEST_C(CTestXdmfGraph
+  matrixfile.xmf
+  matrixfile.h5)
+CLEAN_TEST_C(CTestXdmfGridCollection
+  colfile.xmf
+  colfile.h5)
+CLEAN_TEST_C(CTestXdmfGridController
+  gridControllerReference.xmf
+  gridController.xmf)
+CLEAN_TEST_C(CTestXdmfCurvilinearGrid
+  curvfile.xmf
+  curvfile.h5)
+CLEAN_TEST_C(CTestXdmfRectilinearGrid
+  rectfile.xmf
+  rectfile.h5)
+CLEAN_TEST_C(CTestXdmfRegularGrid
+  regfile.xmf
+  regfile.h5)
+CLEAN_TEST_C(CTestXdmfUnstructuredGrid
+  unfile.xmf
+  unfile.h5)
+CLEAN_TEST_C(CTestXdmfMap
+  mapfile.xmf
+  mapfile.h5)
+CLEAN_TEST_C(CTestXdmfSet
+  setfile.xmf
+  setfile.h5)
diff --git a/tests/C/CTestXdmfAggregate.c b/tests/C/CTestXdmfAggregate.c
new file mode 100644
index 0000000..8b4b55f
--- /dev/null
+++ b/tests/C/CTestXdmfAggregate.c
@@ -0,0 +1,98 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAggregate.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+
+#include "assert.h"
+#include "stdio.h"
+#include "string.h"
+
+int main()
+{
+  int status = 0;
+
+  unsigned int iteration = 0;
+  unsigned int i = 0;
+
+  XDMFAGGREGATE * testAggregate = XdmfAggregateNew();
+
+  for (iteration = 0; iteration < 5; ++iteration)
+  {
+    XDMFARRAY * referenceArray = XdmfArrayNew();
+
+    for (i = 0; i < 27; ++i)
+    {
+      int pushedVal = i*(iteration + 1);
+      XdmfArrayPushBack(referenceArray, &pushedVal, XDMF_ARRAY_TYPE_INT32, &status);
+    }
+    XdmfAggregateInsertArray(testAggregate, referenceArray, 1);
+  }
+
+  XDMFATTRIBUTE * aggregateHolder = XdmfAttributeNew();
+
+  XdmfAttributeSetReference(aggregateHolder, (XDMFARRAYREFERENCE *)testAggregate, 0);
+
+  XdmfAttributeSetReadMode(aggregateHolder, XDMF_ARRAY_READ_MODE_REFERENCE, &status);
+
+
+
+  XDMFWRITER * aggregateWriter = XdmfWriterNew("aggregate.xmf");
+
+  XdmfAttributeAccept(aggregateHolder, (XDMFVISITOR *)aggregateWriter, &status);
+
+  XdmfAttributeReadReference(aggregateHolder, &status);
+
+  printf("%s\n", XdmfAttributeGetValuesString(aggregateHolder));
+
+  XDMFREADER * aggregateReader = XdmfReaderNew();
+
+  XDMFITEM * readItem = XdmfReaderRead(aggregateReader,"aggregate.xmf", &status);
+
+  printf("%s ?= Attribute\n", XdmfItemGetItemTag(readItem));
+
+  assert(strcmp(XdmfItemGetItemTag(readItem), "Attribute") == 0);
+
+  XDMFATTRIBUTE * readAggregateHolder = (XDMFATTRIBUTE *)readItem;
+
+  XdmfAttributeReadReference(readAggregateHolder, &status);
+
+  printf("%s\n?=\n%s\n", XdmfAttributeGetValuesString(readAggregateHolder), XdmfAttributeGetValuesString(aggregateHolder));
+
+  assert(strcmp(XdmfAttributeGetValuesString(readAggregateHolder), XdmfAttributeGetValuesString(aggregateHolder)) == 0);
+
+
+
+  XDMFARRAY * aggregateHolder2 = XdmfArrayNew();
+
+  XdmfArraySetReference(aggregateHolder2, (XDMFARRAYREFERENCE *)testAggregate, 1);
+
+  XdmfArraySetReadMode(aggregateHolder2, XDMF_ARRAY_READ_MODE_REFERENCE, &status);
+
+  XdmfArrayAccept(aggregateHolder2, (XDMFVISITOR *)aggregateWriter, &status);
+
+  XdmfArrayReadReference(aggregateHolder2, &status);
+
+  printf("%s\n", XdmfArrayGetValuesString(aggregateHolder2));
+
+  printf("reading");
+
+  XdmfItemFree(readItem);
+
+  readItem = XdmfReaderRead(aggregateReader, "aggregate.xmf", &status);
+
+  printf("%s ?= DataItem\n", XdmfItemGetItemTag(readItem));
+
+  assert(strcmp(XdmfItemGetItemTag(readItem), "DataItem") == 0);
+
+  XDMFARRAY * readAggregateHolder2 = (XDMFARRAY *)readItem;
+
+  XdmfArrayReadReference(readAggregateHolder2, &status);
+
+  printf("%s\n?=\n%s\n", XdmfArrayGetValuesString(readAggregateHolder2), XdmfArrayGetValuesString(aggregateHolder2));
+
+  assert(strcmp(XdmfArrayGetValuesString(readAggregateHolder2), XdmfArrayGetValuesString(aggregateHolder2)) == 0);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfAttribute.c b/tests/C/CTestXdmfAttribute.c
new file mode 100644
index 0000000..c171826
--- /dev/null
+++ b/tests/C/CTestXdmfAttribute.c
@@ -0,0 +1,88 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  XDMFATTRIBUTE * attrib = XdmfAttributeNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfAttributePushBack(attrib, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfAttributeSetType(attrib, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+
+  XdmfAttributeSetCenter(attrib, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("attributefile.xmf");
+
+  int testype = XdmfAttributeGetType(attrib);
+
+  printf("%d ?= %d\n", testype, XDMF_ATTRIBUTE_TYPE_SCALAR);
+
+  assert(testype == XDMF_ATTRIBUTE_TYPE_SCALAR);
+
+  int testcenter = XdmfAttributeGetCenter(attrib);
+
+  printf("%d ?= %d\n", testcenter, XDMF_ATTRIBUTE_CENTER_NODE);
+
+  assert(testcenter == XDMF_ATTRIBUTE_CENTER_NODE);
+
+  // Write to File
+
+  XdmfAttributeAccept(attrib, (XDMFVISITOR *)writer, &status);
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readArray = XdmfReaderRead(reader, "attributefile.xmf", &status);
+
+  char * valueString = XdmfAttributeGetItemTag(readArray);
+
+  printf("%s ?= %s\n", valueString, "Attribute");
+
+  assert(strcmp(valueString, "Attribute") == 0);
+
+  XdmfAttributeRead(readArray, &status);
+
+  int attributetype = XdmfAttributeGetType(readArray);
+
+  printf("Attribute type code = %d\n", attributetype);
+
+  assert(attributetype == XDMF_ATTRIBUTE_TYPE_SCALAR);
+
+  int attributecenter = XdmfAttributeGetCenter(readArray);
+
+  printf("Attribute center code = %d\n", attributecenter);
+
+  assert(attributecenter == XDMF_ATTRIBUTE_CENTER_NODE);
+
+  valueString = XdmfAttributeGetValuesString(readArray);
+
+  printf("array contains: %s\n", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(readArray);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfBinaryController.c b/tests/C/CTestXdmfBinaryController.c
new file mode 100644
index 0000000..46e66de
--- /dev/null
+++ b/tests/C/CTestXdmfBinaryController.c
@@ -0,0 +1,92 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+#include "stdio.h"
+#include "assert.h"
+
+int main()
+{
+  FILE * binFile = fopen("binary.bin", "w+");
+
+  int status = 0;
+
+  //
+  // write binary file
+  //
+
+  int outputData[4];
+  outputData[0] = 1;
+  outputData[1] = 0;
+  outputData[2] = -1;
+  outputData[3] = 100;
+
+  // Dummy data to test seek
+
+  int dummyData[3];
+  dummyData[0] = 5;
+  dummyData[1] = -5;
+  dummyData[2] = 12;
+
+  fwrite(dummyData, sizeof(int), 3, binFile);
+  fwrite(outputData, sizeof(int), 4, binFile);
+
+//  fprintf(binFile, "%s\n", (char *)dummyData);
+//  fprintf(binFile, "%s\n", (char *)outputData);
+
+  fclose(binFile);
+
+  //
+  // read binary file using XdmfBinaryController
+  // Checking use of seek
+  //
+  unsigned int dims[1] = {4};
+  XDMFBINARYCONTROLLER * binaryController =
+    XdmfBinaryControllerNew("binary.bin",
+                            XDMF_ARRAY_TYPE_INT32,
+                            XDMF_BINARY_CONTROLLER_ENDIAN_NATIVE,
+                            sizeof(int) * 3,
+                            dims,
+                            1,
+                            &status);
+
+
+  XDMFARRAY * testArray = XdmfArrayNew();
+  XdmfArrayInsertHeavyDataController(testArray, (XDMFHEAVYDATACONTROLLER *)binaryController, 1);
+  XdmfArrayRead(testArray, &status);
+
+  printf("%u ?= %u\n", XdmfArrayGetSize(testArray), 4);
+  printf("%d ?= %d\n", ((int *)XdmfArrayGetValue(testArray, 0, XDMF_ARRAY_TYPE_INT32, &status))[0], outputData[0]);
+  printf("%d ?= %d\n", ((int *)XdmfArrayGetValue(testArray, 1, XDMF_ARRAY_TYPE_INT32, &status))[0], outputData[1]);
+  printf("%d ?= %d\n", ((int *)XdmfArrayGetValue(testArray, 2, XDMF_ARRAY_TYPE_INT32, &status))[0], outputData[2]);
+  printf("%d ?= %d\n", ((int *)XdmfArrayGetValue(testArray, 3, XDMF_ARRAY_TYPE_INT32, &status))[0], outputData[3]);
+
+  assert(XdmfArrayGetSize(testArray)== 4);
+  assert(((int *)XdmfArrayGetValue(testArray, 0, XDMF_ARRAY_TYPE_INT32, &status))[0] == outputData[0]);
+  assert(((int *)XdmfArrayGetValue(testArray, 1, XDMF_ARRAY_TYPE_INT32, &status))[0] == outputData[1]);
+  assert(((int *)XdmfArrayGetValue(testArray, 2, XDMF_ARRAY_TYPE_INT32, &status))[0] == outputData[2]);
+  assert(((int *)XdmfArrayGetValue(testArray, 3, XDMF_ARRAY_TYPE_INT32, &status))[0] == outputData[3]);
+
+  XdmfArrayRelease(testArray);
+
+  //
+  // output array to disk
+  //
+  XDMFWRITER * writer = XdmfWriterNew("TestXdmfBinary.xmf");
+  XdmfWriterSetMode(writer, XDMF_WRITER_MODE_DISTRIBUTED_HEAVY_DATA, &status);
+  XdmfArrayAccept(testArray, (XDMFVISITOR *)writer, &status);
+
+  //
+  // read array in
+  //
+  XDMFREADER * reader = XdmfReaderNew();
+  XDMFARRAY * array = (XDMFARRAY *)(XdmfReaderRead(reader, "TestXdmfBinary.xmf", &status));
+
+  printf("%p ?!= %p\n", array, NULL);
+  assert(array != NULL);
+
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfCurvilinearGrid.c b/tests/C/CTestXdmfCurvilinearGrid.c
new file mode 100644
index 0000000..b8eae5a
--- /dev/null
+++ b/tests/C/CTestXdmfCurvilinearGrid.c
@@ -0,0 +1,133 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  XDMFGEOMETRY * geometry = XdmfGeometryNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfGeometryPushBack(geometry, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfGeometrySetType(geometry, XDMF_GEOMETRY_TYPE_XY, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("curvfile.xmf");
+
+  int testype = XdmfGeometryGetType(geometry);
+
+  printf("%d ?= %d\n", testype, XDMF_GEOMETRY_TYPE_XY);
+
+  assert(testype == XDMF_GEOMETRY_TYPE_XY);
+
+  // Write to File
+
+  XdmfGeometryAccept(geometry, (XDMFVISITOR *)writer, &status);
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readArray = XdmfReaderRead(reader, "curvfile.xmf", &status);
+
+  char * valueString = XdmfGeometryGetItemTag(readArray);
+
+  printf("%s ?= %s\n", valueString, "Geometry");
+
+  assert(strcmp(valueString, "Geometry") == 0);
+
+  free(valueString);
+
+  XdmfGeometryRead(readArray, &status);
+
+  unsigned int numPoints = XdmfGeometryGetNumberPoints(readArray);
+
+  printf("%d ?= %d\n", numPoints, 5);
+
+  assert(numPoints == 5);
+
+  int geotype = XdmfGeometryGetType(readArray);
+
+  printf("Geometry type code = %d\n", geotype);
+
+  assert(geotype == XDMF_GEOMETRY_TYPE_XY);
+
+  unsigned int numDims = XdmfGeometryTypeGetDimensions(geotype, &status);
+
+  assert(numDims == 2);
+
+  valueString = XdmfGeometryTypeGetName(geotype);
+
+  printf("Geometry type name: %s\n", valueString);
+
+  free(valueString);
+
+  valueString = XdmfGeometryGetValuesString(readArray);
+
+  printf("array contains: %s\n", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  XdmfItemFree(readArray);
+
+  free(valueString);
+
+  void * curvGrid = XdmfCurvilinearGridNew2D(2, 5);
+
+  XdmfCurvilinearGridSetGeometry(curvGrid, geometry, 1);
+
+  void * dimensions = XdmfArrayNew();
+
+  int dimArray[2];
+  dimArray[0] = 5;
+  dimArray[1] = 2;
+
+  XdmfArrayPushBack(dimensions, &dimArray[0], XDMF_ARRAY_TYPE_INT32, &status);
+  XdmfArrayPushBack(dimensions, &dimArray[1], XDMF_ARRAY_TYPE_INT32, &status);
+
+  XdmfCurvilinearGridSetDimensions(curvGrid, dimensions, 1, &status);
+
+  printf("writing to file\n");
+
+  XdmfCurvilinearGridAccept(curvGrid, (XDMFVISITOR *)writer, &status);
+
+//  XdmfItemFree(curvGrid);
+
+  void * readGrid = XdmfReaderRead(reader, "curvfile.xmf", &status);
+
+  XDMFGEOMETRY * childGeometry = XdmfCurvilinearGridGetGeometry(readGrid);
+
+  valueString = XdmfGeometryGetValuesString(childGeometry);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * childDimensions = XdmfCurvilinearGridGetDimensions(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(childDimensions);
+
+  printf("%s ?= %s\n", valueString, "5 2");
+
+  assert(strcmp(valueString, "5 2") == 0);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfDomain.c b/tests/C/CTestXdmfDomain.c
new file mode 100644
index 0000000..0e77e76
--- /dev/null
+++ b/tests/C/CTestXdmfDomain.c
@@ -0,0 +1,817 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+  int i = 0;
+
+  int status = 0;
+
+  void * domain = XdmfDomainNew();
+
+  printf("Generating interal objects\n");
+
+// Grid Collection
+
+  void * collection = XdmfGridCollectionNew();
+
+  XdmfGridCollectionSetType(collection, XDMF_GRID_COLLECTION_TYPE_SPATIAL, &status);
+
+  char * testName = XdmfGridCollectionGetName(collection);
+
+  printf("%s ?= %s\n", testName, "Collection");
+
+  assert(strcmp(testName, "Collection") == 0);
+
+  XdmfGridCollectionSetName(collection, "Test Grid Collection", &status);
+
+  void * collection1Time = XdmfTimeNew(21.0);
+
+  XdmfGridCollectionSetTime(collection, collection1Time, 1);
+
+  printf("checking time\n");
+
+  void * checkTime = XdmfGridCollectionGetTime(collection);
+
+  double checkTimeVal = XdmfTimeGetValue(checkTime);
+
+  printf("%lf ?= %lf\n", checkTimeVal, 21.0);
+
+  assert(checkTimeVal == 21.0);
+
+  XdmfDomainInsertGridCollection(domain, collection, 1);
+
+  void * collection2 = XdmfGridCollectionNew();
+
+  XdmfGridCollectionSetType(collection2, XDMF_GRID_COLLECTION_TYPE_TEMPORAL, &status);
+
+  XdmfGridCollectionSetName(collection2, "Second Test Grid Collection", &status);
+
+  void * collection2Time = XdmfTimeNew(12.0);
+
+  XdmfGridCollectionSetTime(collection2, collection2Time, 1);
+
+  XdmfDomainInsertGridCollection(domain, collection2, 1);
+
+  printf("Generated Grid Collections\n");
+
+// Curvilinear Grid
+
+  XDMFGEOMETRY * geometry = XdmfGeometryNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfGeometryPushBack(geometry, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfGeometrySetType(geometry, XDMF_GEOMETRY_TYPE_XY, &status);
+
+
+  void * curvGrid = XdmfCurvilinearGridNew2D(2, 5);
+
+  XdmfCurvilinearGridSetGeometry(curvGrid, geometry, 1);
+
+  XdmfCurvilinearGridSetName(curvGrid, "Test Curvilinear Grid", &status);
+
+  XdmfDomainInsertCurvilinearGrid(domain, curvGrid, 1);
+
+  void * curvGrid2 = XdmfCurvilinearGridNew2D(5, 2);
+
+  XdmfCurvilinearGridSetGeometry(curvGrid2, geometry, 1);
+
+  XdmfCurvilinearGridSetName(curvGrid2, "Second Test Curvilinear Grid", &status);
+
+  XdmfDomainInsertCurvilinearGrid(domain, curvGrid2, 1);
+
+  printf("Curvilinear Grids Generated\n");
+
+// Rectilinear Grid
+
+  void * newXDim = XdmfArrayNew();
+
+  for (i = 5; i < 9; ++i) {
+    XdmfArrayPushBack(newXDim, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * newYDim = XdmfArrayNew();
+
+  for (i = 6; i < 10; ++i) {
+    XdmfArrayPushBack(newYDim, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * rectGrid = XdmfRectilinearGridNew2D(newXDim, newYDim, 0);
+
+  XdmfRectilinearGridSetName(rectGrid, "Test Rectilinear Grid", &status);
+
+  XdmfDomainInsertRectilinearGrid(domain, rectGrid, 1);
+
+  void * newXDim2 = XdmfArrayNew();
+
+  for (i = 15; i < 19; ++i) {
+    XdmfArrayPushBack(newXDim2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * newYDim2 = XdmfArrayNew();
+
+  for (i = 16; i < 20; ++i) {
+    XdmfArrayPushBack(newYDim2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * rectGrid2 = XdmfRectilinearGridNew2D(newXDim2, newYDim2, 0);
+
+  XdmfRectilinearGridSetName(rectGrid2, "Second Test Rectilinear Grid", &status);
+
+  XdmfDomainInsertRectilinearGrid(domain, rectGrid2, 1);
+
+  printf("Rectilinear Grids Generated\n");
+
+// Regular Grid
+
+  void * regGrid = XdmfRegularGridNew2D(5, 5, 5, 5, 0, 0);
+
+  XdmfRegularGridSetName(regGrid, "Test Regular Grid", &status);
+
+  XdmfDomainInsertRegularGrid(domain, regGrid, 1);
+
+  void * regGrid2 = XdmfRegularGridNew2D(3, 3, 3, 3, 1, 1);
+
+  XdmfRegularGridSetName(regGrid2, "Second Test Regular Grid", &status);
+
+  XdmfDomainInsertRegularGrid(domain, regGrid2, 1);
+
+  printf("Regular Grids Generated\n");
+
+// Unstuctured Grid
+
+  void * unGrid = XdmfUnstructuredGridNewFromRegularGrid(regGrid, &status);
+
+  XdmfUnstructuredGridSetName(unGrid, "Test Unstructred Grid", &status);
+
+  XdmfDomainInsertUnstructuredGrid(domain, unGrid, 1);
+
+  void * unGrid2 = XdmfUnstructuredGridNewFromRegularGrid(regGrid2, &status);
+
+  XdmfUnstructuredGridSetName(unGrid2, "Second Test Unstructred Grid", &status);
+
+  XdmfDomainInsertUnstructuredGrid(domain, unGrid2, 1);
+
+  printf("Unstructured Grids Generated\n");
+
+// Graph
+
+  XDMFGRAPH * matrix = XdmfGraphNew(3);
+
+  XdmfGraphSetName(matrix, "Test Matrix", &status);
+
+  void * rowPointer = XdmfGraphGetRowPointer(matrix, &status);
+
+  void * columnIndex = XdmfGraphGetColumnIndex(matrix, &status);
+
+  void * values = XdmfGraphGetValues(matrix, &status);
+
+  unsigned int insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  double insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -1.0;
+
+  XdmfArrayInsertValue(values, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfDomainInsertGraph(domain, matrix, 1);
+
+  XDMFGRAPH * matrix2 = XdmfGraphNew(3);
+
+  XdmfGraphSetName(matrix2, "Second Test Matrix", &status);
+
+  void * rowPointer2 = XdmfGraphGetRowPointer(matrix2, &status);
+
+  void * columnIndex2 = XdmfGraphGetColumnIndex(matrix2, &status);
+
+  void * values2 = XdmfGraphGetValues(matrix2, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer2, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer2, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer2, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer2, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex2, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex2, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex2, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values2, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values2, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -2.20;
+
+  XdmfArrayInsertValue(values2, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfDomainInsertGraph(domain, matrix2, 1);
+
+  printf("Graphs Generated\n");
+
+// Write to file
+
+  XDMFWRITER * writer = XdmfWriterNew("domainfile.xmf");
+
+  XdmfDomainAccept(domain, (XDMFVISITOR *)writer, &status);
+
+  printf("After Writing\n");
+
+  void * reader = XdmfReaderNew();
+
+  void * readDomain = XdmfReaderRead(reader, "domainfile.xmf", &status);
+
+  printf("After Reading\n");
+
+  char * valueString = XdmfDomainGetItemTag(readDomain);
+
+  printf("%s ?= %s\n", valueString, "Domain");
+
+  assert(strcmp(valueString, "Domain") == 0);
+
+  free(valueString);
+
+// Curvilinear
+
+  unsigned int numContained = XdmfDomainGetNumberCurvilinearGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readCurvGrid = XdmfDomainGetCurvilinearGrid(readDomain, 0);
+
+  XDMFGEOMETRY * childGeometry = XdmfCurvilinearGridGetGeometry(readCurvGrid);
+
+  valueString = XdmfGeometryGetValuesString(childGeometry);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * childDimensions = XdmfCurvilinearGridGetDimensions(readCurvGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(childDimensions);
+
+  printf("grid 1's dimension = %s\n", valueString);
+
+  assert(strcmp(valueString, "2 5") == 0);
+
+  free(valueString);
+
+  void * readCurvGrid2 = XdmfDomainGetCurvilinearGridByName(readDomain, "Second Test Curvilinear Grid");
+
+  XDMFGEOMETRY * childGeometry2 = XdmfCurvilinearGridGetGeometry(readCurvGrid2);
+
+  valueString = XdmfGeometryGetValuesString(childGeometry2);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * childDimensions2 = XdmfCurvilinearGridGetDimensions(readCurvGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(childDimensions2);
+
+  printf("grid 2's dimension = %s\n", valueString);
+
+  assert(strcmp(valueString, "5 2") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveCurvilinearGridByName(readDomain, "Test Curvilinear Grid");
+
+  numContained = XdmfDomainGetNumberCurvilinearGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readCurvGrid3 = XdmfDomainGetCurvilinearGrid(readDomain, 0);
+
+  valueString = XdmfCurvilinearGridGetName(readCurvGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Curvilinear Grid");
+
+  assert(strcmp(valueString, "Second Test Curvilinear Grid") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveCurvilinearGrid(readDomain, 0);
+
+  numContained = XdmfDomainGetNumberCurvilinearGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+  printf("done with curvilinear grids\n");
+
+// Rectilinear
+
+  numContained = XdmfDomainGetNumberRectilinearGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readRectGrid = XdmfDomainGetRectilinearGrid(readDomain, 0);
+
+  int numCoordinates = XdmfRectilinearGridGetNumberCoordinates(readRectGrid, &status);
+
+  printf("%d ?= %d\n", numCoordinates, 2);
+
+  assert(numCoordinates == 2);
+
+  XDMFARRAY ** readCoordinateArray = XdmfRectilinearGridGetCoordinates(readRectGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray[0]);
+
+  printf("first dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 6 7 8") == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray[1]);
+
+  printf("second dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * readDimensions = XdmfRectilinearGridGetDimensions(readRectGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contain %s\n", valueString);
+
+  assert(strcmp(valueString, "4 4") == 0);
+
+  free(valueString);
+
+  XdmfItemFree(readDimensions);
+
+  void * readRectGrid2 = XdmfDomainGetRectilinearGridByName(readDomain, "Second Test Rectilinear Grid");
+
+  numCoordinates = XdmfRectilinearGridGetNumberCoordinates(readRectGrid2, &status);
+
+  printf("%d ?= %d\n", numCoordinates, 2);
+
+  assert(numCoordinates == 2);
+
+  XDMFARRAY ** readCoordinateArray2 = XdmfRectilinearGridGetCoordinates(readRectGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray2[0]);
+
+  printf("first dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "15 16 17 18") == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray2[1]);
+
+  printf("second dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "16 17 18 19") == 0);
+
+  free(valueString);
+
+  readDimensions = XdmfRectilinearGridGetDimensions(readRectGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contain %s\n", valueString);
+
+  assert(strcmp(valueString, "4 4") == 0);
+
+  free(valueString);
+
+  XdmfItemFree(readDimensions);
+
+  XdmfDomainRemoveRectilinearGridByName(readDomain, "Test Rectilinear Grid");
+
+  numContained = XdmfDomainGetNumberRectilinearGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readRectGrid3 = XdmfDomainGetRectilinearGrid(readDomain, 0);
+
+  valueString = XdmfRectilinearGridGetName(readRectGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Rectilinear Grid");
+
+  assert(strcmp(valueString, "Second Test Rectilinear Grid") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveRectilinearGrid(readDomain, 0);
+
+  numContained = XdmfDomainGetNumberRectilinearGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Regular
+
+  numContained = XdmfDomainGetNumberRegularGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readRegGrid = XdmfDomainGetRegularGrid(readDomain, 0);
+
+  void * readBrick = XdmfRegularGridGetBrickSize(readRegGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readBrick);
+
+  printf("brick contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 5") == 0);
+
+  free(valueString);
+
+  free(readBrick);
+
+  readDimensions = XdmfRegularGridGetDimensions(readRegGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 5") == 0);
+
+  free(valueString);
+
+  free(readDimensions);
+
+  void * readOrigin = XdmfRegularGridGetOrigin(readRegGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readOrigin);
+
+  printf("origin contains %s\n", valueString);
+
+  assert(strcmp(valueString, "0 0") == 0);
+
+  free(valueString);
+
+  free(readOrigin);
+
+  void * readRegGrid2 = XdmfDomainGetRegularGridByName(readDomain, "Second Test Regular Grid");
+
+  void * readBrick2 = XdmfRegularGridGetBrickSize(readRegGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readBrick2);
+
+  printf("brick contains %s\n", valueString);
+
+  assert(strcmp(valueString, "3 3") == 0);
+
+  free(valueString);
+
+  free(readBrick2);
+
+  readDimensions = XdmfRegularGridGetDimensions(readRegGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contains %s\n", valueString);
+
+  assert(strcmp(valueString, "3 3") == 0);
+
+  free(valueString);
+
+  free(readDimensions);
+
+  void * readOrigin2 = XdmfRegularGridGetOrigin(readRegGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readOrigin2);
+
+  printf("origin contains %s\n", valueString);
+
+  assert(strcmp(valueString, "1 1") == 0);
+
+  free(valueString);
+
+  free(readOrigin2);
+
+  XdmfDomainRemoveRegularGridByName(readDomain, "Test Regular Grid");
+
+  numContained = XdmfDomainGetNumberRegularGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readRegGrid3 = XdmfDomainGetRegularGrid(readDomain, 0);
+
+  valueString = XdmfRegularGridGetName(readRegGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Regular Grid");
+
+  assert(strcmp(valueString, "Second Test Regular Grid") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveRegularGrid(readDomain, 0);
+
+  numContained = XdmfDomainGetNumberRegularGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Unstructured
+
+  numContained = XdmfDomainGetNumberUnstructuredGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readUnGrid = XdmfDomainGetUnstructuredGrid(readDomain, 0);
+
+  XDMFTOPOLOGY * readTopology = XdmfUnstructuredGridGetTopology(readUnGrid);
+
+  valueString = XdmfTopologyGetValuesString(readTopology);
+
+  printf("unstructured topology contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 6 5 1 2 7 6 2 3 8 7 3 4 9 8 5 6 11 10 6 7 12 11 7 8 13 12 8 9 14 13 10 11 16 15 11 12 17 16 12 13 18 17 13 14 19 18 15 16 21 20 16 17 22 21 17 18 23 22 18 19 24 23") == 0);
+
+  free(valueString);
+
+  XDMFGEOMETRY * readGeometry = XdmfUnstructuredGridGetGeometry(readUnGrid);
+
+  valueString = XdmfGeometryGetValuesString(readGeometry);
+
+  printf("unstructured geometry contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 0 5 0 10 0 15 0 20 0 0 5 5 5 10 5 15 5 20 5 0 10 5 10 10 10 15 10 20 10 0 15 5 15 10 15 15 15 20 15 0 20 5 20 10 20 15 20 20 20") == 0);
+
+  free(valueString);
+
+  void * readUnGrid2 = XdmfDomainGetUnstructuredGridByName(readDomain, "Second Test Unstructred Grid");
+
+  XDMFTOPOLOGY * readTopology2 = XdmfUnstructuredGridGetTopology(readUnGrid2);
+
+  valueString = XdmfTopologyGetValuesString(readTopology2);
+
+  printf("unstructured topology contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 4 3 1 2 5 4 3 4 7 6 4 5 8 7") == 0);
+
+  free(valueString);
+
+  XDMFGEOMETRY * readGeometry2 = XdmfUnstructuredGridGetGeometry(readUnGrid2);
+
+  valueString = XdmfGeometryGetValuesString(readGeometry2);
+
+  printf("unstructured geometry contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "1 1 4 1 7 1 1 4 4 4 7 4 1 7 4 7 7 7") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveUnstructuredGridByName(readDomain, "Test Unstructred Grid");
+
+  numContained = XdmfDomainGetNumberUnstructuredGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readUnGrid3 = XdmfDomainGetUnstructuredGrid(readDomain, 0);
+
+  valueString = XdmfUnstructuredGridGetName(readUnGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Unstructured Grid");
+
+  assert(strcmp(valueString, "Second Test Unstructred Grid") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveUnstructuredGrid(readDomain, 0);
+
+  numContained = XdmfDomainGetNumberUnstructuredGrids(readDomain);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 0);
+
+// Graph
+
+  numContained = XdmfDomainGetNumberGraphs(readDomain);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  XDMFGRAPH * readGraph = XdmfDomainGetGraph(readDomain, 0);
+
+  unsigned int readNumRows = XdmfGraphGetNumberRows(readGraph);
+
+  unsigned int readNumCols = XdmfGraphGetNumberColumns(readGraph);
+
+  printf("%d ?= %d\n%d ?= %d\n", readNumRows, 3, readNumCols, 3);
+
+  assert(readNumRows == 3);
+
+  assert(readNumCols == 3);
+
+  unsigned int readNumNodes = XdmfGraphGetNumberNodes(readGraph);
+
+  printf("%d ?= %d\n", readNumNodes, 3);
+
+  assert(readNumNodes == 3);
+
+  valueString = XdmfGraphGetValuesString(readGraph, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  XDMFGRAPH * readGraph2 = XdmfDomainGetGraphByName(readDomain, "Test Matrix");
+
+  readNumRows = XdmfGraphGetNumberRows(readGraph2);
+
+  readNumCols = XdmfGraphGetNumberColumns(readGraph2);
+
+  printf("%d ?= %d\n%d ?= %d\n", readNumRows, 3, readNumCols, 3);
+
+  assert(readNumRows == 3);
+
+  assert(readNumCols == 3);
+
+  readNumNodes = XdmfGraphGetNumberNodes(readGraph2);
+
+  printf("%d ?= %d\n", readNumNodes, 3);
+
+  assert(readNumNodes == 3);
+
+  valueString = XdmfGraphGetValuesString(readGraph2, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  XdmfDomainRemoveGraphByName(readDomain, "Test Matrix");
+
+  numContained = XdmfDomainGetNumberGraphs(readDomain);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  XDMFGRAPH * readGraph3 = XdmfDomainGetGraph(readDomain, 0);
+
+  valueString = XdmfGraphGetName(readGraph3);
+
+  assert(strcmp(valueString, "Second Test Matrix") == 0);
+
+  XdmfDomainRemoveGraph(readDomain, 0);
+
+  numContained = XdmfDomainGetNumberGraphs(readDomain);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Grid Collection
+
+  numContained = XdmfDomainGetNumberGridCollections(readDomain);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readCollection = XdmfDomainGetGridCollection(readDomain, 0);
+
+  valueString = XdmfGridCollectionGetName(readCollection);
+
+  printf("First Collection name = %s\n", valueString);
+
+  assert(strcmp(valueString, "Test Grid Collection") == 0);
+
+  free(valueString);
+
+  void * readTime = XdmfGridCollectionGetTime(readCollection);
+
+  double timeVal = XdmfTimeGetValue(readTime);
+
+  printf("%lf ?= %lf\n", timeVal, 21.0);
+
+  assert(timeVal == 21.0);
+
+  void * readCollection2 = XdmfDomainGetGridCollectionByName(readDomain, "Second Test Grid Collection");
+
+  valueString = XdmfGridCollectionGetName(readCollection2);
+
+  printf("%s ?= %s\n", valueString, "Second Test Grid Collection");
+
+  assert(strcmp(valueString, "Second Test Grid Collection") == 0);
+
+  void * readTime2 = XdmfGridCollectionGetTime(readCollection2);
+
+  double timeVal2 = XdmfTimeGetValue(readTime2);
+
+  printf("%lf ?= %lf\n", timeVal2, 12.0);
+
+  assert(timeVal2 == 12.0);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfGeometry.c b/tests/C/CTestXdmfGeometry.c
new file mode 100644
index 0000000..bb0d841
--- /dev/null
+++ b/tests/C/CTestXdmfGeometry.c
@@ -0,0 +1,91 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  XDMFGEOMETRY * geometry = XdmfGeometryNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfGeometryPushBack(geometry, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfGeometrySetType(geometry, XDMF_GEOMETRY_TYPE_XY, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("geofile.xmf");
+
+  int testype = XdmfGeometryGetType(geometry);
+
+  printf("%d ?= %d\n", testype, XDMF_GEOMETRY_TYPE_XY);
+
+  assert(testype == XDMF_GEOMETRY_TYPE_XY);
+
+  // Write to File
+
+  XdmfGeometryAccept(geometry, (XDMFVISITOR *)writer, &status);
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readArray = XdmfReaderRead(reader, "geofile.xmf", &status);
+
+  char * valueString = XdmfGeometryGetItemTag(readArray);
+
+  printf("%s ?= %s\n", valueString, "Geometry");
+
+  assert(strcmp(valueString, "Geometry") == 0);
+
+  XdmfGeometryRead(readArray, &status);
+
+  unsigned int numPoints = XdmfGeometryGetNumberPoints(readArray);
+
+  printf("%d ?= %d\n", numPoints, 5);
+
+  assert(numPoints == 5);
+
+  int geotype = XdmfGeometryGetType(readArray);
+
+  printf("Geometry type code = %d\n", geotype);
+
+  assert(geotype == XDMF_GEOMETRY_TYPE_XY);
+
+  unsigned int numDims = XdmfGeometryTypeGetDimensions(geotype, &status);
+
+  printf("%d ?= %d\n", numDims, 2);
+
+  assert(numDims == 2);
+
+  valueString = XdmfGeometryTypeGetName(geotype);
+
+  printf("Geometry type name: %s\n", valueString);
+
+  free(valueString);
+
+  valueString = XdmfGeometryGetValuesString(readArray);
+
+  printf("array contains: %s\n", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(readArray);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfGraph.c b/tests/C/CTestXdmfGraph.c
new file mode 100644
index 0000000..cc10deb
--- /dev/null
+++ b/tests/C/CTestXdmfGraph.c
@@ -0,0 +1,279 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+#include "assert.h"
+#include "string.h"
+#include "stdio.h"
+#include "stdlib.h"
+
+int main()
+{
+  int status = 0;
+
+  XDMFGRAPH * matrix = XdmfGraphNew(3);
+
+  XdmfGraphSetName(matrix, "testMatrix", &status);
+
+  char * valueString = XdmfSparseMatrixGetName((XDMFSPARSEMATRIX *)((void *)matrix));
+
+  printf("%s ?= %s\n", valueString, "testMatrix");
+
+  assert(strcmp(valueString, "testMatrix") == 0);
+
+  free(valueString);
+
+  valueString = XdmfGraphGetItemTag(matrix);
+
+  printf("%s ?= %s\n", valueString, "Graph");
+
+  assert(strcmp(valueString, "Graph") == 0);
+
+  void * rowPointer = XdmfGraphGetRowPointer(matrix, &status);
+
+  void * columnIndex = XdmfGraphGetColumnIndex(matrix, &status);
+
+  void * values = XdmfGraphGetValues(matrix, &status);
+
+  unsigned int insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  double insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -1.0;
+
+  XdmfArrayInsertValue(values, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  valueString = XdmfSparseMatrixGetValuesString((XDMFSPARSEMATRIX *)((void *)matrix), &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  rowPointer = XdmfArrayNew();
+
+  columnIndex = XdmfArrayNew();
+
+  values = XdmfArrayNew();
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -1.0;
+
+  XdmfArrayInsertValue(values, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfGraphSetColumnIndex(matrix, columnIndex, 0, &status);
+
+  XdmfGraphSetRowPointer(matrix, rowPointer, 0, &status);
+
+  XdmfGraphSetValues(matrix, values, 0, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("matrixfile.xmf");
+
+  XDMFATTRIBUTE * attrib1 = XdmfAttributeNew();
+
+  int i = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfAttributePushBack(attrib1, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfAttributeSetType(attrib1, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+
+  XdmfAttributeSetCenter(attrib1, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfAttributeSetName(attrib1, "Attribute 1", &status);
+
+  XdmfGraphInsertAttribute(matrix, attrib1, 0);
+
+  XDMFATTRIBUTE * attrib2 = XdmfAttributeNew();
+
+  for (i = 10; i < 20; i++) {
+    XdmfAttributePushBack(attrib2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfAttributeSetType(attrib2, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+
+  XdmfAttributeSetCenter(attrib2, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfAttributeSetName(attrib2, "Attribute 2", &status);
+
+  XdmfGraphInsertAttribute(matrix, attrib2, 0);
+
+  XdmfGraphAccept(matrix, (XDMFVISITOR *)writer, &status);
+
+  unsigned int numRows = XdmfGraphGetNumberRows(matrix);
+
+  unsigned int numCols = XdmfGraphGetNumberColumns(matrix);
+
+  printf("%d ?= %d\n%d ?= %d\n", numRows, 3, numCols, 3);
+
+  assert(numRows == 3);
+
+  assert(numCols == 3);
+
+  valueString = XdmfGraphGetValuesString(matrix, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  unsigned int numInfo = XdmfGraphGetNumberInformations(matrix);
+
+  printf("%d ?= %d\n", numInfo, 0);
+
+  assert(numInfo == 0);
+
+  void * reader = XdmfReaderNew();
+
+  XDMFGRAPH * readGraph = (XDMFGRAPH *)XdmfReaderRead(reader, "matrixfile.xmf", &status);
+
+  unsigned int readNumRows = XdmfGraphGetNumberRows(readGraph);
+
+  unsigned int readNumCols = XdmfGraphGetNumberColumns(readGraph);
+
+  printf("%d ?= %d\n%d ?= %d\n", readNumRows, 3, readNumCols, 3);
+
+  assert(readNumRows == 3);
+
+  assert(readNumCols == 3);
+
+  unsigned int readNumNodes = XdmfGraphGetNumberNodes(readGraph);
+
+  printf("%d ?= %d\n", readNumNodes, 3);
+
+  assert(readNumNodes == 3);
+
+  valueString = XdmfGraphGetValuesString(readGraph, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  unsigned int readNumAttributes = XdmfGraphGetNumberAttributes(readGraph);
+
+  printf("%d ?= %d\n", readNumAttributes, 2);
+
+  assert(readNumAttributes == 2);
+
+  XDMFATTRIBUTE * readAttribute = XdmfGraphGetAttribute(readGraph, 1);
+
+  valueString = XdmfAttributeGetName(readAttribute);
+
+  printf("%s ?= %s\n", valueString, "Attribute 2");
+
+  assert(strcmp(valueString, "Attribute 2") == 0);
+
+  free(valueString);
+
+  XDMFATTRIBUTE * readAttribute2 = XdmfGraphGetAttributeByName(readGraph, "Attribute 1");
+
+  valueString = XdmfAttributeGetValuesString(readAttribute2);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  XdmfGraphRemoveAttribute(readGraph, 0);
+
+  readNumAttributes = XdmfGraphGetNumberAttributes(readGraph);
+
+  printf("%d ?= %d\n", readNumAttributes, 1);
+
+  assert(readNumAttributes == 1);
+
+  XDMFATTRIBUTE * readAttribute3 = XdmfGraphGetAttributeByName(readGraph, "Attribute 2");
+
+  valueString = XdmfAttributeGetValuesString(readAttribute3);
+
+  printf("%s ?= %s\n", valueString, "10 11 12 13 14 15 16 17 18 19");
+
+  assert(strcmp(valueString, "10 11 12 13 14 15 16 17 18 19") == 0);
+
+  XdmfGraphRemoveAttributeByName(readGraph, "Attribute 2");
+
+  readNumAttributes = XdmfGraphGetNumberAttributes(readGraph);
+
+  printf("%d ?= %d\n", readNumAttributes, 0);
+
+  assert(readNumAttributes == 0);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfGridCollection.c b/tests/C/CTestXdmfGridCollection.c
new file mode 100644
index 0000000..b887d9f
--- /dev/null
+++ b/tests/C/CTestXdmfGridCollection.c
@@ -0,0 +1,1204 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfSparseMatrix.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+  int i = 0;
+  int j = 0;
+  int k = 0;
+
+  int status = 0;
+
+  void * mainCollection = XdmfGridCollectionNew();
+
+  printf("Generating interal objects\n");
+
+  XDMFATTRIBUTE * attrib = XdmfAttributeNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfAttributePushBack(attrib, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfAttributeSetType(attrib, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+
+  XdmfAttributeSetCenter(attrib, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfAttributeSetName(attrib, "Test Attribute", &status);
+
+  XdmfGridCollectionInsertAttribute(mainCollection, attrib, 1);
+
+  XDMFATTRIBUTE * attrib2 = XdmfAttributeNew();
+
+  for (i = 10; i < 20; i++) {
+    XdmfAttributePushBack(attrib2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfAttributeSetType(attrib2, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+
+  XdmfAttributeSetCenter(attrib2, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfAttributeSetName(attrib2, "Second Test Attribute", &status);
+
+  XdmfGridCollectionInsertAttribute(mainCollection, attrib2, 1);
+
+  XDMFSET * set = XdmfSetNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfSetPushBack(set, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfSetSetType(set, XDMF_SET_TYPE_NODE, &status);
+
+  XdmfSetSetName(set, "Test Set", &status);
+
+  XdmfGridCollectionInsertSet(mainCollection, set, 1);
+
+  XDMFSET * set2 = XdmfSetNew();
+
+  for (i = 10; i < 20; i++) {
+    XdmfSetPushBack(set2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfSetSetType(set2, XDMF_SET_TYPE_NODE, &status);
+
+  XdmfSetSetName(set2, "Second Test Set", &status);
+
+  XdmfGridCollectionInsertSet(mainCollection, set2, 1);
+
+  void * map = XdmfMapNew();
+
+  XdmfMapInsert(map, 1, 0, 8);
+  XdmfMapInsert(map, 1, 3, 7);
+  XdmfMapInsert(map, 1, 5, 9);
+  XdmfMapInsert(map, 2, 4, 6);
+  XdmfMapInsert(map, 2, 7, 5);
+  XdmfMapInsert(map, 3, 8, 3);
+  XdmfMapInsert(map, 3, 2, 4);
+  XdmfMapInsert(map, 3, 6, 2);
+  XdmfMapInsert(map, 3, 1, 1);
+
+  XdmfMapSetName(map, "Test Map");
+
+  XdmfGridCollectionInsertMap(mainCollection, map, 1);
+
+  void * map2 = XdmfMapNew();
+
+  XdmfMapInsert(map2, 1, 0, 8);
+  XdmfMapInsert(map2, 1, 3, 7);
+  XdmfMapInsert(map2, 1, 5, 9);
+  XdmfMapInsert(map2, 2, 4, 6);
+  XdmfMapInsert(map2, 2, 7, 5);
+  XdmfMapInsert(map2, 3, 8, 3);
+  XdmfMapInsert(map2, 3, 2, 4);
+  XdmfMapInsert(map2, 3, 6, 2);
+  XdmfMapInsert(map2, 3, 1, 1);
+
+  XdmfMapSetName(map2, "Second Test Map");
+
+  XdmfGridCollectionInsertMap(mainCollection, map2, 1);
+
+  printf("generated maps, sets, and attributes\n");
+
+// Grid Collection
+
+  void * collection = XdmfGridCollectionNew();
+
+  XdmfGridCollectionSetType(collection, XDMF_GRID_COLLECTION_TYPE_SPATIAL, &status);
+
+  char * testName = XdmfGridCollectionGetName(collection);
+
+  printf("%s ?= %s\n", testName, "Collection");
+
+  assert(strcmp(testName, "Collection") == 0);
+
+  XdmfGridCollectionSetName(collection, "Test Grid Collection", &status);
+
+  void * collection1Time = XdmfTimeNew(21.0);
+
+  XdmfGridCollectionSetTime(collection, collection1Time, 1);
+
+  printf("checking time\n");
+
+  void * checkTime = XdmfGridCollectionGetTime(collection);
+
+  double checkTimeVal = XdmfTimeGetValue(checkTime);
+
+  printf("%lf ?= %lf\n", checkTimeVal, 21.0);
+
+  assert(checkTimeVal == 21.0);
+
+  XdmfGridCollectionInsertGridCollection(mainCollection, collection, 1);
+
+  void * collection2 = XdmfGridCollectionNew();
+
+  XdmfGridCollectionSetType(collection2, XDMF_GRID_COLLECTION_TYPE_TEMPORAL, &status);
+
+  XdmfGridCollectionSetName(collection2, "Second Test Grid Collection", &status);
+
+  void * collection2Time = XdmfTimeNew(12.0);
+
+  XdmfGridCollectionSetTime(collection2, collection2Time, 1);
+
+  XdmfGridCollectionInsertGridCollection(mainCollection, collection2, 1);
+
+  printf("Generated Grid Collections\n");
+
+// Curvilinear Grid
+
+  XDMFGEOMETRY * geometry = XdmfGeometryNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfGeometryPushBack(geometry, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfGeometrySetType(geometry, XDMF_GEOMETRY_TYPE_XY, &status);
+
+
+  void * curvGrid = XdmfCurvilinearGridNew2D(2, 5);
+
+  XdmfCurvilinearGridSetGeometry(curvGrid, geometry, 1);
+
+  XdmfCurvilinearGridSetName(curvGrid, "Test Curvilinear Grid", &status);
+
+  XdmfGridCollectionInsertCurvilinearGrid(mainCollection, curvGrid, 1);
+
+  void * curvGrid2 = XdmfCurvilinearGridNew2D(5, 2);
+
+  XdmfCurvilinearGridSetGeometry(curvGrid2, geometry, 1);
+
+  XdmfCurvilinearGridSetName(curvGrid2, "Second Test Curvilinear Grid", &status);
+
+  XdmfGridCollectionInsertCurvilinearGrid(mainCollection, curvGrid2, 1);
+
+  printf("Curvilinear Grids Generated\n");
+
+// Rectilinear Grid
+
+  void * newXDim = XdmfArrayNew();
+
+  for (i = 5; i < 9; ++i) {
+    XdmfArrayPushBack(newXDim, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * newYDim = XdmfArrayNew();
+
+  for (i = 6; i < 10; ++i) {
+    XdmfArrayPushBack(newYDim, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * rectGrid = XdmfRectilinearGridNew2D(newXDim, newYDim, 0);
+
+  XdmfRectilinearGridSetName(rectGrid, "Test Rectilinear Grid", &status);
+
+  XdmfGridCollectionInsertRectilinearGrid(mainCollection, rectGrid, 1);
+
+  void * newXDim2 = XdmfArrayNew();
+
+  for (i = 15; i < 19; ++i) {
+    XdmfArrayPushBack(newXDim2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * newYDim2 = XdmfArrayNew();
+
+  for (i = 16; i < 20; ++i) {
+    XdmfArrayPushBack(newYDim2, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * rectGrid2 = XdmfRectilinearGridNew2D(newXDim2, newYDim2, 0);
+
+  XdmfRectilinearGridSetName(rectGrid2, "Second Test Rectilinear Grid", &status);
+
+  XdmfGridCollectionInsertRectilinearGrid(mainCollection, rectGrid2, 1);
+
+  printf("Rectilinear Grids Generated\n");
+
+// Regular Grid
+
+  void * regGrid = XdmfRegularGridNew2D(5, 5, 5, 5, 0, 0);
+
+  XdmfRegularGridSetName(regGrid, "Test Regular Grid", &status);
+
+  XdmfGridCollectionInsertRegularGrid(mainCollection, regGrid, 1);
+
+  void * regGrid2 = XdmfRegularGridNew2D(3, 3, 3, 3, 1, 1);
+
+  XdmfRegularGridSetName(regGrid2, "Second Test Regular Grid", &status);
+
+  XdmfGridCollectionInsertRegularGrid(mainCollection, regGrid2, 1);
+
+  printf("Regular Grids Generated\n");
+
+// Unstuctured Grid
+
+  void * unGrid = XdmfUnstructuredGridNewFromRegularGrid(regGrid, &status);
+
+  XdmfUnstructuredGridSetName(unGrid, "Test Unstructred Grid", &status);
+
+  XdmfGridCollectionInsertUnstructuredGrid(mainCollection, unGrid, 1);
+
+  void * unGrid2 = XdmfUnstructuredGridNewFromRegularGrid(regGrid2, &status);
+
+  XdmfUnstructuredGridSetName(unGrid2, "Second Test Unstructred Grid", &status);
+
+  XdmfGridCollectionInsertUnstructuredGrid(mainCollection, unGrid2, 1);
+
+  printf("Unstructured Grids Generated\n");
+
+// Graph
+
+  XDMFGRAPH * matrix = XdmfGraphNew(3);
+
+  XdmfGraphSetName(matrix, "Test Matrix", &status);
+
+  void * rowPointer = XdmfGraphGetRowPointer(matrix, &status);
+
+  void * columnIndex = XdmfGraphGetColumnIndex(matrix, &status);
+
+  void * values = XdmfGraphGetValues(matrix, &status);
+
+  unsigned int insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  double insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -1.0;
+
+  XdmfArrayInsertValue(values, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfGridCollectionInsertGraph(mainCollection, matrix, 1);
+
+  XDMFGRAPH * matrix2 = XdmfGraphNew(3);
+
+  XdmfGraphSetName(matrix2, "Second Test Matrix", &status);
+
+  void * rowPointer2 = XdmfGraphGetRowPointer(matrix2, &status);
+
+  void * columnIndex2 = XdmfGraphGetColumnIndex(matrix2, &status);
+
+  void * values2 = XdmfGraphGetValues(matrix2, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(rowPointer2, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(rowPointer2, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(rowPointer2, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 3;
+
+  XdmfArrayInsertValue(rowPointer2, 3, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 1;
+
+  XdmfArrayInsertValue(columnIndex2, 0, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 2;
+
+  XdmfArrayInsertValue(columnIndex2, 1, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedVal = 0;
+
+  XdmfArrayInsertValue(columnIndex2, 2, &insertedVal, XDMF_ARRAY_TYPE_UINT32, &status);
+
+  insertedDouble = 5.0;
+
+  XdmfArrayInsertValue(values2, 0, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = 6.0;
+
+  XdmfArrayInsertValue(values2, 1, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  insertedDouble = -2.20;
+
+  XdmfArrayInsertValue(values2, 2, &insertedDouble, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfGridCollectionInsertGraph(mainCollection, matrix2, 1);
+
+  printf("Graphs Generated\n");
+
+// Write to file
+
+  XDMFWRITER * writer = XdmfWriterNew("colfile.xmf");
+
+  XdmfGridCollectionAccept(mainCollection, (XDMFVISITOR *)writer, &status);
+
+  printf("After Writing\n");
+
+  void * reader = XdmfReaderNew();
+
+  void * readMainCollection = XdmfReaderRead(reader, "colfile.xmf", &status);
+
+  printf("After Reading\n");
+
+  char * valueString = XdmfGridCollectionGetItemTag(readMainCollection);
+
+  printf("%s ?= %s\n", valueString, "Grid");
+
+  assert(strcmp(valueString, "Grid") == 0);
+
+  free(valueString);
+
+// Curvilinear
+
+  unsigned int numContained = XdmfGridCollectionGetNumberCurvilinearGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readCurvGrid = XdmfGridCollectionGetCurvilinearGrid(readMainCollection, 0);
+
+  XDMFGEOMETRY * childGeometry = XdmfCurvilinearGridGetGeometry(readCurvGrid);
+
+  valueString = XdmfGeometryGetValuesString(childGeometry);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * childDimensions = XdmfCurvilinearGridGetDimensions(readCurvGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(childDimensions);
+
+  printf("grid 1's dimension = %s\n", valueString);
+
+  assert(strcmp(valueString, "2 5") == 0);
+
+  free(valueString);
+
+  void * readCurvGrid2 = XdmfGridCollectionGetCurvilinearGridByName(readMainCollection, "Second Test Curvilinear Grid");
+
+  XDMFGEOMETRY * childGeometry2 = XdmfCurvilinearGridGetGeometry(readCurvGrid2);
+
+  valueString = XdmfGeometryGetValuesString(childGeometry2);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * childDimensions2 = XdmfCurvilinearGridGetDimensions(readCurvGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(childDimensions2);
+
+  printf("grid 2's dimension = %s\n", valueString);
+
+  assert(strcmp(valueString, "5 2") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveCurvilinearGridByName(readMainCollection, "Test Curvilinear Grid");
+
+  numContained = XdmfGridCollectionGetNumberCurvilinearGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readCurvGrid3 = XdmfGridCollectionGetCurvilinearGrid(readMainCollection, 0);
+
+  valueString = XdmfCurvilinearGridGetName(readCurvGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Curvilinear Grid");
+
+  assert(strcmp(valueString, "Second Test Curvilinear Grid") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveCurvilinearGrid(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberCurvilinearGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+  printf("done with curvilinear grids\n");
+
+// Rectilinear
+
+  numContained = XdmfGridCollectionGetNumberRectilinearGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readRectGrid = XdmfGridCollectionGetRectilinearGrid(readMainCollection, 0);
+
+  int numCoordinates = XdmfRectilinearGridGetNumberCoordinates(readRectGrid, &status);
+
+  printf("%d ?= %d\n", numCoordinates, 2);
+
+  assert(numCoordinates == 2);
+
+  XDMFARRAY ** readCoordinateArray = XdmfRectilinearGridGetCoordinates(readRectGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray[0]);
+
+  printf("first dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 6 7 8") == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray[1]);
+
+  printf("second dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * readDimensions = XdmfRectilinearGridGetDimensions(readRectGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contain %s\n", valueString);
+
+  assert(strcmp(valueString, "4 4") == 0);
+
+  free(valueString);
+
+  XdmfItemFree(readDimensions);
+
+  void * readRectGrid2 = XdmfGridCollectionGetRectilinearGridByName(readMainCollection, "Second Test Rectilinear Grid");
+
+  numCoordinates = XdmfRectilinearGridGetNumberCoordinates(readRectGrid2, &status);
+
+  printf("%d ?= %d\n", numCoordinates, 2);
+
+  assert(numCoordinates == 2);
+
+  XDMFARRAY ** readCoordinateArray2 = XdmfRectilinearGridGetCoordinates(readRectGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray2[0]);
+
+  printf("first dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "15 16 17 18") == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray2[1]);
+
+  printf("second dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "16 17 18 19") == 0);
+
+  free(valueString);
+
+  readDimensions = XdmfRectilinearGridGetDimensions(readRectGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contain %s\n", valueString);
+
+  assert(strcmp(valueString, "4 4") == 0);
+
+  free(valueString);
+
+  XdmfItemFree(readDimensions);
+
+  XdmfGridCollectionRemoveRectilinearGridByName(readMainCollection, "Test Rectilinear Grid");
+
+  numContained = XdmfGridCollectionGetNumberRectilinearGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readRectGrid3 = XdmfGridCollectionGetRectilinearGrid(readMainCollection, 0);
+
+  valueString = XdmfRectilinearGridGetName(readRectGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Rectilinear Grid");
+
+  assert(strcmp(valueString, "Second Test Rectilinear Grid") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveRectilinearGrid(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberRectilinearGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Regular
+
+  numContained = XdmfGridCollectionGetNumberRegularGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readRegGrid = XdmfGridCollectionGetRegularGrid(readMainCollection, 0);
+
+  void * readBrick = XdmfRegularGridGetBrickSize(readRegGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readBrick);
+
+  printf("brick contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 5") == 0);
+
+  free(valueString);
+
+  free(readBrick);
+
+  readDimensions = XdmfRegularGridGetDimensions(readRegGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 5") == 0);
+
+  free(valueString);
+
+  free(readDimensions);
+
+  void * readOrigin = XdmfRegularGridGetOrigin(readRegGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readOrigin);
+
+  printf("origin contains %s\n", valueString);
+
+  assert(strcmp(valueString, "0 0") == 0);
+
+  free(valueString);
+
+  free(readOrigin);
+
+  void * readRegGrid2 = XdmfGridCollectionGetRegularGridByName(readMainCollection, "Second Test Regular Grid");
+
+  void * readBrick2 = XdmfRegularGridGetBrickSize(readRegGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readBrick2);
+
+  printf("brick contains %s\n", valueString);
+
+  assert(strcmp(valueString, "3 3") == 0);
+
+  free(valueString);
+
+  free(readBrick2);
+
+  readDimensions = XdmfRegularGridGetDimensions(readRegGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contains %s\n", valueString);
+
+  assert(strcmp(valueString, "3 3") == 0);
+
+  free(valueString);
+
+  free(readDimensions);
+
+  void * readOrigin2 = XdmfRegularGridGetOrigin(readRegGrid2, &status);
+
+  valueString = XdmfArrayGetValuesString(readOrigin2);
+
+  printf("origin contains %s\n", valueString);
+
+  assert(strcmp(valueString, "1 1") == 0);
+
+  free(valueString);
+
+  free(readOrigin2);
+
+  XdmfGridCollectionRemoveRegularGridByName(readMainCollection, "Test Regular Grid");
+
+  numContained = XdmfGridCollectionGetNumberRegularGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readRegGrid3 = XdmfGridCollectionGetRegularGrid(readMainCollection, 0);
+
+  valueString = XdmfRegularGridGetName(readRegGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Regular Grid");
+
+  assert(strcmp(valueString, "Second Test Regular Grid") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveRegularGrid(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberRegularGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Unstructured
+
+  numContained = XdmfGridCollectionGetNumberUnstructuredGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readUnGrid = XdmfGridCollectionGetUnstructuredGrid(readMainCollection, 0);
+
+  XDMFTOPOLOGY * readTopology = XdmfUnstructuredGridGetTopology(readUnGrid);
+
+  valueString = XdmfTopologyGetValuesString(readTopology);
+
+  printf("unstructured topology contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 6 5 1 2 7 6 2 3 8 7 3 4 9 8 5 6 11 10 6 7 12 11 7 8 13 12 8 9 14 13 10 11 16 15 11 12 17 16 12 13 18 17 13 14 19 18 15 16 21 20 16 17 22 21 17 18 23 22 18 19 24 23") == 0);
+
+  free(valueString);
+
+  XDMFGEOMETRY * readGeometry = XdmfUnstructuredGridGetGeometry(readUnGrid);
+
+  valueString = XdmfGeometryGetValuesString(readGeometry);
+
+  printf("unstructured geometry contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 0 5 0 10 0 15 0 20 0 0 5 5 5 10 5 15 5 20 5 0 10 5 10 10 10 15 10 20 10 0 15 5 15 10 15 15 15 20 15 0 20 5 20 10 20 15 20 20 20") == 0);
+
+  free(valueString);
+
+  void * readUnGrid2 = XdmfGridCollectionGetUnstructuredGridByName(readMainCollection, "Second Test Unstructred Grid");
+
+  XDMFTOPOLOGY * readTopology2 = XdmfUnstructuredGridGetTopology(readUnGrid2);
+
+  valueString = XdmfTopologyGetValuesString(readTopology2);
+
+  printf("unstructured topology contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 4 3 1 2 5 4 3 4 7 6 4 5 8 7") == 0);
+
+  free(valueString);
+
+  XDMFGEOMETRY * readGeometry2 = XdmfUnstructuredGridGetGeometry(readUnGrid2);
+
+  valueString = XdmfGeometryGetValuesString(readGeometry2);
+
+  printf("unstructured geometry contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "1 1 4 1 7 1 1 4 4 4 7 4 1 7 4 7 7 7") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveUnstructuredGridByName(readMainCollection, "Test Unstructred Grid");
+
+  numContained = XdmfGridCollectionGetNumberUnstructuredGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readUnGrid3 = XdmfGridCollectionGetUnstructuredGrid(readMainCollection, 0);
+
+  valueString = XdmfUnstructuredGridGetName(readUnGrid3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Unstructred Grid");
+
+  assert(strcmp(valueString, "Second Test Unstructred Grid") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveUnstructuredGrid(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberUnstructuredGrids(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Graph
+
+  numContained = XdmfGridCollectionGetNumberGraphs(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  XDMFGRAPH * readGraph = XdmfGridCollectionGetGraph(readMainCollection, 0);
+
+  unsigned int readNumRows = XdmfGraphGetNumberRows(readGraph);
+
+  unsigned int readNumCols = XdmfGraphGetNumberColumns(readGraph);
+
+  printf("%d ?= %d\n%d ?= %d\n", readNumRows, 3, readNumCols, 3);
+
+  assert(readNumRows == 3);
+
+  assert(readNumCols == 3);
+
+  unsigned int readNumNodes = XdmfGraphGetNumberNodes(readGraph);
+
+  printf("%d ?= %d\n", readNumNodes, 3);
+
+  assert(readNumNodes == 3);
+
+  valueString = XdmfGraphGetValuesString(readGraph, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  XDMFGRAPH * readGraph2 = XdmfGridCollectionGetGraphByName(readMainCollection, "Test Matrix");
+
+  readNumRows = XdmfGraphGetNumberRows(readGraph2);
+
+  readNumCols = XdmfGraphGetNumberColumns(readGraph2);
+
+  printf("%d ?= %d\n%d ?= %d\n", readNumRows, 3, readNumCols, 3);
+
+  assert(readNumRows == 3);
+
+  assert(readNumCols == 3);
+
+  readNumNodes = XdmfGraphGetNumberNodes(readGraph2);
+
+  printf("%d ?= %d\n", readNumNodes, 3);
+
+  assert(readNumNodes == 3);
+
+  valueString = XdmfGraphGetValuesString(readGraph2, &status);
+
+  printf("%s\n?=\n%s\n", valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n");
+
+  assert(strcmp(valueString, "0.0, 5, 0.0, \n0.0, 0.0, 6, \n-1, 0.0, 0.0, \n") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveGraphByName(readMainCollection, "Test Matrix");
+
+  numContained = XdmfGridCollectionGetNumberGraphs(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  XDMFGRAPH * readGraph3 = XdmfGridCollectionGetGraph(readMainCollection, 0);
+
+  valueString = XdmfGraphGetName(readGraph3);
+
+  printf("%s\n?=\n%s\n", valueString, "Second Test Matrix");
+
+  assert(strcmp(valueString, "Second Test Matrix") == 0);
+
+  XdmfGridCollectionRemoveGraph(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberGraphs(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Grid Collection
+
+  numContained = XdmfGridCollectionGetNumberGridCollections(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  void * readCollection = XdmfGridCollectionGetGridCollection(readMainCollection, 0);
+
+  valueString = XdmfGridCollectionGetName(readCollection);
+
+  printf("First Collection name = %s\n", valueString);
+
+  assert(strcmp(valueString, "Test Grid Collection") == 0);
+
+  free(valueString);
+
+  void * readTime = XdmfGridCollectionGetTime(readCollection);
+
+  double timeVal = XdmfTimeGetValue(readTime);
+
+  printf("%lf ?= %lf\n", timeVal, 21.0);
+
+  assert(timeVal == 21.0);
+
+  void * readCollection2 = XdmfGridCollectionGetGridCollectionByName(readMainCollection, "Second Test Grid Collection");
+
+  valueString = XdmfGridCollectionGetName(readCollection2);
+
+  printf("%s ?= %s\n", valueString, "Second Test Grid Collection");
+
+  assert(strcmp(valueString, "Second Test Grid Collection") == 0);
+
+  void * readTime2 = XdmfGridCollectionGetTime(readCollection2);
+
+  double timeVal2 = XdmfTimeGetValue(readTime2);
+
+  printf("%lf ?= %lf\n", timeVal2, 12.0);
+
+  assert(timeVal2 == 12.0);
+
+  XdmfGridCollectionRemoveGridCollectionByName(readMainCollection, "Test Grid Collection");
+
+  numContained = XdmfGridCollectionGetNumberGridCollections(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readCollection3 = XdmfGridCollectionGetGridCollection(readMainCollection, 0);
+
+  valueString = XdmfGridCollectionGetName(readCollection3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Grid Collection");
+
+  assert(strcmp(valueString, "Second Test Grid Collection") == 0);
+
+  XdmfGridCollectionRemoveGridCollection(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberGridCollections(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+  printf("checking map, set, and attribute\n");
+
+// Map
+
+  numContained = XdmfGridCollectionGetNumberMaps(readMainCollection);
+
+  printf("contains %d maps\n", numContained);
+
+  assert(numContained == 2);
+
+  void * readMap = XdmfGridCollectionGetMap(readMainCollection, 0);
+
+  XdmfMapRead(readMap, &status);
+
+  valueString = XdmfMapGetName(readMap);
+
+  printf("%s ?= %s\n", valueString, "Test Map");
+
+  assert(strcmp(valueString, "Test Map") == 0);
+
+  free(valueString);
+
+  int testNumRemoteTaskIds;
+  int * remoteTaskIds;
+  int testNumLocalNodeIds;
+  int * localNodeIds;
+  int testNumRemoteNodeIds;
+  int * remoteNodeIds;
+
+  int expectedRemoteTasks[3];
+  expectedRemoteTasks[0] = 1;
+  expectedRemoteTasks[1] = 2;
+  expectedRemoteTasks[2] = 3;
+
+
+  int expectedLocalNodeIds[3][4];
+  expectedLocalNodeIds[0][0] = 0;
+  expectedLocalNodeIds[0][1] = 3;
+  expectedLocalNodeIds[0][2] = 5;
+  expectedLocalNodeIds[1][0] = 4;
+  expectedLocalNodeIds[1][1] = 7;
+  expectedLocalNodeIds[2][0] = 1;
+  expectedLocalNodeIds[2][1] = 2;
+  expectedLocalNodeIds[2][2] = 6;
+  expectedLocalNodeIds[2][3] = 8;
+
+
+  int expectedRemoteNodeIds[3][4][1];
+  expectedRemoteNodeIds[0][0][0] = 8;
+  expectedRemoteNodeIds[0][1][0] = 7;
+  expectedRemoteNodeIds[0][2][0] = 9;
+  expectedRemoteNodeIds[1][0][0] = 6;
+  expectedRemoteNodeIds[1][1][0] = 5;
+  expectedRemoteNodeIds[2][0][0] = 1;
+  expectedRemoteNodeIds[2][1][0] = 4;
+  expectedRemoteNodeIds[2][2][0] = 2;
+  expectedRemoteNodeIds[2][3][0] = 3;
+
+  testNumRemoteTaskIds = XdmfMapRetrieveNumberRemoteTaskIds(readMap);
+
+  remoteTaskIds = XdmfMapRetrieveRemoteTaskIds(readMap);
+
+  for (i = 0; i < testNumRemoteTaskIds; ++i) {
+    printf("remote task id %d\n", remoteTaskIds[i]);
+    assert(expectedRemoteTasks[i] == remoteTaskIds[i]);
+    testNumLocalNodeIds = XdmfMapRetrieveNumberLocalNodeIds(readMap, remoteTaskIds[i]);
+    localNodeIds = XdmfMapRetrieveLocalNodeIds(readMap, remoteTaskIds[i]);
+    for (j = 0; j < testNumLocalNodeIds; ++j) {
+      printf("\tlocal node id %d == %d\n", localNodeIds[j], expectedLocalNodeIds[i][j]);
+      assert(localNodeIds[j] == expectedLocalNodeIds[i][j]);
+      testNumRemoteNodeIds = XdmfMapRetrieveNumberRemoteNodeIds(readMap, remoteTaskIds[i], localNodeIds[j]);
+      remoteNodeIds = XdmfMapRetrieveRemoteNodeIds(readMap, remoteTaskIds[i], localNodeIds[j]);
+      for (k = 0; k < testNumRemoteNodeIds; ++k) {
+        printf("\t\tremote node id %d == %d\n", remoteNodeIds[k], expectedRemoteNodeIds[i][j][k]);
+        assert(remoteNodeIds[k] == expectedRemoteNodeIds[i][j][k]);
+      }
+      free(remoteNodeIds);
+    }
+    free(localNodeIds);
+  }
+  free(remoteTaskIds);
+
+  void * readMap2 = XdmfGridCollectionGetMapByName(readMainCollection, "Second Test Map");
+
+  valueString = XdmfMapGetName(readMap2);
+
+  printf("%s ?= %s\n", valueString, "Second Test Map");
+
+  assert(strcmp(valueString, "Second Test Map") == 0);
+
+  testNumRemoteTaskIds = XdmfMapRetrieveNumberRemoteTaskIds(readMap2);
+
+  remoteTaskIds = XdmfMapRetrieveRemoteTaskIds(readMap2);
+
+  for (i = 0; i < testNumRemoteTaskIds; ++i) {
+    printf("remote task id %d\n", remoteTaskIds[i]);
+    assert(expectedRemoteTasks[i] == remoteTaskIds[i]);
+    testNumLocalNodeIds = XdmfMapRetrieveNumberLocalNodeIds(readMap2, remoteTaskIds[i]);
+    localNodeIds = XdmfMapRetrieveLocalNodeIds(readMap2, remoteTaskIds[i]);
+    for (j = 0; j < testNumLocalNodeIds; ++j) {
+      printf("\tlocal node id %d == %d\n", localNodeIds[j], expectedLocalNodeIds[i][j]);
+      assert(localNodeIds[j] == expectedLocalNodeIds[i][j]);
+      testNumRemoteNodeIds = XdmfMapRetrieveNumberRemoteNodeIds(readMap2, remoteTaskIds[i], localNodeIds[j]);
+      remoteNodeIds = XdmfMapRetrieveRemoteNodeIds(readMap2, remoteTaskIds[i], localNodeIds[j]);
+      for (k = 0; k < testNumRemoteNodeIds; ++k) {
+        printf("\t\tremote node id %d == %d\n", remoteNodeIds[k], expectedRemoteNodeIds[i][j][k]);
+        assert(remoteNodeIds[k] == expectedRemoteNodeIds[i][j][k]);
+      }
+      free(remoteNodeIds);
+    }
+    free(localNodeIds);
+  }
+  free(remoteTaskIds);
+
+  XdmfGridCollectionRemoveMapByName(readMainCollection, "Test Map");
+
+  numContained = XdmfGridCollectionGetNumberMaps(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  void * readMap3 = XdmfGridCollectionGetMap(readMainCollection, 0);
+
+  valueString = XdmfMapGetName(readMap3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Map");
+
+  assert(strcmp(valueString, "Second Test Map") == 0);
+
+  XdmfGridCollectionRemoveMap(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberMaps(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Set
+
+  numContained = XdmfGridCollectionGetNumberSets(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  XDMFSET * readSet = XdmfGridCollectionGetSet(readMainCollection, 0);
+
+  valueString = XdmfSetGetName(readSet);
+
+  printf("%s ?= %s\n", valueString, "Test Set");
+
+  assert(strcmp(valueString, "Test Set") == 0);
+
+  free(valueString);
+
+  valueString = XdmfSetGetValuesString(readSet);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  XDMFSET * readSet2 = XdmfGridCollectionGetSetByName(readMainCollection, "Second Test Set");
+
+  valueString = XdmfSetGetName(readSet2);
+
+  printf("%s ?= %s\n", valueString, "Second Test Set");
+
+  assert(strcmp(valueString, "Second Test Set") == 0);
+
+  valueString = XdmfSetGetValuesString(readSet2);
+
+  printf("%s ?= %s\n", valueString, "10 11 12 13 14 15 16 17 18 19");
+
+  assert(strcmp(valueString, "10 11 12 13 14 15 16 17 18 19") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveSetByName(readMainCollection, "Test Set");
+
+  numContained = XdmfGridCollectionGetNumberSets(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  XDMFSET * readSet3 = XdmfGridCollectionGetSet(readMainCollection, 0);
+
+  valueString = XdmfSetGetName(readSet3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Set");
+
+  assert(strcmp(valueString, "Second Test Set") == 0);
+
+  XdmfGridCollectionRemoveSet(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberSets(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+// Attribute
+
+  numContained = XdmfGridCollectionGetNumberAttributes(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 2);
+
+  assert(numContained == 2);
+
+  XDMFATTRIBUTE * readAttribute = XdmfGridCollectionGetAttribute(readMainCollection, 0);
+
+  valueString = XdmfAttributeGetName(readAttribute);
+
+  printf("%s ?= %s\n", valueString, "Test Attribute");
+
+  assert(strcmp(valueString, "Test Attribute") == 0);
+
+  free(valueString);
+
+  valueString = XdmfAttributeGetValuesString(readAttribute);
+
+  printf("%s ?= %s\n", valueString, "0 1 2 3 4 5 6 7 8 9");
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+  XDMFATTRIBUTE * readAttribute2 = XdmfGridCollectionGetAttributeByName(readMainCollection, "Second Test Attribute");
+
+  valueString = XdmfAttributeGetName(readAttribute2);
+
+  printf("%s ?= %s\n", valueString, "Second Test Attribute");
+
+  assert(strcmp(valueString, "Second Test Attribute") == 0);
+
+  valueString = XdmfAttributeGetValuesString(readAttribute2);
+
+  printf("%s ?= %s\n", valueString, "10 11 12 13 14 15 16 17 18 19");
+
+  assert(strcmp(valueString, "10 11 12 13 14 15 16 17 18 19") == 0);
+
+  free(valueString);
+
+  XdmfGridCollectionRemoveAttributeByName(readMainCollection, "Test Attribute");
+
+  numContained = XdmfGridCollectionGetNumberAttributes(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 1);
+
+  assert(numContained == 1);
+
+  XDMFATTRIBUTE * readAttribute3 = XdmfGridCollectionGetAttribute(readMainCollection, 0);
+
+  valueString = XdmfAttributeGetName(readAttribute3);
+
+  printf("%s ?= %s\n", valueString, "Second Test Attribute");
+
+  assert(strcmp(valueString, "Second Test Attribute") == 0);
+
+  XdmfGridCollectionRemoveAttribute(readMainCollection, 0);
+
+  numContained = XdmfGridCollectionGetNumberAttributes(readMainCollection);
+
+  printf("%d ?= %d\n", numContained, 0);
+
+  assert(numContained == 0);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfGridController.c b/tests/C/CTestXdmfGridController.c
new file mode 100644
index 0000000..40c56b7
--- /dev/null
+++ b/tests/C/CTestXdmfGridController.c
@@ -0,0 +1,377 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfError.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridController.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include "stdio.h"
+
+#include "assert.h"
+#include "string.h"
+
+int main()
+{
+  int status = 0;
+  unsigned int i, j;
+  XDMFDOMAIN * domain = XdmfDomainNew();
+
+  XDMFGRIDCOLLECTION * collection = XdmfGridCollectionNew();
+
+  for (i = 0; i < 5; ++i)
+  {
+    XDMFUNSTRUCTUREDGRID * colgrid = XdmfUnstructuredGridNew();
+
+    XdmfGridCollectionInsertUnstructuredGrid(collection, colgrid, 1);
+
+    XDMFGEOMETRY * colgeometry = XdmfGeometryNew();
+
+    for (j = 0; j < 9; ++j)
+    {
+      unsigned int val = j+i;
+      XdmfGeometryPushBack(colgeometry, &val, XDMF_ARRAY_TYPE_UINT32, &status);
+    }
+
+    XdmfGeometrySetType(colgeometry, XDMF_GEOMETRY_TYPE_XYZ, &status);
+
+    XdmfUnstructuredGridSetGeometry(colgrid, colgeometry, 1);
+
+    XDMFTOPOLOGY * coltopology = XdmfTopologyNew();
+
+    for (j = 0; j < 3; ++j)
+    {
+      XdmfTopologyPushBack(coltopology, &j, XDMF_ARRAY_TYPE_UINT32, &status);
+    }
+
+    XdmfTopologySetType(coltopology, XDMF_TOPOLOGY_TYPE_TRIANGLE, &status);
+
+    XdmfUnstructuredGridSetTopology(colgrid, coltopology, 1);
+
+    XDMFATTRIBUTE * colattr = XdmfAttributeNew();
+
+    for (j = 0; j < 3; ++j)
+    {
+      unsigned int val = j+i;
+      XdmfAttributePushBack(colattr, &val, XDMF_ARRAY_TYPE_UINT32, &status);
+    }
+
+    XdmfAttributeSetType(colattr, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+    XdmfAttributeSetCenter(colattr, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+    XdmfUnstructuredGridInsertAttribute(colgrid, colattr, 1);
+  }
+
+  XdmfDomainInsertGridCollection(domain, collection, 1);
+
+  XDMFCURVILINEARGRID * curvgrid = XdmfCurvilinearGridNew2D(10, 10);
+
+  XDMFGEOMETRY * curvgeometry = XdmfGeometryNew();
+
+  for (i = 0; i < 9; ++i)
+  {
+    XdmfGeometryPushBack(curvgeometry, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfGeometrySetType(curvgeometry, XDMF_GEOMETRY_TYPE_XYZ, &status);
+
+  XdmfCurvilinearGridSetGeometry(curvgrid, curvgeometry, 1);
+
+  XDMFATTRIBUTE * curvattr = XdmfAttributeNew();
+
+  for (i = 0; i < 100; ++i)
+  {
+    XdmfAttributePushBack(curvattr, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfAttributeSetType(curvattr, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(curvattr, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfCurvilinearGridInsertAttribute(curvgrid, curvattr, 1);
+
+  XdmfDomainInsertCurvilinearGrid(domain, curvgrid, 1);
+
+  XDMFARRAY * xCoordinates = XdmfArrayNew();
+  XDMFARRAY * yCoordinates = XdmfArrayNew();
+
+  for (i = 0; i < 10; ++i)
+  {
+    XdmfArrayPushBack(xCoordinates, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+    XdmfArrayPushBack(yCoordinates, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XDMFRECTILINEARGRID * rectgrid = XdmfRectilinearGridNew2D(xCoordinates, yCoordinates, 1);
+
+  XdmfDomainInsertRectilinearGrid(domain, rectgrid, 1);
+
+  XDMFATTRIBUTE * rectattr = XdmfAttributeNew();
+
+  for (i = 0; i < 100; ++i)
+  {
+    XdmfAttributePushBack(rectattr, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfAttributeSetType(rectattr, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(rectattr, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfRectilinearGridInsertAttribute(rectgrid, rectattr, 1);
+
+  XDMFREGULARGRID * reggrid = XdmfRegularGridNew2D(1, 1, 10, 10, 0, 0);
+
+  XdmfDomainInsertRegularGrid(domain, reggrid, 1);
+
+  XDMFATTRIBUTE * regattr = XdmfAttributeNew();
+
+  for (i = 0; i < 100; ++i)
+  {
+    XdmfAttributePushBack(regattr, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfAttributeSetType(regattr, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(regattr, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfRegularGridInsertAttribute(reggrid, regattr, 1);
+
+  XDMFUNSTRUCTUREDGRID * ungrid = XdmfUnstructuredGridNew();
+
+  XdmfDomainInsertUnstructuredGrid(domain, ungrid, 1);
+
+  XDMFGEOMETRY * ungeometry = XdmfGeometryNew();
+
+  for (i = 0; i < 9; ++i)
+  {
+    XdmfGeometryPushBack(ungeometry, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfGeometrySetType(ungeometry, XDMF_GEOMETRY_TYPE_XYZ, &status);
+
+  XdmfUnstructuredGridSetGeometry(ungrid, ungeometry, 1);
+
+  XDMFTOPOLOGY * untopology = XdmfTopologyNew();
+
+  for (i = 0; i < 3; ++i)
+  {
+    XdmfTopologyPushBack(untopology, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfTopologySetType(untopology, XDMF_TOPOLOGY_TYPE_TRIANGLE, &status);
+
+  XdmfUnstructuredGridSetTopology(ungrid, untopology, 1);
+
+  XDMFATTRIBUTE * unattr = XdmfAttributeNew();
+
+  for (i = 0; i < 3; ++i)
+  {
+    XdmfAttributePushBack(unattr, &i, XDMF_ARRAY_TYPE_UINT32, &status);
+  }
+
+  XdmfAttributeSetType(unattr, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(unattr, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+
+  XdmfUnstructuredGridInsertAttribute(ungrid, unattr, 1);
+
+  XDMFWRITER * writer = XdmfWriterNew("gridControllerReference.xmf");
+
+  XdmfDomainAccept(domain, (XDMFVISITOR *)writer, &status);
+
+  printf("Finished writing reference file\n");
+
+  XDMFDOMAIN * equalDomain = XdmfDomainNew();
+
+  XDMFGRIDCOLLECTION * equalCollection = XdmfGridCollectionNew();
+
+  XDMFGRIDCONTROLLER * collectionController = XdmfGridControllerNew("gridControllerReference.xmf", "/Xdmf/Domain/Grid[1]");
+
+  XdmfGridCollectionSetGridController(equalCollection, collectionController, 1);
+
+  XdmfDomainInsertGridCollection(equalDomain, equalCollection, 1);
+
+  XDMFCURVILINEARGRID * equalCurvGrid = XdmfCurvilinearGridNew2D(0, 0);
+
+  XDMFGRIDCONTROLLER * curvGridController = XdmfGridControllerNew("gridControllerReference.xmf", "/Xdmf/Domain/Grid[2]");
+
+  XdmfCurvilinearGridSetGridController(equalCurvGrid, curvGridController, 1);
+
+  XdmfDomainInsertCurvilinearGrid(equalDomain, equalCurvGrid, 1);
+
+  XDMFARRAY * placeholderXArray = XdmfArrayNew();
+  XDMFARRAY * placeholderYArray = XdmfArrayNew();
+
+  XDMFRECTILINEARGRID * equalRectGrid = XdmfRectilinearGridNew2D(placeholderXArray,
+                                                                 placeholderYArray,
+                                                                 1);
+
+  XDMFGRIDCONTROLLER * rectGridController = XdmfGridControllerNew("gridControllerReference.xmf", "/Xdmf/Domain/Grid[3]");
+
+  XdmfRectilinearGridSetGridController(equalRectGrid, rectGridController, 1);
+
+  XdmfDomainInsertRectilinearGrid(equalDomain, equalRectGrid, 1);
+
+  XDMFREGULARGRID * equalRegGrid = XdmfRegularGridNew2D(0, 0, 0, 0, 0, 0);
+
+  XDMFGRIDCONTROLLER * regGridController = XdmfGridControllerNew("gridControllerReference.xmf", "/Xdmf/Domain/Grid[4]");
+
+  XdmfRegularGridSetGridController(equalRegGrid, regGridController, 1);
+
+  XdmfDomainInsertRegularGrid(equalDomain, equalRegGrid, 1);
+
+  XDMFUNSTRUCTUREDGRID * equalUnGrid = XdmfUnstructuredGridNew();
+
+  XDMFGRIDCONTROLLER * unGridController = XdmfGridControllerNew("gridControllerReference.xmf", "/Xdmf/Domain/Grid[5]");
+
+  XdmfUnstructuredGridSetGridController(equalUnGrid, unGridController, 1);
+
+  XdmfDomainInsertUnstructuredGrid(equalDomain, equalUnGrid, 1);
+
+  XDMFWRITER * controllerWriter = XdmfWriterNew("gridController.xmf");
+
+  XdmfDomainAccept(equalDomain, (XDMFVISITOR *)controllerWriter, &status);
+
+
+
+
+
+
+
+
+
+
+
+  XDMFREADER * reader = XdmfReaderNew();
+
+  XDMFDOMAIN * readReference = (XDMFDOMAIN *)XdmfReaderRead(reader, "gridControllerReference.xmf", &status);
+
+  XDMFDOMAIN * readControllerDomain = (XDMFDOMAIN *)XdmfReaderRead(reader, "gridController.xmf", &status);
+
+  XDMFGRIDCOLLECTION * collectionReference = XdmfDomainGetGridCollection(readReference, 0);
+
+  XDMFGRIDCOLLECTION * compareCollection = XdmfDomainGetGridCollection(readControllerDomain, 0);
+
+  XdmfGridCollectionRead(compareCollection, &status);
+
+  printf("%u ?= %u\n", XdmfGridCollectionGetNumberUnstructuredGrids(compareCollection), XdmfGridCollectionGetNumberUnstructuredGrids(collectionReference));
+
+  assert(XdmfGridCollectionGetNumberUnstructuredGrids(compareCollection) == XdmfGridCollectionGetNumberUnstructuredGrids(collectionReference));
+
+  for (i = 0; i < XdmfGridCollectionGetNumberUnstructuredGrids(compareCollection); ++i)
+  {
+    printf("Checking Grid %d\n", i);
+    XDMFUNSTRUCTUREDGRID * unCollectionReference = XdmfGridCollectionGetUnstructuredGrid(collectionReference, i);
+    XDMFUNSTRUCTUREDGRID * unCollectionRead = XdmfGridCollectionGetUnstructuredGrid(compareCollection, i);
+
+    printf("%s ?= %s\n", XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCollectionRead)), XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCollectionReference)));
+
+    assert(strcmp(XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCollectionRead)), XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCollectionReference))) == 0);
+
+    printf("%s ?= %s\n", XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCollectionRead)), XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCollectionReference)));
+
+    assert(strcmp(XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCollectionRead)), XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCollectionReference))) == 0);
+
+    printf("%s ?= %s\n", XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCollectionRead, 0)), XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCollectionReference, 0)));
+
+    assert(strcmp(XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCollectionRead, 0)), XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCollectionReference, 0))) == 0);
+  }
+
+  XdmfGridCollectionRelease(compareCollection);
+
+
+
+
+
+  XDMFUNSTRUCTUREDGRID * unCompareReference = XdmfDomainGetUnstructuredGrid(readReference, 0);
+
+  XDMFUNSTRUCTUREDGRID * unCompare = XdmfDomainGetUnstructuredGrid(readControllerDomain, 0);
+
+  XdmfUnstructuredGridRead(unCompare, &status);
+
+  printf("%s ?= %s\n", XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCompare)), XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCompareReference)));
+
+  assert(strcmp(XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCompare)), XdmfGeometryGetValuesString(XdmfUnstructuredGridGetGeometry(unCompareReference))) == 0);
+
+  printf("%s ?= %s\n", XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCompare)), XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCompareReference)));
+
+  assert(strcmp(XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCompare)), XdmfTopologyGetValuesString(XdmfUnstructuredGridGetTopology(unCompareReference))) == 0);
+
+  printf("%s ?= %s\n", XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCompare, 0)), XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCompareReference, 0)));
+
+  assert(strcmp(XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCompare, 0)), XdmfAttributeGetValuesString(XdmfUnstructuredGridGetAttribute(unCompareReference, 0))) == 0);
+
+  XdmfUnstructuredGridRelease(unCompare);
+
+  XDMFREGULARGRID * regCompareReference = XdmfDomainGetRegularGrid(readReference, 0);
+
+  XDMFREGULARGRID * regCompare = XdmfDomainGetRegularGrid(readControllerDomain, 0);
+
+  XdmfRegularGridRead(regCompare, &status);
+
+  printf("%s ?= %s\n", XdmfArrayGetValuesString(XdmfRegularGridGetOrigin(regCompare, &status)), XdmfArrayGetValuesString(XdmfRegularGridGetOrigin(regCompareReference, &status)));
+
+  assert(strcmp(XdmfArrayGetValuesString(XdmfRegularGridGetOrigin(regCompare, &status)), XdmfArrayGetValuesString(XdmfRegularGridGetOrigin(regCompareReference, &status))) == 0);
+
+  printf("%s ?= %s\n", XdmfArrayGetValuesString(XdmfRegularGridGetDimensions(regCompare, &status)), XdmfArrayGetValuesString(XdmfRegularGridGetDimensions(regCompareReference, &status)));
+
+  assert(strcmp(XdmfArrayGetValuesString(XdmfRegularGridGetDimensions(regCompare, &status)), XdmfArrayGetValuesString(XdmfRegularGridGetDimensions(regCompareReference, &status))) == 0);
+
+  printf("%s ?= %s\n", XdmfArrayGetValuesString(XdmfRegularGridGetBrickSize(regCompare, &status)), XdmfArrayGetValuesString(XdmfRegularGridGetBrickSize(regCompareReference, &status)));
+
+  assert(strcmp(XdmfArrayGetValuesString(XdmfRegularGridGetBrickSize(regCompare, &status)), XdmfArrayGetValuesString(XdmfRegularGridGetBrickSize(regCompareReference, &status))) == 0);
+
+  printf("%s ?= %s\n", XdmfAttributeGetValuesString(XdmfRegularGridGetAttribute(regCompare, 0)), XdmfAttributeGetValuesString(XdmfRegularGridGetAttribute(regCompareReference, 0)));
+
+  assert(strcmp(XdmfAttributeGetValuesString(XdmfRegularGridGetAttribute(regCompare, 0)), XdmfAttributeGetValuesString(XdmfRegularGridGetAttribute(regCompareReference, 0))) == 0);
+
+  XdmfRegularGridRelease(regCompare);
+
+  XDMFRECTILINEARGRID * rectCompareReference = XdmfDomainGetRectilinearGrid(readReference, 0);
+
+  XDMFRECTILINEARGRID * rectCompare = XdmfDomainGetRectilinearGrid(readControllerDomain, 0);
+
+  XdmfRectilinearGridRead(rectCompare, &status);
+
+  printf("%s ?= %s\n", XdmfAttributeGetValuesString(XdmfRectilinearGridGetAttribute(rectCompare, 0)), XdmfAttributeGetValuesString(XdmfRectilinearGridGetAttribute(rectCompareReference, 0)));
+
+  assert(strcmp(XdmfAttributeGetValuesString(XdmfRectilinearGridGetAttribute(rectCompare, 0)), XdmfAttributeGetValuesString(XdmfRectilinearGridGetAttribute(rectCompareReference, 0))) == 0);
+
+  printf("%s ?= %s\n", XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompare, 0, &status)), XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompareReference, 0, &status)));
+
+  assert(strcmp(XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompare, 0, &status)), XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompareReference, 0, &status))) == 0);
+
+  printf("%s ?= %s\n", XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompare, 1, &status)), XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompareReference, 1, &status)));
+
+  assert(strcmp(XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompare, 1, &status)), XdmfArrayGetValuesString(XdmfRectilinearGridGetCoordinatesByIndex(rectCompareReference, 1, &status))) == 0);
+
+  XdmfRectilinearGridRelease(rectCompare);
+
+  XDMFCURVILINEARGRID * curvCompareReference = XdmfDomainGetCurvilinearGrid(readReference, 0);
+
+  XDMFCURVILINEARGRID * curvCompare = XdmfDomainGetCurvilinearGrid(readControllerDomain, 0);
+
+  XdmfCurvilinearGridRead(curvCompare, &status);
+
+  printf("%s ?= %s\n", XdmfGeometryGetValuesString(XdmfCurvilinearGridGetGeometry(curvCompare)), XdmfGeometryGetValuesString(XdmfCurvilinearGridGetGeometry(curvCompareReference)));
+
+  assert(strcmp(XdmfGeometryGetValuesString(XdmfCurvilinearGridGetGeometry(curvCompare)), XdmfGeometryGetValuesString(XdmfCurvilinearGridGetGeometry(curvCompareReference))) == 0);
+
+  printf("%s ?= %s\n", XdmfAttributeGetValuesString(XdmfCurvilinearGridGetAttribute(curvCompare, 0)), XdmfAttributeGetValuesString(XdmfCurvilinearGridGetAttribute(curvCompareReference, 0)));
+
+  assert(strcmp(XdmfAttributeGetValuesString(XdmfCurvilinearGridGetAttribute(curvCompare, 0)), XdmfAttributeGetValuesString(XdmfCurvilinearGridGetAttribute(curvCompareReference, 0))) == 0);
+
+  printf("%s ?= %s\n", XdmfArrayGetValuesString(XdmfCurvilinearGridGetDimensions(curvCompare, &status)), XdmfArrayGetValuesString(XdmfCurvilinearGridGetDimensions(curvCompareReference, &status)));
+
+  assert(strcmp(XdmfArrayGetValuesString(XdmfCurvilinearGridGetDimensions(curvCompare, &status)), XdmfArrayGetValuesString(XdmfCurvilinearGridGetDimensions(curvCompareReference, &status))) == 0);
+
+  XdmfCurvilinearGridRelease(curvCompare);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfMap.c b/tests/C/CTestXdmfMap.c
new file mode 100644
index 0000000..0d24544
--- /dev/null
+++ b/tests/C/CTestXdmfMap.c
@@ -0,0 +1,307 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfMap.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  void * map = XdmfMapNew();
+
+  int i = 0;
+  int j = 0;
+  int k = 0;
+
+  int status = 0;
+
+  XdmfMapInsert(map, 1, 0, 8);
+  XdmfMapInsert(map, 1, 3, 7);
+  XdmfMapInsert(map, 1, 5, 9);
+  XdmfMapInsert(map, 2, 4, 6);
+  XdmfMapInsert(map, 2, 7, 5);
+  XdmfMapInsert(map, 3, 8, 3);
+  XdmfMapInsert(map, 3, 2, 4);
+  XdmfMapInsert(map, 3, 6, 2);
+  XdmfMapInsert(map, 3, 1, 1);
+
+  int numRemoteTask = XdmfMapRetrieveNumberRemoteTaskIds(map);
+
+  printf("%d ?= %d\n", numRemoteTask, 3);
+
+  assert(numRemoteTask == 3);
+
+  int numLocalNode = XdmfMapRetrieveNumberLocalNodeIds(map, 1);
+
+  printf("%d ?= %d\n", numLocalNode, 3);
+
+  assert(numLocalNode == 3);
+
+  numLocalNode = XdmfMapRetrieveNumberLocalNodeIds(map, 2);
+
+  printf("%d ?= %d\n", numLocalNode, 2);
+
+  assert(numLocalNode == 2);
+
+  numLocalNode = XdmfMapRetrieveNumberLocalNodeIds(map, 3);
+
+  printf("%d ?= %d\n", numLocalNode, 4);
+
+  assert(numLocalNode == 4);
+
+  int numRemoteNode = XdmfMapRetrieveNumberRemoteNodeIds(map, 1, 0);
+
+  printf("%d ?= %d\n", numRemoteNode, 1);
+
+  assert(numRemoteNode == 1);
+
+  char * mapName = "Test Name";
+
+  XdmfMapSetName(map, mapName);
+
+  char * outfile = "mapfile.xmf";
+
+  XDMFWRITER * writer = XdmfWriterNew(outfile);
+
+  // Write to File
+
+  XdmfMapAccept(map, (XDMFVISITOR *)XdmfWriterGetHeavyDataWriter(writer, &status), &status);
+
+  XdmfMapAccept(map, (XDMFVISITOR *)writer, &status);
+
+  XdmfMapRelease(map);
+
+  if (XdmfMapIsInitialized(map))
+  {
+    printf("map is initialized before read\n");
+  }
+  else
+  {
+    printf("map is not initialized before read\n");
+  }
+
+  assert(!XdmfMapIsInitialized(map));
+
+  XdmfMapRead(map, &status);
+
+  if (XdmfMapIsInitialized(map))
+  {
+    printf("map is initialized after read\n");
+  }
+  else
+  {
+    printf("map is not initialized after read\n");
+  }
+
+  assert(XdmfMapIsInitialized(map));
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readMap = XdmfReaderRead(reader, outfile, &status);
+
+  if (XdmfMapIsInitialized(readMap))
+  {
+    printf("map is initialized before read\n");
+  }
+  else
+  {
+    printf("map is not initialized before read\n");
+  }
+
+  assert(!XdmfMapIsInitialized(readMap));
+
+  XdmfMapRead(readMap, &status);
+
+  if (XdmfMapIsInitialized(readMap))
+  {
+    printf("map is initialized after read\n");
+  }
+  else
+  {
+    printf("map is not initialized after read\n");
+  }
+
+  assert(XdmfMapIsInitialized(readMap));
+
+  char * readName = XdmfMapGetName(readMap);
+
+  printf("%s ?= %s\n", readName, "Test Name");
+
+  assert(strcmp(readName, "Test Name") ==  0);
+
+  int * globalNodeIds[3];
+
+  int globalNodes1[5];
+
+  globalNodeIds[0] = globalNodes1;
+
+  globalNodeIds[0][0] = 1;
+  globalNodeIds[0][1] = 2;
+  globalNodeIds[0][2] = 3;
+  globalNodeIds[0][3] = 4;
+  globalNodeIds[0][4] = 5;
+
+  int globalNodes2[6];
+
+  globalNodeIds[1] = globalNodes2;
+
+  globalNodeIds[1][0] = 3;
+  globalNodeIds[1][1] = 4;
+  globalNodeIds[1][2] = 5;
+  globalNodeIds[1][3] = 6;
+  globalNodeIds[1][4] = 7;
+  globalNodeIds[1][5] = 8;
+
+  int globalNodes3[7];
+
+  globalNodeIds[2] = globalNodes3;
+
+  globalNodeIds[2][0] = 9;
+  globalNodeIds[2][1] = 8;
+  globalNodeIds[2][2] = 7;
+  globalNodeIds[2][3] = 6;
+  globalNodeIds[2][4] = 5;
+  globalNodeIds[2][5] = 4;
+  globalNodeIds[2][6] = 3;
+
+  int numIdsOnNode[3] = {5, 6, 7};
+
+  int numIds = 3;
+
+  XDMFMAP ** mapArray = XdmfMapNewFromIdVector(globalNodeIds, numIdsOnNode, numIds);
+
+  int testMapID = 0;
+
+  void * testMap;
+  int testNumRemoteTaskIds;
+  int * remoteTaskIds;
+  int testNumLocalNodeIds;
+  int * localNodeIds;
+  int testNumRemoteNodeIds;
+  int * remoteNodeIds;
+
+  int expectedRemoteTasks[3][2];
+  expectedRemoteTasks[0][0] = 1;
+  expectedRemoteTasks[0][1] = 2;
+  expectedRemoteTasks[1][0] = 0;
+  expectedRemoteTasks[1][1] = 2;
+  expectedRemoteTasks[2][0] = 0;
+  expectedRemoteTasks[2][1] = 1;
+
+  int expectedLocalNodeIds[3][2][6];
+  expectedLocalNodeIds[0][0][0] = 2;
+  expectedLocalNodeIds[0][0][1] = 3;
+  expectedLocalNodeIds[0][0][2] = 4;
+  expectedLocalNodeIds[0][1][0] = 2;
+  expectedLocalNodeIds[0][1][1] = 3;
+  expectedLocalNodeIds[0][1][2] = 4;
+  expectedLocalNodeIds[1][0][0] = 0;
+  expectedLocalNodeIds[1][0][1] = 1;
+  expectedLocalNodeIds[1][0][2] = 2;
+  expectedLocalNodeIds[1][1][0] = 0;
+  expectedLocalNodeIds[1][1][1] = 1;
+  expectedLocalNodeIds[1][1][2] = 2;
+  expectedLocalNodeIds[1][1][3] = 3;
+  expectedLocalNodeIds[1][1][4] = 4;
+  expectedLocalNodeIds[1][1][5] = 5;
+  expectedLocalNodeIds[2][0][0] = 4;
+  expectedLocalNodeIds[2][0][1] = 5;
+  expectedLocalNodeIds[2][0][2] = 6;
+  expectedLocalNodeIds[2][1][0] = 1;
+  expectedLocalNodeIds[2][1][1] = 2;
+  expectedLocalNodeIds[2][1][2] = 3;
+  expectedLocalNodeIds[2][1][3] = 4;
+  expectedLocalNodeIds[2][1][4] = 5;
+  expectedLocalNodeIds[2][1][5] = 6;
+
+  int expectedRemoteNodeIds[3][2][6][1];
+  expectedRemoteNodeIds[0][0][0][0] = 0;
+  expectedRemoteNodeIds[0][0][1][0] = 1;
+  expectedRemoteNodeIds[0][0][2][0] = 2;
+  expectedRemoteNodeIds[0][1][0][0] = 6;
+  expectedRemoteNodeIds[0][1][1][0] = 5;
+  expectedRemoteNodeIds[0][1][2][0] = 4;
+  expectedRemoteNodeIds[1][0][0][0] = 2;
+  expectedRemoteNodeIds[1][0][1][0] = 3;
+  expectedRemoteNodeIds[1][0][2][0] = 4;
+  expectedRemoteNodeIds[1][1][0][0] = 6;
+  expectedRemoteNodeIds[1][1][1][0] = 5;
+  expectedRemoteNodeIds[1][1][2][0] = 4;
+  expectedRemoteNodeIds[1][1][3][0] = 3;
+  expectedRemoteNodeIds[1][1][4][0] = 2;
+  expectedRemoteNodeIds[1][1][5][0] = 1;
+  expectedRemoteNodeIds[2][0][0][0] = 4;
+  expectedRemoteNodeIds[2][0][1][0] = 3;
+  expectedRemoteNodeIds[2][0][2][0] = 2;
+  expectedRemoteNodeIds[2][1][0][0] = 5;
+  expectedRemoteNodeIds[2][1][1][0] = 4;
+  expectedRemoteNodeIds[2][1][2][0] = 3;
+  expectedRemoteNodeIds[2][1][3][0] = 2;
+  expectedRemoteNodeIds[2][1][4][0] = 1;
+  expectedRemoteNodeIds[2][1][5][0] = 0;
+
+  for (testMapID = 0; testMapID < 3; ++testMapID) {
+
+    testMap = mapArray[testMapID];
+
+    printf("Map # %d\n\n", testMapID);
+
+    testNumRemoteTaskIds = XdmfMapRetrieveNumberRemoteTaskIds(testMap);
+
+//    printf("number remote task Ids = %d\n", testNumRemoteTaskIds);
+
+    remoteTaskIds = XdmfMapRetrieveRemoteTaskIds(testMap);
+
+    for (i = 0; i < testNumRemoteTaskIds; ++i) {
+
+      printf("remote task id %d\n", remoteTaskIds[i]);
+      assert(expectedRemoteTasks[testMapID][i] == remoteTaskIds[i]);
+      testNumLocalNodeIds = XdmfMapRetrieveNumberLocalNodeIds(testMap, remoteTaskIds[i]);
+
+//      printf("number local node Ids = %d\n", testNumLocalNodeIds);
+
+      localNodeIds = XdmfMapRetrieveLocalNodeIds(testMap, remoteTaskIds[i]);
+
+      for (j = 0; j < testNumLocalNodeIds; ++j) {
+        printf("\tlocal node id %d\n", localNodeIds[j]);
+        assert(localNodeIds[j] == expectedLocalNodeIds[testMapID][i][j]);
+
+        testNumRemoteNodeIds = XdmfMapRetrieveNumberRemoteNodeIds(testMap, remoteTaskIds[i], localNodeIds[j]);
+
+//        printf("\tnumber remote node ids = %d\n", testNumRemoteNodeIds);
+
+        remoteNodeIds = XdmfMapRetrieveRemoteNodeIds(testMap, remoteTaskIds[i], localNodeIds[j]);
+
+        for (k = 0; k < testNumRemoteNodeIds; ++k) {
+          printf("\t\tremote node id %d\n", remoteNodeIds[k]);
+          assert(remoteNodeIds[k] == expectedRemoteNodeIds[testMapID][i][j][k]);
+        }
+        free(remoteNodeIds);
+      }
+      free(localNodeIds);
+    }
+    free(remoteTaskIds);
+  }
+
+/*
+XDMF_EXPORT void XdmfMapSetHeavyDataControllers(void * map,
+                                                void ** remoteTaskControllers,
+                                                int numRemoteTaskControllers,
+                                                void ** localNodeControllers,
+                                                int numberLocalNodeControllers,
+                                                void ** remoteLocalNodeControllers,
+                                                int numRemoteLocalNodeControllers,
+                                                int passControl);
+*/
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfRectilinearGrid.c b/tests/C/CTestXdmfRectilinearGrid.c
new file mode 100644
index 0000000..83d7384
--- /dev/null
+++ b/tests/C/CTestXdmfRectilinearGrid.c
@@ -0,0 +1,144 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRectilinearGrid.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  int i = 0;
+
+  int status = 0;
+
+  XDMFWRITER * writer = XdmfWriterNew("rectfile.xmf");
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * newXDim = XdmfArrayNew();
+
+  for (i = 5; i < 9; ++i) {
+    XdmfArrayPushBack(newXDim, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * newYDim = XdmfArrayNew();
+
+  for (i = 6; i < 10; ++i) {
+    XdmfArrayPushBack(newYDim, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  void * rectGrid = XdmfRectilinearGridNew2D(newXDim, newYDim, 0);
+
+  XdmfRectilinearGridAccept(rectGrid, (XDMFVISITOR *)writer, &status);
+
+  void * readGrid = XdmfReaderRead(reader, "rectfile.xmf", &status);
+
+  int numCoordinates = XdmfRectilinearGridGetNumberCoordinates(readGrid, &status);
+
+  printf("%d ?= %d\n", numCoordinates, 2);
+
+  assert(numCoordinates == 2);
+
+  XDMFARRAY ** readCoordinateArray = XdmfRectilinearGridGetCoordinates(readGrid, &status);
+
+  char * valueString = XdmfArrayGetValuesString(readCoordinateArray[0]);
+
+  printf("first dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 6 7 8") == 0);
+
+  free(valueString);
+
+  valueString = XdmfArrayGetValuesString(readCoordinateArray[1]);
+
+  printf("second dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "6 7 8 9") == 0);
+
+  free(valueString);
+
+  void * readDimensions = XdmfRectilinearGridGetDimensions(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contain %s\n", valueString);
+
+  assert(strcmp(valueString, "4 4") == 0);
+
+  free(valueString);
+
+  void * childGrid = XdmfRectilinearGridNew(readCoordinateArray, 2, 0);
+
+  void * checkCoordinate = XdmfRectilinearGridGetCoordinatesByIndex(childGrid, 1, &status);
+
+  valueString = XdmfArrayGetValuesString(checkCoordinate);
+
+  printf("second dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "6 7 8 9") == 0);
+
+  free(checkCoordinate);
+
+  free(valueString);
+
+  XDMFARRAY * newCoordinates[2];
+
+  newCoordinates[0] = XdmfArrayNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(newCoordinates[0], &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  newCoordinates[1] = XdmfArrayNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(newCoordinates[1], &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfRectilinearGridSetCoordinates(childGrid, newCoordinates, 2, 0, &status);
+
+  checkCoordinate = XdmfRectilinearGridGetCoordinatesByIndex(childGrid, 0, &status);
+
+  valueString = XdmfArrayGetValuesString(checkCoordinate);
+
+  printf("replaced dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(checkCoordinate);
+
+  free(valueString);
+
+  void * replacementCoordinate = XdmfArrayNew();
+
+  for (i = 10; i < 20; i++) {
+    XdmfArrayPushBack(replacementCoordinate, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfRectilinearGridSetCoordinatesByIndex(childGrid, 0, replacementCoordinate, 0, &status);
+
+  checkCoordinate = XdmfRectilinearGridGetCoordinatesByIndex(childGrid, 0, &status);
+
+  valueString = XdmfArrayGetValuesString(checkCoordinate);
+
+  printf("replaced dimension contains %s\n", valueString);
+
+  assert(strcmp(valueString, "10 11 12 13 14 15 16 17 18 19") == 0);
+
+  free(checkCoordinate);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfRegularGrid.c b/tests/C/CTestXdmfRegularGrid.c
new file mode 100644
index 0000000..33be969
--- /dev/null
+++ b/tests/C/CTestXdmfRegularGrid.c
@@ -0,0 +1,138 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRegularGrid.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  int i = 0;
+
+  int status = 0;
+
+  XDMFWRITER * writer = XdmfWriterNew("regfile.xmf");
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * regGrid = XdmfRegularGridNew2D(5, 5, 5, 5, 0, 0);
+
+  XdmfRegularGridAccept(regGrid, (XDMFVISITOR *)writer, &status);
+
+  void * readGrid = XdmfReaderRead(reader, "regfile.xmf", &status);
+
+  void * readBrick = XdmfRegularGridGetBrickSize(readGrid, &status);
+
+  char * valueString = XdmfArrayGetValuesString(readBrick);
+
+  printf("brick contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 5") == 0);
+
+  free(valueString);
+
+  free(readBrick);
+
+  void * readDimensions = XdmfRegularGridGetDimensions(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contains %s\n", valueString);
+
+  assert(strcmp(valueString, "5 5") == 0);
+
+  free(valueString);
+
+  free(readDimensions);
+
+  void * readOrigin = XdmfRegularGridGetOrigin(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readOrigin);
+
+  printf("origin contains %s\n", valueString);
+
+  assert(strcmp(valueString, "0 0") == 0);
+
+  free(valueString);
+
+  free(readOrigin);
+
+  int insertVal = 7;
+
+  void * newBrick = XdmfArrayNew();
+
+  XdmfArrayPushBack(newBrick, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+  XdmfArrayPushBack(newBrick, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+
+  XdmfRegularGridSetBrickSize(readGrid, newBrick, 0, &status);
+
+  insertVal = 6;
+
+  void * newDimensions = XdmfArrayNew();
+
+  XdmfArrayPushBack(newDimensions, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+  XdmfArrayPushBack(newDimensions, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+
+  XdmfRegularGridSetDimensions(readGrid, newDimensions, 0, &status);
+
+  insertVal = 1;
+
+  void * newOrigin = XdmfArrayNew();
+
+  XdmfArrayPushBack(newOrigin, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+  XdmfArrayPushBack(newOrigin, &insertVal, XDMF_ARRAY_TYPE_INT32, &status);
+
+  XdmfRegularGridSetOrigin(readGrid, newOrigin, 0, &status);
+
+  readBrick = XdmfRegularGridGetBrickSize(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readBrick);
+
+  printf("brick contains %s\n", valueString);
+
+  assert(strcmp(valueString, "7 7") == 0);
+
+  free(valueString);
+
+  readDimensions = XdmfRegularGridGetDimensions(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readDimensions);
+
+  printf("dimensions contains %s\n", valueString);
+
+  assert(strcmp(valueString, "6 6") == 0);
+
+  free(valueString);
+
+  readOrigin = XdmfRegularGridGetOrigin(readGrid, &status);
+
+  valueString = XdmfArrayGetValuesString(readOrigin);
+
+  printf("origin contains %s\n", valueString);
+
+  assert(strcmp(valueString, "1 1") == 0);
+
+  free(valueString);
+
+
+
+/*
+XDMF_EXPORT void * XdmfRegularGridNew(void * brickSize,
+                                      void * numPoints,
+                                      void * origin,
+                                      int passControl);
+*/
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfSet.c b/tests/C/CTestXdmfSet.c
new file mode 100644
index 0000000..f8db830
--- /dev/null
+++ b/tests/C/CTestXdmfSet.c
@@ -0,0 +1,73 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  XDMFSET * set = XdmfSetNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfSetPushBack(set, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfSetSetType(set, XDMF_SET_TYPE_NODE, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("setfile.xmf");
+
+  int testype = XdmfSetGetType(set);
+
+  printf("%d ?= %d\n", testype, XDMF_SET_TYPE_NODE);
+
+  assert(testype == XDMF_SET_TYPE_NODE);
+
+  // Write to File
+
+  XdmfSetAccept(set, (XDMFVISITOR *)writer, &status);
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readArray = XdmfReaderRead(reader, "setfile.xmf", &status);
+
+  char * valueString = XdmfSetGetItemTag(readArray);
+
+  printf("%s ?= %s\n", valueString, "Set");
+
+  assert(strcmp(valueString, "Set") == 0);
+
+  XdmfSetRead(readArray, &status);
+
+  int settype = XdmfSetGetType(readArray);
+
+  printf("Set type code = %d\n", settype);
+
+  assert(settype == XDMF_SET_TYPE_NODE);
+
+  valueString = XdmfSetGetValuesString(readArray);
+
+  printf("array contains: %s\n", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(readArray);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfTIFFReadWriteCompressed.c b/tests/C/CTestXdmfTIFFReadWriteCompressed.c
new file mode 100644
index 0000000..4b8479d
--- /dev/null
+++ b/tests/C/CTestXdmfTIFFReadWriteCompressed.c
@@ -0,0 +1,83 @@
+#include "tiff.h"
+#include "tiffio.h"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfTIFFController.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "stdio.h"
+#include "assert.h"
+
+int main()
+{
+  TIFF* tif = TIFFOpen("compressedstripoutput.tif", "w");
+
+  int status = 0;
+  unsigned int i = 0;
+  unsigned int j = 0;
+
+  if (tif) {
+    unsigned int w, h, sampleSize, pixelWidth;
+    // set a base size
+    pixelWidth = 1000;
+    w = 8 * pixelWidth;
+    h = 1000;
+    sampleSize = 1;
+    size_t npixels;
+    unsigned int * scanline;
+
+    npixels = w * h;
+
+    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);  // set the width of the image
+    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);    // set the height of the image
+    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sampleSize);   // set number of channels per pixel
+    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, XdmfArrayTypeGetElementSize(XDMF_ARRAY_TYPE_INT32, &status));   // Strangely this is in bytes when dealing with Compression
+    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);    // set the origin of the image.
+    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    TIFFSetField(tif, TIFFTAG_COMPRESSION, 5); // Only LZW encoding works in any fashion
+
+     TIFFSetField(tif,
+                  TIFFTAG_ROWSPERSTRIP,
+                  TIFFDefaultStripSize(tif, w*sampleSize));
+
+    unsigned int scanlineSize = TIFFScanlineSize(tif);
+
+    for (i = 0; i < h; ++i)
+    {
+      scanline = (unsigned int *) _TIFFmalloc(scanlineSize);
+      for (j = 0; j < pixelWidth; ++j)
+      {
+        scanline[j] = i * j;
+      }
+      TIFFWriteScanline(tif, scanline, i, 0);
+      _TIFFfree(scanline);
+    }
+  }
+
+  TIFFClose(tif);
+
+  unsigned int dims[1] = {1000 * 1000};
+
+  XDMFTIFFCONTROLLER * controller = XdmfTIFFControllerNew("compressedstripoutput.tif",
+                                                          XDMF_ARRAY_TYPE_INT32,
+                                                          dims,
+                                                          1,
+                                                          &status);
+
+  XDMFARRAY * checkarray = XdmfArrayNew();
+
+  XdmfArrayInsertHeavyDataController(checkarray, (XDMFHEAVYDATACONTROLLER *)controller, 1);
+
+  XdmfArrayRead(checkarray, &status);
+
+  for (i = 0; i < 1000; ++i)
+  {
+    for (j = 0; j < 1000; ++j)
+    {
+      assert(((int *)XdmfArrayGetValue(checkarray, i * 1000 + j, XDMF_ARRAY_TYPE_INT32, &status))[0] == i * j);
+    }
+  }
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfTopology.c b/tests/C/CTestXdmfTopology.c
new file mode 100644
index 0000000..3b3fcfe
--- /dev/null
+++ b/tests/C/CTestXdmfTopology.c
@@ -0,0 +1,101 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  XDMFTOPOLOGY * topology = XdmfTopologyNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 30; i++) {
+    XdmfTopologyPushBack(topology, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfTopologySetType(topology, XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10, &status);
+
+  XDMFWRITER * writer = XdmfWriterNew("topofile.xmf");
+
+  // Write to File
+
+  XdmfTopologyAccept(topology, (XDMFVISITOR *)writer, &status);
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readArray = XdmfReaderRead(reader, "topofile.xmf", &status);
+
+  char * valueString = XdmfTopologyGetItemTag(readArray);
+
+  printf("%s ?= %s\n", valueString, "Topology");
+
+  assert(strcmp(valueString, "Topology") == 0);
+
+  XdmfTopologyRead(readArray, &status);
+
+  int topotype = XdmfTopologyGetType(readArray);
+
+  printf("%d ?= %d\n", topotype, XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10);
+
+  assert(topotype == XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10);
+
+  unsigned int numElements = XdmfTopologyGetNumberElements(readArray, &status);
+
+  printf("array contains %d elements\n", numElements);
+
+  assert(numElements == 3);
+
+  int cellType = XdmfTopologyTypeGetCellType(topotype);
+
+  printf("cell type code = %d\n", cellType);
+
+  assert(cellType == 2);
+
+  unsigned int numEdges = XdmfTopologyTypeGetEdgesPerElement(topotype, &status);
+
+  unsigned int numFaces = XdmfTopologyTypeGetFacesPerElement(topotype, &status);
+
+  unsigned int numNodes = XdmfTopologyTypeGetNodesPerElement(topotype);
+
+  printf("type contains:\n%d edges\n%d faces\n%d nodes\n", numEdges, numFaces, numNodes);
+
+  assert(numEdges == 6);
+
+  assert(numFaces == 4);
+
+  assert(numNodes == 10);
+
+  valueString = XdmfTopologyTypeGetName(topotype);
+
+  printf("Topology type name: %s\n", valueString);
+
+  assert(strcmp("Tetrahedron_10", valueString) == 0);
+
+  free(valueString);
+
+  valueString = XdmfTopologyGetValuesString(readArray);
+
+  printf("array contains: %s\n", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29", valueString) == 0);
+
+  free(readArray);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfUnstructuredGrid.c b/tests/C/CTestXdmfUnstructuredGrid.c
new file mode 100644
index 0000000..99124fa
--- /dev/null
+++ b/tests/C/CTestXdmfUnstructuredGrid.c
@@ -0,0 +1,124 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  printf("test start\n");
+
+  int i = 0;
+
+  int status = 0;
+
+  XDMFWRITER * writer = XdmfWriterNew("unfile.xmf");
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  printf("generating regular grid\n");
+
+  void * regGrid = XdmfRegularGridNew2D(5, 5, 5, 5, 0, 0);
+
+  printf("generating unstructured grid\n");
+
+  void * unGrid = XdmfUnstructuredGridNewFromRegularGrid(regGrid, &status);
+
+  void * unTime = XdmfTimeNew(0.0);
+
+  double testTimeVal = XdmfTimeGetValue(unTime);
+
+  printf("%lf ?= %lf\n", testTimeVal, 0.0);
+
+  assert(testTimeVal == 0.0);
+
+  XdmfTimeSetValue(unTime, 5.0);
+
+  XdmfUnstructuredGridSetTime(unGrid, unTime, 0);
+
+  XdmfUnstructuredGridAccept(unGrid, (XDMFVISITOR *)writer, &status);
+
+  void * readGrid = XdmfReaderRead(reader, "unfile.xmf", &status);
+
+  void * readTime = XdmfUnstructuredGridGetTime(readGrid);
+
+  double readTimeVal = XdmfTimeGetValue(readTime);
+
+  printf("%lf ?= %lf\n", readTimeVal, 5.0);
+
+  assert(readTimeVal == 5.0);
+
+  XDMFTOPOLOGY * readTopology = XdmfUnstructuredGridGetTopology(readGrid);
+
+  char * valueString = XdmfTopologyGetValuesString(readTopology);
+
+  printf("unstructured topology contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 6 5 1 2 7 6 2 3 8 7 3 4 9 8 5 6 11 10 6 7 12 11 7 8 13 12 8 9 14 13 10 11 16 15 11 12 17 16 12 13 18 17 13 14 19 18 15 16 21 20 16 17 22 21 17 18 23 22 18 19 24 23") == 0);
+
+  free(valueString);
+
+  XDMFGEOMETRY * readGeometry = XdmfUnstructuredGridGetGeometry(readGrid);
+
+  valueString = XdmfGeometryGetValuesString(readGeometry);
+
+  printf("unstructured geometry contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 0 5 0 10 0 15 0 20 0 0 5 5 5 10 5 15 5 20 5 0 10 5 10 10 10 15 10 20 10 0 15 5 15 10 15 15 15 20 15 0 20 5 20 10 20 15 20 20 20") == 0);
+
+  free(valueString);
+
+  XDMFGEOMETRY * newGeometry = XdmfGeometryNew();
+
+  for (i = 0; i < 10; ++i) {
+    XdmfGeometryPushBack(newGeometry, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfUnstructuredGridSetGeometry(readGrid, newGeometry, 0);
+
+  void * newTopology = XdmfTopologyNew();
+
+  for (i = 10; i < 20; ++i) {
+    XdmfTopologyPushBack(newTopology, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XdmfUnstructuredGridSetTopology(readGrid, newTopology, 0);
+
+  readTopology = XdmfUnstructuredGridGetTopology(readGrid);
+
+  valueString = XdmfTopologyGetValuesString(readTopology);
+
+  printf("unstructured topology contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "10 11 12 13 14 15 16 17 18 19") == 0);
+
+  free(valueString);
+
+  readGeometry = XdmfUnstructuredGridGetGeometry(readGrid);
+
+  valueString = XdmfGeometryGetValuesString(readGeometry);
+
+  printf("unstructured geometry contains: %s\n", valueString);
+
+  assert(strcmp(valueString, "0 1 2 3 4 5 6 7 8 9") == 0);
+
+  free(valueString);
+
+
+  return 0;
+}
diff --git a/tests/C/CTestXdmfWriter.c b/tests/C/CTestXdmfWriter.c
new file mode 100644
index 0000000..6a32dbf
--- /dev/null
+++ b/tests/C/CTestXdmfWriter.c
@@ -0,0 +1,302 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfFunction.hpp"
+
+#include "stdio.h"
+#include "stdlib.h"
+
+#include "string.h"
+#include "assert.h"
+
+int main()
+{
+
+  void * array = XdmfArrayNew();
+
+  int i = 0;
+
+  int status = 0;
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(array, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  XDMFWRITER * writer = XdmfWriterNew("testfile.xmf");
+
+  char * testFileName = XdmfWriterGetFilePath(writer, &status);
+  int testLimit = XdmfWriterGetLightDataLimit(writer, &status);
+
+  printf("light data limit = %d\n", testLimit);
+
+  assert(testLimit == 100);
+
+  XdmfWriterSetLightDataLimit(writer, 100, &status);
+
+  int writerMode = XdmfWriterGetMode(writer, &status);
+
+  printf("%d ?= %d\n", writerMode, XDMF_WRITER_MODE_DEFAULT);
+
+  assert(writerMode == XDMF_WRITER_MODE_DEFAULT);
+
+  XdmfWriterSetMode(writer, XDMF_WRITER_MODE_DEFAULT, &status);
+
+  int writerXPaths = XdmfWriterGetWriteXPaths(writer, &status);
+
+  if (writerXPaths)
+  {
+    printf("will write XPaths\n");
+  }
+  else
+  {
+    printf("will not write XPaths\n");
+  }
+
+  assert(writerXPaths);
+
+  XdmfWriterSetWriteXPaths(writer, 1, &status);
+
+  int writerXPathParse = XdmfWriterGetXPathParse(writer, &status);
+
+  if (writerXPathParse)
+  {
+    printf("will parse XPaths\n");
+  }
+  else
+  {
+    printf("will not parse XPaths\n");
+  }
+
+  assert(writerXPathParse);
+
+  XdmfWriterSetXPathParse(writer, 1, &status);
+
+  void * heavyWriter = XdmfHDF5WriterNew("secondtestfile.h5", 0);
+
+  unsigned int chunkSize = XdmfHDF5WriterGetChunkSize(heavyWriter, &status);
+
+  XdmfHDF5WriterSetChunkSize(heavyWriter, chunkSize, &status);
+
+  int testmode = XdmfHeavyDataWriterGetMode(heavyWriter);
+
+  printf("%d ?= %d\n", testmode, XDMF_HEAVY_WRITER_MODE_DEFAULT);
+
+  assert(testmode == XDMF_HEAVY_WRITER_MODE_DEFAULT);
+
+  XdmfHeavyDataWriterSetMode(heavyWriter, XDMF_HEAVY_WRITER_MODE_DEFAULT, &status);
+
+  int currentsplitting = XdmfHeavyDataWriterGetAllowSetSplitting(heavyWriter);
+
+  if (writerXPathParse)
+  {
+    printf("will allow dataset splitting\n");
+  }
+  else
+  {
+    printf("will not allow dataset splitting\n");
+  }
+
+  assert(!currentsplitting);
+
+  XdmfHeavyDataWriterSetAllowSetSplitting(heavyWriter, currentsplitting);
+
+  int currentindex = XdmfHeavyDataWriterGetFileIndex(heavyWriter);
+
+  XdmfHeavyDataWriterSetFileIndex(heavyWriter, currentindex);
+
+  unsigned int hdf5overhead = XdmfHeavyDataWriterGetFileOverhead(heavyWriter);
+
+  printf("%d ?= %d\n", hdf5overhead, 800);
+
+  assert(hdf5overhead == 800);
+
+  char * testHeavyName =  XdmfHeavyDataWriterGetFilePath(heavyWriter);
+
+  int currentLimit = XdmfHeavyDataWriterGetFileSizeLimit(heavyWriter);
+
+  XdmfHeavyDataWriterSetFileSizeLimit(heavyWriter, currentLimit);
+
+  int currentReleaseStatus = XdmfHeavyDataWriterGetReleaseData(heavyWriter);
+
+  XdmfHeavyDataWriterSetReleaseData(heavyWriter, currentReleaseStatus);
+
+  XdmfHDF5WriterOpenFile(heavyWriter, &status);
+
+  // Write HDF5 to file
+
+  XdmfArrayAccept(array, (XDMFVISITOR *)heavyWriter, &status);
+
+  XdmfHDF5WriterCloseFile(heavyWriter, &status);
+
+  XDMFWRITER * writerWithHeavy = XdmfWriterNewSpecifyHeavyDataWriter("secondtestfile.xmf", heavyWriter);
+
+  void * heldWriter = XdmfWriterGetHeavyDataWriter(writer, &status);
+
+  XdmfWriterSetHeavyDataWriter(writer, heldWriter, 0, &status);
+
+  // Write to File
+
+  XdmfArrayAccept(array, (XDMFVISITOR *)writerWithHeavy, &status);
+
+  // Read from File
+
+  void * reader = XdmfReaderNew();
+
+  void * readArray = XdmfReaderRead(reader, "secondtestfile.xmf", &status);
+
+  XdmfArrayRead(readArray, &status);
+
+  char * valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("array contains: %s\n", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  XdmfArrayFree(readArray);
+
+/*
+XDMFCORE_EXPORT void * XdmfWriterGetHeavyDataWriter(void * writer);
+
+XDMFCORE_EXPORT void XdmfWriterSetHeavyDataWriter(void * writer, void * heavyDataWriter, int transferOwnership);
+*/
+
+  unsigned int starts[1] = {0};
+  unsigned int strides[1] = {2};
+  unsigned int dimensions[1] = {5};
+
+  unsigned int numDims = 1;
+
+  void * subset = XdmfSubsetNew(array, starts, strides, dimensions, numDims, 0, &status);
+
+  readArray = XdmfSubsetRead(subset, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 2 4 6 8", valueString);
+
+  assert(strcmp("0 2 4 6 8", valueString) == 0);
+
+  free(valueString);
+
+  free(writer);
+
+  XdmfSubsetSetConstructedType(subset, "DataItem");
+
+  XdmfSubsetSetConstructedProperties(subset, readArray);
+
+  free(readArray);
+
+  writer = XdmfWriterNew("subsetfile.xmf");
+
+  XdmfSubsetAccept(subset, (XDMFVISITOR *)writer, &status);
+
+  readArray = XdmfReaderRead(reader, "subsetfile.xmf", &status);
+
+  void * readSubset = XdmfArrayGetReference(readArray);
+
+  void * internalArray = XdmfSubsetGetReferenceArray(readSubset);
+
+  XdmfArrayRead(internalArray, &status);
+
+  valueString = XdmfArrayGetValuesString(internalArray);
+
+  free(valueString);
+
+  XdmfArrayRead(readArray, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 2 4 6 8", valueString);
+
+  assert(strcmp("0 2 4 6 8", valueString) == 0);
+
+  free(valueString);
+
+  free(readArray);
+
+  void * firstarray = XdmfArrayNew();
+
+  for (i = 0; i < 10; i++) {
+    XdmfArrayPushBack(firstarray, &i, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  valueString = XdmfArrayGetValuesString(firstarray);
+
+  printf("%s ?= %s\n", "0 1 2 3 4 5 6 7 8 9", valueString);
+
+  assert(strcmp("0 1 2 3 4 5 6 7 8 9", valueString) == 0);
+
+  free(valueString);
+
+  void * secondarray = XdmfArrayNew();
+
+  int val;
+
+  for (i = 1; i < 11; i++) {
+    val = i * 10;
+    XdmfArrayPushBack(secondarray, &val, XDMF_ARRAY_TYPE_INT32, &status);
+  }
+
+  valueString = XdmfArrayGetValuesString(secondarray);
+
+  printf("%s ?= %s\n", "10 20 30 40 50 60 70 80 90 100", valueString);
+
+  assert(strcmp("10 20 30 40 50 60 70 80 90 100", valueString) == 0);
+
+  free(valueString);
+
+  void * function = XdmfFunctionNew();
+
+  free(function);
+
+  char * keys[2];
+
+  keys[0] = "A";
+  keys[1] = "B";
+
+  char * expression = "A#B";
+
+  XDMFARRAY * values[2];
+
+  values[0] = firstarray;
+  values[1] = secondarray;
+
+  function = XdmfFunctionNewInit(expression, keys, values, 2);
+
+  readArray = XdmfFunctionRead(function, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString);
+
+  assert(strcmp("0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString) == 0);
+
+  free(valueString);
+
+  free(writer);
+
+  XdmfFunctionSetConstructedType(function, "DataItem");
+
+  XdmfFunctionSetConstructedProperties(function, readArray);
+
+  writer = XdmfWriterNew("functionfile.xmf");
+
+  XdmfFunctionAccept(function, (XDMFVISITOR *)writer, &status);
+
+  readArray = XdmfReaderRead(reader, "functionfile.xmf", &status);
+
+  XdmfArrayRead(readArray, &status);
+
+  valueString = XdmfArrayGetValuesString(readArray);
+
+  printf("%s ?= %s\n", "0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString);
+
+  assert(strcmp("0 10 1 20 2 30 3 40 4 50 5 60 6 70 7 80 8 90 9 100", valueString) == 0);
+
+  free(valueString);
+
+  return 0;
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
new file mode 100644
index 0000000..7378d01
--- /dev/null
+++ b/tests/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_subdirectory(C)
+add_subdirectory(Cxx)
+
+if(XDMF_WRAP_PYTHON)
+  add_subdirectory(Python)
+endif(XDMF_WRAP_PYTHON)
+if(XDMF_WRAP_JAVA)
+  add_subdirectory(Java)
+endif(XDMF_WRAP_JAVA)
diff --git a/tests/Cxx/CMakeLists.txt b/tests/Cxx/CMakeLists.txt
new file mode 100644
index 0000000..568e142
--- /dev/null
+++ b/tests/Cxx/CMakeLists.txt
@@ -0,0 +1,163 @@
+# Include our test macros
+include(AddTestsCxx)
+
+# Add any dependencies that the cxx tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_CXX_DEPENDENCIES("Xdmf")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have extra arguments (id: ADD_TEST_CXX(testname inputfile))
+#	Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  IF (MPIEXEC_MAX_NUMPROCS GREATER 5)
+    ADD_MPI_TEST_CXX(DSMFileTest.sh XdmfFileAcceptTest,XdmfFileConnectTest)
+  ENDIF(MPIEXEC_MAX_NUMPROCS GREATER 5)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+ADD_TEST_CXX(TestXdmfAggregate)
+ADD_TEST_CXX(TestXdmfAttribute)
+ADD_TEST_CXX(TestXdmfBinaryController)
+ADD_TEST_CXX(TestXdmfCurvilinearGrid)
+ADD_TEST_CXX(TestXdmfFunction)
+ADD_TEST_CXX(TestXdmfGeometry)
+ADD_TEST_CXX(TestXdmfGraph)
+ADD_TEST_CXX(TestXdmfGridCollection)
+ADD_TEST_CXX(TestXdmfGridController)
+ADD_TEST_CXX(TestXdmfGridTemplate)
+ADD_TEST_CXX(TestXdmfHDF5Hyperslab)
+ADD_TEST_CXX(TestXdmfHDF5Visit)
+ADD_TEST_CXX(TestXdmfMap)
+ADD_TEST_CXX(TestXdmfMultiOpen)
+ADD_TEST_CXX(TestXdmfMultiXPath)
+ADD_TEST_CXX(TestXdmfReader)
+ADD_TEST_CXX(TestXdmfRegularGrid)
+ADD_TEST_CXX(TestXdmfRectilinearGrid)
+ADD_TEST_CXX(XdmfPostFixCalc)
+ADD_TEST_CXX(TestXdmfSet)
+ADD_TEST_CXX(TestXdmfSubset)
+ADD_TEST_CXX(TestXdmfTemplate)
+ADD_TEST_CXX(TestXdmfTime)
+if (TIFF_FOUND)
+  ADD_TEST_CXX(TestXdmfTIFFReadWriteCompressed)
+endif (TIFF_FOUND)
+ADD_TEST_CXX(TestXdmfTopology)
+ADD_TEST_CXX(TestXdmfTopologyMixed)
+ADD_TEST_CXX(TestXdmfUnstructuredGrid)
+ADD_TEST_CXX(TestXdmfVisitorValueCounter)
+ADD_TEST_CXX(TestXdmfWriter)
+ADD_TEST_CXX(TestXdmfWriterHDF5ThenXML)
+ADD_TEST_CXX(TestXdmfXPath)
+ADD_TEST_CXX(TestXdmfXPointerReference)
+#removed due to long execution time
+#ADD_TEST_CXX(HugeWriteArray)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_CXX(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  IF (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    CLEAN_TEST_CXX(DSMFileTest.sh dsmfile.xmf dsmconnect.cfg)
+  ENDIF (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+CLEAN_TEST_CXX(TestXdmfAggregate
+  aggregate.xmf
+  aggregate.h5)
+CLEAN_TEST_CXX(TestXdmfAttribute)
+CLEAN_TEST_CXX(TestXdmfBinaryController
+  TestXdmfBinary.xmf
+  testBinary.bin)
+CLEAN_TEST_CXX(TestXdmfCurvilinearGrid
+  TestXdmfCurvilinearGrid1.xmf
+  TestXdmfCurvilinearGrid2.xmf)
+CLEAN_TEST_CXX(TestXdmfFunction
+  function.xmf
+  function.h5)
+CLEAN_TEST_CXX(TestXdmfGeometry)
+CLEAN_TEST_CXX(TestXdmfGraph
+  TestXdmfGraph.xmf)
+CLEAN_TEST_CXX(TestXdmfGridCollection
+  TestXdmfGridCollection1.xmf
+  TestXdmfGridCollection2.xmf
+  TestXdmfGridCollectionHDF1.h5
+  TestXdmfGridCollectionHDF1.xmf
+  TestXdmfGridCollectionHDF2.xmf)
+CLEAN_TEST_CXX(TestXdmfGridTemplate
+  gridtemplate.xmf
+  gridtemplate.h5
+  gridtemplate2.xmf
+  gridtemplate2.h5)
+CLEAN_TEST_CXX(TestXdmfHDF5Hyperslab
+  TestXdmfHDF5Hyperslab.xmf
+  TestXdmfHDF5Hyperslab.h5
+  TestXdmfHDF5Hyperslab2.xmf)
+CLEAN_TEST_CXX(TestXdmfHDF5Visit
+  TestXdmfHDF5Visit.xmf
+  TestXdmfHDF5Visit.h5)
+CLEAN_TEST_CXX(TestXdmfMap
+  TestXdmfMap1.xmf
+  TestXdmfMap2.xmf
+  TestXdmfMapHDF1.xmf
+  TestXdmfMapHDF1.h5
+  TestXdmfMapHDF2.xmf)
+CLEAN_TEST_CXX(TestXdmfMultiOpen
+  setfile.h5
+  attributefile.h5)
+CLEAN_TEST_CXX(TestXdmfMultiXPath
+  nestedOuter.xmf
+  nestedInner.xmf)
+CLEAN_TEST_CXX(TestXdmfReader
+  TestXdmfReader1.h5
+  TestXdmfReader1.xmf
+  TestXdmfReader2.xmf)
+CLEAN_TEST_CXX(TestXdmfRectilinearGrid
+  TestXdmfRectilinearGrid1.xmf
+  TestXdmfRectilinearGrid2.xmf)
+CLEAN_TEST_CXX(TestXdmfRegularGrid
+  TestXdmfRegularGrid1.xmf
+  TestXdmfRegularGrid2.xmf)
+CLEAN_TEST_CXX(XdmfPostFixCalc)
+CLEAN_TEST_CXX(TestXdmfSet)
+CLEAN_TEST_CXX(TestXdmfSubset
+  subset.xmf
+  subset.h5)
+CLEAN_TEST_CXX(TestXdmfTemplate
+  template.xmf
+  template.h5
+  template2.xmf
+  template2.h5)
+CLEAN_TEST_CXX(TestXdmfTime)
+if (TIFF_FOUND)
+  CLEAN_TEST_CXX(TestXdmfTIFFReadWriteCompressed
+    compressedtiffoutput.xmf
+    compressedoutput.tif
+    compressedstripoutput.tif
+    compresseddirectories.tif)
+endif (TIFF_FOUND)
+CLEAN_TEST_CXX(TestXdmfTopology)
+CLEAN_TEST_CXX(TestXdmfTopologyMixed
+  TestXdmfTopologyMixed1.xmf
+  TestXdmfTopologyMixed2.xmf)
+CLEAN_TEST_CXX(TestXdmfUnstructuredGrid)
+CLEAN_TEST_CXX(TestXdmfVisitorValueCounter)
+CLEAN_TEST_CXX(TestXdmfWriter
+  output.h5
+  output.xmf)
+CLEAN_TEST_CXX(TestXdmfWriterHDF5ThenXML)
+CLEAN_TEST_CXX(TestXdmfXPath
+  XdmfXPath1.xmf
+  XdmfXPath2.xmf)
+CLEAN_TEST_CXX(TestXdmfXPointerReference
+  duplicateXpointer.xmf
+  duplicateXpointer.h5
+  duplicateXpointer2.xmf
+  duplicateXpointer2.h5)
+#removed due to long execution time
+#CLEAN_TEST_CXX(HugeWriteArray
+#  arraydata1.h5
+#  arraydata2.h5
+#  arraydata3.h5
+#  arraydata.h5
+#  arraydata.xmf)
diff --git a/tests/Cxx/DSMFileTest.sh b/tests/Cxx/DSMFileTest.sh
new file mode 100755
index 0000000..7700670
--- /dev/null
+++ b/tests/Cxx/DSMFileTest.sh
@@ -0,0 +1,6 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+#$MPIEXEC -n 4 ./XdmfFileAcceptTest
+$MPIEXEC -n 2 ./XdmfFileAcceptTest &
+sleep 10
+$MPIEXEC -n 2 ./XdmfFileConnectTest
diff --git a/tests/Cxx/ExampleXdmfEdit.cpp b/tests/Cxx/ExampleXdmfEdit.cpp
new file mode 100644
index 0000000..d98ffd8
--- /dev/null
+++ b/tests/Cxx/ExampleXdmfEdit.cpp
@@ -0,0 +1,826 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "string.h"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+        shared_ptr<XdmfReader> exampleReader = XdmfReader::New();
+
+        /*
+        This is assuming that the read item is an XdmfDomain object
+        */
+        shared_ptr<XdmfDomain> primaryDomain = shared_dynamic_cast<XdmfDomain>(exampleReader->read("testoutput.xmf"));
+        shared_ptr<XdmfInformation> outputInformation = primaryDomain->getInformation(0);
+        std::cout << "Key:" << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+        std::cout << "The Domain's tag is: " << primaryDomain->getItemTag().c_str() << std::endl;
+
+        shared_ptr<XdmfGridCollection> gridHolder = primaryDomain->getGridCollection(0);
+
+        std::cout << "The Grid Collection's tag is: " << gridHolder->getItemTag().c_str() << std::endl;
+        std::cout << "The Grid Collection's name is: " << gridHolder->getName().c_str()  << std::endl;
+        outputInformation = gridHolder->getInformation(0);
+        std::cout << "Key:" << outputInformation->getKey().c_str() <<"\nValue:" << outputInformation->getValue().c_str() << std::endl;
+
+	std::map<std::string, std::string>::iterator outputwalker = gridHolder->getItemProperties().begin();
+	for (;outputwalker!=gridHolder->getItemProperties().end(); ++outputwalker)
+	{
+		std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+	}
+ 
+        if (gridHolder->getType() == XdmfGridCollectionType::Spatial())
+	{
+                std::cout << "This is a spatial grid collection" << std::endl;
+	}
+        else
+	{
+                std::cout << "This is not a spatial grid collection" << std::endl;
+	}
+
+
+	//loop controlling integers
+	int i = 0;
+	int j = 0;
+	int k = 0;
+	int m = 0;
+	int task;
+	int node;
+	int remote;
+	std::string blankstring = "";
+	char* outstring = strdup(blankstring.c_str());
+	shared_ptr<XdmfMap> readMap;
+	std::map<int, std::map<int, std::set<int> > > taskIDMap;
+	std::map<int, std::map<int, std::set<int> > >::iterator taskWalker;
+	std::map<int, std::set<int> > nodeIDMap;
+	std::map<int, std::set<int> >::iterator nodeWalker;
+	std::set<int> remoteIDset;
+	std::set<int>::iterator remoteWalker;
+
+	for (i=0; i<gridHolder->getNumberMaps(); ++i)
+	{
+		readMap = gridHolder->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+		std::cout << "Map # " << i << std::endl;
+		taskIDMap = readMap->getMap();
+		for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+		{
+			task = (*taskWalker).first;
+			nodeIDMap = (*taskWalker).second;
+			for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+			{
+				node = (*nodeWalker).first;
+				remoteIDset = (*nodeWalker).second;
+				for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+				{
+					remote = (*remoteWalker);
+					std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+				}
+			}
+		}
+	}
+
+        std::cout << "Unstructured Grid" << std::endl;
+        shared_ptr<XdmfUnstructuredGrid> ungrid = gridHolder->getUnstructuredGrid(0);
+        std::cout << "The Unstructured Grid's tag is: " << ungrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Unstructured Grid's name is: " << ungrid->getName().c_str() << std::endl;
+
+	outputwalker = ungrid->getItemProperties().begin();
+        for (;outputwalker!=ungrid->getItemProperties().end(); ++outputwalker)
+        {
+                std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+        }
+
+        std::cout << "The Unstructured Grid's time is: " << ungrid->getTime()->getValue() << std::endl;
+        i=0;
+        for (i=0; i<ungrid->getNumberMaps(); ++i)
+        {
+                readMap = ungrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+                                        std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+
+	shared_ptr<XdmfSet> readSet;
+	shared_ptr<XdmfAttribute> readAttribute;
+	for (i=0; i < ungrid->getNumberSets(); ++i)
+	{
+		readSet = ungrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+		std::cout << "Set # " << i << std::endl;
+		std::cout << readSet->getName().c_str() << std::endl;
+		if (readSet->getType() == XdmfSetType::Node())
+		{
+			std::cout << "This set is a node" << std::endl;
+		}
+		else
+		{
+			std::cout << "This set is not a node" << std::endl;
+		}
+		outputInformation = readSet->getInformation(0);
+		std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: %s\n" << outputInformation->getValue().c_str() << std::endl;
+		std::cout << readSet->getValuesString().c_str() << std::endl;
+		for (j=0; j < readSet->getNumberAttributes(); ++j)
+		{
+			readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+			std::cout << "Set Attribute # " << j << std::endl;
+			std::cout << readAttribute->getName().c_str() << std::endl;
+			if (readAttribute->getType() == XdmfAttributeType::Scalar())
+			{
+				std::cout << "This attribute is a scalar" << std::endl;
+			}
+			else
+			{
+				std::cout << "This attribute is not a scalar\n" << std::endl;
+			}
+			if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+			{
+				std::cout << "This attribute is a node\n" << std::endl;
+			}
+			else
+			{
+				std::cout << "This attribute is not a node\n" << std::endl;
+			}
+			std::cout << readAttribute->getValuesString().c_str() << std::endl;
+		}
+	}
+	for (i = 0; i < ungrid->getNumberAttributes(); ++i)
+	{
+		readAttribute = ungrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+		std::cout << "Attribute # " << i << std::endl;
+		std::cout << readAttribute->getName().c_str() << std::endl;
+		if (readAttribute->getType() == XdmfAttributeType::Scalar())
+		{
+			std::cout << "This attribute is a scalar" << std::endl;
+		}
+		else
+		{
+			std::cout << "This attribute is not a scalar" << std::endl;
+		}
+		if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+		{
+			std::cout << "This attribute is a node" << std::endl;
+		}
+		else
+		{
+			std::cout << "This attribute is not a node" << std::endl;
+		}
+		std::cout << readAttribute->getValuesString().c_str() << std::endl;
+	}
+
+	std::cout << "Unstructured Topology" << std::endl;
+	shared_ptr<XdmfTopology> untopology = ungrid->getTopology();
+	if (!untopology->isInitialized())
+	{
+		untopology->read();
+	}
+	std::cout << "The topology's tag: " << untopology->getItemTag().c_str()  << std::endl;
+	if (untopology->getType() == XdmfTopologyType::Hexahedron())
+	{
+		std::cout << "This topology is a hexahedron" << std::endl;
+        }
+	else
+	{
+		std::cout << "This topology is not a hexahedron" << std::endl;
+	}
+	std::cout << "Contains " << untopology->getNumberElements() << " elements" << std::endl;
+	std::cout << "Contains the values: " << untopology->getValuesString().c_str() << std::endl;
+
+	std::cout << "Unstructured Geometry" << std::endl;
+	shared_ptr<XdmfGeometry> ungeometry = ungrid->getGeometry();
+	if (!ungeometry->isInitialized())
+	{
+		ungeometry->read();
+	}
+	std::cout << "The geometry's tag: " << ungeometry->getItemTag().c_str() << std::endl;
+	if (ungeometry->getType() == XdmfGeometryType::XYZ())
+	{
+		std::cout << "This geometry is XYZ" << std::endl;
+	}
+	else
+	{
+		std::cout << "This geometry is not XYZ" << std::endl;
+	}
+	outputInformation = ungeometry->getInformation(0);
+	std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+	std::cout << "Contains " << ungeometry->getNumberPoints() << " points" << std::endl;
+	std::cout << "Contains the values: " << ungeometry->getValuesString().c_str() << std::endl;
+
+
+
+
+
+        std::cout << "Curvilinear Grid" << std::endl;
+        shared_ptr<XdmfCurvilinearGrid> curvgrid = gridHolder->getCurvilinearGrid(0);
+        std::cout << "The Curvilinear Grid's tag is: " << curvgrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Curvilinear Grid's name is: " << curvgrid->getName().c_str() << std::endl;
+        outputwalker = curvgrid->getItemProperties().begin();
+        for (;outputwalker!=curvgrid->getItemProperties().end(); ++outputwalker)
+        {
+                std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+        }
+        outputInformation = curvgrid->getInformation(0);
+        std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+        std::cout << "The Curvilinear Grid's time is: " << curvgrid->getTime()->getValue() << std::endl;
+        for (i=0; i<curvgrid->getNumberMaps(); ++i)
+        {
+                readMap = curvgrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+					std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+        for (i=0; i < curvgrid->getNumberSets(); ++i)
+        {
+                readSet = curvgrid->getSet(i);
+		if (!readSet->isInitialized());
+		{
+			readSet->read();
+		}
+                std::cout << "Set # " << i << std::endl;
+                std::cout << readSet->getName().c_str() << std::endl;
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        std::cout << "This set is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This set is not a node" << std::endl;
+                }
+                outputInformation = readSet->getInformation(0);
+                std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: %s\n" << outputInformation->getValue().c_str() << std::endl;
+                std::cout << readSet->getValuesString().c_str() << std::endl;
+                for (j=0; j < readSet->getNumberAttributes(); ++j)
+                {
+                        readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+                        std::cout << "Set Attribute # " << j << std::endl;
+                        std::cout << readAttribute->getName().c_str() << std::endl;
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                std::cout << "This attribute is a scalar" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a scalar" << std::endl;
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                std::cout << "This attribute is a node" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a node" << std::endl;
+                        }
+                        std::cout << readAttribute->getValuesString().c_str() << std::endl;
+                }
+        }
+        for (i = 0; i < curvgrid->getNumberAttributes(); ++i)
+        {
+                readAttribute = curvgrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+                std::cout << "Attribute # " << i << std::endl;
+                std::cout << readAttribute->getName().c_str() << std::endl;
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        std::cout << "This attribute is a scalar" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a scalar" << std::endl;
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        std::cout << "This attribute is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a node" << std::endl;
+                }
+                std::cout << readAttribute->getValuesString().c_str() << std::endl;
+        }
+
+        std::cout << "Curvilinear Dimensions" << std::endl;
+        shared_ptr<XdmfArray> curvdimensions = curvgrid->getDimensions();
+	if (!curvdimensions->isInitialized())
+	{
+		curvdimensions->read();
+	}
+        std::cout << "The dimensions' tag: " << curvdimensions->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << curvdimensions->getValuesString().c_str() << std::endl;
+
+        std::cout << "Curvilinear Geometry" << std::endl;
+        shared_ptr<XdmfGeometry> curvgeometry = curvgrid->getGeometry();
+	if (!curvgeometry->isInitialized())
+	{
+		curvgeometry->read();
+	}
+        std::cout << "The geometry's tag: " << curvgeometry->getItemTag().c_str() << std::endl;
+        if (curvgeometry->getType() == XdmfGeometryType::XYZ())
+	{
+                std::cout << "This geometry is XYZ" << std::endl;
+        }
+	else
+	{
+                std::cout << "This geometry is not XYZ" << std::endl;
+	}
+        outputInformation = curvgeometry->getInformation(0);
+        std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+        std::cout << "Contains " << curvgeometry->getNumberPoints() << " points" << std::endl;
+        std::cout << "Contains the values: " << curvgeometry->getValuesString().c_str() << std::endl;
+
+
+        std::cout << "Rectilinear Grid" << std::endl;
+        shared_ptr<XdmfRectilinearGrid> rectgrid = gridHolder->getRectilinearGrid(0);
+        std::cout << "The Rectilinear Grid's tag is: " << rectgrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Rectilinear Grid's name is: " << rectgrid->getName().c_str() << std::endl;
+        std::cout << "The Rectilinear Grid's time is: " << rectgrid->getTime()->getValue() << std::endl;
+
+	outputwalker = rectgrid->getItemProperties().begin();
+	for (; outputwalker!=rectgrid->getItemProperties().end(); ++outputwalker)
+	{
+		std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+	}
+
+        for (i=0; i<rectgrid->getNumberMaps(); ++i)
+        {
+                readMap = rectgrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+					std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+	for (i=0; i < rectgrid->getNumberSets(); ++i)
+        {
+                readSet = rectgrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+		std::cout << "Set # " << i << std::endl;
+                std::cout << readSet->getName().c_str() << std::endl;
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        std::cout << "This set is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This set is not a node" << std::endl;
+                }
+                outputInformation = readSet->getInformation(0);
+                std::cout << "Key: " << outputInformation->getKey().c_str() <<"\nValue: " << outputInformation->getValue().c_str() << std::endl;
+                std::cout << readSet->getValuesString().c_str() << std::endl;
+                for (j=0; j < readSet->getNumberAttributes(); ++j)
+                {
+                        readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+                        std::cout << "Set Attribute # " << j << std::endl;
+                        std::cout << readAttribute->getName().c_str() << std::endl;
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                std::cout << "This attribute is a scalar" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a scalar" << std::endl;
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                std::cout << "This attribute is a node" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a node" << std::endl;
+                        }
+                        std::cout << readAttribute->getValuesString().c_str() << std::endl;
+                }
+        }
+        for (i = 0; i < rectgrid->getNumberAttributes(); ++i)
+        {
+                readAttribute = rectgrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+                std::cout << "Attribute # " << i << std::endl;
+                std::cout << readAttribute->getName().c_str() << std::endl;
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        std::cout << "This attribute is a scalar" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a scalar" << std::endl;
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        std::cout << "This attribute is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a node" << std::endl;
+                }
+                std::cout << readAttribute->getValuesString().c_str() << std::endl;
+        }
+        std::cout << "Rectilinear Dimensions" << std::endl;
+        shared_ptr<XdmfArray> rectdimensions = rectgrid->getDimensions();
+	if (!rectdimensions->isInitialized())
+	{
+		rectdimensions->read();
+	}
+        std::cout << "The dimensions' tag: " << rectdimensions->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << rectdimensions->getValuesString().c_str() << std::endl;
+
+        std::cout << "Rectilinear Coordinates" << std::endl;
+        std::vector<shared_ptr<XdmfArray> > rectcoordinates = rectgrid->getCoordinates();
+        std::cout << "Contains the values: " << std::endl;
+	for (i=0;i<rectcoordinates.size(); ++i)
+	{
+		if (!rectcoordinates[i]->isInitialized())
+		{
+			rectcoordinates[i]->read();
+		}
+		std::cout << rectcoordinates[i]->getValuesString().c_str() << std::endl;
+	}
+
+
+
+        std::cout << "Regular Grid" << std::endl;
+        shared_ptr<XdmfRegularGrid> reggrid = gridHolder->getRegularGrid(0);
+        std::cout << "The Regular Grid's tag is: " << reggrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Regular Grid's name is: " << reggrid->getName().c_str() << std::endl;
+        outputwalker = reggrid->getItemProperties().begin();
+        for (;outputwalker!=reggrid->getItemProperties().end(); ++outputwalker)
+        {
+                std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str()  << std::endl;
+        }
+        std::cout << "The Regular Grid's time is: " << reggrid->getTime()->getValue() << std::endl;
+        for (i=0; i<reggrid->getNumberMaps(); ++i)
+        {
+                readMap = reggrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+					std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+        for (i=0; i < reggrid->getNumberSets(); ++i)
+        {
+                readSet = reggrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+		std::cout << "Set # " << i << std::endl;
+                std::cout << readSet->getName().c_str() << std::endl;
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        std::cout << "This set is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This set is not a node" << std::endl;
+                }
+                outputInformation = readSet->getInformation(0);
+                std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+                std::cout << readSet->getValuesString().c_str() << std::endl;
+                for (j=0; j < readSet->getNumberAttributes(); ++j)
+                {
+                        readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+                        std::cout << "Set Attribute # " << j << std::endl;
+                        std::cout << readAttribute->getName().c_str() << std::endl;
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                std::cout << "This attribute is a scalar" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a scalar" << std::endl;
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                std::cout << "This attribute is a node" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a node"  << std::endl;
+                        }
+                        std::cout <<  readAttribute->getValuesString().c_str()  << std::endl;
+                }
+        }
+        for (i = 0; i < reggrid->getNumberAttributes(); ++i)
+        {
+                readAttribute = reggrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+                std::cout << "Attribute # " << i << std::endl;
+                std::cout << readAttribute->getName().c_str() << std::endl;
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        std::cout << "This attribute is a scalar" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a scalar" << std::endl;
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        std::cout << "This attribute is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a node" << std::endl;
+                }
+                std::cout << readAttribute->getValuesString().c_str() << std::endl;
+        }
+
+        std::cout << "Regular Brick Size" << std::endl;
+        shared_ptr<XdmfArray> regbricksize = reggrid->getBrickSize();
+	if (!regbricksize->isInitialized())
+	{
+		regbricksize->read();
+	}
+        std::cout << "The brick's tag: " << regbricksize->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << regbricksize->getValuesString().c_str() << std::endl;
+
+        std::cout << "Regular Number of Points" << std::endl;
+        shared_ptr<XdmfArray> regnumpoints = reggrid->getDimensions();
+	if (!regnumpoints->isInitialized())
+	{
+		regnumpoints->read();
+	}
+        std::cout << "The dimensions' tag: " << regnumpoints->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << regnumpoints->getValuesString().c_str() << std::endl;
+
+        std::cout << "Regular Origin" << std::endl;
+        shared_ptr<XdmfArray> regorigin = reggrid->getOrigin();
+	if (!regorigin->isInitialized())
+	{
+		regorigin->read();
+	}
+        std::cout << "The origin's tag: " << regorigin->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << regorigin->getValuesString().c_str() << std::endl;
+
+
+
+
+
+
+        primaryDomain->getInformation(0)->setKey("Edited");
+        primaryDomain->getInformation(0)->setValue("This file is the edited version");
+	std::cout << "edited domain information" << std::endl;
+
+        shared_ptr<XdmfAttribute> unglobalIDs = ungrid->getAttribute(0);
+        int newIDs1 [] = {5,2,8,7,9,1};
+        unglobalIDs->insert(0, newIDs1, 6, 1, 1);
+	std::cout << "edited unstructured attribute: " << unglobalIDs->getValuesString() << std::endl;
+
+        shared_ptr<XdmfSet> unset = ungrid->getSet(0);
+	double newunsetdata [] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 0.23};
+	unset->insert(0, newunsetdata, 10, 1, 1);
+	std::cout << "edited unstructured set: " << unset->getValuesString() << std::endl;
+
+        untopology = ungrid->getTopology();
+	int untoposize = untopology->getSize();
+        int untopologydata [untoposize];
+	untopology->getValues(0, untopologydata, untopology->getSize(), 1, 1);
+        for (i=0; i < untopology->getSize(); ++i)
+	{
+		untopologydata[i] = untopologydata[i] + 1;
+	}
+        untopology->insert(0, untopologydata, untopology->getSize(), 1, 1);
+	std::cout << "edited unstructured topology: " << untopology->getValuesString() << std::endl;
+
+        ungeometry = ungrid->getGeometry();
+	int ungeosize = ungeometry->getSize();
+        double ungeometrydata [ungeosize];
+	ungeometry->getValues(0, ungeometrydata, ungeometry->getSize(), 1, 1);
+        for (i=0; i<ungeometry->getSize(); ++i)
+	{
+		ungeometrydata[i] = ungeometrydata[i] + 1;
+	}
+        ungeometry->insert(0, ungeometrydata, ungeometry->getSize(), 1, 1);
+
+
+        shared_ptr<XdmfAttribute> curvglobalIDs = curvgrid->getAttribute(0);
+        int newIDs2 [] = {3, 6, 2, 8, 1, 7, 5};
+        curvglobalIDs->insert(0, newIDs2, 7, 1, 1);
+
+        curvgeometry = curvgrid->getGeometry();
+	int curvgeosize = curvgeometry->getSize();
+        double curvgeometrydata [curvgeosize];
+	curvgeometry->getValues(0, curvgeometrydata, curvgeometry->getSize(), 1, 1);
+        for (i = 0; i<curvgeometry->getSize(); ++i)
+	{
+		curvgeometrydata[i] = curvgeometrydata[i] + 1;
+	}
+        curvgeometry->insert(0, curvgeometrydata, curvgeometry->getSize(), 1, 1);
+	for (i = 0; i < 3; ++i)
+	{
+		curvgeometry->pushBack(curvgeometry->getSize());
+	}
+
+        curvdimensions = curvgrid->getDimensions();
+	int curvdimensionsize = curvdimensions->getSize();
+        int curvdimensiondata [curvdimensionsize];
+	curvdimensions->getValues(0, curvdimensiondata, curvdimensions->getSize(), 1, 1);
+        for (i = 0;  i< curvdimensions->getSize(); ++i)
+	{
+		curvdimensiondata[i] = curvdimensiondata[i] + 1;
+	}
+        curvdimensions->insert(0, curvdimensiondata, curvdimensions->getSize(), 1, 1);
+
+
+        shared_ptr<XdmfAttribute> rectglobalIDs = rectgrid->getAttribute(0);
+        int newIDs3 [] = {6, 4, 3, 7, 9, 8};
+        rectglobalIDs->insert(0, newIDs3, 6, 1, 1);
+
+        rectdimensions = rectgrid->getDimensions();
+	int rectdimensionsize = rectdimensions->getSize();
+        int rectdimensiondata [rectdimensionsize];
+	rectdimensions->getValues(0, rectdimensiondata, rectdimensions->getSize(), 1, 1);
+        for (i = 0; i < rectdimensions->getSize(); ++i)
+	{
+		rectdimensiondata[i] = rectdimensiondata[i] + 1;
+	}
+        rectdimensions->insert(0, rectdimensiondata, rectdimensions->getSize(), 1, 1);
+
+        std::vector<shared_ptr<XdmfArray> > rectcoordinatevector = rectgrid->getCoordinates();
+	shared_ptr<XdmfArray> coordinateaxis;
+	for (i=0;i<rectcoordinatevector.size(); ++i)
+	{
+		coordinateaxis = rectcoordinatevector[i];
+		int coordinatesize = coordinateaxis->getSize();
+		int coordinatedata [coordinatesize];
+		coordinateaxis->getValues(0, coordinatedata, coordinateaxis->getSize(), 1, 1);
+		for (j = 0; j < coordinateaxis->getSize(); j++)
+		{
+			coordinatedata[i] = coordinatedata[i] + 1;
+		}
+		coordinateaxis->insert(0, coordinatedata, coordinateaxis->getSize(), 1, 1);
+		coordinateaxis->pushBack(coordinateaxis->getSize());
+		rectcoordinatevector[i] = coordinateaxis;
+	}
+	rectgrid->setCoordinates(rectcoordinatevector);
+
+        shared_ptr<XdmfAttribute> regglobalIDs = reggrid->getAttribute(0);
+        int newIDs4 [] = {3, 5, 1, 2, 4, 8, 0};
+        regglobalIDs->insert(0, newIDs4, 7, 1, 1);
+
+        regbricksize = reggrid->getBrickSize();
+	int regbrickdatasize = regbricksize->getSize();
+        double brickdata [regbrickdatasize];
+	regbricksize->getValues(0, brickdata, regbricksize->getSize(), 1, 1);
+	for (i = 0; i < regbricksize->getSize(); ++i)
+	{
+		brickdata[i] = brickdata[i] + 1;
+	}
+        regbricksize->insert(0, brickdata, regbricksize->getSize(), 1, 1);
+        reggrid->setBrickSize(regbricksize);
+
+        shared_ptr<XdmfArray> regdimensions = reggrid->getDimensions();
+	int regdimensionssize = regdimensions->getSize();
+        int regdimensiondata [regdimensionssize];
+	regdimensions->getValues(0, regdimensiondata, regdimensions->getSize(), 1, 1);
+	for (i = 0; i < regdimensions->getSize(); ++i)
+	{
+		regdimensiondata[i] = regdimensiondata[i] + 1;
+	}
+        regdimensions->insert(0, regdimensiondata, regdimensions->getSize(), 1, 1);
+        reggrid->setDimensions(regdimensions);
+
+        regorigin = reggrid->getOrigin();
+	int regoriginsize = regorigin->getSize();
+        double regorigindata [regoriginsize];
+	regorigin->getValues(0, regorigindata, regorigin->getSize(), 1, 1);
+	for (i = 0; i < regorigin->getSize(); ++i)
+	{
+		regorigindata[i] = regorigindata[i] + 1;
+	}
+        regorigin->insert(0, regorigindata, regorigin->getSize(), 1, 1);
+        reggrid->setOrigin(regorigin);
+
+	shared_ptr<XdmfHDF5Writer> exampleHeavyWriter = XdmfHDF5Writer::New("editedtestoutput.h5");
+        shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New("editedtestoutput.xmf", exampleHeavyWriter);
+	//exampleHeavyWriter->setFileSizeLimit(1);
+	primaryDomain->accept(exampleHeavyWriter);
+	exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Overwrite);
+        primaryDomain->accept(exampleWriter);
+
+	return 0;
+}
diff --git a/tests/Cxx/ExampleXdmfRead.cpp b/tests/Cxx/ExampleXdmfRead.cpp
new file mode 100644
index 0000000..8a604c8
--- /dev/null
+++ b/tests/Cxx/ExampleXdmfRead.cpp
@@ -0,0 +1,677 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "string.h"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+	std::cout << "Program Started" << std::endl;
+        shared_ptr<XdmfReader> exampleReader = XdmfReader::New();
+
+        /*
+        This is assuming that the read item is an XdmfDomain object
+        */
+        shared_ptr<XdmfDomain> primaryDomain = shared_dynamic_cast<XdmfDomain>(exampleReader->read("testoutput.xmf"));
+	//shared_ptr<XdmfDomain> primaryDomain = shared_dynamic_cast<XdmfDomain>(exampleReader->read("editedtestoutput.xmf"));
+        shared_ptr<XdmfInformation> outputInformation = primaryDomain->getInformation(0);
+        std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+        std::cout << "The Domain's tag is: " << primaryDomain->getItemTag().c_str() << std::endl;
+
+        shared_ptr<XdmfGridCollection> gridHolder = primaryDomain->getGridCollection(0);
+
+        std::cout << "The Grid Collection's tag is: " << gridHolder->getItemTag().c_str() << std::endl;
+        std::cout << "The Grid Collection's name is: " << gridHolder->getName().c_str() << std::endl;
+        outputInformation = gridHolder->getInformation(0);
+        std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::cout;
+
+	std::map<std::string, std::string>::iterator outputwalker = gridHolder->getItemProperties().begin();
+	for (;outputwalker!=gridHolder->getItemProperties().end(); ++outputwalker)
+	{
+		std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+	}
+ 
+        if (gridHolder->getType() == XdmfGridCollectionType::Spatial())
+	{
+                std::cout << "This is a spatial grid collection" << std::endl;
+	}
+        else
+	{
+                std::cout << "This is not a spatial grid collection" << std::endl;
+	}
+
+
+	//loop controlling integers
+	int i = 0;
+	int j = 0;
+	int k = 0;
+	int m = 0;
+	int task;
+	int node;
+	int remote;
+	std::string blankstring = "";
+	char* outstring = strdup(blankstring.c_str());
+	shared_ptr<XdmfMap> readMap;
+	std::map<int, std::map<int, std::set<int> > > taskIDMap;
+	std::map<int, std::map<int, std::set<int> > >::iterator taskWalker;
+	std::map<int, std::set<int> > nodeIDMap;
+	std::map<int, std::set<int> >::iterator nodeWalker;
+	std::set<int> remoteIDset;
+	std::set<int>::iterator remoteWalker;
+
+	for (i=0; i<gridHolder->getNumberMaps(); ++i)
+	{
+		readMap = gridHolder->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+		std::cout << "Map # " << i << std::endl;
+		taskIDMap = readMap->getMap();
+		for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+		{
+			task = (*taskWalker).first;
+			nodeIDMap = (*taskWalker).second;
+			for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+			{
+				node = (*nodeWalker).first;
+				remoteIDset = (*nodeWalker).second;
+				for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+				{
+					remote = (*remoteWalker);
+					std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+				}
+			}
+		}
+	}
+
+        std::cout << "Unstructured Grid" << std::endl;
+        shared_ptr<XdmfUnstructuredGrid> ungrid = gridHolder->getUnstructuredGrid(0);
+        std::cout << "The Unstructured Grid's tag is: " << ungrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Unstructured Grid's name is: " << ungrid->getName().c_str() << std::endl;
+
+	outputwalker = ungrid->getItemProperties().begin();
+        for (;outputwalker!=ungrid->getItemProperties().end(); ++outputwalker)
+        {
+                std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+        }
+
+        std::cout << "The Unstructured Grid's time is: " << ungrid->getTime()->getValue() << std::endl;
+        i=0;
+        for (i=0; i<ungrid->getNumberMaps(); ++i)
+        {
+                readMap = ungrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+					std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+
+	shared_ptr<XdmfSet> readSet;
+	shared_ptr<XdmfAttribute> readAttribute;
+	for (i=0; i < ungrid->getNumberSets(); ++i)
+	{
+		readSet = ungrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+		std::cout << "Set # " << i << std::endl;
+		std::cout << readSet->getName().c_str() << std::endl;
+		if (readSet->getType() == XdmfSetType::Node())
+		{
+			std::cout << "This set is a node" << std::endl;
+		}
+		else
+		{
+			std::cout << "This set is not a node" << std::endl;
+		}
+		outputInformation = readSet->getInformation(0);
+		std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+		std::cout << readSet->getValuesString().c_str() << std::endl;
+		for (j=0; j < readSet->getNumberAttributes(); ++j)
+		{
+			readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+			std::cout << "Set Attribute # " << j << std::endl;
+			std::cout << readAttribute->getName().c_str() << std::endl;
+			if (readAttribute->getType() == XdmfAttributeType::Scalar())
+			{
+				std::cout << "This attribute is a scalar" << std::endl;
+			}
+			else
+			{
+				std::cout << "This attribute is not a scalar" << std::endl;
+			}
+			if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+			{
+				std::cout << "This attribute is a node" << std::endl;
+			}
+			else
+			{
+				std::cout << "This attribute is not a node" << std::endl;
+			}
+			std::cout << readAttribute->getValuesString().c_str() << std::endl;
+		}
+	}
+	for (i = 0; i < ungrid->getNumberAttributes(); ++i)
+	{
+		readAttribute = ungrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+		std::cout << "Attribute # " << i << std::endl;
+		std::cout << readAttribute->getName().c_str() << std::endl;
+		if (readAttribute->getType() == XdmfAttributeType::Scalar())
+		{
+			std::cout << "This attribute is a scalar" << std::endl;
+		}
+		else
+		{
+			std::cout << "This attribute is not a scalar" << std::endl;
+		}
+		if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+		{
+			std::cout << "This attribute is a node" << std::endl;
+		}
+		else
+		{
+			std::cout << "This attribute is not a node" << std::endl;
+		}
+		std::cout << readAttribute->getValuesString().c_str() << std::endl;
+	}
+
+	std::cout << "Unstructured Topology"  << std::endl;
+	shared_ptr<XdmfTopology> untopology = ungrid->getTopology();
+	if (!untopology->isInitialized())
+	{
+		untopology->read();
+	}
+	std::cout << "The topology's tag: " << untopology->getItemTag().c_str()  << std::endl;
+	if (untopology->getType() == XdmfTopologyType::Hexahedron())
+	{
+		std::cout << "This topology is a hexahedron" << std::endl;
+        }
+	else
+	{
+		std::cout << "This topology is not a hexahedron" << std::endl;
+	}
+	std::cout << "Contains " << untopology->getNumberElements() << " elements" << std::endl;
+	std::cout << "Contains the values: " << untopology->getValuesString().c_str() << std::endl;
+
+	std::cout << "Unstructured Geometry" << std::endl;
+	shared_ptr<XdmfGeometry> ungeometry = ungrid->getGeometry();
+	if (!ungeometry->isInitialized())
+	{
+		ungeometry->read();
+	}
+	std::cout << "The geometry's tag: " << ungeometry->getItemTag().c_str() << std::endl;
+	if (ungeometry->getType() == XdmfGeometryType::XYZ())
+	{
+		std::cout << "This geometry is XYZ" << std::endl;
+	}
+	else
+	{
+		std::cout << "This geometry is not XYZ" << std::endl;
+	}
+	outputInformation = ungeometry->getInformation(0);
+	std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+	std::cout << "Contains " << ungeometry->getNumberPoints() << " points\n" << ungeometry->getNumberPoints() << std::endl;
+	std::cout << "Contains the values: " << ungeometry->getValuesString().c_str() << std::endl;
+
+
+
+
+
+        std::cout << "Curvilinear Grid" << std::endl;
+        shared_ptr<XdmfCurvilinearGrid> curvgrid = gridHolder->getCurvilinearGrid(0);
+        std::cout << "The Curvilinear Grid's tag is: " << curvgrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Curvilinear Grid's name is: " << curvgrid->getName().c_str() << std::endl;
+        outputwalker = curvgrid->getItemProperties().begin();
+        for (;outputwalker!=curvgrid->getItemProperties().end(); ++outputwalker)
+        {
+                std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+        }
+        outputInformation = curvgrid->getInformation(0);
+        std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+        std::cout << "The Curvilinear Grid's time is: " << curvgrid->getTime()->getValue() << std::endl;
+        for (i=0; i<curvgrid->getNumberMaps(); ++i)
+        {
+                readMap = curvgrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+                                        std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+        for (i=0; i < curvgrid->getNumberSets(); ++i)
+        {
+                readSet = curvgrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+                std::cout << "Set # " << i << std::endl;
+                std::cout << readSet->getName().c_str() << std::endl;
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        std::cout << "This set is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This set is not a node" << std::endl;
+                }
+                outputInformation = readSet->getInformation(0);
+                std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: "<< outputInformation->getValue().c_str() << std::endl;
+                std::cout << readSet->getValuesString().c_str() << std::endl;
+                for (j=0; j < readSet->getNumberAttributes(); ++j)
+                {
+                        readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+                        std::cout << "Set Attribute # " << j << std::endl;
+                        std::cout << readAttribute->getName().c_str() << std::endl;
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                std::cout << "This attribute is a scalar" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a scalar" << std::endl;
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                std::cout << "This attribute is a node" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a node" << std::endl;
+                        }
+                        std::cout << readAttribute->getValuesString().c_str() << std::endl;
+                }
+        }
+        for (i = 0; i < curvgrid->getNumberAttributes(); ++i)
+        {
+                readAttribute = curvgrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+                std::cout << "Attribute # " << i << std::endl;
+                std::cout << readAttribute->getName().c_str() << std::endl;
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        std::cout << "This attribute is a scalar" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a scalar" << std::endl;
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        std::cout << "This attribute is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a node" << std::endl;
+                }
+                std::cout << readAttribute->getValuesString().c_str() << std::endl;
+        }
+
+        std::cout << "Curvilinear Dimensions" << std::endl;
+        shared_ptr<XdmfArray> curvdimensions = curvgrid->getDimensions();
+	if (!curvdimensions->isInitialized())
+	{
+		curvdimensions->read();
+	}
+        std::cout << "The dimensions' tag: " << curvdimensions->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << curvdimensions->getValuesString().c_str() << std::endl;
+
+        std::cout << "Curvilinear Geometry" << std::endl;
+        shared_ptr<XdmfGeometry> curvgeometry = curvgrid->getGeometry();
+	if (!curvgeometry->isInitialized())
+	{
+		curvgeometry->read();
+	}
+        std::cout << "The geometry's tag: " << curvgeometry->getItemTag().c_str() << std::endl;
+        if (curvgeometry->getType() == XdmfGeometryType::XYZ())
+	{
+                std::cout << "This geometry is XYZ" << std::endl;
+        }
+	else
+	{
+                std::cout << "This geometry is not XYZ" << std::endl;
+	}
+        outputInformation = curvgeometry->getInformation(0);
+        std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+        std::cout << "Contains " << curvgeometry->getNumberPoints() << " points\n" << std::endl;
+        std::cout << "Contains the values: " << curvgeometry->getValuesString().c_str() << std::endl;
+
+
+        std::cout << "Rectilinear Grid" << std::endl;
+        shared_ptr<XdmfRectilinearGrid> rectgrid = gridHolder->getRectilinearGrid(0);
+        std::cout << "The Rectilinear Grid's tag is: " << rectgrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Rectilinear Grid's name is: " << rectgrid->getName().c_str() << std::endl;
+        std::cout << "The Rectilinear Grid's time is: " << rectgrid->getTime()->getValue() << std::endl;
+
+	outputwalker = rectgrid->getItemProperties().begin();
+	for (; outputwalker!=rectgrid->getItemProperties().end(); ++outputwalker)
+	{
+		std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+	}
+
+        for (i=0; i<rectgrid->getNumberMaps(); ++i)
+        {
+                readMap = rectgrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+                                        std::cout << "taskID: " << task <<"\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+	for (i=0; i < rectgrid->getNumberSets(); ++i)
+        {
+                readSet = rectgrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+                std::cout << "Set # " << i << std::endl;
+                std::cout << readSet->getName().c_str() << std::endl;
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        std::cout << "This set is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This set is not a node" << std::endl;
+                }
+                outputInformation = readSet->getInformation(0);
+                std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+                std::cout << readSet->getValuesString().c_str() << std::endl;
+                for (j=0; j < readSet->getNumberAttributes(); ++j)
+                {
+                        readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+                        std::cout << "Set Attribute # " << j << std::endl;
+                        std::cout << readAttribute->getName().c_str() << std::endl;
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                std::cout << "This attribute is a scalar" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a scalar" << std::endl;
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                std::cout << "This attribute is a node" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a node" << std::endl;
+                        }
+                        std::cout << readAttribute->getValuesString().c_str() << std::endl;
+                }
+        }
+        for (i = 0; i < rectgrid->getNumberAttributes(); ++i)
+        {
+                readAttribute = rectgrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+                std::cout << "Attribute # " << i << std::endl;
+                std::cout << readAttribute->getName().c_str() << std::endl;
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        std::cout << "This attribute is a scalar" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a scalar" << std::endl;
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        std::cout << "This attribute is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a node" << std::endl;
+                }
+                std::cout << readAttribute->getValuesString().c_str() << std::endl;
+        }
+        std::cout << "Rectilinear Dimensions" << std::endl;
+        shared_ptr<XdmfArray> rectdimensions = rectgrid->getDimensions();
+	if (!rectdimensions->isInitialized())
+	{
+		rectdimensions->read();
+	}
+        std::cout << "The dimensions' tag: " << rectdimensions->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << rectdimensions->getValuesString().c_str() << std::endl;
+
+        std::cout << "Rectilinear Coordinates" << std::endl;
+        std::vector<shared_ptr<XdmfArray> > rectcoordinates = rectgrid->getCoordinates();
+        std::cout << "Contains the values: " << std::endl;
+	for (i=0;i<rectcoordinates.size(); ++i)
+	{
+		if (!rectcoordinates[i]->isInitialized())
+		{
+			rectcoordinates[i]->read();
+		}
+		std::cout << rectcoordinates[i]->getValuesString().c_str() << std::endl;
+	}
+
+        std::cout << "Regular Grid" << std::endl;
+        shared_ptr<XdmfRegularGrid> reggrid = gridHolder->getRegularGrid(0);
+        std::cout << "The Regular Grid's tag is: " << reggrid->getItemTag().c_str() << std::endl;
+        std::cout << "The Regular Grid's name is: " << reggrid->getName().c_str() << std::endl;
+        outputwalker = reggrid->getItemProperties().begin();
+        for (;outputwalker!=reggrid->getItemProperties().end(); ++outputwalker)
+        {
+                std::cout << (*outputwalker).first.c_str() << ": " << (*outputwalker).second.c_str() << std::endl;
+        }
+std::cout << "test1" << std::endl;
+        std::cout << "The Regular Grid's time is: " << reggrid->getTime()->getValue() << std::endl;
+        for (i=0; i<reggrid->getNumberMaps(); ++i)
+        {
+                readMap = reggrid->getMap(i);
+		if (!readMap->isInitialized())
+		{
+			readMap->read();
+		}
+                std::cout << "Map # " << i << std::endl;
+                taskIDMap = readMap->getMap();
+                for (taskWalker = taskIDMap.begin(); taskWalker!= taskIDMap.end(); ++taskWalker)
+                {
+                        task = (*taskWalker).first;
+                        nodeIDMap = (*taskWalker).second;
+                        for (nodeWalker = nodeIDMap.begin(); nodeWalker != nodeIDMap.end(); ++nodeWalker)
+                        {
+                                node = (*nodeWalker).first;
+                                remoteIDset = (*nodeWalker).second;
+                                for (remoteWalker = remoteIDset.begin(); remoteWalker != remoteIDset.end(); ++remoteWalker)
+                                {
+                                        remote = (*remoteWalker);
+                                        std::cout << "taskID: " << task << "\tlocalnodeID: " << node << "\tremotenodeID: " << remote << std::endl;
+                                }
+                        }
+                }
+        }
+        for (i=0; i < reggrid->getNumberSets(); ++i)
+        {
+                readSet = reggrid->getSet(i);
+		if (!readSet->isInitialized())
+		{
+			readSet->read();
+		}
+                std::cout << "Set # " << i << std::endl;
+                std::cout << readSet->getName().c_str() << std::endl;
+                if (readSet->getType() == XdmfSetType::Node())
+                {
+                        std::cout << "This set is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This set is not a node" << std::endl;
+                }
+                outputInformation = readSet->getInformation(0);
+                std::cout << "Key: " << outputInformation->getKey().c_str() << "\nValue: " << outputInformation->getValue().c_str() << std::endl;
+                std::cout << readSet->getValuesString().c_str() << std::endl;
+                for (j=0; j < readSet->getNumberAttributes(); ++j)
+                {
+                        readAttribute = readSet->getAttribute(j);
+			if (!readAttribute->isInitialized())
+			{
+				readAttribute->read();
+			}
+                        std::cout << "Set Attribute # " << j << std::endl;
+                        std::cout << readAttribute->getName().c_str() << std::endl;
+                        if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                        {
+                                std::cout << "This attribute is a scalar" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a scalar" << std::endl;
+                        }
+                        if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                        {
+                                std::cout << "This attribute is a node" << std::endl;
+                        }
+                        else
+                        {
+                                std::cout << "This attribute is not a node" << std::endl;
+                        }
+                        std::cout << readAttribute->getValuesString().c_str() << std::endl;
+                }
+        }
+        for (i = 0; i < reggrid->getNumberAttributes(); ++i)
+        {
+                readAttribute = reggrid->getAttribute(i);
+		if (!readAttribute->isInitialized())
+		{
+			readAttribute->read();
+		}
+                std::cout << "Attribute # " << i << std::endl;
+                std::cout << readAttribute->getName().c_str() << std::endl;
+                if (readAttribute->getType() == XdmfAttributeType::Scalar())
+                {
+                        std::cout << "This attribute is a scalar" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a scalar" << std::endl;
+                }
+                if (readAttribute->getCenter() == XdmfAttributeCenter::Node())
+                {
+                        std::cout << "This attribute is a node" << std::endl;
+                }
+                else
+                {
+                        std::cout << "This attribute is not a node" << std::endl;
+                }
+                std::cout << readAttribute->getValuesString().c_str() << std::endl;
+        }
+
+        std::cout << "Regular Brick Size" << std::endl;
+        shared_ptr<XdmfArray> regbricksize = reggrid->getBrickSize();
+	if (!regbricksize->isInitialized())
+	{
+		regbricksize->read();
+	}
+        std::cout << "The brick's tag: " << regbricksize->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << regbricksize->getValuesString().c_str() << std::endl;
+
+        std::cout << "Regular Number of Points" << std::endl;
+        shared_ptr<XdmfArray> regnumpoints = reggrid->getDimensions();
+        std::cout << "The dimensions' tag: " << regnumpoints->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << regnumpoints->getValuesString().c_str() << std::endl;
+
+        std::cout << "Regular Origin" << std::endl;
+        shared_ptr<XdmfArray> regorigin = reggrid->getOrigin();
+	if (!regorigin->isInitialized())
+	{
+		regorigin->read();
+	}
+        std::cout << "The origin's tag: " << regorigin->getItemTag().c_str() << std::endl;
+        std::cout << "Contains the values: " << regorigin->getValuesString().c_str() << std::endl;
+
+	return 0;
+}
diff --git a/tests/Cxx/ExampleXdmfWrite.cpp b/tests/Cxx/ExampleXdmfWrite.cpp
new file mode 100644
index 0000000..f400d98
--- /dev/null
+++ b/tests/Cxx/ExampleXdmfWrite.cpp
@@ -0,0 +1,244 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+	shared_ptr<XdmfDomain> primaryDomain = XdmfDomain::New();
+        shared_ptr<XdmfInformation> domaininfo = XdmfInformation::New("Domain", "This is the primary data structure in Xdmf");
+        shared_ptr<XdmfInformation> domaininfoinfo = XdmfInformation::New("Information", "Information can have information");
+        domaininfo->insert(domaininfoinfo);
+        primaryDomain->insert(domaininfo);
+
+        shared_ptr<XdmfGridCollection> gridHolder = XdmfGridCollection::New();
+        gridHolder->setType(XdmfGridCollectionType::Spatial());
+        shared_ptr<XdmfInformation> holderInfo = XdmfInformation::New("Grid Collection 1", "This is the main grid collection");
+        gridHolder->insert(holderInfo);
+        gridHolder->setName("GridCollection Example");
+
+
+        shared_ptr<XdmfUnstructuredGrid> ungrid = XdmfUnstructuredGrid::New();
+        ungrid->setName("Unstructured Grid Example");
+        shared_ptr<XdmfTime> untime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> untimeinfo = XdmfInformation::New("Time", "This is the time for the Unstructured Grid");
+        untime->insert(untimeinfo);
+        ungrid->setTime(untime);
+        shared_ptr<XdmfAttribute> unglobalID = XdmfAttribute::New();
+        unglobalID->setType(XdmfAttributeType::GlobalId());
+        unglobalID->setCenter(XdmfAttributeCenter::Node());
+        unglobalID->setName("Global Node Equivalencies");
+        int task1globalnodes [] = {1, 4, 5, 7, 3, 6};
+        unglobalID->insert(0, task1globalnodes, 6, 1, 1 );
+        shared_ptr<XdmfInformation> unglobalIDinfo = XdmfInformation::New("Global Nodes", "This is the global nodes that accociate with the local nodes");
+        ungrid->insert(unglobalID);
+        shared_ptr<XdmfSet> unset = XdmfSet::New();
+        shared_ptr<XdmfInformation> unsetinfo = XdmfInformation::New("Data Set", "This is a set of arbitrary data");
+        unset->insert(unsetinfo);
+        unset->setName("Unstructured Grid's Set");
+        unset->setType(XdmfSetType::Node());
+        shared_ptr<XdmfAttribute> unsetattribute = XdmfAttribute::New();
+        unsetattribute->setType(XdmfAttributeType::Scalar());
+        unsetattribute->setCenter(XdmfAttributeCenter::Node());
+        unsetattribute->setName("The Set's attribute");
+        double unsetattribdata [] = {1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1};
+        unsetattribute->insert(0, unsetattribdata, 9, 1, 1);
+        unset->insert(unsetattribute);
+        double unsetdata [] = {5.1, 4.2, 3.3, 2.4, 1.5};
+        unset->insert(0, unsetdata, 5, 1, 1);
+        ungrid->insert(unset);
+        shared_ptr<XdmfGeometry> ungeometry = XdmfGeometry::New();
+        ungeometry->setType(XdmfGeometryType::XYZ());
+        ungeometry->setName("Unstructured Geometry");
+        double ungeopoints [] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1,
+                1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1,
+                0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1};
+        ungeometry->insert(0, ungeopoints, 36, 1, 1);
+        shared_ptr<XdmfInformation> ungeometryinfo = XdmfInformation::New("Geometry", "This is the geometry associated with the unstructured grid");
+        ungeometry->insert(ungeometryinfo);
+        ungrid->setGeometry(ungeometry);
+        shared_ptr<XdmfTopology> untopology = XdmfTopology::New();
+        untopology->setType(XdmfTopologyType::Hexahedron());
+        untopology->setName("Unstructured Topology");
+        int untopovalues [] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
+        untopology->insert(0, untopovalues, 16, 1, 1);
+        shared_ptr<XdmfInformation> untopologyinfo = XdmfInformation::New("Topology", "This is the topology associated with the unstructured grid");
+        ungrid->setTopology(untopology);
+
+
+        shared_ptr<XdmfArray> curvdimensions = XdmfArray::New();
+        curvdimensions->pushBack(12);
+        curvdimensions->pushBack(12);
+        curvdimensions->pushBack(12);
+        shared_ptr<XdmfCurvilinearGrid> curvgrid = XdmfCurvilinearGrid::New(curvdimensions);
+        curvgrid->setName("Curvilinear Grid Example");
+        shared_ptr<XdmfInformation> curvgridinfo = XdmfInformation::New("Curvilinear Grid", "This is an example curvilinear grid");
+        curvgrid->insert(curvgridinfo);
+        shared_ptr<XdmfTime>curvtime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> curvtimeinfo = XdmfInformation::New("Time", "The Time of the Curvilinear Grid");
+        curvtime->insert(curvtimeinfo);
+        curvgrid->setTime(curvtime);
+        shared_ptr<XdmfAttribute> curvglobalID = XdmfAttribute::New();
+        curvglobalID->setType(XdmfAttributeType::GlobalId());
+        curvglobalID->setCenter(XdmfAttributeCenter::Node());
+        curvglobalID->setName("Global Node Equivalencies");
+        int task2globalnodes [] = {7, 3, 8, 2, 5, 1};
+        curvglobalID->insert(0, task1globalnodes, 6, 1, 1);
+        shared_ptr<XdmfInformation> curvglobalIDinfo = XdmfInformation::New("Global Node Equivalencies", "These are the global nodes that accociate with the local nodes");
+        curvglobalID->insert(curvglobalIDinfo);
+        curvgrid->insert(curvglobalID);
+        shared_ptr<XdmfGeometry> curvgeometry = XdmfGeometry::New();
+        curvgeometry->setType(XdmfGeometryType::XYZ());
+        curvgeometry->setName("Curvilinear Geometry");
+        double curvgeopoints [] = {1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1, 2.1,
+                2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1, 4.1,
+                1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1};
+        curvgeometry->insert(0, curvgeopoints, 36, 1, 1);
+        shared_ptr<XdmfInformation> curvgeometryinfo = XdmfInformation::New("Geometry", "The geometry of the curvilinear grid");
+        curvgeometry->insert(curvgeometryinfo);
+        curvgrid->setGeometry(curvgeometry);
+
+
+        double rectXcoordinates [] = {1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1};
+        double rectYcoordinates [] = {2.1, 2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1};
+        double rectZcoordinates [] = {4.1, 1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1};
+	shared_ptr<XdmfArray> rectXarray = XdmfArray::New();
+        rectXarray->insert(0, rectXcoordinates, 12, 1, 1);
+        shared_ptr<XdmfArray> rectYarray = XdmfArray::New();
+        rectYarray->insert(0, rectYcoordinates, 12, 1, 1);
+        shared_ptr<XdmfArray> rectZarray = XdmfArray::New();
+        rectZarray->insert(0, rectZcoordinates, 12, 1, 1);
+        std::vector<shared_ptr<XdmfArray> > coordinatecontainer;
+        coordinatecontainer.push_back(rectXarray);
+        coordinatecontainer.push_back(rectYarray);
+        coordinatecontainer.push_back(rectZarray);
+        shared_ptr<XdmfRectilinearGrid> rectgrid = XdmfRectilinearGrid::New(coordinatecontainer);
+        rectgrid->setName("Rectilinear Grid Example");
+        shared_ptr<XdmfInformation> rectgridinfo = XdmfInformation::New("Rectilinear Grid", "This is an example of a rectilinear grid");
+        shared_ptr<XdmfAttribute> rectglobalID = XdmfAttribute::New();
+        rectglobalID->setType(XdmfAttributeType::GlobalId());
+        rectglobalID->setCenter(XdmfAttributeCenter::Node());
+        rectglobalID->setName("Global Node Equivalencies");
+        int task3globalnodes [] = {2, 7, 9, 0, 8, 6};
+        rectglobalID->insert(0, task3globalnodes, 6, 1, 1);
+        shared_ptr<XdmfInformation> rectglobalIDinfo = XdmfInformation::New("Global Node Equivalencies", "These are the global nodes that associate with the local nodes");
+        rectglobalID->insert(rectglobalIDinfo);
+        shared_ptr<XdmfTime> recttime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> recttimeinfo = XdmfInformation::New("Time", "The time of the rectiliniear grid");
+        recttime->insert(recttimeinfo);
+        rectgrid->setTime(recttime);
+        rectgrid->insert(rectglobalID);
+
+
+        shared_ptr<XdmfArray> regbrick = XdmfArray::New();
+        double regbrickvals [] = {10, 10, 10};
+        regbrick->insert(0, regbrickvals, 3, 1, 1);
+        shared_ptr<XdmfArray> regdimensions = XdmfArray::New();
+        int regdimensionvals [] = {5, 5, 5};
+        regdimensions->insert(0, regdimensionvals, 3, 1, 1);
+        shared_ptr<XdmfArray> regorigin = XdmfArray::New();
+        double regoriginvals [] = {0, 0, 0};
+        regorigin->insert(0, regoriginvals, 3, 1, 1);
+        shared_ptr<XdmfRegularGrid> reggrid = XdmfRegularGrid::New(regbrick, regdimensions, regorigin);
+        reggrid->setName("Regular Grid Example");
+        shared_ptr<XdmfInformation> reggridinfo = XdmfInformation::New("Regular Grid", "This is an example of a regular grid");
+        shared_ptr<XdmfTime> regtime = XdmfTime::New(5.0);
+        shared_ptr<XdmfInformation> regtimeinfo = XdmfInformation::New("Time", "This is the time for the regular grid");
+        regtime->insert(regtimeinfo);
+	reggrid->setTime(regtime);
+        shared_ptr<XdmfAttribute> regglobalID = XdmfAttribute::New();
+        regglobalID->setType(XdmfAttributeType::GlobalId());
+        regglobalID->setCenter(XdmfAttributeCenter::Node());
+        regglobalID->setName("Global Node Equivalencies");
+        int task4globalnodes [] = {3, 6, 1, 4, 2, 5, 9};
+        regglobalID->insert(0, task4globalnodes, 7, 1, 1);
+        shared_ptr<XdmfInformation> regglobalIDinfo = XdmfInformation::New("Global Node Equivalencies", "These are the global nodes that associate with the local nodes");
+        regglobalID->insert(regglobalIDinfo);
+	reggrid->insert(regglobalID);
+
+
+
+        std::vector<shared_ptr<XdmfAttribute> > nodeholder;
+        nodeholder.push_back(unglobalID);
+        nodeholder.push_back(curvglobalID);
+        nodeholder.push_back(rectglobalID);
+        nodeholder.push_back(regglobalID);
+        std::vector<shared_ptr<XdmfMap> > mapcollection = XdmfMap::New(nodeholder);
+
+        ungrid->insert(mapcollection[0]);
+        curvgrid->insert(mapcollection[1]);
+        rectgrid->insert(mapcollection[2]);
+        reggrid->insert(mapcollection[3]);
+
+        /*
+        the version of XdmfMap::New() used here returns a number of maps equal to the number of attributes it was provided with.
+        */
+        for (int i = 0; i<mapcollection.size(); i++)
+	{
+		gridHolder->insert(mapcollection[i]);
+	}
+
+        gridHolder->insert(ungrid);
+        gridHolder->insert(curvgrid);
+        gridHolder->insert(rectgrid);
+        gridHolder->insert(reggrid);
+
+        shared_ptr<XdmfGridCollection> secondaryHolder = XdmfGridCollection::New();
+        secondaryHolder->setName("Secondary grid collection");
+        gridHolder->insert(secondaryHolder);
+        /*
+        grid collections can be placed inside other grid collections
+        */
+
+        primaryDomain->insert(gridHolder);
+        /*
+        grids can be inserted into the domain in the same way as the grid collection
+        */
+        primaryDomain->insert(ungrid);
+        primaryDomain->insert(curvgrid);
+        primaryDomain->insert(rectgrid);
+        primaryDomain->insert(reggrid);
+
+        shared_ptr<XdmfHDF5Writer> exampleHeavyWriter = XdmfHDF5Writer::New("testoutput.h5");
+        shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New("testoutput.xmf", exampleHeavyWriter);
+
+	exampleHeavyWriter->setFileSizeLimit(1);
+
+	primaryDomain->accept(exampleHeavyWriter);
+	exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Overwrite);//do this so that the data isn't in the hdf5 file twice.
+	exampleHeavyWriter->setFileIndex(0);
+        exampleWriter->setLightDataLimit(1);
+	primaryDomain->accept(exampleWriter);
+
+        exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+	for (int i = 0; i <= 797; i++)
+	{//overflow occurs at around 509
+		primaryDomain->accept(exampleHeavyWriter);
+	}
+	exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Default);
+	primaryDomain->accept(exampleHeavyWriter);
+	exampleHeavyWriter->setMode(XdmfHeavyDataWriter::Append);
+	for (int i = 0; i<500; i++)
+	{
+		primaryDomain->accept(exampleHeavyWriter);
+	}
+	primaryDomain->accept(exampleWriter);
+  return 0;
+}
diff --git a/tests/Cxx/HugeReadArray.cpp b/tests/Cxx/HugeReadArray.cpp
new file mode 100644
index 0000000..c08d1f3
--- /dev/null
+++ b/tests/Cxx/HugeReadArray.cpp
@@ -0,0 +1,14 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfReader.hpp>
+
+
+int main(int, char **)
+{
+	shared_ptr<XdmfReader> testReader = XdmfReader::New();
+	shared_ptr<XdmfArray> readArray = shared_dynamic_cast<XdmfArray>(testReader->read("arraydata.xmf"));
+	readArray->read();
+	std::cout << "Array contains " << readArray->getValuesString() << std::endl;
+	return 0;
+}
diff --git a/tests/Cxx/HugeWriteArray.cpp b/tests/Cxx/HugeWriteArray.cpp
new file mode 100644
index 0000000..df07637
--- /dev/null
+++ b/tests/Cxx/HugeWriteArray.cpp
@@ -0,0 +1,96 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfWriter.hpp>
+#include <XdmfHDF5Writer.hpp>
+#include <XdmfHDF5Controller.hpp>
+#include <sys/timeb.h>
+
+int main(int, char **)
+{
+	timeb tb;
+	ftime(&tb);
+	int start = tb.millitm + (tb.time & 0xfffff) * 1000;
+
+
+
+	shared_ptr<XdmfArray> writtenArray = XdmfArray::New();
+	for (int i = 0; i < 9000000; i++)
+	{
+		writtenArray->pushBack(i);
+	}
+	std::vector<unsigned int> starts;
+	std::vector<unsigned int> strides;
+	std::vector<unsigned int> dimensions;
+	std::vector<unsigned int> dataspaces;
+	starts.push_back(0);
+	starts.push_back(0);
+	strides.push_back(3);
+	strides.push_back(3);
+	dimensions.push_back(1000);
+	dimensions.push_back(1000);
+	dataspaces.push_back(3000);
+	dataspaces.push_back(3000);
+	shared_ptr<XdmfHDF5Controller> arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+	writtenArray->insert(arrayController);
+	starts[0] = 1;
+	arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+	writtenArray->insert(arrayController);
+        starts[0] = 2;
+        arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+	writtenArray->insert(arrayController);
+	starts[1] = 1;
+        starts[0] = 0;
+        arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+	writtenArray->insert(arrayController);
+        starts[0] = 1;
+        arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+	writtenArray->insert(arrayController);
+        starts[0] = 2;
+	arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+        writtenArray->insert(arrayController);
+	starts[1] = 2;
+        starts[0] = 0;
+        arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+        writtenArray->insert(arrayController);
+        starts[0] = 1;
+        arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+        writtenArray->insert(arrayController);
+        starts[0] = 2;
+        arrayController = XdmfHDF5Controller::New("arraydata.h5", "TestingData", XdmfArrayType::Int32(), starts, strides, dimensions, dataspaces);
+        writtenArray->insert(arrayController);
+
+	shared_ptr<XdmfHDF5Writer> arrayHeavyWriter = XdmfHDF5Writer::New("arraydata.h5");
+	arrayHeavyWriter->setFileSizeLimit(10);
+	arrayHeavyWriter->setAllowSetSplitting(true);
+	arrayHeavyWriter->setMode(XdmfHDF5Writer::Hyperslab);
+	shared_ptr<XdmfWriter> arrayWriter = XdmfWriter::New("arraydata.xmf", arrayHeavyWriter);
+	arrayWriter->setLightDataLimit(5);
+	writtenArray->accept(arrayWriter);
+
+	writtenArray->release();
+	writtenArray->read();
+	std::cout << "after read" << std::endl;
+	std::cout << "array size = " << writtenArray->getSize() << std::endl;
+	assert(writtenArray->getSize() == 9000000);
+	for (int i = 0; i < (int)writtenArray->getSize(); ++i)
+        {
+                if (i != writtenArray->getValue<int>(i))
+		{
+			std::cout << i << " doesn't match " << writtenArray->getValue<int>(i) << std::endl;
+		}
+		assert(i == writtenArray->getValue<int>(i));
+        }
+
+
+	ftime(&tb);
+        int end = tb.millitm + (tb.time & 0xfffff) * 1000;
+
+	int nSpan = end - start;
+	if(nSpan < 0)
+		nSpan += 0x100000 * 1000;
+	std::cout << nSpan << std::endl;
+
+	return 0;
+}
diff --git a/tests/Cxx/ReadArray.cpp b/tests/Cxx/ReadArray.cpp
new file mode 100644
index 0000000..c12bd2e
--- /dev/null
+++ b/tests/Cxx/ReadArray.cpp
@@ -0,0 +1,61 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfDomain.hpp>
+#include <XdmfUnstructuredGrid.hpp>
+#include <XdmfRectilinearGrid.hpp>
+#include <XdmfGeometry.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfReader.hpp>
+#include <XdmfWriter.hpp>
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values);
+
+int main(int, char **)
+{
+	XdmfArray::addFunction("MAX", maximum);
+	shared_ptr<XdmfReader> testReader = XdmfReader::New();
+	/*
+	shared_ptr<XdmfArray> readArray = shared_dynamic_cast<XdmfArray>(testReader->read("array.xmf"));
+	std::cout << "Array ocntains " << readArray->getValuesString() << std::endl;
+	*/
+	shared_ptr<XdmfDomain> readDomain = shared_dynamic_cast<XdmfDomain>(testReader->read("array.xmf"));
+	std::cout << "pulling out unstructured grid" << std::endl;
+	shared_ptr<XdmfRectilinearGrid> readGrid = readDomain->getRectilinearGrid(0);
+	//std::cout << "pulling out geometry" << std::endl;
+	//shared_ptr<XdmfGeometry> readGeometry = readGrid->getGeometry();
+	std::cout << "pulling out dimensions" << std::endl;
+	std::vector<shared_ptr<XdmfArray> > readDimensions = readGrid->getCoordinates();
+	std::cout << "Geometry contains " << readDimensions[0]->getValuesString() << std::endl;
+	shared_ptr<XdmfWriter> testWriter = XdmfWriter::New("arrayoutput.xmf");
+	readGrid->accept(testWriter);
+	//readArray->accept(testWriter);
+	return 0;
+}
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values)
+{
+	if (values[0]->getArrayType() == XdmfArrayType::String())
+	{
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(values[0]->getValue<std::string>(0));
+		return returnArray;
+	}
+	else
+	{
+		double maxVal = values[0]->getValue<double>(0);
+		for (int i = 0; i < values.size(); i++)
+		{
+			for (int j = 0; j < values[i]->getSize(); j++)
+			{
+				if (maxVal < values[i]->getValue<double>(j))
+				{
+					maxVal = values[i]->getValue<double>(j);
+				}
+			}
+		}
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(maxVal);
+		return returnArray;
+	}
+}
diff --git a/tests/Cxx/ReadFunctionArray.cpp b/tests/Cxx/ReadFunctionArray.cpp
new file mode 100644
index 0000000..8c567b2
--- /dev/null
+++ b/tests/Cxx/ReadFunctionArray.cpp
@@ -0,0 +1,61 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfDomain.hpp>
+#include <XdmfUnstructuredGrid.hpp>
+#include <XdmfRectilinearGrid.hpp>
+#include <XdmfGeometry.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfReader.hpp>
+#include <XdmfWriter.hpp>
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values);
+
+int main(int, char **)
+{
+	XdmfArray::addFunction("MAX", maximum);
+	shared_ptr<XdmfReader> testReader = XdmfReader::New();
+	/*
+	shared_ptr<XdmfArray> readArray = shared_dynamic_cast<XdmfArray>(testReader->read("array.xmf"));
+	printf("Array ocntains %s\n", readArray->getValuesString());
+	*/
+	shared_ptr<XdmfDomain> readDomain = shared_dynamic_cast<XdmfDomain>(testReader->read("array.xmf"));
+	printf("pulling out unstructured grid\n");
+	shared_ptr<XdmfRectilinearGrid> readGrid = readDomain->getRectilinearGrid(0);
+	//printf("pulling out geometry\n");
+	//shared_ptr<XdmfGeometry> readGeometry = readGrid->getGeometry();
+	printf("pulling out dimensions\n");
+	std::vector<shared_ptr<XdmfArray> > readDimensions = readGrid->getCoordinates();
+	printf("Geometry contains %s\n", readDimensions[0]->getValuesString());
+	shared_ptr<XdmfWriter> testWriter = XdmfWriter::New("arrayoutput.xmf");
+	readGrid->accept(testWriter);
+	//readArray->accept(testWriter);
+	return 0;
+}
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values)
+{
+	if (values[0]->getArrayType() == XdmfArrayType::String())
+	{
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(values[0]->getValue<std::string>(0));
+		return returnArray;
+	}
+	else
+	{
+		double maxVal = values[0]->getValue<double>(0);
+		for (int i = 0; i < values.size(); i++)
+		{
+			for (int j = 0; j < values[i]->getSize(); j++)
+			{
+				if (maxVal < values[i]->getValue<double>(j))
+				{
+					maxVal = values[i]->getValue<double>(j);
+				}
+			}
+		}
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(maxVal);
+		return returnArray;
+	}
+}
diff --git a/tests/Cxx/TestXdmfAggregate.cpp b/tests/Cxx/TestXdmfAggregate.cpp
new file mode 100644
index 0000000..0ac68e1
--- /dev/null
+++ b/tests/Cxx/TestXdmfAggregate.cpp
@@ -0,0 +1,88 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAggregate.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include <map>
+#include <iostream>
+
+int main(int, char **)
+{
+	shared_ptr<XdmfAggregate> testAggregate = XdmfAggregate::New();
+
+	for (unsigned int iteration = 0; iteration < 5; ++iteration)
+	{
+		shared_ptr<XdmfArray> referenceArray = XdmfArray::New();
+
+		for (unsigned int i = 0; i < 27; ++i)
+		{
+			referenceArray->pushBack(i*(iteration + 1));
+		}
+		testAggregate->insert(referenceArray);
+	}
+
+	shared_ptr<XdmfAttribute> aggregateHolder = XdmfAttribute::New();
+
+	aggregateHolder->setReference(testAggregate);
+
+	aggregateHolder->setReadMode(XdmfArray::Reference);
+
+
+
+	shared_ptr<XdmfWriter> aggregateWriter = XdmfWriter::New("aggregate.xmf");
+
+	aggregateHolder->accept(aggregateWriter);
+
+	aggregateHolder->readReference();
+
+	std::cout << aggregateHolder->getValuesString() << std::endl;
+
+	shared_ptr<XdmfReader> aggregateReader = XdmfReader::New();
+
+	shared_ptr<XdmfItem> readItem = aggregateReader->read("aggregate.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= Attribute" << std::endl;
+
+	assert(readItem->getItemTag().compare("Attribute") == 0);
+
+	shared_ptr<XdmfAttribute> readAggregateHolder = shared_dynamic_cast<XdmfAttribute>(readItem);
+
+	readAggregateHolder->readReference();
+
+	std::cout << readAggregateHolder->getValuesString() << "\n?=\n" << aggregateHolder->getValuesString() << std::endl;
+
+	assert(readAggregateHolder->getValuesString().compare(aggregateHolder->getValuesString()) == 0);
+
+        shared_ptr<XdmfArray> aggregateHolder2 = XdmfArray::New();
+
+        aggregateHolder2->setReference(testAggregate);
+
+        aggregateHolder2->setReadMode(XdmfArray::Reference);
+
+        aggregateHolder2->accept(aggregateWriter);
+
+        aggregateHolder2->readReference();
+
+        std::cout << aggregateHolder2->getValuesString() << std::endl;
+
+        std::cout << "reading" << std::endl;
+
+        readItem = aggregateReader->read("aggregate.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= DataItem" << std::endl;
+
+        assert(readItem->getItemTag().compare("DataItem") == 0);
+
+        shared_ptr<XdmfArray> readAggregateHolder2 = shared_dynamic_cast<XdmfArray>(readItem);
+
+        readAggregateHolder2->readReference();
+
+        std::cout << readAggregateHolder2->getValuesString() 
+                  << "\n?=\n" << aggregateHolder2->getValuesString() << std::endl;
+
+        assert(readAggregateHolder2->getValuesString().compare(aggregateHolder2->getValuesString()) == 0);
+
+
+	return 0;
+}
diff --git a/tests/Cxx/TestXdmfAttribute.cpp b/tests/Cxx/TestXdmfAttribute.cpp
new file mode 100644
index 0000000..60185d4
--- /dev/null
+++ b/tests/Cxx/TestXdmfAttribute.cpp
@@ -0,0 +1,23 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  // Test != and == operators
+  std::cout << XdmfAttributeType::Scalar() << " ?= " << XdmfAttributeType::Scalar() << std::endl;
+  std::cout << XdmfAttributeType::Scalar() << " ?!= " << XdmfAttributeType::Vector() << std::endl;
+  assert(XdmfAttributeType::Scalar() == XdmfAttributeType::Scalar());
+  assert((XdmfAttributeType::Scalar() == XdmfAttributeType::Vector()) == false);
+  assert((XdmfAttributeType::Scalar() != XdmfAttributeType::Scalar()) == false);
+  assert(XdmfAttributeType::Scalar() != XdmfAttributeType::Vector());
+
+  shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+  std::cout << attribute->getType() << " ?= " << XdmfAttributeType::NoAttributeType() << std::endl;
+  assert(attribute->getType() == XdmfAttributeType::NoAttributeType());
+  attribute->setType(XdmfAttributeType::Scalar());
+  std::cout << attribute->getType() << " ?= " << XdmfAttributeType::Scalar() << std::endl;
+  assert(attribute->getType() == XdmfAttributeType::Scalar());
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfBinaryController.cpp b/tests/Cxx/TestXdmfBinaryController.cpp
new file mode 100644
index 0000000..956dd23
--- /dev/null
+++ b/tests/Cxx/TestXdmfBinaryController.cpp
@@ -0,0 +1,86 @@
+#include <fstream>
+#include <iostream>
+#include <vector>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+int main(int, char **)
+{
+  
+  //
+  // write binary file
+  //
+
+  std::vector<int> outputData;
+  outputData.push_back(1);
+  outputData.push_back(0);
+  outputData.push_back(-1);  
+  outputData.push_back(100);
+                       
+  std::ofstream output("binary.bin",
+                       std::ofstream::binary);
+
+  // Dummy data to test seek
+
+  std::vector<int> dummyData;
+  dummyData.push_back(5);
+  dummyData.push_back(-5);
+  dummyData.push_back(12);
+
+  output.write(reinterpret_cast<char *>(&(dummyData[0])),
+               sizeof(int) * dummyData.size());
+
+  output.write(reinterpret_cast<char *>(&(outputData[0])),
+               sizeof(int) * outputData.size());
+  output.close();
+
+  //
+  // read binary file using XdmfBinaryController
+  // Checking use of seek
+  //
+  shared_ptr<XdmfBinaryController> binaryController = 
+    XdmfBinaryController::New("binary.bin",
+                              XdmfArrayType::Int32(),
+                              XdmfBinaryController::NATIVE,
+                              sizeof(int) * dummyData.size(),
+                              std::vector<unsigned int>(1, 4));
+  
+  shared_ptr<XdmfArray> testArray = XdmfArray::New();
+  testArray->setHeavyDataController(binaryController);
+  testArray->read();
+
+  std::cout << testArray->getSize() << " ?= " << 4 << std::endl;
+  std::cout << testArray->getValue<int>(0) << " ?= " << outputData[0] << std::endl;
+  std::cout << testArray->getValue<int>(1) << " ?= " << outputData[1] << std::endl;
+  std::cout << testArray->getValue<int>(2) << " ?= " << outputData[2] << std::endl;
+  std::cout << testArray->getValue<int>(3) << " ?= " << outputData[3] << std::endl;
+
+  assert(testArray->getSize() == 4);
+  assert(testArray->getValue<int>(0) == outputData[0]);
+  assert(testArray->getValue<int>(1) == outputData[1]);
+  assert(testArray->getValue<int>(2) == outputData[2]);
+  assert(testArray->getValue<int>(3) == outputData[3]);
+  
+  testArray->release();
+
+  //
+  // output array to disk
+  //
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("TestXdmfBinary.xmf");
+  writer->setMode(XdmfWriter::DistributedHeavyData);
+  testArray->accept(writer);
+
+  //
+  // read array in
+  //
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfArray> array = 
+    shared_dynamic_cast<XdmfArray>(reader->read("TestXdmfBinary.xmf"));
+  std::cout << array << " ?!= " << "NULL" << std::endl;
+  assert(array != NULL);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfCurvilinearGrid.cpp b/tests/Cxx/TestXdmfCurvilinearGrid.cpp
new file mode 100644
index 0000000..a14828d
--- /dev/null
+++ b/tests/Cxx/TestXdmfCurvilinearGrid.cpp
@@ -0,0 +1,78 @@
+#include "XdmfArray.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfCurvilinearGrid> grid = XdmfCurvilinearGrid::New(2, 2, 3);
+  shared_ptr<XdmfArray> dimensions = grid->getDimensions();
+  std::cout << dimensions->getSize() << " ?= " << 3 << std::endl;
+  std::cout << dimensions->getValue<unsigned int>(0) << " ?= " << 2 << std::endl;
+  std::cout << dimensions->getValue<unsigned int>(1) << " ?= " << 2 << std::endl;
+  std::cout << dimensions->getValue<unsigned int>(2) << " ?= " << 3 << std::endl;
+  assert(dimensions->getSize() == 3);
+  assert(dimensions->getValue<unsigned int>(0) == 2);
+  assert(dimensions->getValue<unsigned int>(1) == 2);
+  assert(dimensions->getValue<unsigned int>(2) == 3);
+
+  shared_ptr<XdmfGeometry> geometry = grid->getGeometry();
+  geometry->setType(XdmfGeometryType::XYZ());
+  geometry->resize<int>(36);
+  const int coordinates[36] = {0, 0, 0, 1, 0, 0, 4, 0, 0, 0, 0, 2, 1, 0, 2, 4,
+			       0, 2, 0, 1, 0, 1, 1, 0, 4, 1, 0, 0, 1, 2, 1, 1,
+			       2, 4, 1, 2};
+  geometry->insert(0, &coordinates[0], 36);
+
+  // Check values under the hood
+
+  shared_ptr<const XdmfTopology> topology = grid->getTopology();
+  std::cout << topology->getNumberElements() << " ?= " << 2 << std::endl;
+  assert(topology->getNumberElements() == 2);
+  shared_ptr<const XdmfTopologyType> topologyType = topology->getType();
+  std::cout << topologyType->getNodesPerElement() << " ?= " << 8 << std::endl;
+  assert(topologyType->getNodesPerElement() == 8);
+
+  std::cout << geometry->getNumberPoints() << " ?= " << 12 << std::endl;
+  assert(geometry->getNumberPoints() == 12);
+  shared_ptr<const XdmfGeometryType> geometryType = geometry->getType();
+  std::cout << geometryType->getDimensions() << " ?= " << 3 << std::endl;
+  assert(geometryType->getDimensions() == 3);
+
+  // Input / Output
+
+  shared_ptr<XdmfWriter> writer =
+    XdmfWriter::New("TestXdmfCurvilinearGrid1.xmf");
+  grid->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfCurvilinearGrid> grid2 = 
+    shared_dynamic_cast<XdmfCurvilinearGrid>
+    (reader->read("TestXdmfCurvilinearGrid1.xmf"));
+
+  shared_ptr<XdmfWriter> writer2 = 
+    XdmfWriter::New("TestXdmfCurvilinearGrid2.xmf");
+  grid2->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfCurvilinearGrid1.xmf",
+                                         "TestXdmfCurvilinearGrid2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfCurvilinearGrid1.xmf",
+					    "TestXdmfCurvilinearGrid2.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfFunction.cpp b/tests/Cxx/TestXdmfFunction.cpp
new file mode 100644
index 0000000..3be357a
--- /dev/null
+++ b/tests/Cxx/TestXdmfFunction.cpp
@@ -0,0 +1,349 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include <map>
+#include <iostream>
+#include <iomanip>
+#include <cmath>
+#include "string.h"
+#include "stdio.h"
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values);
+
+shared_ptr<XdmfArray> prepend(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+
+int main(int, char **)
+{
+	std::string functionExpression = "MAX(A,B)@(A#B)";
+
+	int numOperations = XdmfFunction::addOperation('@', (shared_ptr<XdmfArray>(*)(shared_ptr<XdmfArray>, shared_ptr<XdmfArray>))prepend, 2);
+	std::cout << "Number of operations after addition: " << numOperations << std::endl;
+	int numFunctions = XdmfFunction::addFunction("MAX", (shared_ptr<XdmfArray>(*)(std::vector<shared_ptr<XdmfArray> >))maximum);
+	std::cout << "Number of functions after addition: " << numFunctions << std::endl;
+
+	std::map<std::string, shared_ptr<XdmfArray> > functionVariables;
+
+	shared_ptr<XdmfArray> variable1 = XdmfArray::New();
+
+
+
+	for (unsigned int i = 0; i < 15; ++i)
+	{
+		variable1->pushBack(i*3);
+	}
+
+	functionVariables["A"] = variable1;
+
+
+
+        shared_ptr<XdmfArray> variable2 = XdmfArray::New();
+
+        for (unsigned int i = 0; i < 15; ++i)
+        {
+                variable2->pushBack(i*5);
+        }
+
+        functionVariables["B"] = variable2;
+
+
+
+	shared_ptr<XdmfFunction> testFunction = XdmfFunction::New(functionExpression, functionVariables);
+
+	shared_ptr<XdmfAttribute> functionHolder = XdmfAttribute::New();
+
+	functionHolder->setReference(testFunction);
+
+	functionHolder->setReadMode(XdmfArray::Reference);
+
+
+
+	shared_ptr<XdmfWriter> functionWriter = XdmfWriter::New("function.xmf");
+
+	functionHolder->accept(functionWriter);
+
+
+
+	functionHolder->readReference();
+
+	std::cout << functionHolder->getValuesString() << std::endl;
+
+	shared_ptr<XdmfReader> functionReader = XdmfReader::New();
+
+	shared_ptr<XdmfItem> readItem = functionReader->read("function.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= Attribute" << std::endl;
+
+	assert(readItem->getItemTag().compare("Attribute") == 0);
+
+	shared_ptr<XdmfAttribute> readFunctionHolder = shared_dynamic_cast<XdmfAttribute>(readItem);
+
+	readFunctionHolder->release();
+
+        std::cout << "before reading: " << readFunctionHolder->getValuesString() << std::endl;
+
+	readFunctionHolder->readReference();
+
+	std::cout << "check: " << readFunctionHolder->getValuesString() << " = " << functionHolder->getValuesString() << std::endl;
+
+	assert(readFunctionHolder->getValuesString().compare(functionHolder->getValuesString()) == 0);
+
+
+        shared_ptr<XdmfSet> functionHolder2 = XdmfSet::New();
+
+        functionHolder2->setReference(testFunction);
+
+        functionHolder2->setReadMode(XdmfArray::Reference);
+
+        functionHolder2->accept(functionWriter);
+
+        functionHolder2->readReference();
+
+        std::cout << functionHolder2->getValuesString() << std::endl;
+
+        readItem = functionReader->read("function.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= Set" << std::endl;
+
+        assert(readItem->getItemTag().compare("Set") == 0);
+
+        shared_ptr<XdmfSet> readFunctionHolder2 = shared_dynamic_cast<XdmfSet>(readItem);
+
+        readFunctionHolder2->release();
+
+        std::cout << "before reading: " << readFunctionHolder2->getValuesString() << std::endl;
+
+        readFunctionHolder2->readReference();
+
+        std::cout << "check: " << readFunctionHolder2->getValuesString() << " = " << functionHolder2->getValuesString() << std::endl;
+
+        assert(readFunctionHolder2->getValuesString().compare(functionHolder2->getValuesString()) == 0);
+
+
+
+        shared_ptr<XdmfArray> functionHolder3 = XdmfArray::New();
+
+        functionHolder3->setReference(testFunction);
+
+        functionHolder3->setReadMode(XdmfArray::Reference);
+
+        functionHolder3->accept(functionWriter);
+
+        functionHolder3->readReference();
+
+        std::cout << functionHolder3->getValuesString() << std::endl;
+
+        readItem = functionReader->read("function.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= DataItem" << std::endl;
+
+        assert(readItem->getItemTag().compare("DataItem") == 0);
+
+        shared_ptr<XdmfArray> readFunctionHolder3 = shared_dynamic_cast<XdmfArray>(readItem);
+
+        readFunctionHolder3->release();
+
+        std::cout << "before reading: " << readFunctionHolder3->getValuesString() << std::endl;
+
+        readFunctionHolder3->readReference();
+
+        std::cout << "check: " << readFunctionHolder3->getValuesString() << " = " << functionHolder3->getValuesString() << std::endl;
+
+        assert(readFunctionHolder3->getValuesString().compare(functionHolder3->getValuesString()) == 0);
+
+
+
+        // Testing individual Functions/Operations
+
+        shared_ptr<XdmfArray> valArray1 = XdmfArray::New();
+        valArray1->pushBack(-0.5);
+        shared_ptr<XdmfArray> valArray2 = XdmfArray::New();
+        valArray2->pushBack(-0.25);
+        shared_ptr<XdmfArray> valArray3 = XdmfArray::New();
+        valArray3->pushBack((double)2);
+
+        std::map<std::string, shared_ptr<XdmfArray> > testVals;
+
+        testVals["A"] = valArray1;
+        testVals["B"] = valArray2;
+        testVals["C"] = valArray3;
+
+        shared_ptr<XdmfArray> functionResult;
+        double checkResult;
+        double compareResult;
+
+        // Trig functions have issues with being consistent to the degree of 10^-16
+        // Ensure that the functions are accurate to the degree of 10^-15
+
+        printf("Accepted Tolerance 10^15\n");
+
+        printf("ABS(-0.5) = %lf\n", std::abs((double)-0.5));
+        checkResult = std::abs((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("ABS(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("ARCCOS(-0.5) = %lf\n", std::acos((double)-0.5));
+        checkResult = std::acos((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("ACOS(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("ARCSIN(-0.5) = %lf\n", std::asin((double)-0.5));
+        checkResult = std::asin((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("ASIN(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("ARCTAN(-0.5) = %lf\n", std::atan((double)-0.5));
+        checkResult = std::atan((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("ATAN(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("EXP(-0.5, 2) = %lf\n", std::pow((double)-0.5, 2));
+        checkResult = std::pow((double)-0.5, 2);
+        functionResult = XdmfFunction::evaluateExpression("EXP(A, C)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("COS(-0.5) = %lf\n", std::cos((double)-0.5));
+        checkResult = std::cos((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("COS(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("LOG(2) = %lf\n", std::log((double)2));
+        checkResult = std::log((double)2);
+        functionResult = XdmfFunction::evaluateExpression("LOG(C)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+        printf("LOG(2, 4) = %lf\n", std::log((double)2)/std::log((double)4));
+        checkResult = std::log((double)2)/std::log((double)4);
+        functionResult = XdmfFunction::evaluateExpression("LOG(C, 4)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("SQRT(2) = %lf\n", std::sqrt((double)2));
+        checkResult = std::sqrt((double)2);
+        functionResult = XdmfFunction::evaluateExpression("SQRT(C)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("SIN(-0.5) = %lf\n", std::sin((double)-0.5));
+        checkResult = std::sin((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("SIN(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("TAN(-0.5) = %lf\n", std::tan((double)-0.5));
+        checkResult = std::tan((double)-0.5);
+        functionResult = XdmfFunction::evaluateExpression("TAN(A)", testVals);
+        compareResult = functionResult->getValue<double>(0);
+        checkResult = floor(checkResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        compareResult = floor(compareResult * pow((double)10, 15) + 0.5) / pow((double)10, 15);
+        printf("array contains: %s\n", functionResult->getValuesString().c_str());
+        printf("%.15lf ?= %.15lf\n", checkResult, compareResult);
+        assert(checkResult == compareResult);
+
+        printf("JOIN(A, B, C)\n");
+        printf("array contains: %s\n", XdmfFunction::evaluateExpression("JOIN(A, B, C)", testVals)->getValuesString().c_str());
+        assert(strcmp(XdmfFunction::evaluateExpression("JOIN(A, B, C)", testVals)->getValuesString().c_str(), "-0.5 -0.25 2") == 0);
+
+        printf("A + B = %lf\n", -0.5 + -0.25);
+        printf("array contains: %s\n", XdmfFunction::evaluateExpression("A+B", testVals)->getValuesString().c_str());
+        assert(strcmp(XdmfFunction::evaluateExpression("A+B", testVals)->getValuesString().c_str(), "-0.75") == 0);
+
+        printf("A - B = %lf\n", -0.5 - -0.25);
+        printf("array contains: %s\n", XdmfFunction::evaluateExpression("A-B", testVals)->getValuesString().c_str());
+        assert(strcmp(XdmfFunction::evaluateExpression("A-B", testVals)->getValuesString().c_str(), "-0.25") == 0);
+
+        printf("A * B = %lf\n", -0.5 * -0.25);
+        printf("array contains: %s\n", XdmfFunction::evaluateExpression("A*B", testVals)->getValuesString().c_str());
+        assert(strcmp(XdmfFunction::evaluateExpression("A*B", testVals)->getValuesString().c_str(), "0.125") == 0);
+
+        printf("A / B = %lf\n", -0.5 / -0.25);
+        printf("array contains: %s\n", XdmfFunction::evaluateExpression("A/B", testVals)->getValuesString().c_str());
+        assert(strcmp(XdmfFunction::evaluateExpression("A/B", testVals)->getValuesString().c_str(), "2") == 0);
+
+	return 0;
+}
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values)
+{
+	if (values[0]->getArrayType() == XdmfArrayType::String())
+	{
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(values[0]->getValue<std::string>(0));
+		return returnArray;
+	}
+	else
+	{
+		double maxVal = values[0]->getValue<double>(0);
+		for (unsigned int i = 0; i < values.size(); ++i)
+		{
+			for (unsigned int j = 0; j < values[i]->getSize(); ++j)
+			{
+				if (maxVal < values[i]->getValue<double>(j))
+				{
+					maxVal = values[i]->getValue<double>(j);
+				}
+			}
+		}
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(maxVal);
+		return returnArray;
+	}
+}
+
+shared_ptr<XdmfArray> prepend(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+	//joins into new array and returns it
+	shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+	returnArray->insert(0, val2, 0, val2->getSize(),  1, 1);
+	returnArray->insert(val2->getSize(), val1, 0, val1->getSize(), 1, 1);
+	return returnArray;
+}
diff --git a/tests/Cxx/TestXdmfGeometry.cpp b/tests/Cxx/TestXdmfGeometry.cpp
new file mode 100644
index 0000000..3a2fd92
--- /dev/null
+++ b/tests/Cxx/TestXdmfGeometry.cpp
@@ -0,0 +1,33 @@
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfSharedPtr.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+  // Test != and == operators
+  std::cout << XdmfGeometryType::XYZ() << " ?= " << XdmfGeometryType::XYZ() << std::endl;
+  std::cout << XdmfGeometryType::XYZ() << " ?!= " << XdmfGeometryType::XY() << std::endl;
+  assert(XdmfGeometryType::XYZ() == XdmfGeometryType::XYZ());
+  assert((XdmfGeometryType::XYZ() == XdmfGeometryType::XY()) == false);
+  assert((XdmfGeometryType::XYZ() != XdmfGeometryType::XYZ()) == false);
+  assert(XdmfGeometryType::XYZ() != XdmfGeometryType::XY());
+
+  shared_ptr<XdmfGeometry> geometry = XdmfGeometry::New();
+  std::cout << geometry->getType() << " ?= " << XdmfGeometryType::NoGeometryType() << std::endl;
+  std::cout << geometry->getType()->getDimensions() << " ?= " << 0 << std::endl;
+  std::cout << geometry->getType()->getName() << " ?= None" << std::endl;
+  assert(geometry->getType() == XdmfGeometryType::NoGeometryType());
+  assert(geometry->getType()->getDimensions() == 0);
+  assert(geometry->getType()->getName().compare("None") == 0);
+  geometry->setType(XdmfGeometryType::XYZ());
+  std::cout << geometry->getType() << " ?= " << XdmfGeometryType::XYZ() << std::endl;
+  std::cout << geometry->getType()->getDimensions() << " ?= " << 3 << std::endl;
+  std::cout << geometry->getType()->getName() << " ?= XYZ" << std::endl;
+  assert(geometry->getType() == XdmfGeometryType::XYZ());
+  assert(geometry->getType()->getDimensions() == 3);
+  assert(geometry->getType()->getName().compare("XYZ") == 0);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfGraph.cpp b/tests/Cxx/TestXdmfGraph.cpp
new file mode 100644
index 0000000..af0eb57
--- /dev/null
+++ b/tests/Cxx/TestXdmfGraph.cpp
@@ -0,0 +1,69 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+
+  shared_ptr<XdmfGraph> graph = XdmfGraph::New(3);
+  graph->setName("foo");
+  shared_ptr<XdmfArray> rowPointer = graph->getRowPointer();
+  shared_ptr<XdmfArray> columnIndex = graph->getColumnIndex();
+  shared_ptr<XdmfArray> values = graph->getValues();
+  rowPointer->insert<unsigned int>(0, 0);
+  rowPointer->insert<unsigned int>(1, 0);
+  rowPointer->insert<unsigned int>(2, 2);
+  rowPointer->insert<unsigned int>(3, 3);
+  columnIndex->pushBack<unsigned int>(1);
+  columnIndex->pushBack<unsigned int>(2);
+  columnIndex->pushBack<unsigned int>(0);
+  values->pushBack<double>(5.0);
+  values->pushBack<double>(6.0);
+  values->pushBack<double>(-1.0);
+
+  shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+  attribute->setName("Node Weight");
+  attribute->setCenter(XdmfAttributeCenter::Node());
+  attribute->setType(XdmfAttributeType::Scalar());
+  attribute->pushBack<double>(0.0);
+  attribute->pushBack<double>(1.0);
+  attribute->pushBack<double>(2.0);
+  graph->insert(attribute);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("TestXdmfGraph.xmf");
+  graph->accept(writer);
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfGraph> readGraph = 
+    shared_dynamic_cast<XdmfGraph>(reader->read("TestXdmfGraph.xmf"));
+
+  if (readGraph)
+  {
+    std::cout << "graph exists" << std::endl;
+  }
+  else
+  {
+    std::cout << "graph does not exist" << std::endl;
+  }
+
+  std::cout << readGraph->getNumberNodes() << " ?= " << graph->getNumberNodes() << std::endl;
+  std::cout << readGraph->getNumberAttributes() << " ?= " << graph->getNumberAttributes() << std::endl;
+
+  assert(readGraph);
+  assert(readGraph->getNumberNodes() == graph->getNumberNodes());
+  assert(readGraph->getNumberAttributes() == graph->getNumberAttributes());
+  
+  shared_ptr<XdmfAttribute> readAttribute = readGraph->getAttribute(0);
+
+  std::cout << readAttribute->getName() << " ?= " << attribute->getName() << std::endl;
+  std::cout << readAttribute->getSize() << " ?= " << attribute->getSize() << std::endl;
+
+  assert(readAttribute->getName().compare(attribute->getName()) == 0);
+  assert(readAttribute->getSize() == attribute->getSize());
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfGridCollection.cpp b/tests/Cxx/TestXdmfGridCollection.cpp
new file mode 100644
index 0000000..fe6c748
--- /dev/null
+++ b/tests/Cxx/TestXdmfGridCollection.cpp
@@ -0,0 +1,112 @@
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+  // Test != and == operators
+  std::cout << XdmfGridCollectionType::Spatial() << " ?= " << XdmfGridCollectionType::Spatial() << std::endl;
+  std::cout << XdmfGridCollectionType::Spatial() << " ?!= " << XdmfGridCollectionType::Temporal() << std::endl;
+  assert(XdmfGridCollectionType::Spatial() == 
+         XdmfGridCollectionType::Spatial());
+  assert((XdmfGridCollectionType::Spatial() ==
+         XdmfGridCollectionType::Temporal()) == false);
+  assert((XdmfGridCollectionType::Spatial() !=
+         XdmfGridCollectionType::Spatial()) == false);
+  assert(XdmfGridCollectionType::Spatial() !=
+         XdmfGridCollectionType::Temporal());
+
+  shared_ptr<XdmfGridCollection> gridCollection = XdmfGridCollection::New();
+
+  gridCollection->setName("Collection2");
+  std::cout << gridCollection->getName() << " ?= " << "Collection2" << std::endl;
+  assert(gridCollection->getName().compare("Collection2") == 0);
+
+  shared_ptr<XdmfUnstructuredGrid> childGrid1 = 
+    XdmfTestDataGenerator::createHexahedron();
+  shared_ptr<XdmfUnstructuredGrid> childGrid2 =
+    XdmfTestDataGenerator::createHexahedron();
+
+  std::cout << gridCollection->getNumberUnstructuredGrids() << " ?= " << 0 << std::endl;
+  assert(gridCollection->getNumberUnstructuredGrids() == 0);
+  gridCollection->insert(childGrid1);
+  std::cout << gridCollection->getNumberUnstructuredGrids() << " ?= " << 1 << std::endl;
+  std::cout << gridCollection->getUnstructuredGrid(0) << " ?= " << childGrid1 << std::endl;
+  assert(gridCollection->getNumberUnstructuredGrids() == 1);
+  assert(gridCollection->getUnstructuredGrid(0) == childGrid1);
+  gridCollection->removeUnstructuredGrid(0);
+  std::cout << gridCollection->getNumberUnstructuredGrids() << " ?= " << 0 << std::endl;
+  assert(gridCollection->getNumberUnstructuredGrids() == 0);
+  gridCollection->insert(childGrid1);
+  gridCollection->insert(childGrid2);
+
+  shared_ptr<XdmfInformation> information = XdmfInformation::New("Key", 
+                                                                 "Value");
+  gridCollection->insert(information);
+
+  gridCollection->setType(XdmfGridCollectionType::Temporal());
+  std::cout << gridCollection->getType() << " ?= " << XdmfGridCollectionType::Temporal() << std::endl;
+  assert(gridCollection->getType() == XdmfGridCollectionType::Temporal());
+
+  shared_ptr<XdmfWriter> writer = 
+    XdmfWriter::New("TestXdmfGridCollection1.xmf");
+  gridCollection->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfGridCollection> gridCollection2 =
+    shared_dynamic_cast<XdmfGridCollection>
+    (reader->read("TestXdmfGridCollection1.xmf"));
+
+  shared_ptr<XdmfWriter> writer2 =
+    XdmfWriter::New("TestXdmfGridCollection2.xmf");
+  gridCollection2->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfGridCollection1.xmf",
+                                         "TestXdmfGridCollection2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfGridCollection1.xmf",
+                                            "TestXdmfGridCollection2.xmf"));
+
+  shared_ptr<XdmfWriter> writer3 =
+    XdmfWriter::New("TestXdmfGridCollectionHDF1.xmf");
+  writer3->setLightDataLimit(0);
+  gridCollection->accept(writer3);
+
+  shared_ptr<XdmfGridCollection> gridCollection3 =
+    shared_dynamic_cast<XdmfGridCollection>
+    (reader->read("TestXdmfGridCollectionHDF1.xmf"));
+
+  shared_ptr<XdmfWriter> writer4 =
+    XdmfWriter::New("TestXdmfGridCollectionHDF2.xmf");
+  writer4->setLightDataLimit(0);
+  writer4->setMode(XdmfWriter::DistributedHeavyData);
+  gridCollection3->accept(writer4);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfGridCollectionHDF1.xmf",
+                                         "TestXdmfGridCollectionHDF2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfGridCollectionHDF1.xmf",
+                                            "TestXdmfGridCollectionHDF2.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfGridController.cpp b/tests/Cxx/TestXdmfGridController.cpp
new file mode 100644
index 0000000..957dc1f
--- /dev/null
+++ b/tests/Cxx/TestXdmfGridController.cpp
@@ -0,0 +1,411 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfError.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridController.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+
+  shared_ptr<XdmfGridCollection> collection = XdmfGridCollection::New();
+
+  for (unsigned int i = 0; i < 5; ++i)
+  {
+    shared_ptr<XdmfUnstructuredGrid> colgrid = XdmfUnstructuredGrid::New();
+
+    collection->insert(colgrid);
+
+
+    shared_ptr<XdmfGeometry> colgeometry = XdmfGeometry::New();
+
+    for (unsigned int j = 0; j < 9; ++j)
+    {
+      colgeometry->pushBack(j+i);
+    }
+
+    colgeometry->setType(XdmfGeometryType::XYZ());
+
+    colgrid->setGeometry(colgeometry);
+
+    shared_ptr<XdmfTopology> coltopology = XdmfTopology::New();
+
+    for (unsigned int j = 0; j < 3; ++j)
+    {
+      coltopology->pushBack(j);
+    }
+
+    coltopology->setType(XdmfTopologyType::Triangle());
+
+    colgrid->setTopology(coltopology);
+
+    shared_ptr<XdmfAttribute> colattr = XdmfAttribute::New();
+
+    for (unsigned int j = 0; j < 3; ++j)
+    {
+      colattr->pushBack(j+i);
+    }
+
+    colattr->setType(XdmfAttributeType::Scalar());
+    colattr->setCenter(XdmfAttributeCenter::Node());
+
+    colgrid->insert(colattr);
+  }
+
+  domain->insert(collection);
+
+  shared_ptr<XdmfCurvilinearGrid> curvgrid = XdmfCurvilinearGrid::New(10, 10);
+
+  shared_ptr<XdmfGeometry> curvgeometry = XdmfGeometry::New();
+
+  for (unsigned int i = 0; i < 9; ++i)
+  {
+    curvgeometry->pushBack(i);
+  }
+
+  curvgeometry->setType(XdmfGeometryType::XYZ());
+
+  curvgrid->setGeometry(curvgeometry);
+
+  shared_ptr<XdmfAttribute> curvattr = XdmfAttribute::New();
+
+  for (unsigned int i = 0; i < 100; ++i)
+  {
+    curvattr->pushBack(i);
+  }
+
+  curvattr->setType(XdmfAttributeType::Scalar());
+  curvattr->setCenter(XdmfAttributeCenter::Node());
+
+  curvgrid->insert(curvattr);
+
+  domain->insert(curvgrid);
+
+  shared_ptr<XdmfArray> xCoordinates = XdmfArray::New();
+  shared_ptr<XdmfArray> yCoordinates = XdmfArray::New();
+  for (unsigned int i = 0; i < 10; ++i)
+  {
+    xCoordinates->pushBack(i);
+    yCoordinates->pushBack(i);
+  }
+
+  shared_ptr<XdmfRectilinearGrid> rectgrid = XdmfRectilinearGrid::New(xCoordinates, yCoordinates);
+
+  domain->insert(rectgrid);
+
+  shared_ptr<XdmfAttribute> rectattr = XdmfAttribute::New();
+
+  for (unsigned int i = 0; i < 100; ++i)
+  {
+    rectattr->pushBack(i);
+  }
+
+  rectattr->setType(XdmfAttributeType::Scalar());
+  rectattr->setCenter(XdmfAttributeCenter::Node());
+
+  rectgrid->insert(rectattr);
+
+  shared_ptr<XdmfRegularGrid> reggrid = XdmfRegularGrid::New(1, 1, 10, 10, 0, 0);
+
+  domain->insert(reggrid);
+
+  shared_ptr<XdmfAttribute> regattr = XdmfAttribute::New();
+
+  for (unsigned int i = 0; i < 100; ++i)
+  {
+    regattr->pushBack(i);
+  }
+
+  regattr->setType(XdmfAttributeType::Scalar());
+  regattr->setCenter(XdmfAttributeCenter::Node());
+
+  reggrid->insert(regattr);
+
+  shared_ptr<XdmfUnstructuredGrid> ungrid = XdmfUnstructuredGrid::New();
+
+  domain->insert(ungrid);
+
+  shared_ptr<XdmfGeometry> ungeometry = XdmfGeometry::New();
+
+  for (unsigned int i = 0; i < 9; ++i)
+  {
+    ungeometry->pushBack(i);
+  }
+
+  ungeometry->setType(XdmfGeometryType::XYZ());
+
+  ungrid->setGeometry(ungeometry);
+
+  shared_ptr<XdmfTopology> untopology = XdmfTopology::New();
+
+  for (unsigned int i = 0; i < 3; ++i)
+  {
+    untopology->pushBack(i);
+  }
+
+  untopology->setType(XdmfTopologyType::Triangle());
+
+  ungrid->setTopology(untopology);
+
+  shared_ptr<XdmfAttribute> unattr = XdmfAttribute::New();
+
+  for (unsigned int i = 0; i < 3; ++i)
+  {
+    unattr->pushBack(i);
+  }
+
+  unattr->setType(XdmfAttributeType::Scalar());
+  unattr->setCenter(XdmfAttributeCenter::Node());
+
+  ungrid->insert(unattr);
+
+//  shared_ptr<XdmfCurvilinearGrid> curvgrid = XdmfCurvilinearGrid::New();
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("gridControllerReference.xmf");
+
+  domain->accept(writer);
+
+  std::cout << "Finished writing reference file" << std::endl;
+
+/*
+XdmfGridCollection
+XdmfCurvilinearGrid
+XdmfGraph
+XdmfRectilinearGrid
+XdmfRegularGrid
+XdmfUnstructuredGrid
+*/
+
+
+  shared_ptr<XdmfDomain> equalDomain = XdmfDomain::New();
+
+  shared_ptr<XdmfGridCollection> equalCollection = XdmfGridCollection::New();
+
+  shared_ptr<XdmfGridController> collectionController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[1]");
+
+  equalCollection->setGridController(collectionController);
+
+  equalDomain->insert(equalCollection);
+
+  shared_ptr<XdmfCurvilinearGrid> equalCurvGrid = XdmfCurvilinearGrid::New(0, 0);
+
+  shared_ptr<XdmfGridController> curvGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[2]");
+
+  equalCurvGrid->setGridController(curvGridController);
+
+  equalDomain->insert(equalCurvGrid);
+
+  shared_ptr<XdmfArray> placeholderXArray = XdmfArray::New();
+  shared_ptr<XdmfArray> placeholderYArray = XdmfArray::New();
+
+  shared_ptr<XdmfRectilinearGrid> equalRectGrid = XdmfRectilinearGrid::New(placeholderXArray,
+                                                                           placeholderYArray);
+
+  shared_ptr<XdmfGridController> rectGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[3]");
+
+  equalRectGrid->setGridController(rectGridController);
+
+  equalDomain->insert(equalRectGrid);
+
+  shared_ptr<XdmfRegularGrid> equalRegGrid = XdmfRegularGrid::New(0, 0, 0, 0, 0, 0);
+
+  shared_ptr<XdmfGridController> regGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[4]");
+
+  equalRegGrid->setGridController(regGridController);
+
+  equalDomain->insert(equalRegGrid);
+
+  shared_ptr<XdmfUnstructuredGrid> equalUnGrid = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfGridController> unGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[5]");
+
+  equalUnGrid->setGridController(unGridController);
+
+  equalDomain->insert(equalUnGrid);
+
+  shared_ptr<XdmfWriter> controllerWriter = XdmfWriter::New("gridController.xmf");
+
+  equalDomain->accept(controllerWriter);
+
+
+
+
+
+
+
+
+
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+
+  shared_ptr<XdmfDomain> readReference = shared_dynamic_cast<XdmfDomain>(reader->read("gridControllerReference.xmf"));
+
+  shared_ptr<XdmfDomain> readControllerDomain = shared_dynamic_cast<XdmfDomain>(reader->read("gridController.xmf"));
+
+  shared_ptr<XdmfGridCollection> collectionReference = readReference->getGridCollection(0);
+
+  shared_ptr<XdmfGridCollection> compareCollection = readControllerDomain->getGridCollection(0);
+
+  compareCollection->read();
+
+  std::cout << compareCollection->getNumberUnstructuredGrids() << " ?= " << collectionReference->getNumberUnstructuredGrids() << std::endl;
+
+  assert(compareCollection->getNumberUnstructuredGrids() == collectionReference->getNumberUnstructuredGrids());
+
+
+  for (unsigned int i = 0; i < compareCollection->getNumberUnstructuredGrids(); ++i)
+  {
+    shared_ptr<XdmfUnstructuredGrid> unCollectionReference = collectionReference->getUnstructuredGrid(i);
+    shared_ptr<XdmfUnstructuredGrid> unCollectionRead = compareCollection->getUnstructuredGrid(i);
+
+    std::cout << unCollectionRead->getGeometry()->getValuesString() << " ?= " << unCollectionReference->getGeometry()->getValuesString() << std::endl;
+
+    assert(unCollectionRead->getGeometry()->getValuesString().compare(unCollectionReference->getGeometry()->getValuesString()) == 0);
+
+    std::cout << unCollectionRead->getTopology()->getValuesString() << " ?= " << unCollectionReference->getTopology()->getValuesString() << std::endl;
+
+    assert(unCollectionRead->getTopology()->getValuesString().compare(unCollectionReference->getTopology()->getValuesString()) == 0);
+
+    std::cout << unCollectionRead->getAttribute(0)->getValuesString() << " ?= " << unCollectionReference->getAttribute(0)->getValuesString() << std::endl;
+
+    assert(unCollectionRead->getAttribute(0)->getValuesString().compare(unCollectionReference->getAttribute(0)->getValuesString()) == 0);
+  }
+
+  compareCollection->release();
+
+
+
+
+  shared_ptr<XdmfUnstructuredGrid> unCompareReference = readReference->getUnstructuredGrid(0);
+
+  shared_ptr<XdmfUnstructuredGrid> unCompare = readControllerDomain->getUnstructuredGrid(0);
+
+  unCompare->read();
+
+  std::cout << unCompare->getGeometry()->getValuesString() << " ?= " << unCompareReference->getGeometry()->getValuesString() << std::endl;
+
+  assert(unCompare->getGeometry()->getValuesString().compare(unCompareReference->getGeometry()->getValuesString()) == 0);
+
+  std::cout << unCompare->getTopology()->getValuesString() << " ?= " << unCompareReference->getTopology()->getValuesString() << std::endl;
+
+  assert(unCompare->getTopology()->getValuesString().compare(unCompareReference->getTopology()->getValuesString()) == 0);
+
+  std::cout << unCompare->getAttribute(0)->getValuesString() << " ?= " << unCompareReference->getAttribute(0)->getValuesString() << std::endl;
+
+  assert(unCompare->getAttribute(0)->getValuesString().compare(unCompareReference->getAttribute(0)->getValuesString()) == 0);
+
+  unCompare->release();
+
+  shared_ptr<XdmfRegularGrid> regCompareReference = readReference->getRegularGrid(0);
+
+  shared_ptr<XdmfRegularGrid> regCompare = readControllerDomain->getRegularGrid(0);
+
+  regCompare->read();
+
+  std::cout << regCompare->getOrigin()->getValuesString() << " ?= " << regCompareReference->getOrigin()->getValuesString() << std::endl;
+
+  assert(regCompare->getOrigin()->getValuesString().compare(regCompareReference->getOrigin()->getValuesString()) == 0);
+
+  std::cout << regCompare->getDimensions()->getValuesString() << " ?= " << regCompareReference->getDimensions()->getValuesString() << std::endl;
+
+  assert(regCompare->getDimensions()->getValuesString().compare(regCompareReference->getDimensions()->getValuesString()) == 0);
+
+  std::cout << regCompare->getBrickSize()->getValuesString() << " ?= " << regCompareReference->getBrickSize()->getValuesString() << std::endl;
+
+  assert(regCompare->getBrickSize()->getValuesString().compare(regCompareReference->getBrickSize()->getValuesString()) == 0);
+
+  std::cout << regCompare->getAttribute(0)->getValuesString() << " ?= " << regCompareReference->getAttribute(0)->getValuesString() << std::endl;
+
+  assert(regCompare->getAttribute(0)->getValuesString().compare(regCompareReference->getAttribute(0)->getValuesString()) == 0);
+
+  regCompare->release();
+
+  shared_ptr<XdmfRectilinearGrid> rectCompareReference = readReference->getRectilinearGrid(0);
+
+  shared_ptr<XdmfRectilinearGrid> rectCompare = readControllerDomain->getRectilinearGrid(0);
+
+  rectCompare->read();
+
+  std::cout << rectCompare->getAttribute(0)->getValuesString() << " ?= " << rectCompareReference->getAttribute(0)->getValuesString() << std::endl;
+
+  assert(rectCompare->getAttribute(0)->getValuesString().compare(rectCompareReference->getAttribute(0)->getValuesString()) == 0);
+
+  std::cout << rectCompare->getCoordinates(0)->getValuesString() << " ?= " << rectCompareReference->getCoordinates(0)->getValuesString() << std::endl;
+
+  assert(rectCompare->getCoordinates(0)->getValuesString().compare(rectCompareReference->getCoordinates(0)->getValuesString()) == 0);
+
+  std::cout << rectCompare->getCoordinates(1)->getValuesString() << " ?= " << rectCompareReference->getCoordinates(1)->getValuesString() << std::endl;
+
+  assert(rectCompare->getCoordinates(1)->getValuesString().compare(rectCompareReference->getCoordinates(1)->getValuesString()) == 0);
+
+  rectCompare->release();
+
+  shared_ptr<XdmfCurvilinearGrid> curvCompareReference = readReference->getCurvilinearGrid(0);
+
+  shared_ptr<XdmfCurvilinearGrid> curvCompare = readControllerDomain->getCurvilinearGrid(0);
+
+  curvCompare->read();
+
+  std::cout << curvCompare->getGeometry()->getValuesString() << " ?= " << curvCompareReference->getGeometry()->getValuesString() << std::endl;
+
+  assert(curvCompare->getGeometry()->getValuesString().compare(curvCompareReference->getGeometry()->getValuesString()) == 0);
+
+  std::cout << curvCompare->getAttribute(0)->getValuesString() << " ?= " << curvCompareReference->getAttribute(0)->getValuesString() << std::endl;
+
+  assert(curvCompare->getAttribute(0)->getValuesString().compare(curvCompareReference->getAttribute(0)->getValuesString()) == 0);
+
+  std::cout << curvCompare->getDimensions()->getValuesString() << " ?= " << curvCompareReference->getDimensions()->getValuesString() << std::endl;
+
+  assert(curvCompare->getDimensions()->getValuesString().compare(curvCompareReference->getDimensions()->getValuesString()) == 0);
+
+  curvCompare->release();
+
+
+
+
+  // Error Checking
+
+  shared_ptr<XdmfDomain> errorDomain = XdmfDomain::New();
+
+  shared_ptr<XdmfUnstructuredGrid> errorUnGrid = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfGridController> errorUnGridController = XdmfGridController::New("gridControllerReference.xmf", "/Xdmf/Domain/Grid[3]");
+
+  errorUnGrid->setGridController(errorUnGridController);
+
+  errorDomain->insert(errorUnGrid);
+
+  shared_ptr<XdmfWriter> errorControllerWriter = XdmfWriter::New("errorGridController.xmf");
+
+  errorDomain->accept(errorControllerWriter);
+
+
+
+  shared_ptr<XdmfDomain> readErrorDomain = shared_dynamic_cast<XdmfDomain>(reader->read("errorGridController.xmf"));
+
+  try
+  {
+    readErrorDomain->getUnstructuredGrid(0)->read();
+  }
+  catch (XdmfError e)
+  {
+    std::cout << "Intentional Error" << std::endl;
+  }
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfGridTemplate.cpp b/tests/Cxx/TestXdmfGridTemplate.cpp
new file mode 100644
index 0000000..957d5a7
--- /dev/null
+++ b/tests/Cxx/TestXdmfGridTemplate.cpp
@@ -0,0 +1,306 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfGridTemplate.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  unsigned int arraySize = 12;
+  unsigned int numSteps = 3;
+
+  std::cout << "HDF5" << std::endl;
+
+  shared_ptr<XdmfGridTemplate> temp = XdmfGridTemplate::New();
+
+  shared_ptr<XdmfUnstructuredGrid> ungrid = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topo = XdmfTopology::New();
+
+  topo->initialize(XdmfArrayType::Float64(), 12);
+
+  shared_ptr<XdmfGeometry> geo = XdmfGeometry::New();
+
+  geo->initialize(XdmfArrayType::Float64(), 36);
+
+  ungrid->setTopology(topo);
+  ungrid->setGeometry(geo);
+
+  shared_ptr<XdmfAttribute> attr = XdmfAttribute::New();
+
+  attr->initialize(XdmfArrayType::Float64(), 12);
+
+  attr->release();
+
+  shared_ptr<XdmfAttribute> attr2 = XdmfAttribute::New();
+
+  attr2->initialize(XdmfArrayType::Float64(), 12);
+
+  attr2->release();
+
+  shared_ptr<XdmfAttribute> attr3 = XdmfAttribute::New();
+
+  attr3->initialize(XdmfArrayType::Float64(), 12);
+
+  attr3->release();
+
+  ungrid->insert(attr);
+  ungrid->insert(attr2);
+  ungrid->insert(attr3);
+
+  shared_ptr<XdmfTime> time = XdmfTime::New(0.0);
+
+  ungrid->setTime(time);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("gridtemplate.xmf");
+
+  shared_ptr<XdmfHeavyDataWriter> heavyWriter = writer->getHeavyDataWriter();
+
+  temp->setHeavyDataWriter(heavyWriter);
+
+  temp->setBase(ungrid);
+
+  for (int iteration = 1; iteration <= numSteps; ++iteration)
+  {
+    time->setValue(10.0 * iteration);
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      attr->insert<double>(i, 1.0 * iteration);
+      attr2->insert<double>(i, 2.0 * iteration);
+      attr3->insert<double>(i, 3.0 * iteration);
+    }
+
+    temp->addStep();
+
+    temp->clearStep();
+  }
+
+  assert(temp->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    temp->setStep(iteration);
+
+    attr->read();
+    attr2->read();
+    attr3->read();
+
+    std::cout << "Time:" << time->getValue() << std::endl;
+
+    assert(time->getValue() == 10.0 * (1 + iteration));
+
+    std::cout << attr->getValuesString() << std::endl;
+    std::cout << attr2->getValuesString() << std::endl;
+    std::cout << attr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(attr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(attr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(attr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    temp->clearStep();
+  }
+
+  temp->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+
+  shared_ptr<XdmfGridTemplate> readTemp = shared_dynamic_cast<XdmfGridTemplate>(reader->read("gridtemplate.xmf"));
+
+  assert(readTemp);
+
+  shared_ptr<XdmfUnstructuredGrid> readungrid = shared_dynamic_cast<XdmfUnstructuredGrid>(readTemp->getBase());
+
+  std::cout << "?" << readungrid << std::endl;
+
+  assert(readungrid);
+
+  shared_ptr<XdmfTime> readTime = readungrid->getTime();
+
+  shared_ptr<XdmfAttribute> readAttr = readungrid->getAttribute(0);
+  shared_ptr<XdmfAttribute> readAttr2 = readungrid->getAttribute(1);
+  shared_ptr<XdmfAttribute> readAttr3 = readungrid->getAttribute(2);
+
+  std::cout << readTemp->getNumberSteps() << " ?= " << numSteps << std::endl;
+
+  assert(readTemp->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    readTemp->setStep(iteration);
+
+    readAttr->read();
+    readAttr2->read();
+    readAttr3->read();
+
+    std::cout << "Time:" << readTime->getValue() << std::endl;
+
+    assert(readTime->getValue() == 10.0 * (1 + iteration));
+
+    std::cout << readAttr->getValuesString() << std::endl;
+    std::cout << readAttr2->getValuesString() << std::endl;
+    std::cout << readAttr3->getValuesString() << std::endl;
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(readAttr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(readAttr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(readAttr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    readTemp->clearStep();
+  }
+
+  // Without writing to hdf5
+
+  std::cout << "XML" << std::endl;
+
+  shared_ptr<XdmfGridTemplate> temp2 = XdmfGridTemplate::New();
+
+  shared_ptr<XdmfUnstructuredGrid> ungrid2 = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topo2 = XdmfTopology::New();
+
+  topo2->initialize(XdmfArrayType::Float64(), 12);
+
+  shared_ptr<XdmfGeometry> geo2 = XdmfGeometry::New();
+
+  geo2->initialize(XdmfArrayType::Float64(), 36);
+
+  ungrid2->setTopology(topo2);
+  ungrid2->setGeometry(geo2);
+
+  shared_ptr<XdmfAttribute> secondattr = XdmfAttribute::New();
+
+  secondattr->initialize(XdmfArrayType::Float64(), 12);
+
+  secondattr->release();
+
+  shared_ptr<XdmfAttribute> secondattr2 = XdmfAttribute::New();
+
+  secondattr2->initialize(XdmfArrayType::Float64(), 12);
+
+  secondattr2->release();
+
+  shared_ptr<XdmfAttribute> secondattr3 = XdmfAttribute::New();
+
+  secondattr3->initialize(XdmfArrayType::Float64(), 12);
+
+  secondattr3->release();
+
+  ungrid2->insert(secondattr);
+  ungrid2->insert(secondattr2);
+  ungrid2->insert(secondattr3);
+
+  shared_ptr<XdmfTime> time2 = XdmfTime::New(0.0);
+
+  ungrid2->setTime(time2);
+
+  shared_ptr<XdmfWriter> writer2 = XdmfWriter::New("gridtemplate2.xmf");
+
+  temp2->setBase(ungrid2);
+
+  for (int iteration = 1; iteration <= numSteps; ++iteration)
+  {
+    time2->setValue(10.0 * iteration);
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      secondattr->insert<double>(i, 1.0 * iteration);
+      secondattr2->insert<double>(i, 2.0 * iteration);
+      secondattr3->insert<double>(i, 3.0 * iteration);
+    }
+
+    temp2->addStep();
+
+    temp2->clearStep();
+  }
+
+  assert(temp2->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    temp2->setStep(iteration);
+
+    secondattr->read();
+    secondattr2->read();
+    secondattr3->read();
+
+    std::cout << "Time:" << time2->getValue() << std::endl;
+
+    assert(time2->getValue() == 10.0 * (1 + iteration));
+
+    std::cout << secondattr->getValuesString() << std::endl;
+    std::cout << secondattr2->getValuesString() << std::endl;
+    std::cout << secondattr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(secondattr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(secondattr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(secondattr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    temp2->clearStep();
+  }
+
+  temp2->accept(writer2);
+
+  shared_ptr<XdmfGridTemplate> readTemp2 = shared_dynamic_cast<XdmfGridTemplate>(reader->read("gridtemplate2.xmf"));
+
+  assert(readTemp2);
+
+  shared_ptr<XdmfUnstructuredGrid> readungrid2 = shared_dynamic_cast<XdmfUnstructuredGrid>(readTemp2->getBase());
+
+  std::cout << "?" << readungrid2 << std::endl;
+
+  assert(readungrid2);
+
+  shared_ptr<XdmfTime> secondreadTime = readungrid2->getTime();
+
+  shared_ptr<XdmfAttribute> secondreadAttr = readungrid2->getAttribute(0);
+  shared_ptr<XdmfAttribute> secondreadAttr2 = readungrid2->getAttribute(1);
+  shared_ptr<XdmfAttribute> secondreadAttr3 = readungrid2->getAttribute(2);
+
+  std::cout << readTemp2->getNumberSteps() << " ?= " << numSteps << std::endl;
+
+  assert(readTemp2->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    readTemp2->setStep(iteration);
+
+    secondreadAttr->read();
+    secondreadAttr2->read();
+    secondreadAttr3->read();
+
+    std::cout << "Time:" << secondreadTime->getValue() << std::endl;
+
+    assert(secondreadTime->getValue() == 10.0 * (1 + iteration));
+
+    std::cout << secondreadAttr->getValuesString() << std::endl;
+    std::cout << secondreadAttr2->getValuesString() << std::endl;
+    std::cout << secondreadAttr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(secondreadAttr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(secondreadAttr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(secondreadAttr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    readTemp2->clearStep();
+  }
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfHDF5Hyperslab.cpp b/tests/Cxx/TestXdmfHDF5Hyperslab.cpp
new file mode 100644
index 0000000..29a340c
--- /dev/null
+++ b/tests/Cxx/TestXdmfHDF5Hyperslab.cpp
@@ -0,0 +1,233 @@
+#include "XdmfArray.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+
+  //
+  // Create 2x2 array.
+  //
+  shared_ptr<XdmfArray> array = XdmfArray::New();
+  std::vector<unsigned int> dimensions(2, 2);
+  array->initialize<int>(dimensions);
+  int values[] = {0, 1, 2, 3};
+  array->insert(0, &values[0], 4);
+  std::cout << array->getSize() << " ?= " << 4 << std::endl;
+  assert(array->getSize() == 4);
+  dimensions = array->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << dimensions[1] << " ?= " << 2 << std::endl;
+  assert(dimensions.size() == 2);
+  assert(dimensions[0] == 2 && dimensions[1] == 2);
+
+  //
+  // Write array to disk.
+  //
+  shared_ptr<XdmfWriter> writer =
+    XdmfWriter::New("TestXdmfHDF5Hyperslab.xmf");
+  writer->setLightDataLimit(0);
+  array->accept(writer);
+
+  //
+  // Read array from disk.
+  //
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfItem> item = reader->read("TestXdmfHDF5Hyperslab.xmf");
+  shared_ptr<XdmfArray> readArray = shared_dynamic_cast<XdmfArray>(item);
+  if (readArray)
+  {
+    std::cout << "array exists" << std::endl;
+  }
+  else
+  {
+    std::cout << "array does not exist" << std::endl;
+  }
+  std::cout << readArray->getSize() << " ?= " << 4 << std::endl;
+  assert(readArray);
+  assert(readArray->getSize() == 4);
+  std::vector<unsigned int> readDimensions = readArray->getDimensions();
+  std::cout << readDimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[1] << " ?= " << 2 << std::endl;
+  assert(readDimensions.size() == 2);
+  assert(readDimensions[0] == 2 && readDimensions[1] == 2);
+
+  //
+  // Read heavy values from disk.
+  //
+  readArray->read();
+  if (readArray->isInitialized())
+  {
+    std::cout << "array is initialized" << std::endl;
+  }
+  else
+  {
+    std::cout << "array is not initialized" << std::endl;
+  }
+  std::cout << readArray->getSize() << " ?= " << 4 << std::endl;
+  assert(readArray->isInitialized());
+  assert(readArray->getSize() == 4);
+  readDimensions = readArray->getDimensions();
+  std::cout << readDimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[1] << " ?= " << 2 << std::endl;
+  assert(readDimensions.size() == 2);
+  assert(readDimensions[0] == 2 && readDimensions[1] == 2);
+
+  for(int i=0; i<4; ++i) {
+    std::cout << readArray->getValue<int>(i) << " ?= " << i << std::endl;
+    assert(readArray->getValue<int>(i) == i);
+  }
+
+  //
+  // Modify read array to do an overwrite of a different sized dataset.
+  //
+  dimensions = std::vector<unsigned int>(2,3);
+  readArray->resize(dimensions, 1000);
+  for(int i=0; i<9; ++i) {
+    readArray->insert(i, i);
+  }
+  std::cout << readArray->getSize() << " ?= " << 9 << std::endl;
+  assert(readArray->getSize() == 9);
+  dimensions = readArray->getDimensions();
+  std::cout << dimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << dimensions[0] << " ?= " << 3 << std::endl;
+  std::cout << dimensions[1] << " ?= " << 3 << std::endl;
+  assert(dimensions.size() == 2);
+  assert(dimensions[0] == 3 && dimensions[1] == 3);
+
+  shared_ptr<XdmfWriter> writer2 =
+    XdmfWriter::New("TestXdmfHDF5Hyperslab2.xmf");
+  writer2->setLightDataLimit(0);
+  writer2->getHeavyDataWriter()->setMode(XdmfHeavyDataWriter::Overwrite);
+
+  readArray->accept(writer2);
+
+  //
+  // Read array from disk.
+  //
+
+  shared_ptr<XdmfItem> item2 = reader->read("TestXdmfHDF5Hyperslab2.xmf");
+  shared_ptr<XdmfArray> readArray2 = shared_dynamic_cast<XdmfArray>(item2);
+  if (readArray2)
+  {
+    std::cout << "array exists" << std::endl;
+  }
+  else
+  {
+    std::cout << "array does not exist" << std::endl;
+  }
+  std::cout << readArray2->getSize() << " ?= " << 9 << std::endl;
+  assert(readArray2);
+  assert(readArray2->getSize() == 9);
+  readDimensions = readArray2->getDimensions();
+  std::cout << readDimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[0] << " ?= " << 3 << std::endl;
+  std::cout << readDimensions[1] << " ?= " << 3 << std::endl;
+  assert(readDimensions.size() == 2);
+  assert(readDimensions[0] == 3 && readDimensions[1] == 3);
+
+  //
+  // Read heavy values from disk.
+  //
+  readArray2->read();
+  if (readArray2->isInitialized())
+  {
+    std::cout << "array is initialized" << std::endl;
+  }
+  else
+  {
+    std::cout << "array is not initialized" << std::endl;
+  }
+  std::cout << readArray2->getSize() << " ?= " << 9 << std::endl;
+  assert(readArray2->isInitialized());
+  assert(readArray2->getSize() == 9);
+  readDimensions = readArray2->getDimensions();
+  std::cout << readDimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << readDimensions[0] << " ?= " << 3 << std::endl;
+  std::cout << readDimensions[1] << " ?= " << 3 << std::endl;
+  assert(readDimensions.size() == 2);
+  assert(readDimensions[0] == 3 && readDimensions[1] == 3);
+
+  for(int i=0; i<9; ++i) {
+    std::cout << readArray2->getValue<int>(i) << " ?= " << i << std::endl;
+    assert(readArray2->getValue<int>(i) == i);
+  }
+
+  //
+  // Read hyperslab of data
+  //
+  // 0 1 2
+  // 3 4 5
+  // 6 7 8
+  //
+  // becomes...
+  //
+  // 4 5
+  // 7 8
+  //
+  const std::vector<unsigned int> start(2, 1);
+  const std::vector<unsigned int> stride(2, 1);
+  const std::vector<unsigned int> count(2, 2);
+  const std::vector<unsigned int> dataSpaceSize(2, 3);
+
+  shared_ptr<XdmfHDF5Controller> controller =
+    shared_dynamic_cast<XdmfHDF5Controller>(readArray2->getHeavyDataController());
+
+  if (controller)
+  {
+    std::cout << "HDF5 controller exists" << std::endl;
+  }
+  else
+  {
+    std::cout << "HDF5 controller does not exists" << std::endl;
+  }
+
+  assert(controller);
+
+  shared_ptr<XdmfHDF5Controller> hyperslabController =
+    XdmfHDF5Controller::New(controller->getFilePath(),
+                            controller->getDataSetPath(),
+                            controller->getType(),
+                            start,
+                            stride,
+                            count,
+                            dataSpaceSize);
+
+  shared_ptr<XdmfArray> hyperslabArray = XdmfArray::New();
+  hyperslabArray->setHeavyDataController(hyperslabController);
+  std::cout << hyperslabArray->getSize() << " ?= " << 4 << std::endl;
+  assert(hyperslabArray->getSize() == 4);
+  std::vector<unsigned int> hyperslabDimensions =
+    hyperslabArray->getDimensions();
+  std::cout << hyperslabDimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << hyperslabDimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << hyperslabDimensions[1] << " ?= " << 2 << std::endl;
+  assert(hyperslabDimensions.size() == 2);
+  assert(hyperslabDimensions[0] == 2 && hyperslabDimensions[1] == 2);
+  hyperslabArray->read();
+
+  hyperslabDimensions = hyperslabArray->getDimensions();
+  std::cout << hyperslabDimensions.size() << " ?= " << 2 << std::endl;
+  std::cout << hyperslabDimensions[0] << " ?= " << 2 << std::endl;
+  std::cout << hyperslabDimensions[1] << " ?= " << 2 << std::endl;
+  std::cout << hyperslabArray->getValue<int>(0) << " ?= " << 4 << std::endl;
+  std::cout << hyperslabArray->getValue<int>(1) << " ?= " << 5 << std::endl;
+  std::cout << hyperslabArray->getValue<int>(2) << " ?= " << 7 << std::endl;
+  std::cout << hyperslabArray->getValue<int>(3) << " ?= " << 8 << std::endl;
+  assert(hyperslabDimensions.size() == 2);
+  assert(hyperslabDimensions[0] == 2 && hyperslabDimensions[1] == 2);
+  assert(hyperslabArray->getValue<int>(0) == 4);
+  assert(hyperslabArray->getValue<int>(1) == 5);
+  assert(hyperslabArray->getValue<int>(2) == 7);
+  assert(hyperslabArray->getValue<int>(3) == 8);
+
+  return 0;
+
+}
diff --git a/tests/Cxx/TestXdmfHDF5Visit.cpp b/tests/Cxx/TestXdmfHDF5Visit.cpp
new file mode 100644
index 0000000..9d34e6f
--- /dev/null
+++ b/tests/Cxx/TestXdmfHDF5Visit.cpp
@@ -0,0 +1,114 @@
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfArray> vx = XdmfArray::New();
+  vx->resize<unsigned int>(4);
+  vx->insert(0, 0);
+  vx->insert(1, 1);
+  vx->insert(2, 2);
+  vx->insert(3, 4);
+
+  shared_ptr<XdmfArray> vy = XdmfArray::New();
+  vy->resize<unsigned int>(3);
+  vy->insert(0, 0);
+  vy->insert(1, 1);
+  vy->insert(2, 3);
+
+  shared_ptr<XdmfArray> vz = XdmfArray::New();
+  vz->resize<unsigned int>(3);
+  vz->insert(0, 0);
+  vz->insert(1, 1);
+  vz->insert(2, 3);
+
+  shared_ptr<XdmfRectilinearGrid> grid = XdmfRectilinearGrid::New(vx,
+                                                                  vy,
+                                                                  vz);
+
+  std::cout << grid->getDimensions()->getValuesString() << " ?= " << "4 3 3" << std::endl;
+  std::cout << vx << " ?= " << grid->getCoordinates(0) << std::endl;
+  std::cout << vy << " ?= " << grid->getCoordinates(1) << std::endl;
+  std::cout << vz << " ?= " << grid->getCoordinates(2) << std::endl;
+  assert(grid->getDimensions()->getValuesString().compare("4 3 3") == 0);
+  assert(vx == grid->getCoordinates(0));
+  assert(vy == grid->getCoordinates(1));
+  assert(vz == grid->getCoordinates(2));
+
+  // Check values under the hood
+  shared_ptr<const XdmfTopology> topology = grid->getTopology();
+  std::cout << topology->getNumberElements() << " ?= " << 12 << std::endl;
+  assert(topology->getNumberElements() == 12);
+  shared_ptr<const XdmfTopologyType> topologyType = topology->getType();
+  std::cout << topologyType->getNodesPerElement() << " ?= " << 8 << std::endl;
+  assert(topologyType->getNodesPerElement() == 8);
+
+  shared_ptr<const XdmfGeometry> geometry = grid->getGeometry();
+  std::cout << geometry->getNumberPoints() << " ?= " << 36 << std::endl;
+  assert(geometry->getNumberPoints() == 36);
+  shared_ptr<const XdmfGeometryType> geometryType = geometry->getType();
+  std::cout << geometryType->getDimensions() << " ?= " << 3 << std::endl;
+  assert(geometryType->getDimensions() == 3);
+
+  // Input / Output
+
+  shared_ptr<XdmfWriter> writer =
+    XdmfWriter::New("TestXdmfHDF5Visit.xmf");
+  grid->accept(writer->getHeavyDataWriter());
+  grid->accept(writer);
+
+  // Testing writing to specified datasets
+
+  shared_ptr<XdmfArray> array1 = XdmfArray::New();
+
+  shared_ptr<XdmfArray> array2 = XdmfArray::New();
+
+  for (unsigned int i = 0; i < 10; ++i)
+  {
+    array1->pushBack(i);
+    array2->pushBack(i + 5);
+  }
+
+  shared_ptr<XdmfHDF5Controller> controller1 =
+    XdmfHDF5Controller::New("TestXdmfHDF5Visit.h5",
+                            "Test Dataset1",
+                            array1->getArrayType(),
+                            std::vector<unsigned int>(1, 0),
+                            std::vector<unsigned int>(1, 1),
+                            std::vector<unsigned int>(1, 10),
+                            std::vector<unsigned int>(1, 10));
+
+  shared_ptr<XdmfHDF5Controller> controller2 =
+    XdmfHDF5Controller::New("TestXdmfHDF5Visit.h5",
+                            "Test Dataset2",
+                            array2->getArrayType(),
+                            std::vector<unsigned int>(1, 0),
+                            std::vector<unsigned int>(1, 1),
+                            std::vector<unsigned int>(1, 10),
+                            std::vector<unsigned int>(1, 10));
+
+  array1->insert(controller1);
+  array2->insert(controller2);
+
+  std::cout << "writing array 1 to specified dataset" << std::endl;
+
+  array1->accept(writer->getHeavyDataWriter());
+
+  std::cout << "writing array 2 to specified dataset" << std::endl;
+
+  array2->accept(writer->getHeavyDataWriter());
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfMap.cpp b/tests/Cxx/TestXdmfMap.cpp
new file mode 100644
index 0000000..08d9dae
--- /dev/null
+++ b/tests/Cxx/TestXdmfMap.cpp
@@ -0,0 +1,169 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTestCompareFiles.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+#include <iostream>
+
+void performTests(std::vector<shared_ptr<XdmfMap> > & boundaryMaps)
+{
+  boundaryMaps[0]->read();
+  boundaryMaps[1]->read();
+
+  // localNodeId || remoteLocalNodeId
+  XdmfMap::node_id_map mapping;
+
+  mapping = boundaryMaps[0]->getRemoteNodeIds(1);
+  std::cout << mapping.size() << " ?= " << 1 << std::endl;
+  std::cout << mapping[1].size() << " ?= " << 1 << std::endl;
+  std::cout << *(mapping[1].begin()) << " ?= " << 0 << std::endl;
+  assert(mapping.size() == 1);
+  assert(mapping[1].size() == 1);
+  assert(*(mapping[1].begin()) == 0);
+
+  mapping = boundaryMaps[1]->getRemoteNodeIds(0);
+  std::cout << mapping.size() << " ?= " << 1 << std::endl;
+  std::cout << mapping[0].size() << " ?= " << 1 << std::endl;
+  std::cout << *(mapping[0].begin()) << " ?= " << 1 << std::endl;
+  assert(mapping.size() == 1);
+  assert(mapping[0].size() == 1);
+  assert(*(mapping[0].begin()) == 1);
+}
+
+/*
+ * (local, global)
+ *
+ * Grid 0:
+ *
+ * (0, 0) - - - (1, 1)
+ *
+ * Grid 1:
+ *
+ * (0, 1) - - - (1, 2)
+ *
+ */
+
+int main(int, char **)
+{
+  // Grid 0
+  shared_ptr<XdmfUnstructuredGrid> grid0 = XdmfUnstructuredGrid::New();
+  grid0->getGeometry()->setType(XdmfGeometryType::XYZ());
+  double points0[] = {-1, 0, 0, 0, 0, 0};
+  grid0->getGeometry()->insert(0, &points0[0], 6);
+  grid0->getTopology()->setType(XdmfTopologyType::Polyline(2));
+  unsigned int connectivity0[] = {0, 1};
+  grid0->getTopology()->insert(0, &connectivity0[0], 2);
+  shared_ptr<XdmfAttribute> globalNodeIds0 = XdmfAttribute::New();
+  globalNodeIds0->setName("GlobalNodeId");
+  globalNodeIds0->setCenter(XdmfAttributeCenter::Node());
+  globalNodeIds0->setType(XdmfAttributeType::GlobalId());
+  unsigned int globalVals0[] = {0, 1};
+  globalNodeIds0->insert(0, &globalVals0[0], 2);
+
+  // Grid 1
+  shared_ptr<XdmfUnstructuredGrid> grid1 = XdmfUnstructuredGrid::New();
+  grid1->getGeometry()->setType(XdmfGeometryType::XYZ());
+  double points1[] = {0, 0, 0, 1, 0, 0};
+  grid1->getGeometry()->insert(0, &points1[0], 6);
+  grid1->getTopology()->setType(XdmfTopologyType::Polyline(2));
+  unsigned int connectivity1[] = {0, 1};
+  grid1->getTopology()->insert(0, &connectivity1[0], 2);
+  shared_ptr<XdmfAttribute> globalNodeIds1 = XdmfAttribute::New();
+  globalNodeIds1->setName("GlobalNodeId");
+  globalNodeIds1->setCenter(XdmfAttributeCenter::Node());
+  globalNodeIds1->setType(XdmfAttributeType::GlobalId());
+  unsigned int globalVals1[] = {1, 2};
+  globalNodeIds1->insert(0, &globalVals1[0], 2);
+
+  std::vector<shared_ptr<XdmfAttribute> > globalNodeIds;
+  globalNodeIds.push_back(globalNodeIds0);
+  globalNodeIds.push_back(globalNodeIds1);
+
+  std::vector<shared_ptr<XdmfMap> > boundaryMaps =
+    XdmfMap::New(globalNodeIds);
+
+  performTests(boundaryMaps);
+  grid0->insert(boundaryMaps[0]);
+  grid1->insert(boundaryMaps[1]);
+
+  // Grid Collection
+  shared_ptr<XdmfGridCollection> collection = XdmfGridCollection::New();
+  collection->setType(XdmfGridCollectionType::Spatial());
+  collection->insert(grid0);
+  collection->insert(grid1);
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+  domain->insert(collection);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("TestXdmfMap1.xmf");
+  domain->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfDomain> domain2 =
+    shared_dynamic_cast<XdmfDomain>(reader->read("TestXdmfMap1.xmf"));
+
+  boundaryMaps.clear();
+  boundaryMaps.push_back(domain2->getGridCollection(0)->getUnstructuredGrid(0)->getMap(0));
+  boundaryMaps.push_back(domain2->getGridCollection(0)->getUnstructuredGrid(1)->getMap(0));
+  performTests(boundaryMaps);
+
+  shared_ptr<XdmfWriter> writer2 = XdmfWriter::New("TestXdmfMap2.xmf");
+  domain2->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfMap1.xmf",
+                                         "TestXdmfMap2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfMap1.xmf",
+                                            "TestXdmfMap2.xmf"));
+
+  shared_ptr<XdmfWriter> writerHDF =
+    XdmfWriter::New("TestXdmfMapHDF1.xmf");
+  writerHDF->setLightDataLimit(0);
+  domain->accept(writerHDF);
+
+  shared_ptr<XdmfDomain> domainHDF =
+    shared_dynamic_cast<XdmfDomain>(reader->read("TestXdmfMapHDF1.xmf"));
+
+  boundaryMaps.clear();
+  boundaryMaps.push_back(domainHDF->getGridCollection(0)->getUnstructuredGrid(0)->getMap(0));
+  boundaryMaps.push_back(domainHDF->getGridCollection(0)->getUnstructuredGrid(1)->getMap(0));
+  performTests(boundaryMaps);
+
+  shared_ptr<XdmfWriter> writerHDF2 =
+    XdmfWriter::New("TestXdmfMapHDF2.xmf");
+  writerHDF2->getHeavyDataWriter()->setMode(XdmfHeavyDataWriter::Overwrite);
+  writerHDF2->setLightDataLimit(0);
+  domainHDF->accept(writerHDF2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfMapHDF1.xmf",
+                                         "TestXdmfMapHDF2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfMapHDF1.xmf",
+                                            "TestXdmfMapHDF2.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfMultiOpen.cpp b/tests/Cxx/TestXdmfMultiOpen.cpp
new file mode 100644
index 0000000..dc8bac1
--- /dev/null
+++ b/tests/Cxx/TestXdmfMultiOpen.cpp
@@ -0,0 +1,110 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "stdio.h"
+#include <sstream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfHDF5Writer> hdf5writer1 = XdmfHDF5Writer::New("attributefile.h5");
+  shared_ptr<XdmfHDF5Writer> hdf5writer2 = XdmfHDF5Writer::New("setfile.h5");
+
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+
+  shared_ptr<XdmfGeometry> geometry = XdmfGeometry::New();
+
+  shared_ptr<XdmfTopology> topology = XdmfTopology::New();
+
+  unsigned int numGrids = 20;
+
+  std::stringstream attributeName;
+  std::stringstream setName;
+
+  hdf5writer1->openFile();
+  hdf5writer2->openFile();
+
+  for (unsigned int i = 0; i < numGrids; ++i)
+  {
+    shared_ptr<XdmfUnstructuredGrid> grid = XdmfUnstructuredGrid::New();
+    std::string gridName = "Grid" + i;
+
+    grid->setName(gridName);
+    assert(grid->getName().compare(gridName) == 0);
+
+    attributeName << "Grid" << i << " Attribute";
+
+    shared_ptr<XdmfAttribute> attr = XdmfAttribute::New();
+    attr->setName(attributeName.str());
+    attr->resize<int>(2000, 0);
+    attr->accept(hdf5writer1);
+    grid->insert(attr);
+
+    attributeName.str(std::string());
+
+    setName << "Grid" << i << " Set";
+
+    shared_ptr<XdmfSet> set = XdmfSet::New();
+    set->setName(setName.str());
+    set->resize<int>(2000, 0);
+    set->accept(hdf5writer2);
+    grid->insert(set);
+
+    setName.str(std::string());
+
+    shared_ptr<XdmfTime> time = XdmfTime::New(i);
+    grid->setTime(time);
+
+    grid->setTopology(topology);
+    grid->setGeometry(geometry);
+
+    domain->insert(grid);
+  }
+
+  hdf5writer1->closeFile();
+  hdf5writer2->closeFile();
+
+  printf("data written to file\n");
+
+  for (unsigned int i = 0; i < numGrids; ++i)
+  {
+    domain->getUnstructuredGrid(i)->getAttribute(0)->read();
+    domain->getUnstructuredGrid(i)->getSet(0)->read();
+  }
+
+  XdmfHDF5Controller::closeFiles();
+
+  for (unsigned int i = 0; i < numGrids; ++i)
+  {
+    domain->getUnstructuredGrid(i)->getAttribute(0)->release();
+    domain->getUnstructuredGrid(i)->getSet(0)->release();
+  }
+
+  XdmfHDF5Controller::setMaxOpenedFiles(2);
+
+  for (unsigned int i = 0; i < numGrids; ++i)
+  {
+    domain->getUnstructuredGrid(i)->getAttribute(0)->read();
+    domain->getUnstructuredGrid(i)->getSet(0)->read();
+  }
+
+  XdmfHDF5Controller::closeFiles();
+
+  for (unsigned int i = 0; i < numGrids; ++i)
+  {
+    domain->getUnstructuredGrid(i)->getAttribute(0)->release();
+    domain->getUnstructuredGrid(i)->getSet(0)->release();
+  }
+
+  return 0;
+}
+
diff --git a/tests/Cxx/TestXdmfMultiXPath.cpp b/tests/Cxx/TestXdmfMultiXPath.cpp
new file mode 100644
index 0000000..7af319e
--- /dev/null
+++ b/tests/Cxx/TestXdmfMultiXPath.cpp
@@ -0,0 +1,49 @@
+#include <XdmfDomain.hpp>
+#include <XdmfInformation.hpp>
+#include <XdmfReader.hpp>
+
+#include <iostream>
+#include <fstream>
+
+int main(int ac, char * av[]) 
+{
+  
+  //
+  // write outer file
+  //
+  std::ofstream outerFile("nestedOuter.xmf");
+  outerFile << "<?xml version=\"1.0\" ?><Xdmf Version=\"2.1\" xmlns:xi=\"http://www.w3.org/2001/XInclude\"><Domain><xi:include href=\"nestedInner.xmf\" xpointer=\"element(/1/1/2)\"/></Domain></Xdmf>";
+  outerFile.close();
+
+  //
+  // write inner file
+  //
+  std::ofstream innerFile("nestedInner.xmf");
+  innerFile << "<?xml version=\"1.0\" ?><!DOCTYPE Xdmf SYSTEM \"Xdmf.dtd\" []><Xdmf xmlns:xi=\"http://www.w3.org/2003/XInclude\" Version=\"2.1\"><Domain><Information Name=\"foo\" Value=\"bar\"/><xi:include xpointer=\"element(/1/1/1)\"/></Domain></Xdmf>";
+  innerFile.close();
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+ 
+  shared_ptr<XdmfDomain> innerDomain = 
+    shared_dynamic_cast<XdmfDomain>(reader->read("nestedInner.xmf"));
+  std::cout << innerDomain->getNumberInformations() << " ?= " << 2 << std::endl;
+  assert(innerDomain->getNumberInformations() == 2);
+  shared_ptr<XdmfInformation> information0 = innerDomain->getInformation(0);
+  shared_ptr<XdmfInformation> information1 = innerDomain->getInformation(1);
+  
+  // should be the same since 1 is xpoint to 1
+  std::cout << information0 << " ?= " << information1 << std::endl;
+  assert(information0 == information1);
+  
+  shared_ptr<XdmfDomain> outerDomain = 
+    shared_dynamic_cast<XdmfDomain>(reader->read("nestedOuter.xmf"));
+
+  std::cout << outerDomain->getNumberInformations() << " ?= " << 1 << std::endl;
+  assert(outerDomain->getNumberInformations() == 1);
+  shared_ptr<XdmfInformation> information = outerDomain->getInformation(0);
+  std::cout << information->getKey() << " ?= " << "foo" << std::endl;
+  std::cout << information->getValue() << " ?= " << "bar" << std::endl;
+  assert(information->getKey().compare("foo") == 0);
+  assert(information->getValue().compare("bar") == 0);
+
+}
diff --git a/tests/Cxx/TestXdmfReader.cpp b/tests/Cxx/TestXdmfReader.cpp
new file mode 100644
index 0000000..cee2e41
--- /dev/null
+++ b/tests/Cxx/TestXdmfReader.cpp
@@ -0,0 +1,72 @@
+#include "XdmfDomain.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("TestXdmfReader1.xmf");
+  writer->setLightDataLimit(10);
+
+  shared_ptr<XdmfUnstructuredGrid> grid1 =
+    XdmfTestDataGenerator::createHexahedron();
+  shared_ptr<XdmfUnstructuredGrid> grid2 =
+    XdmfTestDataGenerator::createHexahedron();
+
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+  domain->insert(grid1);
+  domain->insert(grid2);
+  domain->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfDomain> readDomain =
+    shared_dynamic_cast<XdmfDomain>(reader->read("TestXdmfReader1.xmf"));
+
+  shared_ptr<XdmfWriter> writer2 = XdmfWriter::New("TestXdmfReader2.xmf");
+  writer2->setMode(XdmfWriter::DistributedHeavyData);
+  readDomain->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfReader1.xmf",
+                                         "TestXdmfReader2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfReader1.xmf",
+                                            "TestXdmfReader2.xmf"));
+
+  std::vector<shared_ptr<XdmfItem> > readItems =
+    reader->read("TestXdmfReader1.xmf", "/Xdmf/Domain/Grid[1]");
+
+  std::cout << readItems.size() << " ?= " << 1 << std::endl;
+
+  assert(readItems.size() == 1);
+  shared_ptr<XdmfUnstructuredGrid> readGrid =
+    shared_dynamic_cast<XdmfUnstructuredGrid>(readItems[0]);
+
+  std::cout << readGrid->getName() << " ?= " << "Hexahedron" << std::endl;
+
+  assert(readGrid->getName().compare("Hexahedron") == 0);
+
+  std::vector<shared_ptr<XdmfItem> > readItems2 =
+    reader->read("TestXdmfReader1.xmf", "//Attribute");
+
+  std::cout << readItems2.size() << " ?= " << 8 << std::endl;
+
+  assert(readItems2.size() == 8);
+  shared_ptr<XdmfAttribute> readAttribute =
+    shared_dynamic_cast<XdmfAttribute>(readItems2[0]);
+
+  std::cout << readAttribute->getName() << " ?= " << "Nodal Attribute" << std::endl;
+
+  assert(readAttribute->getName().compare("Nodal Attribute") == 0);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfRectilinearGrid.cpp b/tests/Cxx/TestXdmfRectilinearGrid.cpp
new file mode 100644
index 0000000..7760d20
--- /dev/null
+++ b/tests/Cxx/TestXdmfRectilinearGrid.cpp
@@ -0,0 +1,114 @@
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfArray> vx = XdmfArray::New();
+  vx->resize<unsigned int>(4);
+  vx->insert(0, 0);
+  vx->insert(1, 1);
+  vx->insert(2, 2);
+  vx->insert(3, 4);
+
+  shared_ptr<XdmfArray> vy = XdmfArray::New();
+  vy->resize<unsigned int>(3);
+  vy->insert(0, 0);
+  vy->insert(1, 1);
+  vy->insert(2, 3);
+
+  shared_ptr<XdmfArray> vz = XdmfArray::New();
+  vz->resize<unsigned int>(3);
+  vz->insert(0, 0);
+  vz->insert(1, 1);
+  vz->insert(2, 3);
+
+  shared_ptr<XdmfRectilinearGrid> grid = XdmfRectilinearGrid::New(vx,
+                                                                  vy,
+                                                                  vz);
+
+  std::cout << grid->getDimensions()->getValuesString() << " ?= 4 3 3" << std::endl;
+  std::cout << vx << " ?= " << grid->getCoordinates(0) << std::endl;
+  std::cout << vy << " ?= " << grid->getCoordinates(1) << std::endl;
+  std::cout << vz << " ?= " << grid->getCoordinates(2) << std::endl;
+
+  assert(grid->getDimensions()->getValuesString().compare("4 3 3") == 0);
+  assert(vx == grid->getCoordinates(0));
+  assert(vy == grid->getCoordinates(1));
+  assert(vz == grid->getCoordinates(2));
+
+  // Check values under the hood
+  shared_ptr<const XdmfTopology> topology = grid->getTopology();
+  std::cout << topology->getNumberElements() << " ?= " << 12 << std::endl;
+  assert(topology->getNumberElements() == 12);
+  shared_ptr<const XdmfTopologyType> topologyType = topology->getType();
+  std::cout << topologyType->getNodesPerElement() << " ?= " << 8 << std::endl;
+  assert(topologyType->getNodesPerElement() == 8);
+
+  shared_ptr<const XdmfGeometry> geometry = grid->getGeometry();
+  std::cout << geometry->getNumberPoints() << " ?= " << 36 << std::endl;
+  assert(geometry->getNumberPoints() == 36);
+  shared_ptr<const XdmfGeometryType> geometryType = geometry->getType();
+  std::cout << geometryType->getDimensions() << " ?= " << 3 << std::endl;
+  assert(geometryType->getDimensions() == 3);
+
+  // Input / Output
+
+  shared_ptr<XdmfWriter> writer =
+    XdmfWriter::New("TestXdmfRectilinearGrid1.xmf");
+  grid->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfRectilinearGrid> grid2 = 
+    shared_dynamic_cast<XdmfRectilinearGrid>
+    (reader->read("TestXdmfRectilinearGrid1.xmf"));
+
+  shared_ptr<XdmfWriter> writer2 =
+    XdmfWriter::New("TestXdmfRectilinearGrid2.xmf");
+  grid2->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfRectilinearGrid1.xmf",
+                                            "TestXdmfRectilinearGrid2.xmf"))
+  {
+    std::cout << "compared files are equal" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not equal" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfRectilinearGrid1.xmf",
+                                            "TestXdmfRectilinearGrid2.xmf"));
+
+  // Testing 1d meshes
+
+  shared_ptr<XdmfArray> dim1d = XdmfArray::New();
+  dim1d->pushBack(4);
+  dim1d->pushBack(5);
+  dim1d->pushBack(6);
+  dim1d->pushBack(7);
+
+  std::vector<shared_ptr<XdmfArray> > dimvector;
+  dimvector.push_back(dim1d);
+
+  shared_ptr<XdmfRectilinearGrid> grid3 = XdmfRectilinearGrid::New(dimvector);
+
+  shared_ptr<XdmfWriter> writer3 =
+    XdmfWriter::New("TestXdmfRectilinearGrid3.xmf");
+
+  grid3->accept(writer3);
+
+  shared_ptr<XdmfRectilinearGrid> readgrid =
+    shared_dynamic_cast<XdmfRectilinearGrid>(reader->read("TestXdmfRectilinearGrid3.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfRegularGrid.cpp b/tests/Cxx/TestXdmfRegularGrid.cpp
new file mode 100644
index 0000000..f53e81b
--- /dev/null
+++ b/tests/Cxx/TestXdmfRegularGrid.cpp
@@ -0,0 +1,151 @@
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfWriter.hpp"
+
+#include "XdmfTestCompareFiles.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfRegularGrid> grid = XdmfRegularGrid::New(1, 1, 1,
+                                                          1, 1, 1,
+                                                          0, 0, 0);
+  shared_ptr<XdmfArray> brickSize = grid->getBrickSize();
+  std::cout << brickSize->getSize() << " ?= " << 3 << std::endl;
+  assert(brickSize->getSize() == 3);
+  for(unsigned int i=0; i<brickSize->getSize(); ++i) {
+    std::cout << brickSize->getValue<unsigned int>(i) << " ?= " << 1 << std::endl;
+    assert(brickSize->getValue<unsigned int>(i) == 1);
+  }
+  shared_ptr<XdmfArray> dimensions = grid->getDimensions();
+  std::cout << dimensions->getSize() << " ?= " << 3 << std::endl;
+  assert(dimensions->getSize() == 3);
+  for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+    std::cout << dimensions->getValue<unsigned int>(i) << " ?= " << 1 << std::endl;
+    assert(dimensions->getValue<unsigned int>(i) == 1);
+  }
+  shared_ptr<XdmfArray> origin = grid->getOrigin();
+  std::cout << origin->getSize() << " ?= " << 3 << std::endl;
+  assert(origin->getSize() == 3);
+  for(unsigned int i=0; i<origin->getSize(); ++i) {
+    std::cout << origin->getValue<unsigned int>(i) << " ?= " << 0 << std::endl;
+    assert(origin->getValue<unsigned int>(i) == 0);
+  }
+
+  // Setting brickSize, dimensions, origin
+
+  shared_ptr<XdmfArray> newBrickSize = XdmfArray::New();
+  newBrickSize->initialize<double>(3);
+  newBrickSize->insert(0, 2);
+  newBrickSize->insert(1, 2);
+  newBrickSize->insert(2, 2);
+  grid->setBrickSize(newBrickSize);
+  brickSize = grid->getBrickSize();
+  std::cout << brickSize->getSize() << " ?= " << 3 << std::endl;
+  assert(brickSize->getSize() == 3);
+  for(unsigned int i=0; i<brickSize->getSize(); ++i) {
+    std::cout << brickSize->getValue<unsigned int>(i) << " ?= " << 2 << std::endl;
+    assert(brickSize->getValue<unsigned int>(i) == 2);
+  }
+
+  shared_ptr<XdmfArray> newDimensions = XdmfArray::New();
+  newDimensions->initialize<unsigned int>(3);
+  newDimensions->insert(0, 2);
+  newDimensions->insert(1, 2);
+  newDimensions->insert(2, 2);
+  grid->setDimensions(newDimensions);
+  dimensions = grid->getDimensions();
+  std::cout << dimensions->getSize() << " ?= " << 3 << std::endl;
+  assert(dimensions->getSize() == 3);
+  for(unsigned int i=0; i<dimensions->getSize(); ++i) {
+    std::cout << dimensions->getValue<unsigned int>(i) << " ?= " << 2 << std::endl;
+    assert(dimensions->getValue<unsigned int>(i) == 2);
+  }
+
+  shared_ptr<XdmfArray> newOrigin = XdmfArray::New();
+  newOrigin->initialize<double>(3);
+  newOrigin->insert(0, 1);
+  newOrigin->insert(1, 1);
+  newOrigin->insert(2, 1);
+  grid->setOrigin(newOrigin);
+  origin = grid->getOrigin();
+  std::cout << origin->getSize() << " ?= " << 3 << std::endl;
+  assert(origin->getSize() == 3);
+  for(unsigned int i=0; i<origin->getSize(); ++i) {
+    std::cout << origin->getValue<unsigned int>(i) << " ?= " << 1 << std::endl;
+    assert(origin->getValue<unsigned int>(i) == 1);
+  }
+
+  // Check values under the hood
+
+  shared_ptr<const XdmfTopology> topology = grid->getTopology();
+  std::cout << topology->getNumberElements() << " ?= " << 1 << std::endl;
+  assert(topology->getNumberElements() == 1);
+  shared_ptr<const XdmfTopologyType> topologyType = topology->getType();
+  std::cout << topologyType->getNodesPerElement() << " ?= " << 8 << std::endl;
+  assert(topologyType->getNodesPerElement() == 8);
+
+  shared_ptr<const XdmfGeometry> geometry = grid->getGeometry();
+  std::cout << geometry->getNumberPoints() << " ?= " << 8 << std::endl;
+  assert(geometry->getNumberPoints() == 8);
+  shared_ptr<const XdmfGeometryType> geometryType = geometry->getType();
+  std::cout << geometryType->getDimensions() << " ?= " << 3 << std::endl;
+  assert(geometryType->getDimensions() == 3);
+
+  // Input / Output
+
+  shared_ptr<XdmfWriter> writer =
+    XdmfWriter::New("TestXdmfRegularGrid1.xmf");
+  grid->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfRegularGrid> grid2 =
+    shared_dynamic_cast<XdmfRegularGrid>
+    (reader->read("TestXdmfRegularGrid1.xmf"));
+
+  shared_ptr<XdmfWriter> writer2 =
+    XdmfWriter::New("TestXdmfRegularGrid2.xmf");
+  grid2->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfRegularGrid1.xmf",
+                                         "TestXdmfRegularGrid2.xmf"))
+  {
+    std::cout << "compared files match" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files do not match" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfRegularGrid1.xmf",
+                                            "TestXdmfRegularGrid2.xmf"));
+
+  // Testing 1d meshes
+
+  shared_ptr<XdmfArray> origin1d = XdmfArray::New();
+  origin1d->pushBack(0);
+
+  shared_ptr<XdmfArray> dim1d = XdmfArray::New();
+  dim1d->pushBack(4);
+
+  shared_ptr<XdmfArray> brick1d = XdmfArray::New();
+  brick1d->pushBack(1);
+
+  shared_ptr<XdmfRegularGrid> grid3 = XdmfRegularGrid::New(origin1d, dim1d, brick1d);
+
+  shared_ptr<XdmfWriter> writer3 =
+    XdmfWriter::New("TestXdmfRegularGrid3.xmf");
+
+  grid3->accept(writer3);
+
+  shared_ptr<XdmfRegularGrid> readgrid =
+    shared_dynamic_cast<XdmfRegularGrid>(reader->read("TestXdmfRegularGrid3.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfSet.cpp b/tests/Cxx/TestXdmfSet.cpp
new file mode 100644
index 0000000..85f079a
--- /dev/null
+++ b/tests/Cxx/TestXdmfSet.cpp
@@ -0,0 +1,52 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  // Test != and == operators
+  std::cout << XdmfSetType::Node() << " ?= " << XdmfSetType::Node() << std::endl;
+  std::cout << XdmfSetType::Node() << " ?!= " << XdmfSetType::Cell() << std::endl;
+  assert(XdmfSetType::Node() == XdmfSetType::Node());
+  assert((XdmfSetType::Node() == XdmfSetType::Cell()) == false);
+  assert((XdmfSetType::Node() != XdmfSetType::Node()) == false);
+  assert(XdmfSetType::Node() != XdmfSetType::Cell());
+
+  shared_ptr<XdmfSet> set = XdmfSet::New();
+  std::cout << set->getType() << " ?= " << XdmfSetType::NoSetType() << std::endl;
+  assert(set->getType() == XdmfSetType::NoSetType());
+  set->setType(XdmfSetType::Node());
+  std::cout << set->getType() << " ?= " << XdmfSetType::Node() << std::endl;
+  assert(set->getType() == XdmfSetType::Node());
+  set->setName("TEST");
+  std::cout << set->getName() << " ?= TEST" << std::endl;
+  assert(set->getName().compare("TEST") == 0);
+
+  std::cout << set->getNumberAttributes() << " ?= " << 0 << std::endl;
+  std::cout << set->getAttribute("") << " ?= " << "NULL" << std::endl;
+  std::cout << set->getAttribute(0) << " ?= " << "NULL" << std::endl;
+  assert(set->getNumberAttributes() == 0);
+  assert(set->getAttribute("") == NULL);
+  assert(set->getAttribute(0) == NULL);
+  shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+  attribute->setName("foo");
+  set->insert(attribute);
+  std::cout << set->getNumberAttributes() << " ?= " << 1 << std::endl;
+  std::cout << set->getAttribute("foo") << " ?= " << attribute << std::endl;
+  std::cout << set->getAttribute(0) << " ?= " << attribute << std::endl;
+  assert(set->getNumberAttributes() == 1);
+  assert(set->getAttribute(0) == attribute);
+  assert(set->getAttribute("foo") == attribute);
+  set->removeAttribute(0);
+  std::cout << set->getNumberAttributes() << " ?= " << 0 << std::endl;
+  assert(set->getNumberAttributes() == 0);
+  set->insert(attribute);
+  set->removeAttribute("no");
+  std::cout << set->getNumberAttributes() << " ?= " << 1 << std::endl;
+  assert(set->getNumberAttributes() == 1);
+  set->removeAttribute("foo");
+  std::cout << set->getNumberAttributes() << " ?= " << 0 << std::endl;
+  assert(set->getNumberAttributes() == 0);
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfSubset.cpp b/tests/Cxx/TestXdmfSubset.cpp
new file mode 100644
index 0000000..b67ecb0
--- /dev/null
+++ b/tests/Cxx/TestXdmfSubset.cpp
@@ -0,0 +1,131 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include <map>
+#include <iostream>
+
+int main(int, char **)
+{
+	shared_ptr<XdmfArray> referenceArray = XdmfArray::New();
+
+	for (unsigned int i = 0; i < 27; ++i)
+	{
+		referenceArray->pushBack(i);
+	}
+
+	std::vector<unsigned int> initDimensions;
+	initDimensions.push_back(3);
+	initDimensions.push_back(3);
+	initDimensions.push_back(3);
+
+	referenceArray->resize(initDimensions, 0);
+
+	std::vector<unsigned int> newStarts;
+	newStarts.push_back(0);
+	newStarts.push_back(0);
+	newStarts.push_back(0);
+	std::vector<unsigned int> newStrides;
+	newStrides.push_back(2);
+	newStrides.push_back(2);
+	newStrides.push_back(2);
+	std::vector<unsigned int> newDimensions;
+	newDimensions.push_back(2);
+	newDimensions.push_back(2);
+	newDimensions.push_back(2);
+
+	shared_ptr<XdmfSubset> testSubset = XdmfSubset::New(referenceArray,
+                                                            newStarts,
+                                                            newStrides,
+                                                            newDimensions);
+
+	shared_ptr<XdmfAttribute> subsetHolder = XdmfAttribute::New();
+
+	subsetHolder->setReference(testSubset);
+
+	subsetHolder->setReadMode(XdmfArray::Reference);
+
+
+
+	shared_ptr<XdmfWriter> subsetWriter = XdmfWriter::New("subset.xmf");
+
+	subsetHolder->accept(subsetWriter);
+
+
+
+
+	subsetHolder->readReference();
+
+	std::cout << subsetHolder->getValuesString() << std::endl;
+
+	shared_ptr<XdmfReader> subsetReader = XdmfReader::New();
+
+	shared_ptr<XdmfItem> readItem = subsetReader->read("subset.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= Attribute" << std::endl;
+
+	assert(readItem->getItemTag().compare("Attribute") == 0);
+
+	shared_ptr<XdmfAttribute> readSubsetHolder = shared_dynamic_cast<XdmfAttribute>(readItem);
+
+	readSubsetHolder->readReference();
+
+	std::cout << shared_dynamic_cast<XdmfSubset>(readSubsetHolder->getReference())->getReferenceArray()->getValuesString() << std::endl;
+
+	std::cout << readSubsetHolder->getValuesString() << std::endl;
+
+	assert(readSubsetHolder->getValuesString().compare(subsetHolder->getValuesString()) == 0);
+
+	shared_ptr<XdmfArray> referenceArray2 = XdmfArray::New();
+
+	for (unsigned int i = 10; i < 37; ++i)
+	{
+		referenceArray2->pushBack(i);
+	}
+
+	referenceArray2->resize(initDimensions, 0);
+
+        testSubset->setReferenceArray(referenceArray2);
+
+	std::string changedSubsetOutput = testSubset->read()->getValuesString();
+
+	std::cout << "after changing reference Array: " << changedSubsetOutput << std::endl;
+
+	assert(changedSubsetOutput.compare("10 12 16 18 28 30 34 36") == 0);
+
+
+
+        shared_ptr<XdmfArray> subsetHolder2 = XdmfArray::New();
+
+        subsetHolder2->setReference(testSubset);
+
+        subsetHolder2->setReadMode(XdmfArray::Reference);
+
+        subsetHolder2->accept(subsetWriter);
+
+        subsetHolder2->readReference();
+
+        std::cout << subsetHolder2->getValuesString() << std::endl;
+
+        readItem = subsetReader->read("subset.xmf");
+
+        std::cout << readItem->getItemTag() << " ?= DataItem" << std::endl;
+
+        assert(readItem->getItemTag().compare("DataItem") == 0);
+
+        shared_ptr<XdmfArray> readSubsetHolder2 = shared_dynamic_cast<XdmfArray>(readItem);
+
+        readSubsetHolder2->readReference();
+
+        std::cout <<
+          shared_dynamic_cast<XdmfSubset>(readSubsetHolder2->getReference())->getReferenceArray()->getValuesString() 
+          << std::endl;
+
+        std::cout << readSubsetHolder2->getValuesString() << std::endl;
+
+        assert(readSubsetHolder2->getValuesString().compare(subsetHolder2->getValuesString()) == 0);
+
+	return 0;
+}
diff --git a/tests/Cxx/TestXdmfTIFFReadWriteCompressed.cpp b/tests/Cxx/TestXdmfTIFFReadWriteCompressed.cpp
new file mode 100644
index 0000000..ed0b675
--- /dev/null
+++ b/tests/Cxx/TestXdmfTIFFReadWriteCompressed.cpp
@@ -0,0 +1,359 @@
+#include "tiff.h"
+#include "tiffio.h"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfTIFFController.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfReader.hpp"
+#include "stdio.h"
+
+int main(int, char **)
+{
+  TIFF* tif = TIFFOpen("compressedstripoutput.tif", "w");
+
+  if (tif) {
+    unsigned int w, h, sampleSize, pixelWidth;
+    // set a base size
+    pixelWidth = 1000;
+    w = 8 * pixelWidth;
+    h = 1000;
+    sampleSize = 1;
+    size_t npixels;
+    unsigned int * scanline;
+
+    npixels = w * h;
+
+    TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);  // set the width of the image
+    TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);    // set the height of the image
+    TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sampleSize);   // set number of channels per pixel
+    TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, XdmfArrayType::UInt32()->getElementSize());   // Strangely this is in bytes when dealing with Compression 
+    TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);    // set the origin of the image.
+    TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+    TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+    TIFFSetField(tif, TIFFTAG_COMPRESSION, 5); // Only LZW encoding works in any fashion
+
+     TIFFSetField(tif,
+                  TIFFTAG_ROWSPERSTRIP,
+                  TIFFDefaultStripSize(tif, w*sampleSize));
+
+    unsigned int scanlineSize = TIFFScanlineSize(tif);
+
+    for (unsigned int i = 0; i < h; ++i)
+    {
+      scanline = (unsigned int *) _TIFFmalloc(scanlineSize);
+      for (unsigned int j = 0; j < pixelWidth; ++j)
+      {
+        scanline[j] = i * j;
+      }
+      TIFFWriteScanline(tif, scanline, i, 0);
+      _TIFFfree(scanline);
+    }
+  }
+
+  TIFFClose(tif);
+
+  shared_ptr<XdmfTIFFController> controller = XdmfTIFFController::New("compressedstripoutput.tif",
+                                                                      XdmfArrayType::UInt32(),
+                                                                      std::vector<unsigned int>(1, 1000 * 1000));
+
+  shared_ptr<XdmfArray> checkarray = XdmfArray::New();
+
+  checkarray->insert(controller);
+
+  checkarray->read();
+
+
+  for (unsigned int i = 0; i < 1000; ++i)
+  {
+    for (unsigned int j = 0; j < 1000; ++j)
+    {
+//      printf("%u ", checkarray->getValue<unsigned int>(i * 1000 + j));
+      assert(checkarray->getValue<unsigned int>(i * 1000 + j) == i * j);
+    }
+//    printf("\n");
+  }
+
+  shared_ptr<XdmfTIFFController> hyperslabcontroller = XdmfTIFFController::New("compressedstripoutput.tif",
+                                                                               XdmfArrayType::UInt32(),
+                                                                               std::vector<unsigned int>(2, 0),
+                                                                               std::vector<unsigned int>(2, 2),
+                                                                               std::vector<unsigned int>(2, 500),
+                                                                               std::vector<unsigned int>(2, 1000));
+
+  shared_ptr<XdmfArray> checkarray2 = XdmfArray::New();
+
+  checkarray2->insert(hyperslabcontroller);
+
+  checkarray2->read();
+
+  for (unsigned int i = 0; i < 500; ++i)
+  {
+    for (unsigned int j = 0; j < 500; ++j)
+    {
+//      printf("%u ", checkarray2->getValue<unsigned int>(i * 500 + j));
+      assert(checkarray2->getValue<unsigned int>(i * 500 + j) == (2 * i) * (2 * j));
+    }
+//    printf("\n");
+  }
+
+  shared_ptr<XdmfTIFFController> hyperslabcontroller2 = XdmfTIFFController::New("compressedstripoutput.tif",
+                                                                                XdmfArrayType::UInt32(),
+                                                                                std::vector<unsigned int>(1, 0),
+                                                                                std::vector<unsigned int>(1, 2),
+                                                                                std::vector<unsigned int>(1, (1000 * 1000) / 2),
+                                                                                std::vector<unsigned int>(1, 1000 * 1000));
+
+  shared_ptr<XdmfArray> checkarray3 = XdmfArray::New();
+
+  checkarray3->insert(hyperslabcontroller2);
+
+  checkarray3->read();
+
+  for (unsigned int i = 0; i < 1000; ++i)
+  {
+    for (unsigned int j = 0; j < 500; ++j)
+    {
+//      printf("%u ", checkarray3->getValue<unsigned int>(i * 500 + j));
+      assert(checkarray3->getValue<unsigned int>(i * 500 + j) == i * (2 * j));
+    }
+//    printf("\n");
+}
+
+  tif = TIFFOpen("compressedstripoutput.tif", "r");
+  unsigned int dircount = 0;
+  if (tif) {
+    do {
+      dircount++;
+    } while (TIFFReadDirectory(tif));
+    TIFFClose(tif);
+  }
+
+  printf("%d directories in file stripoutput.tif\n", dircount);
+
+  tif = TIFFOpen("compresseddirectories.tif", "w");
+
+  if (tif) {
+    unsigned int w, h, sampleSize, pixelWidth;
+    // set a base size
+    pixelWidth = 1000;
+    w = 8 * 1000;
+    h = 1000;
+    sampleSize = 1;
+    size_t npixels;
+    unsigned int * scanline;
+
+    npixels = w * h;
+
+    for (unsigned int dirID = 0; dirID < 10; ++dirID)
+    {
+      TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w);  // set the width of the image
+      TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h);    // set the height of the image
+      TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sampleSize);   // set number of channels per pixel
+      TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, XdmfArrayType::UInt32()->getElementSize());    // set the size of the channels
+      TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);    // set the origin of the image.
+      TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
+      TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
+      TIFFSetField(tif, TIFFTAG_COMPRESSION, 5); // Only LZW encoding works in any fashion
+
+      unsigned int scanlineSize = TIFFScanlineSize(tif);
+
+      for (unsigned int i = 0; i < h; ++i)
+      {
+        scanline = (unsigned int *) _TIFFmalloc(scanlineSize);
+        for (unsigned int j = 0; j < pixelWidth; ++j)
+        {
+          scanline[j] = (1 + dirID) * (i + j);
+        }
+        TIFFWriteScanline(tif, scanline, i, 0);
+        _TIFFfree(scanline);
+      }
+      TIFFWriteDirectory(tif);
+    }
+  }
+
+  TIFFClose(tif);
+
+  tif = TIFFOpen("compresseddirectories.tif", "r");
+  dircount = 0;
+  if (tif) {
+    do {
+      dircount++;
+    } while (TIFFReadDirectory(tif));
+    TIFFClose(tif);
+  }
+
+  printf("%d directories in file directories.tif\n", dircount);
+
+  std::vector<unsigned int> dirstarts;
+  dirstarts.push_back(0);
+  dirstarts.push_back(0);
+  dirstarts.push_back(0);
+  std::vector<unsigned int> dirstrides;
+  dirstrides.push_back(1);
+  dirstrides.push_back(1);
+  dirstrides.push_back(1);
+  std::vector<unsigned int> dirdims;
+  dirdims.push_back(1000);
+  dirdims.push_back(1000);
+  dirdims.push_back(10);
+  std::vector<unsigned int> dirdataspace;
+  dirdataspace.push_back(1000);
+  dirdataspace.push_back(1000);
+  dirdataspace.push_back(10);
+
+  shared_ptr<XdmfTIFFController> dircontroller = XdmfTIFFController::New("compresseddirectories.tif",
+                                                                         XdmfArrayType::UInt32(),
+                                                                         dirstarts,
+                                                                         dirstrides,
+                                                                         dirdims,
+                                                                         dirdataspace);
+
+  shared_ptr<XdmfArray> dirArray = XdmfArray::New();
+
+  dirArray->insert(dircontroller);
+
+  dirArray->read();
+
+  for (unsigned int dimiter = 0; dimiter < 10; ++dimiter)
+  {
+    for (unsigned int i = 0; i < 1000; ++i)
+    {
+      for (unsigned int j = 0; j < 1000; ++j)
+      {
+//        printf("%u ", dirArray->getValue<unsigned int>((1000 * 1000 * dimiter) + i * 1000 + j));
+        assert(dirArray->getValue<unsigned int>((1000 * 1000 * dimiter) + i * 1000 + j) == (1 + dimiter) * (i + j));
+      }
+//      printf("\n");
+    }
+//    printf("\n\n");
+  }
+
+  dirstrides[2] = 2;
+
+  dirdims[2] = 5;
+
+  shared_ptr<XdmfTIFFController> dircontroller2 = XdmfTIFFController::New("compresseddirectories.tif",
+                                                                          XdmfArrayType::UInt32(),
+                                                                          dirstarts,
+                                                                          dirstrides,
+                                                                          dirdims,
+                                                                          dirdataspace);
+
+  shared_ptr<XdmfArray> dirArray2 = XdmfArray::New();
+
+  dirArray2->insert(dircontroller2);
+
+  dirArray2->read();
+
+  for (unsigned int dimiter = 0; dimiter < 10; dimiter += 2)
+  {
+    for (unsigned int i = 0; i < 1000; ++i)
+    {
+      for (unsigned int j = 0; j < 1000; ++j)
+      {
+//        printf("%u ", dirArray->getValue<unsigned int>((1000 * 1000 * (dimiter / 2)) + i * 1000 + j));
+        assert(dirArray2->getValue<unsigned int>((1000 * 1000 * (dimiter / 2)) + i * 1000 + j) == (1 + dimiter) * (i + j));
+      }
+//      printf("\n");
+    }
+//    printf("\n\n");
+  }
+
+  shared_ptr<XdmfTIFFController> dircontroller3 = XdmfTIFFController::New("compresseddirectories.tif",
+                                                                          XdmfArrayType::UInt32(),
+                                                                          std::vector<unsigned int>(1, 0),
+                                                                          std::vector<unsigned int>(1, 1),
+                                                                          std::vector<unsigned int>(1, 10 * 1000 * 1000),
+                                                                          std::vector<unsigned int>(1, 10 * 1000 * 1000));
+
+  shared_ptr<XdmfArray> dirArray3 = XdmfArray::New();
+
+  dirArray3->insert(dircontroller3);
+
+  dirArray3->read();
+
+  for (unsigned int dimiter = 0; dimiter < 10; ++dimiter)
+  {
+    for (unsigned int i = 0; i < 1000; ++i)
+    {
+      for (unsigned int j = 0; j < 1000; ++j)
+      {
+//        printf("%u ", dirArray3->getValue<unsigned int>((1000 * 1000 * dimiter) + i * 1000 + j));
+        assert(dirArray3->getValue<unsigned int>((1000 * 1000 * dimiter) + i * 1000 + j) == (1 + dimiter) * (i + j));
+      }
+//      printf("\n");
+    }
+//    printf("\n\n");
+  }
+
+  shared_ptr<XdmfTIFFController> dircontroller4 = XdmfTIFFController::New("compresseddirectories.tif",
+                                                                          XdmfArrayType::UInt32(),
+                                                                          std::vector<unsigned int>(1, 2),
+                                                                          std::vector<unsigned int>(1, 6),
+                                                                          std::vector<unsigned int>(1, (10 * 1000 * 1000) / 6),
+                                                                          std::vector<unsigned int>(1, 10 * 1000 * 1000));
+
+  shared_ptr<XdmfArray> dirArray4 = XdmfArray::New();
+
+  dirArray4->insert(dircontroller4);
+
+  dirArray4->read();
+
+  unsigned int hdim = 0;
+  unsigned int wdim = 2;
+  unsigned int dirdim = 0;
+
+  for (unsigned int i = 0; i < dirArray4->getSize(); ++i)
+  {
+    assert(dirArray4->getValue<unsigned int>(i) == (1 + dirdim) * (hdim + wdim));
+    wdim += 6;
+    if (wdim >= 1000)
+    {
+      wdim = wdim % 1000;
+      ++hdim;
+      if (hdim >= 1000)
+      {
+        hdim = hdim % 1000;
+        ++dirdim;
+      }
+    } 
+  }
+
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("compressedtiffoutput.xmf");
+
+  dirArray4->release();
+
+  writer->setMode(XdmfWriter::DistributedHeavyData);
+
+  dirArray4->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+
+  shared_ptr<XdmfArray> readArray = shared_dynamic_cast<XdmfArray>(reader->read("compressedtiffoutput.xmf"));
+
+  readArray->read();
+
+  hdim = 0;
+  wdim = 2;
+  dirdim = 0;
+
+
+  for (unsigned int i = 0; i < readArray->getSize(); ++i)
+  {
+    assert(readArray->getValue<unsigned int>(i) == (1 + dirdim) * (hdim + wdim));
+    wdim += 6;
+    if (wdim >= 1000)
+    {
+      wdim = wdim % 1000;
+      ++hdim;
+      if (hdim >= 1000)
+      {
+        hdim = hdim % 1000;
+        ++dirdim;
+      }
+    }
+  }
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfTemplate.cpp b/tests/Cxx/TestXdmfTemplate.cpp
new file mode 100644
index 0000000..4f506dd
--- /dev/null
+++ b/tests/Cxx/TestXdmfTemplate.cpp
@@ -0,0 +1,569 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfTemplate.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include <iostream>
+
+
+#include "stdio.h"
+
+int main(int, char **)
+{
+  unsigned int arraySize = 12;
+  unsigned int numSteps = 5;
+
+  std::cout << "HDF5" << std::endl;
+
+  shared_ptr<XdmfTemplate> temp = XdmfTemplate::New();
+
+  shared_ptr<XdmfUnstructuredGrid> ungrid = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topo = XdmfTopology::New();
+
+  topo->initialize(XdmfArrayType::Float64(), 12);
+
+  shared_ptr<XdmfGeometry> geo = XdmfGeometry::New();
+
+  geo->initialize(XdmfArrayType::Float64(), 36);
+
+  ungrid->setTopology(topo);
+  ungrid->setGeometry(geo);
+
+  shared_ptr<XdmfAttribute> attr = XdmfAttribute::New();
+
+  attr->initialize(XdmfArrayType::Float64(), 12);
+
+  attr->release();
+
+  shared_ptr<XdmfAttribute> attr2 = XdmfAttribute::New();
+
+  attr2->initialize(XdmfArrayType::Float64(), 12);
+
+  attr2->release();
+
+  shared_ptr<XdmfAttribute> attr3 = XdmfAttribute::New();
+
+  attr3->initialize(XdmfArrayType::Float64(), 12);
+
+  attr3->release();
+
+  ungrid->insert(attr);
+  ungrid->insert(attr2);
+  ungrid->insert(attr3);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("template.xmf");
+
+  shared_ptr<XdmfHeavyDataWriter> heavyWriter = writer->getHeavyDataWriter();
+
+  temp->setHeavyDataWriter(heavyWriter);
+
+  temp->setBase(ungrid);
+
+  for (int iteration = 1; iteration <= numSteps; ++iteration)
+  {
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      attr->insert<double>(i, 1.0 * iteration);
+      attr2->insert<double>(i, 2.0 * iteration);
+      attr3->insert<double>(i, 3.0 * iteration);
+    }
+
+    temp->addStep();
+
+    temp->clearStep();
+  }
+
+  assert(temp->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    temp->setStep(iteration);
+
+    attr->read();
+    attr2->read();
+    attr3->read();
+
+    std::cout << attr->getValuesString() << std::endl;
+    std::cout << attr2->getValuesString() << std::endl;
+    std::cout << attr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(attr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(attr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(attr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    temp->clearStep();
+  }
+
+  temp->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+
+  shared_ptr<XdmfTemplate> readTemp = shared_dynamic_cast<XdmfTemplate>(reader->read("template.xmf"));
+
+  shared_ptr<XdmfUnstructuredGrid> readungrid = shared_dynamic_cast<XdmfUnstructuredGrid>(readTemp->getBase());
+
+  std::cout << "?" << readungrid << std::endl;
+
+  assert(readungrid);
+
+  shared_ptr<XdmfAttribute> readAttr = readungrid->getAttribute(0);
+  shared_ptr<XdmfAttribute> readAttr2 = readungrid->getAttribute(1);
+  shared_ptr<XdmfAttribute> readAttr3 = readungrid->getAttribute(2);
+
+  std::cout << readTemp->getNumberSteps() << " ?= " << numSteps << std::endl;
+
+  assert(readTemp->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    readTemp->setStep(iteration);
+
+    readAttr->read();
+    readAttr2->read();
+    readAttr3->read();
+
+    std::cout << readAttr->getValuesString() << std::endl;
+    std::cout << readAttr2->getValuesString() << std::endl;
+    std::cout << readAttr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(readAttr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(readAttr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(readAttr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    readTemp->clearStep();
+  }
+
+  // Without writing to hdf5
+
+  std::cout << "XML" << std::endl;
+
+  shared_ptr<XdmfTemplate> temp2 = XdmfTemplate::New();
+
+  shared_ptr<XdmfUnstructuredGrid> ungrid2 = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topo2 = XdmfTopology::New();
+
+  topo2->initialize(XdmfArrayType::Float64(), 12);
+
+  shared_ptr<XdmfGeometry> geo2 = XdmfGeometry::New();
+
+  geo2->initialize(XdmfArrayType::Float64(), 36);
+
+  ungrid2->setTopology(topo2);
+  ungrid2->setGeometry(geo2);
+
+  shared_ptr<XdmfAttribute> secondattr = XdmfAttribute::New();
+
+  secondattr->initialize(XdmfArrayType::Float64(), 12);
+
+  secondattr->release();
+
+  shared_ptr<XdmfAttribute> secondattr2 = XdmfAttribute::New();
+
+  secondattr2->initialize(XdmfArrayType::Float64(), 12);
+
+  secondattr2->release();
+
+  shared_ptr<XdmfAttribute> secondattr3 = XdmfAttribute::New();
+
+  secondattr3->initialize(XdmfArrayType::Float64(), 12);
+
+  secondattr3->release();
+
+  ungrid2->insert(secondattr);
+  ungrid2->insert(secondattr2);
+  ungrid2->insert(secondattr3);
+
+  shared_ptr<XdmfWriter> writer2 = XdmfWriter::New("template2.xmf");
+
+  temp2->setBase(ungrid2);
+
+  for (int iteration = 1; iteration <= numSteps; ++iteration)
+  {
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      secondattr->insert<double>(i, 1.0 * iteration);
+      secondattr2->insert<double>(i, 2.0 * iteration);
+      secondattr3->insert<double>(i, 3.0 * iteration);
+    }
+
+    temp2->addStep();
+
+    temp2->clearStep();
+  }
+
+  assert(temp2->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    temp2->setStep(iteration);
+
+    secondattr->read();
+    secondattr2->read();
+    secondattr3->read();
+
+    std::cout << secondattr->getValuesString() << std::endl;
+    std::cout << secondattr2->getValuesString() << std::endl;
+    std::cout << secondattr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(secondattr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(secondattr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(secondattr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    temp2->clearStep();
+  }
+
+  temp2->accept(writer2);
+
+  shared_ptr<XdmfTemplate> readTemp2 = shared_dynamic_cast<XdmfTemplate>(reader->read("template2.xmf"));
+
+  shared_ptr<XdmfUnstructuredGrid> readungrid2 = shared_dynamic_cast<XdmfUnstructuredGrid>(readTemp2->getBase());
+
+  std::cout << "?" << readungrid2 << std::endl;
+
+  assert(readungrid2);
+
+  shared_ptr<XdmfAttribute> secondreadAttr = readungrid2->getAttribute(0);
+  shared_ptr<XdmfAttribute> secondreadAttr2 = readungrid2->getAttribute(1);
+  shared_ptr<XdmfAttribute> secondreadAttr3 = readungrid2->getAttribute(2);
+
+  std::cout << readTemp2->getNumberSteps() << " ?= " << numSteps << std::endl;
+
+  assert(readTemp2->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    readTemp2->setStep(iteration);
+
+    secondreadAttr->read();
+    secondreadAttr2->read();
+    secondreadAttr3->read();
+
+    std::cout << secondreadAttr->getValuesString() << std::endl;
+    std::cout << secondreadAttr2->getValuesString() << std::endl;
+    std::cout << secondreadAttr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(secondreadAttr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(secondreadAttr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(secondreadAttr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    readTemp2->clearStep();
+  }
+
+  readTemp2->removeStep(2);
+
+  assert(readTemp2->getNumberSteps() == numSteps - 1);
+
+  unsigned int offset = 0;
+
+  for (int iteration = 0; iteration < numSteps-1; ++iteration)
+  {
+    if (iteration == 2)
+    {
+      offset++;
+    }
+    readTemp2->setStep(iteration);
+
+    secondreadAttr->read();
+    secondreadAttr2->read();
+    secondreadAttr3->read();
+
+    std::cout << secondreadAttr->getValuesString() << std::endl;
+    std::cout << secondreadAttr2->getValuesString() << std::endl;
+    std::cout << secondreadAttr3->getValuesString() << std::endl;
+
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(secondreadAttr->getValue<double>(i) ==  1.0 * (1 + iteration + offset));
+      assert(secondreadAttr2->getValue<double>(i) == 2.0 * (1 + iteration + offset));
+      assert(secondreadAttr3->getValue<double>(i) == 3.0 * (1 + iteration + offset));
+    }
+
+    readTemp2->clearStep();
+  }
+
+  // Testing Append mode
+
+  shared_ptr<XdmfTemplate> appendtemp = XdmfTemplate::New();
+
+  shared_ptr<XdmfUnstructuredGrid> appendungrid = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> appendtopo = XdmfTopology::New();
+
+  appendtopo->initialize(XdmfArrayType::Float64(), 12);
+
+  shared_ptr<XdmfGeometry> appendgeo = XdmfGeometry::New();
+
+  appendgeo->initialize(XdmfArrayType::Float64(), 36);
+
+  appendungrid->setTopology(appendtopo);
+  appendungrid->setGeometry(appendgeo);
+
+  shared_ptr<XdmfAttribute> appendattr = XdmfAttribute::New();
+
+  appendattr->initialize(XdmfArrayType::Float64(), 12);
+
+  appendattr->release();
+
+  shared_ptr<XdmfAttribute> appendattr2 = XdmfAttribute::New();
+
+  appendattr2->initialize(XdmfArrayType::Float64(), 12);
+
+  appendattr2->release();
+
+  shared_ptr<XdmfAttribute> appendattr3 = XdmfAttribute::New();
+
+  appendattr3->initialize(XdmfArrayType::Float64(), 12);
+
+  appendattr3->release();
+
+  appendungrid->insert(appendattr);
+  appendungrid->insert(appendattr2);
+  appendungrid->insert(appendattr3);
+
+  shared_ptr<XdmfWriter> writer3 = XdmfWriter::New("template3.xmf");
+  writer3->setLightDataLimit(2);
+
+  shared_ptr<XdmfHeavyDataWriter> heavyWriter3 = writer3->getHeavyDataWriter();
+
+  heavyWriter3->setMode(XdmfHeavyDataWriter::Append);
+
+  appendtemp->setHeavyDataWriter(heavyWriter3);
+
+  appendtemp->setBase(appendungrid);
+
+  for (int iteration = 1; iteration <= numSteps; ++iteration)
+  {
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      appendattr->insert<double>(i, 1.0 * iteration);
+      appendattr2->insert<double>(i, 2.0 * iteration);
+      appendattr3->insert<double>(i, 3.0 * iteration);
+    }
+
+    appendtemp->addStep();
+
+    appendtemp->clearStep();
+  }
+
+  std::cout << "writing" << std::endl;
+
+  heavyWriter3->setMode(XdmfHeavyDataWriter::Default);
+
+  appendtemp->accept(writer3); 
+
+  std::cout << "reading" << std::endl;
+
+  shared_ptr<XdmfTemplate> appendreadTemp = shared_dynamic_cast<XdmfTemplate>(reader->read("template3.xmf"));
+
+  shared_ptr<XdmfUnstructuredGrid> appendreadungrid = shared_dynamic_cast<XdmfUnstructuredGrid>(appendreadTemp->getBase());
+
+  std::cout << "?" << appendreadungrid << std::endl;
+
+  assert(appendreadungrid);
+
+  shared_ptr<XdmfAttribute> appendreadAttr = appendreadungrid->getAttribute(0);
+  shared_ptr<XdmfAttribute> appendreadAttr2 = appendreadungrid->getAttribute(1);
+  shared_ptr<XdmfAttribute> appendreadAttr3 = appendreadungrid->getAttribute(2);
+
+  std::cout << appendreadTemp->getNumberSteps() << " ?= " << numSteps << std::endl;
+
+  assert(appendreadTemp->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    appendreadTemp->setStep(iteration);
+
+    appendreadAttr->read();
+    appendreadAttr2->read();
+    appendreadAttr3->read();
+
+    std::cout << appendreadAttr->getValuesString() << std::endl;
+    std::cout << appendreadAttr2->getValuesString() << std::endl;
+    std::cout << appendreadAttr3->getValuesString() << std::endl;
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(appendreadAttr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(appendreadAttr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(appendreadAttr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    appendreadTemp->clearStep();
+  }
+
+  // Overwrite
+
+  shared_ptr<XdmfTemplate> overwritetemp = XdmfTemplate::New();
+
+  shared_ptr<XdmfUnstructuredGrid> overwriteungrid = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> overwritetopo = XdmfTopology::New();
+
+  overwritetopo->initialize(XdmfArrayType::Float64(), 12);
+
+  shared_ptr<XdmfGeometry> overwritegeo = XdmfGeometry::New();
+
+  overwritegeo->initialize(XdmfArrayType::Float64(), 36);
+
+  overwriteungrid->setTopology(overwritetopo);
+  overwriteungrid->setGeometry(overwritegeo);
+
+  shared_ptr<XdmfAttribute> overwriteattr = XdmfAttribute::New();
+
+  overwriteattr->initialize(XdmfArrayType::Float64(), 12);
+
+  overwriteattr->release();
+
+  shared_ptr<XdmfAttribute> overwriteattr2 = XdmfAttribute::New();
+
+  overwriteattr2->initialize(XdmfArrayType::Float64(), 12);
+
+  overwriteattr2->release();
+
+  shared_ptr<XdmfAttribute> overwriteattr3 = XdmfAttribute::New();
+
+  overwriteattr3->initialize(XdmfArrayType::Float64(), 12);
+
+  overwriteattr3->release();
+
+  overwriteungrid->insert(overwriteattr);
+  overwriteungrid->insert(overwriteattr2);
+  overwriteungrid->insert(overwriteattr3);
+
+  shared_ptr<XdmfWriter> writer4 = XdmfWriter::New("template4.xmf");
+  writer4->setLightDataLimit(2);
+
+  shared_ptr<XdmfHeavyDataWriter> heavyWriter4 = writer4->getHeavyDataWriter();
+
+  overwritetemp->setHeavyDataWriter(heavyWriter4);
+
+  overwritetemp->setBase(overwriteungrid);
+
+  for (unsigned int i = 0; i < arraySize; ++i)
+  {
+    overwriteattr->insert<double>(i, 0.0);
+    overwriteattr2->insert<double>(i, 0.0);
+    overwriteattr3->insert<double>(i, 0.0);
+  }
+
+  overwritetemp->preallocateSteps(numSteps);
+
+  for (int iteration = 1; iteration <= numSteps; ++iteration)
+  {
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      overwriteattr->insert<double>(i, 1.0 * iteration);
+      overwriteattr2->insert<double>(i, 2.0 * iteration);
+      overwriteattr3->insert<double>(i, 3.0 * iteration);
+    }
+
+    overwritetemp->addStep();
+
+    overwritetemp->clearStep();
+  }
+
+  std::cout << "writing" << std::endl;
+
+  heavyWriter3->setMode(XdmfHeavyDataWriter::Default);
+
+  overwritetemp->accept(writer4);
+
+  std::cout << "reading" << std::endl;
+
+  shared_ptr<XdmfTemplate> overwritereadTemp = shared_dynamic_cast<XdmfTemplate>(reader->read("template4.xmf"));
+
+  shared_ptr<XdmfUnstructuredGrid> overwritereadungrid = shared_dynamic_cast<XdmfUnstructuredGrid>(overwritereadTemp->getBase());
+
+  std::cout << "?" << overwritereadungrid << std::endl;
+
+  assert(overwritereadungrid);
+
+  shared_ptr<XdmfAttribute> overwritereadAttr = overwritereadungrid->getAttribute(0);
+  shared_ptr<XdmfAttribute> overwritereadAttr2 = overwritereadungrid->getAttribute(1);
+  shared_ptr<XdmfAttribute> overwritereadAttr3 = overwritereadungrid->getAttribute(2);
+
+  std::cout << overwritereadTemp->getNumberSteps() << " ?= " << numSteps << std::endl;
+
+  assert(overwritereadTemp->getNumberSteps() == numSteps);
+
+  for (int iteration = 0; iteration < numSteps; ++iteration)
+  {
+    overwritereadTemp->setStep(iteration);
+
+    overwritereadAttr->read();
+    overwritereadAttr2->read();
+    overwritereadAttr3->read();
+
+    std::cout << overwritereadAttr->getValuesString() << std::endl;
+    std::cout << overwritereadAttr2->getValuesString() << std::endl;
+    std::cout << overwritereadAttr3->getValuesString() << std::endl;
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(overwritereadAttr->getValue<double>(i) ==  1.0 * (1 + iteration));
+      assert(overwritereadAttr2->getValue<double>(i) == 2.0 * (1 + iteration));
+      assert(overwritereadAttr3->getValue<double>(i) == 3.0 * (1 + iteration));
+    }
+
+    overwritereadTemp->clearStep();
+  }
+
+  std::cout << "Removing step 2" << std::endl;
+
+  offset = 0;
+
+  overwritereadTemp->removeStep(2);
+
+  for (int iteration = 0; iteration < numSteps - 1; ++iteration)
+  {
+    if (iteration == 2)
+    {
+      ++offset;
+    }
+    overwritereadTemp->setStep(iteration);
+
+    overwritereadAttr->read();
+    overwritereadAttr2->read();
+    overwritereadAttr3->read();
+
+    std::cout << overwritereadAttr->getValuesString() << std::endl;
+    std::cout << overwritereadAttr2->getValuesString() << std::endl;
+    std::cout << overwritereadAttr3->getValuesString() << std::endl;
+
+    for (unsigned int i = 0; i < arraySize; ++i)
+    {
+      assert(overwritereadAttr->getValue<double>(i) ==  1.0 * (1 + iteration+offset));
+      assert(overwritereadAttr2->getValue<double>(i) == 2.0 * (1 + iteration+offset));
+      assert(overwritereadAttr3->getValue<double>(i) == 3.0 * (1 + iteration+offset));
+    }
+
+    overwritereadTemp->clearStep();
+  }
+    
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfTime.cpp b/tests/Cxx/TestXdmfTime.cpp
new file mode 100644
index 0000000..d0bc2e4
--- /dev/null
+++ b/tests/Cxx/TestXdmfTime.cpp
@@ -0,0 +1,16 @@
+#include "XdmfTime.hpp"
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfTime> time = XdmfTime::New();
+  std::cout << time->getValue() << " ?= " << 0 << std::endl;
+  assert(time->getValue() == 0);
+  time->setValue(50);
+
+  shared_ptr<XdmfTime> time2 = XdmfTime::New(50);
+  std::cout << time->getValue() << " ?= " << time2->getValue() << std::endl;
+  assert(time->getValue() == time2->getValue());
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfTopology.cpp b/tests/Cxx/TestXdmfTopology.cpp
new file mode 100644
index 0000000..faf28a5
--- /dev/null
+++ b/tests/Cxx/TestXdmfTopology.cpp
@@ -0,0 +1,59 @@
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+
+#include <iostream>
+
+void setPolyTopology(shared_ptr<XdmfTopology> polyTop)
+{
+  polyTop->setType(XdmfTopologyType::Polygon(6));
+}
+
+int main(int, char **)
+{
+  // Test != and == operators
+  std::cout << XdmfTopologyType::Hexahedron() << " ?= " << XdmfTopologyType::Hexahedron() << std::endl;
+  std::cout << XdmfTopologyType::Hexahedron() << " ?!= " << XdmfTopologyType::Tetrahedron() << std::endl;
+  assert(XdmfTopologyType::Hexahedron() == XdmfTopologyType::Hexahedron());
+  assert((XdmfTopologyType::Hexahedron() ==
+         XdmfTopologyType::Tetrahedron()) == false);
+  assert((XdmfTopologyType::Hexahedron() !=
+         XdmfTopologyType::Hexahedron()) == false);
+  assert(XdmfTopologyType::Hexahedron() != XdmfTopologyType::Tetrahedron());
+
+  shared_ptr<XdmfTopology> top = XdmfTopology::New();
+
+  std::cout << top->getType() << " ?= " << XdmfTopologyType::NoTopologyType() << std::endl;
+  std::cout << top->getType()->getNodesPerElement() << " ?= " << 0 << std::endl;
+  std::cout << top->getType()->getName() << " ?= NoTopology" << std::endl;
+
+  assert(top->getType() == XdmfTopologyType::NoTopologyType());
+  assert(top->getType()->getNodesPerElement() == 0);
+  assert(top->getType()->getName().compare("NoTopology") == 0);
+
+  top->setType(XdmfTopologyType::Hexahedron());
+
+  std::cout << top->getType() << " ?= " << XdmfTopologyType::Hexahedron() << std::endl;
+  std::cout << top->getType()->getNodesPerElement() << " ?= " << 9 << std::endl;
+  std::cout << top->getType()->getName() << " ?= Hexahedron" << std::endl;
+
+  assert(top->getType() == XdmfTopologyType::Hexahedron());
+  assert(top->getType()->getNodesPerElement() == 8);
+  assert(top->getType()->getName().compare("Hexahedron") == 0);
+
+  shared_ptr<const XdmfTopologyType> polygon = XdmfTopologyType::Polygon(6);
+  shared_ptr<const XdmfTopologyType> polygon6 = XdmfTopologyType::Polygon(6);
+  shared_ptr<const XdmfTopologyType> polygon12 = XdmfTopologyType::Polygon(12);
+
+  std::cout << polygon << " ?= " << polygon6 << std::endl;
+  std::cout << polygon << " ?!= " << polygon12 << std::endl;
+
+  assert(polygon == polygon6);
+  assert((polygon == polygon12) == false);
+
+  shared_ptr<XdmfTopology> polyTop = XdmfTopology::New();
+  setPolyTopology(polyTop);
+  std::cout << polyTop->getType()->getNodesPerElement() << " ?= " << 6 << std::endl;
+  assert(polyTop->getType()->getNodesPerElement() == 6);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfTopologyMixed.cpp b/tests/Cxx/TestXdmfTopologyMixed.cpp
new file mode 100644
index 0000000..20731c6
--- /dev/null
+++ b/tests/Cxx/TestXdmfTopologyMixed.cpp
@@ -0,0 +1,81 @@
+#include "XdmfDomain.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+
+int main(int, char **)
+{
+
+  //
+  // Create a unstructured grid consisting of a quadrilateral element
+  // and a polyline element connected to each other by a single node at
+  // the corner of each.
+  //
+  shared_ptr<XdmfUnstructuredGrid> grid = XdmfUnstructuredGrid::New();
+  grid->setName("Mixed");
+
+  // Set Geometry
+  double points[] = {0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 2.0, 2.0, 3.0,
+                     1.0, 4.0, 2.0, 5.0, 1.0, 6.0, 2.0};
+  grid->getGeometry()->setType(XdmfGeometryType::XY());
+  grid->getGeometry()->insert(0, &points[0], 18);
+
+  // Set Topology
+  shared_ptr<XdmfTopology> topology = grid->getTopology();
+  topology->setType(XdmfTopologyType::Mixed());
+  topology->pushBack(XdmfTopologyType::Quadrilateral()->getID());
+  topology->pushBack(0);
+  topology->pushBack(1);
+  topology->pushBack(2);
+  topology->pushBack(3);
+  topology->pushBack(XdmfTopologyType::Polyline(0)->getID());
+  topology->pushBack(6);
+  topology->pushBack(2);
+  topology->pushBack(4);
+  topology->pushBack(5);
+  topology->pushBack(6);
+  topology->pushBack(7);
+  topology->pushBack(8);
+
+  std::cout << topology->getNumberElements() << " ?= " << 2 << std::endl;
+
+  assert(topology->getNumberElements() == 2);
+
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+  domain->insert(grid);
+
+  shared_ptr<XdmfWriter> writer =
+    XdmfWriter::New("TestXdmfTopologyMixed1.xmf");
+  domain->accept(writer);
+
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfDomain> readDomain =
+    shared_dynamic_cast<XdmfDomain>
+    (reader->read("TestXdmfTopologyMixed1.xmf"));
+
+  shared_ptr<XdmfWriter> writer2 =
+    XdmfWriter::New("TestXdmfTopologyMixed2.xmf");
+  readDomain->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("TestXdmfTopologyMixed1.xmf",
+                                         "TestXdmfTopologyMixed2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("TestXdmfTopologyMixed1.xmf",
+                                            "TestXdmfTopologyMixed2.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfUnstructuredGrid.cpp b/tests/Cxx/TestXdmfUnstructuredGrid.cpp
new file mode 100644
index 0000000..42f1d25
--- /dev/null
+++ b/tests/Cxx/TestXdmfUnstructuredGrid.cpp
@@ -0,0 +1,98 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfTime.hpp"
+
+#include <iostream>
+
+int main(int, char **)
+{
+  shared_ptr<XdmfUnstructuredGrid> grid = XdmfUnstructuredGrid::New();
+  std::string gridName = "Grid1";
+
+  grid->setName(gridName);
+  std::cout << grid->getName() << " ?= " << gridName << std::endl;
+  assert(grid->getName().compare(gridName) == 0);
+
+  // Insert Attributes
+  shared_ptr<XdmfAttribute> attr = XdmfAttribute::New();
+  attr->setName("foo");
+  std::cout << grid->getNumberAttributes() << " ?= " << 0 << std::endl;
+  assert(grid->getNumberAttributes() == 0);
+  grid->insert(attr);
+  std::cout << grid->getNumberAttributes() << " ?= " << 1 << std::endl;
+  std::cout << grid->getAttribute(0) << " ?= " << attr << std::endl;
+  std::cout << grid->getAttribute("foo") << " ?= " << attr << std::endl;
+  std::cout << grid->getAttribute(1) << " ?= " << "NULL" << std::endl;
+  std::cout << grid->getAttribute("foo1") << " ?= " << "NULL" << std::endl;
+  assert(grid->getNumberAttributes() == 1);
+  assert(grid->getAttribute(0) == attr);
+  assert(grid->getAttribute("foo") == attr);
+  assert(grid->getAttribute(1) == NULL);
+  assert(grid->getAttribute("foo1") == NULL);
+
+  // Insert Sets
+  shared_ptr<XdmfSet> set = XdmfSet::New();
+  set->setName("foo");
+  std::cout << grid->getNumberSets() << " ?= " << 0 << std::endl;
+  assert(grid->getNumberSets() == 0);
+  grid->insert(set);
+  std::cout << grid->getNumberSets() << " ?= " << 1 << std::endl;
+  std::cout << grid->getSet(0) << " ?= " << set << std::endl;
+  std::cout << grid->getSet("foo") << " ?= " << set << std::endl;
+  std::cout << grid->getSet(1) << " ?= " << "NULL" << std::endl;
+  std::cout << grid->getSet("foo1") << " ?= " << "NULL" << std::endl;
+  assert(grid->getNumberSets() == 1);
+  assert(grid->getSet(0) == set);
+  assert(grid->getSet("foo") == set);
+  assert(grid->getSet("foo1") == NULL);
+  assert(grid->getSet(1) == NULL);
+
+  // Insert Time
+  std::cout << grid->getTime() << " ?= " << "NULL" << std::endl;
+  assert(grid->getTime() == NULL);
+  shared_ptr<XdmfTime> time = XdmfTime::New(0);
+  grid->setTime(time);
+  std::cout << grid->getTime() << " ?= " << time << std::endl;
+  assert(grid->getTime() == time);
+
+  // Remove Attributes and Sets
+  grid->insert(attr);
+  grid->insert(set);
+  std::cout << grid->getNumberAttributes() << " ?= " << 2 << std::endl;
+  std::cout << grid->getNumberSets() << " ?= " << 2 << std::endl;
+  assert(grid->getNumberAttributes() == 2);
+  assert(grid->getNumberSets() == 2);
+  grid->removeAttribute(2);
+  grid->removeSet(2);
+  std::cout << grid->getNumberAttributes() << " ?= " << 2 << std::endl;
+  std::cout << grid->getNumberSets() << " ?= " << 2 << std::endl;
+  assert(grid->getNumberAttributes() == 2);
+  assert(grid->getNumberSets() == 2);
+  grid->removeAttribute(0);
+  grid->removeSet(0);
+  std::cout << grid->getNumberAttributes() << " ?= " << 1 << std::endl;
+  std::cout << grid->getNumberSets() << " ?= " << 1 << std::endl;
+  assert(grid->getNumberAttributes() == 1);
+  assert(grid->getNumberSets() == 1);
+  grid->removeAttribute("foo1");
+  grid->removeSet("foo1");
+  std::cout << grid->getNumberAttributes() << " ?= " << 1 << std::endl;
+  std::cout << grid->getNumberSets() << " ?= " << 1 << std::endl;
+  assert(grid->getNumberAttributes() == 1);
+  assert(grid->getNumberSets() == 1);
+  grid->removeAttribute("foo");
+  grid->removeSet("foo");
+  std::cout << grid->getNumberAttributes() << " ?= " << 0 << std::endl;
+  std::cout << grid->getNumberSets() << " ?= " << 0 << std::endl;
+  assert(grid->getNumberAttributes() == 0);
+  assert(grid->getNumberSets() == 0);
+
+  // Insert Information
+  shared_ptr<XdmfInformation> information =
+    XdmfInformation::New("key", "value");
+  grid->insert(information);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfVisitorValueCounter.cpp b/tests/Cxx/TestXdmfVisitorValueCounter.cpp
new file mode 100644
index 0000000..965be6e
--- /dev/null
+++ b/tests/Cxx/TestXdmfVisitorValueCounter.cpp
@@ -0,0 +1,67 @@
+#include "XdmfTestDataGenerator.hpp"
+#include "XdmfVisitor.hpp"
+#include "XdmfGrid.hpp"
+#include <iostream>
+
+// Make a new XdmfVisitor that simply counts number of values
+class XdmfVisitorValueCounter : public XdmfVisitor,
+                                public Loki::Visitor<XdmfArray> {
+
+public:
+
+  /**
+   * Create a new XdmfVisitorValueCounter.
+   *
+   * @return constructed XdmfVisitorValueCounter.
+   */
+  static shared_ptr<XdmfVisitorValueCounter>
+  New()
+  {
+    shared_ptr<XdmfVisitorValueCounter> p(new XdmfVisitorValueCounter());
+    return p;
+  };
+
+  ~XdmfVisitorValueCounter()
+  {
+  };
+
+  int
+  getCount()
+  {
+    return mCount;
+  }
+
+  using XdmfVisitor::visit;
+
+  void
+  visit(XdmfArray & array, 
+        const shared_ptr<XdmfBaseVisitor>)
+  {
+    mCount += array.getSize();
+  }
+
+protected:
+
+  XdmfVisitorValueCounter() :
+    mCount(0)
+  {
+  }
+
+private:
+
+  int mCount;
+};
+
+int main(int, char **)
+{
+  shared_ptr<XdmfVisitorValueCounter> visitor = XdmfVisitorValueCounter::New();
+  shared_ptr<XdmfGrid> grid = XdmfTestDataGenerator::createHexahedron();
+
+  grid->accept(visitor);
+
+  std::cout << visitor->getCount() << " ?= " << 71 << std::endl;
+
+  assert(visitor->getCount() == 71);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfWriter.cpp b/tests/Cxx/TestXdmfWriter.cpp
new file mode 100644
index 0000000..b8d474d
--- /dev/null
+++ b/tests/Cxx/TestXdmfWriter.cpp
@@ -0,0 +1,31 @@
+#include "XdmfDomain.hpp"
+#include "XdmfSystemUtils.hpp"
+#include "XdmfWriter.hpp"
+#include <iostream>
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("output.xmf");
+
+  std::string realPath = XdmfSystemUtils::getRealPath("output.xmf");
+
+  std::cout << writer->getFilePath() << " ?= " << realPath << std::endl;
+
+  assert(writer->getFilePath().compare(realPath) == 0);
+  writer->setLightDataLimit(10);
+
+  std::cout << writer->getLightDataLimit() << " ?= " << 10 << std::endl;
+
+  assert(writer->getLightDataLimit() == 10);
+
+  shared_ptr<XdmfUnstructuredGrid> grid =
+    XdmfTestDataGenerator::createHexahedron();
+
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+  domain->insert(grid);
+  domain->accept(writer);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfWriterHDF5ThenXML.cpp b/tests/Cxx/TestXdmfWriterHDF5ThenXML.cpp
new file mode 100644
index 0000000..2ce7650
--- /dev/null
+++ b/tests/Cxx/TestXdmfWriterHDF5ThenXML.cpp
@@ -0,0 +1,34 @@
+#include "XdmfDomain.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfUnstructuredGrid> grid = 
+    XdmfTestDataGenerator::createHexahedron();
+
+  // First write and release heavy data
+  shared_ptr<XdmfHDF5Writer> hdf5Writer = XdmfHDF5Writer::New("output.h5");
+  grid->getGeometry()->accept(hdf5Writer);
+  grid->getGeometry()->release();
+
+  grid->getTopology()->accept(hdf5Writer);
+  grid->getTopology()->release();
+
+  for(unsigned int i=0; i<grid->getNumberAttributes(); ++i) {
+    grid->getAttribute(i)->accept(hdf5Writer);
+    grid->getAttribute(i)->release();
+  }
+
+  // Now insert into domain and write light data
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+  domain->insert(grid);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("output.xmf", hdf5Writer);
+  writer->setLightDataLimit(10);
+  domain->accept(writer);
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfXPath.cpp b/tests/Cxx/TestXdmfXPath.cpp
new file mode 100644
index 0000000..93fe947
--- /dev/null
+++ b/tests/Cxx/TestXdmfXPath.cpp
@@ -0,0 +1,93 @@
+#include "XdmfDomain.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+#include <iostream>
+
+#include "XdmfTestCompareFiles.hpp"
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("XdmfXPath1.xmf");
+  shared_ptr<XdmfUnstructuredGrid> grid =
+    XdmfTestDataGenerator::createHexahedron();
+
+  shared_ptr<XdmfUnstructuredGrid> newGrid = XdmfUnstructuredGrid::New();
+  newGrid->setName("NoAttributes");
+  newGrid->setGeometry(grid->getGeometry());
+  newGrid->setTopology(grid->getTopology());
+
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+  domain->insert(grid);
+  domain->insert(grid);
+  domain->insert(newGrid);
+  domain->accept(writer);
+
+  // Try to find xpaths written to file
+  std::ifstream file("XdmfXPath1.xmf");
+  std::stringstream fileBuffer;
+  fileBuffer << file.rdbuf();
+  std::string fileContents(fileBuffer.str());
+
+  if (fileContents.find("xpointer=\"element(/1/1/1)\"") !=
+      std::string::npos)
+  {
+    std::cout << "XPointer 1 found" << std::endl;
+  }
+  else
+  {
+    std::cout << "XPointer 1 not found" << std::endl;
+  }
+
+  if (fileContents.find("xpointer=\"element(/1/1/1/2)\"") !=
+      std::string::npos)
+  {
+    std::cout << "XPointer 2 found" << std::endl;
+  }
+  else
+  {
+    std::cout << "XPointer 2 not found" << std::endl;
+  }
+
+  if (fileContents.find("xpointer=\"element(/1/1/1/3)\"") !=
+      std::string::npos)
+  {
+    std::cout << "XPointer 3 found" << std::endl;
+  }
+  else
+  {
+    std::cout << "XPointer 3 not found" << std::endl;
+  }
+
+  assert(fileContents.find("xpointer=\"element(/1/1/1)\"") !=
+         std::string::npos);
+  assert(fileContents.find("xpointer=\"element(/1/1/1/2)\"") !=
+         std::string::npos);
+  assert(fileContents.find("xpointer=\"element(/1/1/1/3)\"") !=
+         std::string::npos);
+
+  // Make sure when we read it in we get the same structure as when we wrote
+  // it out (multiple items holding the same shared pointers)
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  shared_ptr<XdmfDomain> domain2 =
+    shared_dynamic_cast<XdmfDomain>(reader->read("XdmfXPath1.xmf"));
+  shared_ptr<XdmfWriter> writer2 =
+    XdmfWriter::New("XdmfXPath2.xmf");
+  domain2->accept(writer2);
+
+  if (XdmfTestCompareFiles::compareFiles("XdmfXPath1.xmf",
+                                            "XdmfXPath2.xmf"))
+  {
+    std::cout << "compared files are the same" << std::endl;
+  }
+  else
+  {
+    std::cout << "compared files are not the same" << std::endl;
+  }
+
+  assert(XdmfTestCompareFiles::compareFiles("XdmfXPath1.xmf",
+                                            "XdmfXPath2.xmf"));
+
+  return 0;
+}
diff --git a/tests/Cxx/TestXdmfXPointerReference.cpp b/tests/Cxx/TestXdmfXPointerReference.cpp
new file mode 100644
index 0000000..db6036c
--- /dev/null
+++ b/tests/Cxx/TestXdmfXPointerReference.cpp
@@ -0,0 +1,57 @@
+#include <iostream>
+#include <XdmfDomain.hpp>
+#include <XdmfGridCollection.hpp>
+#include <XdmfWriter.hpp>
+#include <XdmfUnstructuredGrid.hpp>
+#include <XdmfTime.hpp>
+#include <XdmfReader.hpp>
+
+int main(int ac, char *av[])
+{
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+
+  shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+
+  shared_ptr<XdmfGridCollection> collection1 = XdmfGridCollection::New();
+  shared_ptr<XdmfGridCollection> collection2 = XdmfGridCollection::New();
+
+  shared_ptr<XdmfUnstructuredGrid> unstructuredGrid = XdmfUnstructuredGrid::New();
+
+  collection1->insert(unstructuredGrid);
+  collection2->insert(unstructuredGrid);
+  domain->insert(collection1);
+  domain->insert(collection2);
+
+  shared_ptr<XdmfWriter> writer = XdmfWriter::New("duplicateXpointer.xmf");
+
+  domain->accept(writer);
+
+  shared_ptr<XdmfDomain> readDomain = shared_dynamic_cast<XdmfDomain>(reader->read("duplicateXpointer.xmf"));
+
+  assert(readDomain->getGridCollection(0)->getUnstructuredGrid(0) == readDomain->getGridCollection(1)->getUnstructuredGrid(0));
+
+  assert(readDomain->getGridCollection(0)->getUnstructuredGrid(0).get() == readDomain->getGridCollection(1)->getUnstructuredGrid(0).get());
+
+  readDomain->getGridCollection(0)->getUnstructuredGrid(0)->setName("Test Grid");
+
+  shared_ptr<XdmfTime> time = XdmfTime::New(5.5);
+
+  readDomain->getGridCollection(1)->getUnstructuredGrid(0)->setTime(time);
+
+  shared_ptr<XdmfWriter> writer2 = XdmfWriter::New("duplicateXpointer2.xmf");
+
+  readDomain->accept(writer2);
+
+  shared_ptr<XdmfDomain> readDomain2 = shared_dynamic_cast<XdmfDomain>(reader->read("duplicateXpointer2.xmf"));
+
+  std::cout << readDomain2->getGridCollection(1)->getUnstructuredGrid(0)->getName() << " ?= Test Grid" << std::endl;
+
+  std::cout << readDomain2->getGridCollection(0)->getUnstructuredGrid(0)->getTime()->getValue() << " ?= " << 5.5 << std::endl;
+
+  assert(readDomain2->getGridCollection(1)->getUnstructuredGrid(0)->getName() =="Test Grid");
+
+  assert(readDomain2->getGridCollection(0)->getUnstructuredGrid(0)->getTime()->getValue() == 5.5);
+
+
+  return 0;
+}
diff --git a/tests/Cxx/WriteArray.cpp b/tests/Cxx/WriteArray.cpp
new file mode 100644
index 0000000..1a5aa3e
--- /dev/null
+++ b/tests/Cxx/WriteArray.cpp
@@ -0,0 +1,42 @@
+#include <iostream>
+#include <stdlib.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfWriter.hpp>
+#include <XdmfDomain.hpp>
+#include <XdmfUnstructuredGrid.hpp>
+#include <XdmfGeometry.hpp>
+#include <XdmfTopology.hpp>
+
+int main(int, char **)
+{
+	
+	shared_ptr<XdmfArray> writtenArray = XdmfArray::New();
+	for (int i = 0; i < 20; i++)
+	{
+		writtenArray->pushBack(i);
+	}
+	shared_ptr<XdmfWriter> arrayWriter = XdmfWriter::New("arraydata.xmf");
+	arrayWriter->setLightDataLimit(5);
+	writtenArray->accept(arrayWriter);
+	
+
+	/*
+	shared_ptr<XdmfDomain> primaryDomain = XdmfDomain::New();
+	shared_ptr<XdmfUnstructuredGrid> testGrid = XdmfUnstructuredGrid::New();
+	primaryDomain->insert(testGrid);
+	shared_ptr<XdmfGeometry> testGeometry = XdmfGeometry::New();
+	for (int i = 0; i < 12; i++)
+	{
+		testGeometry->pushBack(i);
+	}
+	testGrid->setGeometry(testGeometry);
+	shared_ptr<XdmfTopology> testTopology = XdmfTopology::New();
+	testGrid->setTopology(testTopology);
+
+	shared_ptr<XdmfWriter> arrayWriter = XdmfWriter::New("array.xmf");
+	primaryDomain->accept(arrayWriter);
+	*/
+
+	return 0;
+}
diff --git a/tests/Cxx/XdmfExampleCollect.cpp b/tests/Cxx/XdmfExampleCollect.cpp
new file mode 100644
index 0000000..9432191
--- /dev/null
+++ b/tests/Cxx/XdmfExampleCollect.cpp
@@ -0,0 +1,42 @@
+#include "XdmfDomain.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfArray.hpp"
+
+int main(int, char **)
+{
+	shared_ptr<XdmfDomain> primaryDomain = XdmfDomain::New();
+	shared_ptr<XdmfInformation> domaininfo = XdmfInformation::New("Domain", "This is the primary data structure in Xdmf");
+	shared_ptr<XdmfInformation> domaininfoinfo = XdmfInformation::New("Information", "Information can have information");
+	domaininfo->insert(domaininfoinfo);
+	primaryDomain->insert(domaininfo);
+
+
+	shared_ptr<XdmfInformation> mergedInformation = XdmfInformation::New("XIncludes", "3");
+	shared_ptr<XdmfInformation> sourceInformation = XdmfInformation::New("testoutput.xmf", "xpointer(//Xdmf/Domain/Grid[1])");
+	mergedInformation->insert(sourceInformation);
+	sourceInformation = XdmfInformation::New("testoutput2.xmf", "xpointer(//Xdmf/Domain/Grid[1])");
+	mergedInformation->insert(sourceInformation);
+        sourceInformation = XdmfInformation::New("editedtestoutput.xmf", "xpointer(//Xdmf/Domain/Grid[1])");
+        mergedInformation->insert(sourceInformation);
+	primaryDomain->insert(mergedInformation);
+
+
+	shared_ptr<XdmfInformation> secondaryDomainInfo = XdmfInformation::New("Domain", "This is the primary data structure in Xdmf");
+	secondaryDomainInfo->insert(domaininfoinfo);
+	primaryDomain->insert(secondaryDomainInfo);
+
+
+	shared_ptr<XdmfHDF5Writer> exampleHeavyWriter = XdmfHDF5Writer::New("combinedout.h5");
+	shared_ptr<XdmfWriter> exampleWriter = XdmfWriter::New("combinedout.xmf", exampleHeavyWriter);
+
+	//set this to false to stop the writer from parsing information for XIncludes
+	exampleWriter->setXPathParse(true);
+
+
+	primaryDomain->accept(exampleWriter);
+
+	return 0;
+}
diff --git a/tests/Cxx/XdmfFileAcceptTest.cpp b/tests/Cxx/XdmfFileAcceptTest.cpp
new file mode 100644
index 0000000..51abf00
--- /dev/null
+++ b/tests/Cxx/XdmfFileAcceptTest.cpp
@@ -0,0 +1,166 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+
+        std::vector<unsigned int> outputVector;
+
+        shared_ptr<XdmfArray> testArray = XdmfArray::New();
+        testArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> testArray2 = XdmfArray::New();
+        testArray2->initialize<int>(0);
+
+        std::string newPath = "dsm";
+        std::string newSetPath = "dataspace";
+        std::string secondSetPath = "data2";
+
+        // Change this to determine the number of cores used as servers
+        unsigned int numServersCores = 2;
+        // Change this to determine the size of the arrays generated when initializing
+        unsigned int writeArraySize = 4;
+
+        std::vector<unsigned int> writeStartVector;
+        std::vector<unsigned int> writeStrideVector;
+        std::vector<unsigned int> writeCountVector;
+        std::vector<unsigned int> writeDataSizeVector;
+
+        std::vector<unsigned int> readStartVector;
+        std::vector<unsigned int> readStrideVector;
+        std::vector<unsigned int> readCountVector;
+        std::vector<unsigned int> readDataSizeVector;
+
+        std::vector<unsigned int> readOutputCountVector;
+
+        shared_ptr<XdmfArray> readArray = XdmfArray::New();
+        readArray->initialize<int>(0);
+
+        shared_ptr<XdmfArray> readArray2 = XdmfArray::New();
+        readArray2->initialize<int>(0);
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController;
+
+        shared_ptr<XdmfHDF5ControllerDSM> readController2;
+        shared_ptr<XdmfHDF5ControllerDSM> readOutputController2;
+        shared_ptr<XdmfHDF5ControllerDSM> writeController2;
+
+        MPI_Comm workerComm;
+
+        MPI_Group workers, dsmgroup;
+
+        MPI_Comm_group(comm, &dsmgroup);
+        int * ServerIds = (int *)calloc((numServersCores), sizeof(int));
+        unsigned int index = 0;
+        for(int i=size-numServersCores ; i <= size-1 ; ++i)
+        {
+                ServerIds[index++] = i;
+        }
+
+        MPI_Group_excl(dsmgroup, index, ServerIds, &workers);
+        int testval = MPI_Comm_create(comm, workers, &workerComm);
+        cfree(ServerIds);
+
+        shared_ptr<XdmfHDF5WriterDSM> exampleWriter = XdmfHDF5WriterDSM::New(newPath, comm, dsmSize/numServersCores, 1, 1);
+
+        exampleWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+        exampleWriter->setReleaseData(true);
+
+        shared_ptr<XdmfWriter> fileWriter = XdmfWriter::New("dsmfile.xmf", exampleWriter);
+
+        shared_ptr<XdmfReader> fileReader = XdmfReader::New();
+
+        //split out sub-comm for the worker cores
+        //server cores will not progress to this point until after the servers are done running
+
+        if (id != 1)
+        {
+
+          shared_ptr<XdmfDomain> domain = XdmfDomain::New();
+
+          shared_ptr<XdmfUnstructuredGrid> ungrid = XdmfUnstructuredGrid::New();
+
+          domain->insert(ungrid);
+
+          shared_ptr<XdmfGeometry> geo = XdmfGeometry::New();
+
+          shared_ptr<XdmfTopology> topo = XdmfTopology::New();
+
+          shared_ptr<XdmfAttribute> array = XdmfAttribute::New();
+
+          ungrid->setTopology(topo);
+          ungrid->setGeometry(geo);
+
+          ungrid->insert(array);
+          
+          for (unsigned int i = 0; i < 1000; ++i)
+          {
+            geo->pushBack(i);
+            topo->pushBack(i);
+            array->pushBack(i);
+          }
+
+          if (id == 0)
+          {
+            exampleWriter->getServerBuffer()->GetComm()->OpenPort();
+          }
+
+          domain->accept(exampleWriter);
+          if (id == 0)
+          {
+            domain->accept(fileWriter);
+          }
+
+          exampleWriter->getServerBuffer()->GetComm()->Barrier(XDMF_DSM_INTRA_COMM);
+
+/*
+          if (id == 2)
+          {
+            shared_ptr<XdmfArray> readArray = shared_dynamic_cast<XdmfArray>(fileReader->read("dsmfile.xmf"));
+          }
+*/
+
+        }
+
+        if (id == 0)
+        {
+           exampleWriter->getServerBuffer()->SendAccept(1);
+        }
+
+        MPI_Barrier(exampleWriter->getServerBuffer()->GetComm()->GetInterComm());
+
+        if (id == 0)
+        {
+           exampleWriter->getServerBuffer()->GetComm()->ClosePort();
+        }
+
+        MPI_Barrier(comm);
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/tests/Cxx/XdmfFileConnectTest.cpp b/tests/Cxx/XdmfFileConnectTest.cpp
new file mode 100644
index 0000000..f17b21d
--- /dev/null
+++ b/tests/Cxx/XdmfFileConnectTest.cpp
@@ -0,0 +1,118 @@
+#include <mpi.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <fstream>
+#include <sstream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfDSMDriver.hpp"
+#include "XdmfDSMBuffer.hpp"
+#include "XdmfHDF5WriterDSM.hpp"
+#include "XdmfHDF5ControllerDSM.hpp"
+
+int main(int argc, char *argv[])
+{
+        int size, id, dsmSize;
+        dsmSize = 64;//The total size of the DSM being created
+        MPI_Comm comm = MPI_COMM_WORLD;
+
+        MPI_Init(&argc, &argv);
+
+        MPI_Comm_rank(comm, &id);
+        MPI_Comm_size(comm, &size);
+
+        // The read should cause a connect to the dsm of the other process.
+        #ifdef  _WIN32
+                Sleep(500)
+        #else
+                sleep(5);
+        #endif
+
+        std::string configFileName = "dsmfile.xmf";
+
+        std::ifstream testStream;
+        const char * configFileNamePtr = configFileName.c_str();
+        testStream.open(configFileNamePtr);
+
+        while (!testStream.good()) { // Wait for the config file to be generated
+          testStream.close();
+          #ifdef  _WIN32
+            Sleep(500)
+          #else
+            sleep(5);
+          #endif
+          testStream.open(configFileNamePtr);
+        }
+
+        XdmfDSMBuffer * dsmBuffer = new XdmfDSMBuffer();
+        dsmBuffer->SetComm(new XdmfDSMCommMPI());
+        dsmBuffer->GetComm()->DupComm(MPI_COMM_WORLD);
+        dsmBuffer->GetComm()->DupInterComm(MPI_COMM_WORLD);
+
+        dsmBuffer->GetComm()->Init();
+
+        xdmf_dsm_set_manager(dsmBuffer);
+
+        shared_ptr<XdmfReader> fileReader = XdmfReader::New();
+
+        assert(fileReader);
+
+        shared_ptr<XdmfDomain> readDomain = shared_dynamic_cast<XdmfDomain>(fileReader->read("dsmfile.xmf"));
+
+        shared_ptr<XdmfUnstructuredGrid> readUnGrid = readDomain->getUnstructuredGrid(0);
+
+        assert(readUnGrid);
+
+        shared_ptr<XdmfGeometry> readGeo = readUnGrid->getGeometry();
+
+        assert(readGeo);
+
+        readGeo->read();
+
+        for (unsigned int i = 0; i < readGeo->getSize(); ++i)
+        {
+          assert(readGeo->getValue<unsigned int>(i) == i);
+        }
+
+        shared_ptr<XdmfTopology> readTopo = readUnGrid->getTopology();
+
+        assert(readTopo);
+
+        readTopo->read();
+
+        for (unsigned int i = 0; i < readTopo->getSize(); ++i)
+        {
+          assert(readTopo->getValue<unsigned int>(i) == i);
+        }
+
+        shared_ptr<XdmfAttribute> readAttr = readUnGrid->getAttribute(0);
+
+        assert(readAttr);
+
+        readAttr->read();
+
+        for (unsigned int i = 0; i < readAttr->getSize(); ++i)
+        {
+          assert(readAttr->getValue<unsigned int>(i) == i);
+        }
+
+        if (id == 0)
+        {
+          shared_dynamic_cast<XdmfHDF5ControllerDSM>(readAttr->getHeavyDataController(0))->stopDSM();
+        }
+
+        MPI_Barrier(shared_dynamic_cast<XdmfHDF5ControllerDSM>(readAttr->getHeavyDataController(0))->getServerBuffer()->GetComm()->GetInterComm());
+
+        MPI_Barrier(comm);
+
+        MPI_Finalize();
+
+        return 0;
+}
diff --git a/tests/Cxx/XdmfFortranExample.f90 b/tests/Cxx/XdmfFortranExample.f90
new file mode 100644
index 0000000..3aaa2e1
--- /dev/null
+++ b/tests/Cxx/XdmfFortranExample.f90
@@ -0,0 +1,104 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Kenneth Leiter (kenneth.leiter at arl.army.mil)
+!!
+!!     Use the Xdmf Fortran Bindings to write out a simple mesh consisting of
+!!     two hexahedrons.  Link against the XdmfFortran library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+PROGRAM XdmfFortranExample
+IMPLICIT NONE
+
+  INTEGER*8 obj
+  character*256 filename
+  REAL*4 myPoints(3,3,4)
+  INTEGER myConnections(8,2)
+  REAL*8 myCellAttribute(2), myNodeAttribute(3,4)
+
+  filename = 'my_output'//CHAR(0)
+  
+  myPoints(1,1,1) = 0
+  myPoints(2,1,1) = 0
+  myPoints(3,1,1) = 1
+  myPoints(1,2,1) = 1
+  myPoints(2,2,1) = 0
+  myPoints(3,2,1) = 1
+  myPoints(1,3,1) = 3
+  myPoints(2,3,1) = 0
+  myPoints(3,3,1) = 2
+  myPoints(1,1,2) = 0
+  myPoints(2,1,2) = 1
+  myPoints(3,1,2) = 1
+  myPoints(1,2,2) = 1
+  myPoints(2,2,2) = 1
+  myPoints(3,2,2) = 1
+  myPoints(1,3,2) = 3
+  myPoints(2,3,2) = 2
+  myPoints(3,3,2) = 2
+  myPoints(1,1,3) = 0
+  myPoints(2,1,3) = 0
+  myPoints(3,1,3) = -1
+  myPoints(1,2,3) = 1
+  myPoints(2,2,3) = 0
+  myPoints(3,2,3) = -1
+  myPoints(1,3,3) = 3
+  myPoints(2,3,3) = 0
+  myPoints(3,3,3) = -2
+  myPoints(1,1,4) = 0
+  myPoints(2,1,4) = 1
+  myPoints(3,1,4) = -1
+  myPoints(1,2,4) = 1
+  myPoints(2,2,4) = 1
+  myPoints(3,2,4) = -1
+  myPoints(1,3,4) = 3
+  myPoints(2,3,4) = 2
+  myPoints(3,3,4) = -2
+  
+  myConnections(1,1) = 0
+  myConnections(2,1) = 1
+  myConnections(3,1) = 7
+  myConnections(4,1) = 6
+  myConnections(5,1) = 3
+  myConnections(6,1) = 4
+  myConnections(7,1) = 10
+  myConnections(8,1) = 9
+  myConnections(1,2) = 1
+  myConnections(2,2) = 2
+  myConnections(3,2) = 8
+  myConnections(4,2) = 7
+  myConnections(5,2) = 4
+  myConnections(6,2) = 5
+  myConnections(7,2) = 11
+  myConnections(8,2) = 10
+  
+  myNodeAttribute(1,1) = 100
+  myNodeAttribute(1,2) = 300
+  myNodeAttribute(1,3) = 300
+  myNodeAttribute(1,4) = 500
+  myNodeAttribute(2,1) = 200
+  myNodeAttribute(2,2) = 400
+  myNodeAttribute(2,3) = 400
+  myNodeAttribute(2,4) = 600
+  myNodeAttribute(3,1) = 300
+  myNodeAttribute(3,2) = 500
+  myNodeAttribute(3,3) = 500
+  myNodeAttribute(3,4) = 700
+  
+  myCellAttribute(1) = 100
+  myCellAttribute(2) = 200
+  
+  CALL XDMFINIT(obj, filename)
+!  CALL XDMFSETGRIDTOPOLOGY(obj, 'Hexahedron'//CHAR(0), 2, myConnections)\
+!  CALL XDMFSETGEOMETRY(obj, foo, 36, XDMF_ARRAY_TYPE_FLOAT64, myPoints)
+!  CALL XDMFADDGRIDATTRIBUTE(obj, 'NodeValues'//CHAR(0),'XDMF_FLOAT64_TYPE'//CHAR(0), 'NODE'//CHAR(0), &
+!       'SCALAR'//CHAR(0), 12, myNodeAttribute)
+!  CALL XDMFADDGRIDATTRIBUTE(obj, 'CellValues'//CHAR(0),'XDMF_FLOAT64_TYPE'//CHAR(0), 'CELL'//CHAR(0), &
+!       'SCALAR'//CHAR(0), 2, myCellAttribute)
+  CALL XDMFADDGRID(obj, 'TestGrid'//CHAR(0))
+!  CALL XDMFWRITETOFILE(obj)
+!  CALL XDMFSERIALIZE(obj)
+  CALL XDMFCLOSE(obj)
+
+END PROGRAM XdmfFortranExample
+       
diff --git a/tests/Cxx/XdmfPostFixCalc.cpp b/tests/Cxx/XdmfPostFixCalc.cpp
new file mode 100644
index 0000000..fdec28f
--- /dev/null
+++ b/tests/Cxx/XdmfPostFixCalc.cpp
@@ -0,0 +1,1215 @@
+#include <iostream>
+#include <stack>
+#include <map>
+#include <string>
+#include <stdlib.h>
+#include <math.h>
+#include <XdmfArray.hpp>
+#include <XdmfArrayType.hpp>
+#include <XdmfFunction.hpp>
+#include "boost/assign.hpp"
+
+double parse(std::string expression, std::map<std::string, double> variables);
+double calculation(double val1, double val2, char operation);
+double function(std::vector<double> valueVector, std::string functionName);
+double sum(std::vector<double> values);
+double ave(std::vector<double> values);
+shared_ptr<XdmfArray> parse(std::string expression, std::map<std::string, shared_ptr<XdmfArray> > variables);
+shared_ptr<XdmfArray> calculation(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2, char operation);
+shared_ptr<XdmfArray> invChunk(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+shared_ptr<XdmfArray> function(std::vector<shared_ptr<XdmfArray> > valueVector, std::string functionName);
+shared_ptr<XdmfArray> subtract(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2);
+shared_ptr<XdmfArray> sum(std::vector<shared_ptr<XdmfArray> > values);
+shared_ptr<XdmfArray> ave(std::vector<shared_ptr<XdmfArray> > values);
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values);
+
+std::string validDigitChars = "-1234567890.";
+std::string validVariableChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_:.";
+
+//std::map<std::string,  double (*)(std::vector<double>)> functions = boost::assign::map_list_of ("SUM", sum) ("AVE", ave);
+std::map<std::string,  double (*)(std::vector<double>)> functions = boost::assign::map_list_of ("SUM", (double (*)(std::vector<double>))sum);
+
+//note, it doesn't handle overloaded functions well. Will generate errors unless typecast
+//std::map<std::string,  double (*)(std::vector<double>)> functions = boost::assign::map_list_of ("SUM", sum) ("AVE", ave);
+std::map<std::string,  shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >)> arrayFunctions = boost::assign::map_list_of ("SUM", (shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))sum) ("MAX", (shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))maximum);
+
+
+
+int main(int, char **)
+{
+	XdmfFunction::addFunction("MAX", maximum);
+        XdmfFunction::addOperation('&', invChunk, 2);
+	XdmfFunction::addOperation('!', invChunk, 2);
+	XdmfFunction::addOperation('^', invChunk, 2);
+	XdmfFunction::addOperation('>', invChunk, 2);
+	XdmfFunction::addOperation('<', invChunk, 2);
+	XdmfFunction::addOperation('@', invChunk, 2);
+
+	functions["AVE"] = ave;
+	//sometimes typecasts are required, sometimes they cause errors
+	//I think it needs to be cast if it isn't the first variation of the function listed
+	arrayFunctions["AVE"] = (shared_ptr<XdmfArray> (*)(std::vector<shared_ptr<XdmfArray> >))ave;
+
+	std::string problemToSolve = "2*twentyfive+2*3+2^(3+8)/3+8/(4+1)+SUM(4, twentyfive*4, 6) + AVE(100, 0, 0, 0)";
+
+	std::map<std::string, double> variableTable;
+	variableTable["twentyfive"] = 25;
+	variableTable["one"] = 1;
+	variableTable["two"] = 2;
+	variableTable["three"] = 3;
+	variableTable["four"] = 4;
+	variableTable["eight"] = 8;
+
+	double answer = parse(problemToSolve, variableTable);
+
+	std::cout << answer << " ?= " << (2*25+2*3+(double)2048/3+(double)8/5+4+100+6+25) << std::endl;
+
+	//unless the calculation is fully written out it won't equal properly
+	assert(answer == 2*25+2*3+(double)2048/3+(double)8/5+4+100+6+25);
+
+	//std::string arrayExpression = "A|B#C|D";
+	std::string arrayExpression = "MAX(2,(AVE(A at B)#AVE(C|D)))";
+
+	shared_ptr<XdmfArray> testArray1 = XdmfArray::New();
+	for (int i = 0; i < 10; i++)
+	{
+		testArray1->pushBack(1);
+	}
+	shared_ptr<XdmfArray> testArray2 = XdmfArray::New();
+	for (int i = 0; i < 10; i++)
+	{
+		testArray2->pushBack(2);
+	}
+	shared_ptr<XdmfArray> testArray3 = XdmfArray::New();
+	for (int i = 0; i < 10; i++)
+	{
+		testArray3->pushBack(3);
+	}
+	shared_ptr<XdmfArray> testArray4 = XdmfArray::New();
+	for (int i = 0; i < 10; i++)
+	{
+		testArray4->pushBack(4);
+	}
+	shared_ptr<XdmfArray> testArray5 = XdmfArray::New();
+	for (int i = 0; i < 13; i++)
+	{
+		testArray5->pushBack(5);
+	}
+
+	std::map<std::string, shared_ptr<XdmfArray> > arrayVariable;
+	arrayVariable["A"] = testArray1;
+	arrayVariable["B"] = testArray2;
+	arrayVariable["C"] = testArray3;
+	arrayVariable["D"] = testArray4;
+	arrayVariable["E"] = testArray5;
+
+	std::cout << "before parsing" << std::endl;
+
+	shared_ptr<XdmfArray> answerArray;
+	answerArray = parse(arrayExpression, arrayVariable);
+
+	std::cout << "after parsing" << std::endl;
+
+	std::cout << "answer array = " << answerArray->getValuesString() << std::endl;
+
+	assert(answerArray->getValuesString().compare("3.5") == 0);
+
+	std::cout << "array size = " << answerArray->getSize() << std::endl;
+
+	assert(answerArray->getSize() == 1);
+
+	std::cout << "interlace" << std::endl;
+	answerArray = XdmfFunction::evaluateOperation(testArray1, testArray5, '#');
+	std::cout << "answer array = " << answerArray->getValuesString() << std::endl;
+
+	assert(answerArray->getValuesString().compare("1 5 1 5 1 5 1 5 1 5 1 5 1 5 1 5 1 5 1 5 5 5 5") == 0);
+
+	std::cout << "chunk" << std::endl;
+	answerArray = XdmfFunction::evaluateOperation(testArray1, testArray5, '|');
+	std::cout << "answer array = " << answerArray->getValuesString() << std::endl;
+
+	assert(answerArray->getValuesString().compare("1 1 1 1 1 1 1 1 1 1 5 5 5 5 5 5 5 5 5 5 5 5 5") == 0);
+
+	std::cout << "inverse chunk" << std::endl;
+	answerArray = XdmfFunction::evaluateOperation(testArray1, testArray5, '@');
+	std::cout << "answer array = " << answerArray->getValuesString() << std::endl;
+
+	assert(answerArray->getValuesString().compare("5 5 5 5 5 5 5 5 5 5 5 5 5 1 1 1 1 1 1 1 1 1 1") == 0);
+
+	answerArray = XdmfFunction::evaluateExpression(arrayExpression, arrayVariable);
+
+	std::cout << "after parsing" << std::endl;
+
+	std::cout << "answer array = " << answerArray->getValuesString() << std::endl;
+
+	assert(answerArray->getValuesString().compare("3.5") == 0);
+
+	std::cout << "array size = " << answerArray->getSize() << std::endl;
+
+	assert(answerArray->getSize() == 1);
+
+	// - is a special case since it can be considered a negative sign
+
+	std::map<std::string, shared_ptr<XdmfArray> > minusVariable;
+
+	std::string minusExpression = "-5--5";
+
+	shared_ptr<XdmfArray> minusResult = XdmfFunction::evaluateExpression(minusExpression, minusVariable);
+
+	std::cout << "result of minus equation = " << minusResult->getValuesString() << std::endl;
+
+	assert(strcmp("0", minusResult->getValuesString().c_str()) == 0);
+
+	shared_ptr<XdmfArray> minusTest1 = XdmfArray::New();
+	minusTest1->pushBack<int>(-5);
+
+	minusVariable["A"] = minusTest1;
+
+	minusExpression = "-5-A";
+
+	minusResult = XdmfFunction::evaluateExpression(minusExpression, minusVariable);
+
+	std::cout << "result of minus equation = " << minusResult->getValuesString() << std::endl;
+
+	assert(strcmp("0", minusResult->getValuesString().c_str()) == 0);
+
+	minusExpression = "A--5";
+
+	minusResult = XdmfFunction::evaluateExpression(minusExpression, minusVariable);
+
+	std::cout << "result of minus equation = " << minusResult->getValuesString() << std::endl;
+
+	assert(strcmp("0", minusResult->getValuesString().c_str()) == 0);
+
+	minusExpression = "MAX(-5, -4, -3, -2, -1)";
+
+        minusResult = XdmfFunction::evaluateExpression(minusExpression, minusVariable);
+
+        std::cout << "result of negative equation = " << minusResult->getValuesString() << std::endl;
+
+	assert(strcmp("-1", minusResult->getValuesString().c_str()) == 0);
+
+	shared_ptr<XdmfArray> minusTest2 = XdmfArray::New();
+	minusTest2->pushBack<int>(13);
+
+	shared_ptr<XdmfArray> minusTestResult = subtract(minusTest1, minusTest2);
+
+	std::cout << "result of subtract function = " << minusTestResult->getValuesString() << std::endl;
+
+	return 0;
+}
+
+double parse(std::string expression, std::map<std::string, double> variables)
+{
+	std::stack<double> valueStack;
+	std::stack<char> operationStack;
+
+	std::string validOperationChars = "+-*/()^"; //will be global at some point, all supported operations
+	int * operationPriority = new int[validOperationChars.size()]();
+	//list the priorities for the operations, based on the order of operations
+	//the index of the corresponding operation in validOperationChars is the same as the index of its priority in this array
+	operationPriority[0] = 1;//+
+	operationPriority[1] = 1;//-
+	operationPriority[2] = 2;//*
+	operationPriority[3] = 2;///
+	operationPriority[4] = 0;//(
+	operationPriority[5] = 0;//)
+	operationPriority[6] = 3;//^
+	//the higher the value, the earlier the operation is evaluated in the order of operations
+	//with the exception of parenthesis which are evaluated as soon as the closing parenthesis is found
+
+	//string is parsed left to right
+	//elements of the same priority are evaluated right to left
+	for (unsigned int i = 0; i < expression.size(); i++)
+	{
+		if (validDigitChars.find(expression[i]) != std::string::npos)//found to be a digit
+		{
+			//progress until a non-digit is found
+			int valueStart = i;
+			while (validDigitChars.find(expression[i + 1]) != std::string::npos)
+			{
+				i++;
+			}
+			//push back to the value stack
+			valueStack.push(atof(expression.substr(valueStart, i + 1 - valueStart).c_str()));//use this to convert to double
+		}
+		else if (validVariableChars.find(expression[i]) != std::string::npos)//found to be a variable
+		{
+			int valueStart = i;
+			//progress until a nonvariable value is found
+			while (validVariableChars.find(expression[i + 1]) != std::string::npos)
+			{
+				i++;
+			}
+			//convert to equivalent
+			if (variables.find(expression.substr(valueStart, i + 1 - valueStart)) == variables.end())
+			{
+				if (functions.find(expression.substr(valueStart, i + 1 - valueStart)) == functions.end())
+				{
+					std::cout << "Error: Invalid Variable or Function: " << expression.substr(valueStart, i + 1 - valueStart) << std::endl;
+					return 0;
+				}
+				else
+				{
+					std::string currentFunction = expression.substr(valueStart, i + 1 - valueStart);
+					//check if next character is an open parenthesis
+					if (expression[i+1] != '(')
+					{
+						std::cout << "Error: No values supplied to function " << expression.substr(valueStart, i + 1 - valueStart) << std::endl;
+						return 0;
+					}
+					//if it is grab the string between paranthesis
+					i = i + 2;
+					valueStart = i;
+					int unsigned numOpenParenthesis = 0;
+					while ((expression[i] != ')' || numOpenParenthesis) && i < expression.size())
+					{
+						if (expression[i] == '(')
+						{
+							numOpenParenthesis++;
+						}
+						else if (expression[i] == ')')
+						{
+							numOpenParenthesis--;
+						}
+						i++;
+					}
+					std::string functionParameters = expression.substr(valueStart, i - valueStart);
+					std::vector<double> parameterVector;
+					//split that string at commas
+					size_t parameterSplit = 0;
+					while (parameterSplit != std::string::npos)
+					{
+						parameterSplit = 0;
+						parameterSplit = functionParameters.find_first_of(",", parameterSplit);
+						//feed the substrings to the parse function
+						if (parameterSplit == std::string::npos)
+						{
+							parameterVector.push_back(parse(functionParameters, variables));
+						}
+						else
+						{
+							parameterVector.push_back(parse(functionParameters.substr(0, parameterSplit), variables));
+							functionParameters = functionParameters.substr(parameterSplit+1);
+						}
+					}
+					valueStack.push(function(parameterVector, currentFunction));
+				}
+			}
+			else
+			{
+				//push equivalent to value stack
+				valueStack.push(variables.find(expression.substr(valueStart, i + 1 - valueStart))->second);
+			}
+		}
+		else if (validOperationChars.find(expression[i]) != std::string::npos)//found to be an operation
+		{
+			//pop operations off the stack until one of a lower or equal importance is found
+			if (operationStack.size() > 0)
+			{
+				if (expression[i] == ')')
+				{
+					//to close a parenthesis pop off all operations until another parentheis is found
+					while (operationStack.size() > 0 && operationStack.top() != '(')
+					{
+						if (valueStack.size() < 2)//must be at least two values for this loop to work properly
+						{
+							//error, not enough values
+							std::cout << "Error: Not Enough Values" << std::endl;
+							return 0;
+						}
+						else
+						{
+							double val2 = valueStack.top();
+							valueStack.pop();
+							double val1 = valueStack.top();
+							valueStack.pop();
+							valueStack.push(calculation(val1, val2, operationStack.top()));
+							operationStack.pop();
+						}
+					}
+					operationStack.pop();
+				}
+				else if (expression[i] == '(')
+				{
+					//just add it if it's a start parenthesis
+					//nothing happens here in that case
+					//addition happens after the if statement
+				}
+				else
+				{
+					size_t operationLocation = validOperationChars.find(expression[i]);
+					size_t topOperationLocation = validOperationChars.find(operationStack.top());
+					//see order of operations to determine importance
+					while (operationStack.size() > 0 && operationPriority[operationLocation] < operationPriority[topOperationLocation])
+					{
+						if (valueStack.size() < 2)//must be at least two values for this loop to work properly
+						{
+							//error, not enough values
+							std::cout << "Error: Not Enough Values" << std::endl;
+							return 0;
+						}
+						else
+						{
+							double val2 = valueStack.top();
+							valueStack.pop();
+							double val1 = valueStack.top();
+							valueStack.pop();
+							valueStack.push(calculation(val1, val2, operationStack.top()));
+							operationStack.pop();
+							if (operationStack.size() == 0) 
+							{
+								break;
+							}
+							topOperationLocation = validOperationChars.find(operationStack.top());
+						}
+					}
+				}
+			}
+			if (expression[i] != ')')
+			{
+				//add the operation to the operation stack
+				operationStack.push(expression[i]);
+			}
+		}
+		//if not a value or operation the character is ignored
+	}
+
+	//empty what's left in the stacks before finishing
+	while (valueStack.size() > 1)
+	{
+		if (valueStack.size() < 2)//must be at least two values for this loop to work properly
+		{
+			//error, not enough values
+			std::cout << "Error: Not Enough Values" << std::endl;
+			return 0;
+		}
+		else
+		{
+			if(operationStack.top() == '(')
+			{
+				std::cout << "Warning: Unpaired Parenthesis" << std::endl;
+				operationStack.pop();
+			}
+			else
+			{
+				double val2 = valueStack.top();
+				valueStack.pop();
+				double val1 = valueStack.top();
+				valueStack.pop();
+				if (operationStack.size() == 0)
+				{
+					//error, not enough operations
+					std::cout << "Error: Not Enough Operators" << std::endl;
+					return 0;
+				}
+				else
+				{
+					valueStack.push(calculation(val1, val2, operationStack.top()));
+					operationStack.pop();
+				}
+			}
+		}
+	}
+
+	//throw error if there's extra operations
+	if (operationStack.size() > 0)
+	{
+		std::cout << "Warning: Left Over Operators" << std::endl;
+	}
+
+	return valueStack.top();
+}
+
+double calculation(double val1, double val2, char operation)
+{
+	//perform the appropriate operation as designated by the string supplied
+	if (operation == '+')//addition
+	{
+		return val1 + val2;
+	}
+	else if (operation == '-')//subtraction
+	{
+		return val1 - val2;
+	}
+	else if (operation == '*')//multiplication
+	{
+		return val1 * val2;
+	}
+	else if (operation == '/')//division
+	{
+		return val1 / val2;
+	}
+	else if (operation == '^')//exponent
+	{
+		return pow(val1, val2);
+	}
+	//insert new operations into this huge if statement
+	return 0.0;//return 0 as a default
+}
+
+//this is how you use references to functions
+double function(std::vector<double> valueVector, std::string functionName)
+{
+	return (*functions[functionName])(valueVector);
+}
+
+double sum(std::vector<double> values)
+{
+	double total = 0.0;
+	for (unsigned int i = 0; i < values.size(); i++)
+	{
+		total += values[i];
+	}
+	return total;
+}
+
+double ave(std::vector<double> values)
+{
+	double total = sum(values);
+	return total/values.size();
+}
+
+shared_ptr<XdmfArray> parse(std::string expression, std::map<std::string, shared_ptr<XdmfArray> > variables)
+{
+	std::stack<shared_ptr<XdmfArray> > valueStack;
+	std::stack<char> operationStack;
+
+	std::string validOperationChars = "|#()@"; //will be global at some point, all supported operations
+	int * operationPriority = new int[validOperationChars.size()]();
+	//list the priorities for the operations, based on the order of operations
+	//the index of the corresponding operation in validOperationChars is the same as the index of its priority in this array
+	operationPriority[0] = 2;//|
+	operationPriority[1] = 1;//#
+	operationPriority[2] = 0;//(
+	operationPriority[3] = 0;//)
+	operationPriority[4] = 2;//@
+	//the higher the value, the earlier the operation is evaluated in the order of operations
+	//with the exception of parenthesis which are evaluated as soon as the closing parenthesis is found
+
+	//string is parsed left to right
+	//elements of the same priority are evaluated right to left
+	for (unsigned int i = 0; i < expression.size(); i++)
+	{
+		if (validDigitChars.find(expression[i]) != std::string::npos)//found to be a digit
+		{
+			//progress until a non-digit is found
+			int valueStart = i;
+			while (validDigitChars.find(expression[i + 1]) != std::string::npos)
+			{
+				i++;
+			}
+			//push back to the value stack
+			//create a new array to hold the value
+			shared_ptr<XdmfArray> valueArray = XdmfArray::New();
+			valueArray->insert(0, atof(expression.substr(valueStart, i + 1 - valueStart).c_str()));
+			valueStack.push(valueArray);
+		}
+		else if (validVariableChars.find(expression[i]) != std::string::npos)//found to be a variable
+		{
+			int valueStart = i;
+			//progress until a nonvariable value is found
+			while (validVariableChars.find(expression[i + 1]) != std::string::npos)
+			{
+				i++;
+			}
+			//convert to equivalent
+			if (variables.find(expression.substr(valueStart, i + 1 - valueStart)) == variables.end())
+			{
+				if (arrayFunctions.find(expression.substr(valueStart, i + 1 - valueStart)) == arrayFunctions.end())
+				{
+					std::cout << "Error: Invalid Variable or Function" << std::endl;
+					return XdmfArray::New();
+				}
+				else
+				{
+					std::string currentFunction = expression.substr(valueStart, i + 1 - valueStart);
+					//check if next character is an open parenthesis
+					if (expression[i+1] != '(')
+					{
+						std::cout << "Error: No Values Supplied to Function " << expression.substr(valueStart, i + 1 - valueStart) << std::endl;
+						return XdmfArray::New();
+					}
+					//if it is grab the string between paranthesis
+					i = i + 2;
+					valueStart = i;
+					unsigned int numOpenParenthesis = 0;
+					while ((expression[i] != ')' || numOpenParenthesis) && i < expression.size())
+					{
+						if (expression[i] == '(')
+						{
+							numOpenParenthesis++;
+						}
+						else if (expression[i] == ')')
+						{
+							numOpenParenthesis--;
+						}
+						i++;
+					}
+					std::string functionParameters = expression.substr(valueStart, i - valueStart);
+					std::vector<shared_ptr<XdmfArray> > parameterVector;
+					//split that string at commas
+					size_t parameterSplit = 0;
+					while (parameterSplit != std::string::npos)
+					{
+						parameterSplit = 0;
+						parameterSplit = functionParameters.find_first_of(",", parameterSplit);
+						//feed the substrings to the parse function
+						if (parameterSplit == std::string::npos)
+						{
+							parameterVector.push_back(parse(functionParameters, variables));
+						}
+						else
+						{
+							parameterVector.push_back(parse(functionParameters.substr(0, parameterSplit), variables));
+							functionParameters = functionParameters.substr(parameterSplit+1);
+						}
+					}
+					valueStack.push(function(parameterVector, currentFunction));
+				}
+			}
+			else
+			{
+				//push equivalent to value stack
+				valueStack.push(variables.find(expression.substr(valueStart, i + 1 - valueStart))->second);
+			}
+		}
+		else if (validOperationChars.find(expression[i]) != std::string::npos)//found to be an operation
+		{
+			//pop operations off the stack until one of a lower or equal importance is found
+			if (operationStack.size() > 0)
+			{
+				if (expression[i] == ')')
+				{
+					//to close a parenthesis pop off all operations until another parentheis is found
+					while (operationStack.size() > 0 && operationStack.top() != '(')
+					{
+						if (valueStack.size() < 2)//must be at least two values for this loop to work properly
+						{
+							//error, not enough values
+							return XdmfArray::New();
+						}
+						else
+						{
+							shared_ptr<XdmfArray> val2 = valueStack.top();
+							valueStack.pop();
+							shared_ptr<XdmfArray> val1 = valueStack.top();
+							valueStack.pop();
+							valueStack.push(calculation(val1, val2, operationStack.top()));
+							operationStack.pop();
+						}
+					}
+					operationStack.pop();
+				}
+				else if (expression[i] == '(')
+				{
+					//just add it if it's a start parenthesis
+					//nothing happens here in that case
+					//addition happens after the if statement
+				}
+				else
+				{
+					size_t operationLocation = validOperationChars.find(expression[i]);
+					size_t topOperationLocation = validOperationChars.find(operationStack.top());
+					//see order of operations to determine importance
+					while (operationStack.size() > 0 && operationPriority[operationLocation] < operationPriority[topOperationLocation])
+					{
+						if (valueStack.size() < 2)//must be at least two values for this loop to work properly
+						{
+							//error, not enough values
+							std::cout << "Error: Not Enough Values" << std::endl;
+							return XdmfArray::New();
+						}
+						else
+						{
+							shared_ptr<XdmfArray> val2 = valueStack.top();
+							valueStack.pop();
+							shared_ptr<XdmfArray> val1 = valueStack.top();
+							valueStack.pop();
+							valueStack.push(calculation(val1, val2, operationStack.top()));
+							operationStack.pop();
+							if (operationStack.size() == 0)
+							{
+								break;
+							}
+							topOperationLocation = validOperationChars.find(operationStack.top());
+						}
+					}
+				}
+			}
+			if (expression[i] != ')')
+			{
+				//add the operation to the operation stack
+				operationStack.push(expression[i]);
+			}
+		}
+		//if not a value or operation the character is ignored
+	}
+
+
+	//empty what's left in the stacks before finishing
+	while (valueStack.size() > 1 && operationStack.size() > 0)
+	{
+		if(operationStack.top() == '(')
+		{
+			std::cout << "Warning: Unpaired Parenthesis" << std::endl;
+			operationStack.pop();
+		}
+		else if (valueStack.size() < 2)//must be at least two values for this loop to work properly
+		{
+			//error, not enough values
+			std::cout << "Error: Not Enough Values" << std::endl;
+			return XdmfArray::New();
+		}
+		else
+		{
+			shared_ptr<XdmfArray> val2 = valueStack.top();
+			valueStack.pop();
+			shared_ptr<XdmfArray> val1 = valueStack.top();
+			valueStack.pop();
+			if (operationStack.size() == 0)
+			{
+				//error, not enough operations
+				std::cout << "Error: Not Enough Operators" << std::endl;
+				return XdmfArray::New();
+			}
+			else
+			{
+				valueStack.push(calculation(val1, val2, operationStack.top()));
+				operationStack.pop();
+			}
+		}
+	}
+
+	//throw error if there's extra operations
+	if (operationStack.size() > 0)
+	{
+		std::cout << "Warning: Left Over Operators" << std::endl;
+	}
+
+	if (valueStack.size() > 1)
+	{
+		std::cout << "Warning: Left Over Values" << std::endl;
+	}
+
+	return valueStack.top();
+}
+
+shared_ptr<XdmfArray> calculation(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2, char operation)
+{
+	//perform the appropriate operation as designated by the string supplied
+	if (operation == '|')//join chunk (add the new array to the end of the first one)
+	{
+		//joins into new array and returns it
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->insert(0, val1, 0, val1->getSize(),  1, 1);
+		returnArray->insert(val1->getSize(), val2, 0, val2->getSize(), 1, 1);
+		return returnArray;
+	}
+	else if (operation == '@')//inverse chunk
+	{
+		//joins into new array and returns it
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->insert(0, val2, 0, val2->getSize(),  1, 1);
+		returnArray->insert(val2->getSize(), val1, 0, val1->getSize(), 1, 1);
+		return returnArray;
+	}
+	else if (operation == '#')//join interlace (evenly space the second array within the first one)
+	{
+		//builds a new array
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		//resize to the combined size of both arrays
+		//might not be required?
+		//what type to class it as?
+		shared_ptr<const XdmfArrayType> arrayType1 = val1->getArrayType();
+		shared_ptr<const XdmfArrayType> arrayType2 = val2->getArrayType();
+		if (arrayType1 == XdmfArrayType::Int8())
+		{
+			//if floats reclass as floats of the appropriate size
+			if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if uints reclass as ints of the appropriate size
+			else if (arrayType2 == XdmfArrayType::Int64() || arrayType2 == XdmfArrayType::UInt32())
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Int32() || arrayType2 == XdmfArrayType::UInt16())
+			{
+				int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Int16() || arrayType2 == XdmfArrayType::UInt8())
+			{
+				short sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else
+			{
+				char sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+		}
+		else if (arrayType1 == XdmfArrayType::Int16())
+		{
+			//if floats reclass as floats of the appropriate size
+			if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if uints reclass as ints of the appropriate size
+			else if (arrayType2 == XdmfArrayType::Int64() || arrayType2 == XdmfArrayType::UInt32())
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Int32() || arrayType2 == XdmfArrayType::UInt16())
+			{
+				int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else
+			{
+				short sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+		}
+		else if (arrayType1 == XdmfArrayType::Int32())
+                {
+			//if floats reclass as floats of the appropriate size
+			if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if uints reclass as ints of the appropriate size
+			else if (arrayType2 == XdmfArrayType::Int64() || arrayType2 == XdmfArrayType::UInt32())
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else
+			{
+				int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+                }
+		else if (arrayType1 == XdmfArrayType::Int64())
+                {
+			//if floats reclass as floats of the appropriate size
+			if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+                                double sampleValue = 0.0;
+                                returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+                        }
+			//if uints reclass as ints of the appropriate size
+			else
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+                }
+                else if (arrayType1 == XdmfArrayType::Float32())
+                {
+			//use floats of the appropriate size
+			if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+                }
+                else if (arrayType1 == XdmfArrayType::Float64())
+                {
+			//use floats of the appropriate size
+			if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+                }
+                else if (arrayType1 == XdmfArrayType::UInt8())
+                {
+			//if int are used reclass as int of the larger size
+			if (arrayType2 == XdmfArrayType::Int8() || arrayType2 == XdmfArrayType::Int16())
+			{
+				short sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Int32())
+			{
+				int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Int64())
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if floats are used, reclass as floats of the appropriate size
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if uints are used, adjust size as required
+			else if (arrayType2 == XdmfArrayType::UInt8())
+			{
+				unsigned char sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::UInt16())
+			{
+				unsigned short sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::UInt32())
+			{
+				unsigned int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+		}
+		else if (arrayType1 == XdmfArrayType::UInt16())
+		{
+			//if int are used reclass as int of the larger size
+                        if (arrayType2 == XdmfArrayType::Int8() || arrayType2 == XdmfArrayType::Int16() || arrayType2 == XdmfArrayType::Int32())
+			{
+				int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Int64())
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if floats are used, reclass as floats of the appropriate size
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if uints are used, adjust size as required
+			else if (arrayType2 == XdmfArrayType::UInt8() || arrayType2 == XdmfArrayType::UInt16())
+			{
+				unsigned short sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::UInt32())
+			{
+				unsigned int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+                }
+                else if (arrayType1 == XdmfArrayType::UInt32())
+                {
+			//if int are used reclass as int of the larger size
+			if (arrayType2 == XdmfArrayType::Int8() || arrayType2 == XdmfArrayType::Int16() || arrayType2 == XdmfArrayType::Int32() || arrayType2 == XdmfArrayType::Int64())
+			{
+				long sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if floats are used, reclass as floats of the appropriate size
+			else if (arrayType2 == XdmfArrayType::Float32())
+			{
+				float sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::Float64())
+			{
+				double sampleValue = 0.0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			//if uints are used, adjust size as required
+			else if (arrayType2 == XdmfArrayType::UInt8() || arrayType2 == XdmfArrayType::UInt16() || arrayType2 == XdmfArrayType::UInt32())
+			{
+				unsigned int sampleValue = 0;
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+			else if (arrayType2 == XdmfArrayType::String())
+			{
+				//string is the only compatible type here
+				std::string sampleValue = "";
+				returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+			}
+                }
+                else if (arrayType1 == XdmfArrayType::String())
+                {
+			//string is the only compatible type here
+			std::string sampleValue = "";
+			returnArray->resize(val1->getSize()+val2->getSize(), sampleValue);
+                }
+		//determine ratio of array sizes
+		int arrayRatio1 = (int)floor(static_cast<double>(val1->getSize())/val2->getSize());
+		int arrayRatio2 = (int)floor(static_cast<double>(val2->getSize())/val1->getSize());
+		if (arrayRatio1 < 1)
+		{
+			arrayRatio1 = 1;
+		}
+		if (arrayRatio2 < 1)
+		{
+			arrayRatio2 = 1;
+		}
+		//stride is equal to the ratios rounded up and added together
+		int stride = arrayRatio1+arrayRatio2;
+		int arrayExcess1 = 0;
+		int arrayExcess2 = 0;
+		for (int i = 0; i < stride; i++)
+		{
+			//add the values of each array, using strides to interlace and starting index to offset
+			//first array gets the first value of the new array
+			if (i<arrayRatio1)
+			{
+				int amountWritten = val1->getSize()/arrayRatio1;
+				if (((amountWritten * arrayRatio1) + i) < (int)val1->getSize())
+				{
+					amountWritten++;
+				}
+				if (amountWritten > (int)floor(val2->getSize()/arrayRatio2))
+				{
+					arrayExcess1 += amountWritten - (int)floor(val2->getSize()/arrayRatio2);
+					amountWritten = (int)floor(val2->getSize()/arrayRatio2);
+				}
+				returnArray->insert(i, val1, i, amountWritten, stride, arrayRatio1);
+			}
+			else //second array takes the rest
+			{
+				int amountWritten = val2->getSize()/arrayRatio2;
+				if (((amountWritten * arrayRatio2) + i) < (int)val2->getSize())
+				{
+					amountWritten++;
+				}
+				if (amountWritten > (int)floor(val1->getSize()/arrayRatio1))
+				{
+					arrayExcess2 += amountWritten - (int)floor(val1->getSize()/arrayRatio1);
+					amountWritten = (int)floor(val1->getSize()/arrayRatio1);
+				}
+				returnArray->insert(i, val2, i-arrayRatio1, amountWritten, stride, arrayRatio2);
+			}
+			
+		}
+		if (arrayExcess1 > 0)
+		{
+			returnArray->insert(val1->getSize()+val2->getSize()-arrayExcess1, val1, 0, arrayExcess1, 1, 1);
+		}
+		else if (arrayExcess2 > 0)
+		{
+			returnArray->insert(val1->getSize()+val2->getSize()-arrayExcess2, val2, 0, arrayExcess2, 1, 1);
+		}
+		returnArray->resize(val1->getSize()+val2->getSize(), 0);
+		//after all inserts are done, add the excess values to the end of the array
+		return returnArray;
+	}
+	//insert new operations into this huge if statement
+	return XdmfArray::New();//return a blank array as a default
+}
+
+shared_ptr<XdmfArray> invChunk(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+	//joins into new array and returns it
+	shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+	returnArray->insert(0, val2, 0, val2->getSize(),  1, 1);
+	returnArray->insert(val2->getSize(), val1, 0, val1->getSize(), 1, 1);
+	return returnArray;
+}
+
+shared_ptr<XdmfArray> subtract(shared_ptr<XdmfArray> val1, shared_ptr<XdmfArray> val2)
+{
+	shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+	shared_ptr<const XdmfArrayType> returnType = XdmfArrayType::comparePrecision(val1->getArrayType(), val2->getArrayType());
+	for (unsigned int i = 0; i < val1->getSize() && i < val2->getSize(); ++i)
+	{
+		if (returnType == XdmfArrayType::UInt8())
+		{
+			returnArray->insert(i, val1->getValue<unsigned char>(i) - val2->getValue<unsigned char>(i));
+		}
+		else if (returnType == XdmfArrayType::UInt16())
+		{
+			returnArray->insert(i, val1->getValue<unsigned short>(i) - val2->getValue<unsigned short>(i));
+		}
+		else if (returnType == XdmfArrayType::UInt32())
+		{
+			returnArray->insert(i, val1->getValue<unsigned int>(i) - val2->getValue<unsigned int>(i));
+		}
+		else if (returnType == XdmfArrayType::Int8())
+		{
+			returnArray->insert(i, val1->getValue<char>(i) - val2->getValue<char>(i));
+		}
+		else if (returnType == XdmfArrayType::Int16())
+		{
+			returnArray->insert(i, val1->getValue<short>(i) - val2->getValue<short>(i));
+		}
+		else if (returnType == XdmfArrayType::Int32())
+		{
+			returnArray->insert(i, val1->getValue<int>(i) - val2->getValue<int>(i));
+		}
+		else if (returnType == XdmfArrayType::Int64())
+		{
+			returnArray->insert(i, val1->getValue<long>(i) - val2->getValue<long>(i));
+		}
+		else if (returnType == XdmfArrayType::Float32())
+		{
+			returnArray->insert(i, val1->getValue<float>(i) - val2->getValue<float>(i));
+		}
+		else if (returnType == XdmfArrayType::Float64())
+		{
+			returnArray->insert(i, val1->getValue<double>(i) - val2->getValue<double>(i));
+		}
+	}
+	return returnArray;
+}
+
+//this is how you use references to functions
+shared_ptr<XdmfArray> function(std::vector<shared_ptr<XdmfArray> > valueVector, std::string functionName)
+{
+	if (arrayFunctions.find(functionName) == arrayFunctions.end())
+	{
+		return XdmfArray::New();
+	}
+	else
+	{
+		return (*arrayFunctions[functionName])(valueVector);
+	}
+}
+
+shared_ptr<XdmfArray> sum(std::vector<shared_ptr<XdmfArray> > values)
+{
+        double total = 0.0;
+        for (unsigned int i = 0; i < values.size(); i++)
+        {
+		for (unsigned int j = 0; j < values[i]->getSize(); j++)
+		{
+                	total += values[i]->getValue<double>(j);
+		}
+        }
+	shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+	returnArray->insert(0, total);
+        return returnArray;
+}
+
+
+
+shared_ptr<XdmfArray> ave(std::vector<shared_ptr<XdmfArray> > values)
+{
+	double total = sum(values)->getValue<double>(0);;
+	int totalSize = 0;
+	for (unsigned int i = 0; i < values.size(); i++)
+	{
+		totalSize += values[i]->getSize();
+	}
+	shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+	returnArray->insert(0, total/totalSize);
+	return returnArray;
+}
+
+shared_ptr<XdmfArray> maximum(std::vector<shared_ptr<XdmfArray> > values)
+{
+	if (values[0]->getArrayType() == XdmfArrayType::String())
+	{
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(values[0]->getValue<std::string>(0));
+		return returnArray;
+	}
+	else
+	{
+		double maxVal = values[0]->getValue<double>(0);
+		for (unsigned int i = 0; i < values.size(); i++)
+		{
+			for (unsigned int j = 0; j < values[i]->getSize(); j++)
+			{
+				if (maxVal < values[i]->getValue<double>(j))
+				{
+					maxVal = values[i]->getValue<double>(j);
+				}
+			}
+		}
+		shared_ptr<XdmfArray> returnArray = XdmfArray::New();
+		returnArray->pushBack(maxVal);
+		return returnArray;
+	}
+}
diff --git a/tests/Cxx/XdmfTestCompareFiles.hpp b/tests/Cxx/XdmfTestCompareFiles.hpp
new file mode 100644
index 0000000..84b23d4
--- /dev/null
+++ b/tests/Cxx/XdmfTestCompareFiles.hpp
@@ -0,0 +1,35 @@
+#include <fstream>
+#include <sstream>
+
+class XdmfTestCompareFiles {
+public:
+
+  /**
+   * Compares two files on disk for equality.
+   *
+   * @param firstFileName the path to the first file to compare.
+   * @param secondFileName the path to the second file to compare.
+   *
+   * @return true if the two files are equivalent.
+   */
+  static bool compareFiles(const std::string & firstFileName, 
+			   const std::string & secondFileName)
+  {
+    // Compare two files for equality
+    std::ifstream firstFile(firstFileName.c_str());
+    std::ifstream secondFile(secondFileName.c_str());
+
+    std::stringstream firstBuffer;
+    std::stringstream secondBuffer;
+
+    firstBuffer << firstFile.rdbuf();
+    secondBuffer << secondFile.rdbuf();
+
+    std::string firstContents(firstBuffer.str());
+    std::string secondContents(secondBuffer.str());
+
+    return(firstContents.compare(secondContents) == 0);
+  }
+
+};
+
diff --git a/tests/Cxx/XdmfTestDataGenerator.hpp b/tests/Cxx/XdmfTestDataGenerator.hpp
new file mode 100644
index 0000000..224c6e7
--- /dev/null
+++ b/tests/Cxx/XdmfTestDataGenerator.hpp
@@ -0,0 +1,102 @@
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfArray.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+class XdmfTestDataGenerator {
+public:
+
+  /**
+   * Number of Cells = 2
+   * Number of Points = 12
+   * Number of Attributes = 2
+   *   Cell Attributes = 1
+   *   Nodal Attributes = 1
+   *   Grid Attributes = 1
+   * Number of Sets = 1
+   *   Nodal Set = 1
+   * Time = 100
+   * Total Number of Values = 71
+   */
+  static shared_ptr<XdmfUnstructuredGrid> createHexahedron()
+  {
+    shared_ptr<XdmfUnstructuredGrid> grid = XdmfUnstructuredGrid::New();
+    grid->setName("Hexahedron");
+
+    // Set Geometry
+    double points[] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                       1.1, 1.1, 1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                       0.1, -1.1, 3.1, 0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                       -1.1, 3.1, 2.1, -2.1};
+    grid->getGeometry()->setType(XdmfGeometryType::XYZ());
+    grid->getGeometry()->insert(0, &points[0], 36);
+    //grid->getGeometry()->setName("Geom 1");
+
+    // Set Topology
+    int connectivity[] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
+    grid->getTopology()->setType(XdmfTopologyType::Hexahedron());
+    grid->getTopology()->insert(0, &connectivity[0], 16);
+
+    // Add Node Attribute
+    shared_ptr<XdmfAttribute> nodalAttribute = XdmfAttribute::New();
+    int nodeValues[] = {100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600,
+                        700};
+    nodalAttribute->setName("Nodal Attribute");
+    nodalAttribute->setType(XdmfAttributeType::Scalar());
+    nodalAttribute->setCenter(XdmfAttributeCenter::Node());
+    nodalAttribute->insert(0, &nodeValues[0], 12);
+
+    // Add Cell Attribute
+    shared_ptr<XdmfAttribute> cellAttribute = XdmfAttribute::New();
+    int cellValues[] = {100, 200};
+    cellAttribute->setName("Cell Attribute");
+    cellAttribute->setType(XdmfAttributeType::Scalar());
+    cellAttribute->setCenter(XdmfAttributeCenter::Cell());
+    cellAttribute->insert(0, &cellValues[0], 2);
+
+    // Add Grid Attribute
+    shared_ptr<XdmfAttribute> gridAttribute = XdmfAttribute::New();
+    std::string gridValues[] = {"foo", "bar"};
+    //int gridValues[] = {1, 2};
+    gridAttribute->setName("Grid Attribute");
+    gridAttribute->setType(XdmfAttributeType::Vector());
+    gridAttribute->setCenter(XdmfAttributeCenter::Grid());
+    gridAttribute->insert(0, &gridValues[0], 2);
+
+    // Add Node Set
+    shared_ptr<XdmfSet> nodeSet = XdmfSet::New();
+    int nodeIds[] = {0, 1, 2};
+    nodeSet->setName("Node Set");
+    nodeSet->setType(XdmfSetType::Node());
+    nodeSet->insert(0, &nodeIds[0], 3);
+
+    // Add Node Set Attribute
+    double nodeSetAttributeValues[] = {10, 11, 12};
+    shared_ptr<XdmfAttribute> nodeSetAttribute = XdmfAttribute::New();
+    nodeSetAttribute->setName("Node Set Attribute");
+    nodeSetAttribute->setType(XdmfAttributeType::Scalar());
+    nodeSetAttribute->setCenter(XdmfAttributeCenter::Node());
+    nodeSetAttribute->insert(0, &nodeSetAttributeValues[0], 3);
+    nodeSet->insert(nodeSetAttribute);
+
+    // Add Time
+    shared_ptr<XdmfTime> time = XdmfTime::New(100);
+    grid->setTime(time);
+
+    grid->insert(nodalAttribute);
+    grid->insert(cellAttribute);
+    grid->insert(gridAttribute);
+    grid->insert(nodeSet);
+    return grid;
+  }
+
+};
+
diff --git a/tests/Java/CMakeLists.txt b/tests/Java/CMakeLists.txt
new file mode 100644
index 0000000..cfd86c6
--- /dev/null
+++ b/tests/Java/CMakeLists.txt
@@ -0,0 +1,44 @@
+INCLUDE(AddTestsJava)
+
+# Add any dependencies that the java tests may need
+# Note: The tests already depend on their own file
+#	JAVA_TEST_DEPENDENCIES is also set in core
+ADD_TEST_JAVA_DEPENDENCIES(Compiled_Xdmf_Jar)
+
+# Add any classpath directories that the java tests may need
+# Note: JAVA_TEST_CLASSPATH is also set in core
+ADD_TEST_JAVA_CLASSPATH("${Xdmf_JAVA_JAR}")
+
+# Add any ldpath directories that the java tests may need
+# Note: JAVA_TEST_LDPATH is also set in core
+ADD_TEST_JAVA_LDPATH("")
+
+# Add any java tests here:
+# Note:	We don't want to use a foreach loop to test the files incase we
+#	have extra arguments (ie: ADD_TEST_JAVA(testname inputfile))
+#	Read UseJavaTest.cmake for more information
+# ------------------------
+ADD_TEST_JAVA(TestXdmfJava)
+ADD_TEST_JAVA(TestXdmfEquals)
+ADD_TEST_JAVA(TestXdmfGC)
+
+# Add any java cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have multiple files (ie: CLEAN_TEST_JAVA(testname outputfile1 ...))
+#	Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_JAVA(TestXdmfJava
+	outputJavaTest.xmf
+)
+CLEAN_TEST_JAVA(TestXdmfEquals)
+CLEAN_TEST_JAVA(TestXdmfGC outputXdmfGC.xmf)
+
+# Add a custom target for all java tests 
+# Note: ${TARGETS} is set in ADD_TEST_JAVA
+#IF(EXISTS Java_Core_Test_target)
+#	SET(Java_Core_Test_target Java_Core_Test_target)
+#ENDIF(EXISTS Java_Core_Test_target)
+
+#GET_PROPERTY(targets GLOBAL PROPERTY JAVA_TEST_TARGETS)
+#ADD_CUSTOM_TARGET(Java_ALLTEST ALL DEPENDS ${Java_Core_Test_target} XdmfJava ${targets}) 
+CREATE_TARGET_TEST_JAVA()
diff --git a/tests/Java/TestXdmfEquals.java b/tests/Java/TestXdmfEquals.java
new file mode 100644
index 0000000..46d515e
--- /dev/null
+++ b/tests/Java/TestXdmfEquals.java
@@ -0,0 +1,149 @@
+import mil.army.arl.xdmf.*;
+
+public class TestXdmfEquals
+{
+    public static void main (String argv[])
+	{
+        System.out.println("Hello World");
+
+	System.out.println("Checking XdmfAttributeCenter");	
+	XdmfAttributeCenter xac1 = XdmfAttributeCenter.Grid();
+	XdmfAttributeCenter xac2 = XdmfAttributeCenter.Grid();
+	XdmfAttributeCenter xac3 = XdmfAttributeCenter.Cell();
+	
+	// Check IsEquals
+	if(!(xac1.IsEqual(xac2))) /*True*/
+		throw new SecurityException("Failed True Check");
+	if((xac1.IsEqual(xac3))) /*False*/ 
+    		throw new SecurityException("Failed False Check");	
+
+	// Check equals
+	if(!(xac1.equals(xac2))) /*True*/ 
+		throw new SecurityException("Failed True Check (equals)");
+	if(xac1.equals(xac3)) /*False*/ 
+		throw new SecurityException("Failed False Check (equals)");
+
+    	// Check ==
+	if(xac1 == xac2) /*False*/ 
+		throw new SecurityException("Failed True Check (==)");
+	if(xac1 == xac3) /*False*/ 
+		throw new SecurityException("Failed False Check (==)");
+
+	System.out.println("Checking XdmfAttributeType");	
+	XdmfAttributeType xat1 = XdmfAttributeType.Scalar();
+	XdmfAttributeType xat2 = XdmfAttributeType.Scalar();
+	XdmfAttributeType xat3 = XdmfAttributeType.Tensor();
+	
+	// Check IsEquals
+	if(!(xat1.IsEqual(xat2))) /*True*/
+		throw new SecurityException("Failed True Check");
+	if((xat1.IsEqual(xat3))) /*False*/ 
+    		throw new SecurityException("Failed False Check");	
+
+	// Check equals
+	if(!(xat1.equals(xat2))) /*True*/ 
+		throw new SecurityException("Failed True Check (equals)");
+	if(xat1.equals(xat3)) /*False*/ 
+		throw new SecurityException("Failed False Check (equals)");
+
+    	// Check ==
+	if(xat1 == xat2) /*False*/ 
+		throw new SecurityException("Failed True Check (==)");
+	if(xat1 == xat3) /*False*/ 
+		throw new SecurityException("Failed False Check (==)");
+
+	System.out.println("Checking XdmfGeometryType");	
+	XdmfGeometryType xgt1 = XdmfGeometryType.XYZ();
+	XdmfGeometryType xgt2 = XdmfGeometryType.XYZ();
+	XdmfGeometryType xgt3 = XdmfGeometryType.XY();
+	
+	// Check IsEquals
+	if(!(xgt1.IsEqual(xgt2))) /*True*/
+		throw new SecurityException("Failed True Check");
+	if((xgt1.IsEqual(xgt3))) /*False*/ 
+    		throw new SecurityException("Failed False Check");	
+
+	// Check equals
+	if(!(xgt1.equals(xgt2))) /*True*/ 
+		throw new SecurityException("Failed True Check (equals)");
+	if(xgt1.equals(xgt3)) /*False*/ 
+		throw new SecurityException("Failed False Check (equals)");
+
+    	// Check ==
+	if(xgt1 == xgt2) /*False*/ 
+		throw new SecurityException("Failed True Check (==)");
+	if(xgt1 == xgt3) /*False*/ 
+		throw new SecurityException("Failed False Check (==)");
+
+	System.out.print("Checking XdmfGridCollection");
+	XdmfGridCollectionType xgct1 = XdmfGridCollectionType.Spatial();
+        XdmfGridCollectionType xgct2 = XdmfGridCollectionType.Spatial();
+        XdmfGridCollectionType xgct3 = XdmfGridCollectionType.Temporal();
+
+        // Check IsEquals
+        if(!(xgct1.IsEqual(xgct2))) /*True*/
+                throw new SecurityException("Failed True Check");
+        if((xgct1.IsEqual(xgct3))) /*False*/
+                throw new SecurityException("Failed False Check");
+
+        // Check equals
+        if(!(xgct1.equals(xgct2))) /*True*/
+                throw new SecurityException("Failed True Check (equals)");
+        if(xgct1.equals(xgct3)) /*False*/
+                throw new SecurityException("Failed False Check (equals)");
+
+        // Check ==
+        if(xgct1 == xgct2) /*False*/
+                throw new SecurityException("Failed True Check (==)");
+        if(xgct1 == xgct3) /*False*/
+                throw new SecurityException("Failed False Check (==)");
+	
+	System.out.println("Checking XdmfSetType");
+	XdmfSetType xst1 = XdmfSetType.Node();
+        XdmfSetType xst2 = XdmfSetType.Node();
+        XdmfSetType xst3 = XdmfSetType.Face();
+
+        // Check IsEquals
+        if(!(xst1.IsEqual(xst2))) /*True*/
+                throw new SecurityException("Failed True Check");
+        if((xst1.IsEqual(xst3))) /*False*/
+                throw new SecurityException("Failed False Check");
+
+        // Check equals
+        if(!(xst1.equals(xst2))) /*True*/
+                throw new SecurityException("Failed True Check (equals)");
+        if(xst1.equals(xst3)) /*False*/
+                throw new SecurityException("Failed False Check (equals)");
+
+        // Check ==
+        if(xst1 == xst2) /*False*/
+                throw new SecurityException("Failed True Check (==)");
+        if(xst1 == xst3) /*False*/
+                throw new SecurityException("Failed False Check (==)");
+
+
+	System.out.println("Checking XdmfTopologyType");
+ 	XdmfTopologyType xtt1 = XdmfTopologyType.Polyvertex();
+        XdmfTopologyType xtt2 = XdmfTopologyType.Polyvertex();
+        XdmfTopologyType xtt3 = XdmfTopologyType.Polyline(0);
+
+        // Check IsEquals
+        if(!(xtt1.IsEqual(xtt2))) /*True*/
+                throw new SecurityException("Failed True Check");
+        if((xtt1.IsEqual(xtt3))) /*False*/
+                throw new SecurityException("Failed False Check");
+
+        // Check equals
+        if(!(xtt1.equals(xtt2))) /*True*/
+                throw new SecurityException("Failed True Check (equals)");
+        if(xtt1.equals(xtt3)) /*False*/
+                throw new SecurityException("Failed False Check (equals)");
+
+        // Check ==
+        if(xtt1 == xtt2) /*False*/
+                throw new SecurityException("Failed True Check (==)");
+        if(xtt1 == xtt3) /*False*/
+                throw new SecurityException("Failed False Check (==)");
+
+    }
+}
diff --git a/tests/Java/TestXdmfGC.java b/tests/Java/TestXdmfGC.java
new file mode 100644
index 0000000..df3177a
--- /dev/null
+++ b/tests/Java/TestXdmfGC.java
@@ -0,0 +1,17 @@
+import mil.army.arl.xdmf.*;
+
+public class TestXdmfGC {
+    public static void main (String argv[]) {
+        System.out.println("Hello Java World (Garbage Collector)");
+
+	for(int i = 0; i < 10; i++)        
+	{
+	    System.gc();
+	    XdmfWriter w = XdmfWriter.New("outputXdmfGC"); 
+	    XdmfDomain d = XdmfDomain.New();
+	    d.accept(w);
+	}
+        
+        System.out.println("Done");
+    }	    
+}
diff --git a/tests/Java/TestXdmfJava.java b/tests/Java/TestXdmfJava.java
new file mode 100644
index 0000000..77f4b81
--- /dev/null
+++ b/tests/Java/TestXdmfJava.java
@@ -0,0 +1,17 @@
+import mil.army.arl.xdmf.*;
+
+public class TestXdmfJava {
+    public static void main (String argv[]) {
+        System.out.println("Hello World");
+        XdmfWriter writer = XdmfWriter.New("outputJavaTest.xmf");
+        writer.setLightDataLimit((long)10);
+        
+        XdmfUnstructuredGrid grid = XdmfUnstructuredGrid.New();
+        grid.setName("test");
+        grid.getGeometry().setType(XdmfGeometryType.XYZ());
+
+        XdmfDomain domain = XdmfDomain.New();
+        domain.insert(grid);
+        domain.accept(writer);
+    }
+}
diff --git a/tests/Python/CMakeLists.txt b/tests/Python/CMakeLists.txt
new file mode 100644
index 0000000..877deea
--- /dev/null
+++ b/tests/Python/CMakeLists.txt
@@ -0,0 +1,65 @@
+include(AddTestsPython)
+
+# Add any dependencies that the python tests may need
+# Note: The tests already depend on their own file
+#	PYTHON_TEST_DEPENDENCIES is also set in core
+ADD_TEST_PYTHON_DEPENDENCIES("")
+
+# Add any pythonpath directories that the python tests may need
+# Note: PYTHON_TEST_PYTHONPATH is also set in core
+ADD_TEST_PYTHON_PYTHONPATH("${PYTHON_INCLUDE_MPI4PY_DIR}/../..")
+
+# Add any python tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have extra arguments (ie: ADD_TEST_PYTHON(testname inputfile))
+#	Read UsePythonTest.cmake for more information
+# -----------------------
+ADD_TEST_PYTHON(TestXdmfEquals)
+ADD_TEST_PYTHON(TestXdmfFunction)
+ADD_TEST_PYTHON(TestXdmfFunctionRead)
+ADD_TEST_PYTHON(TestXdmfHDF5Writer)
+ADD_TEST_PYTHON(TestXdmfRead)
+ADD_TEST_PYTHON(TestXdmfSet)
+ADD_TEST_PYTHON(TestXdmfWriter)
+ADD_TEST_PYTHON(TestXdmfXPointerReference)
+ADD_TEST_PYTHON(ReadTypeTest)
+
+
+# Add any python cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have multiple files (ie: CLEAN_TEST_PYTHON(testname outputfile1 ...))
+#	Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_PYTHON(TestXdmfEquals)
+CLEAN_TEST_PYTHON(TestXdmfFunction
+  function.xmf
+  function.h5)
+CLEAN_TEST_PYTHON(TestXdmfFunctionRead)
+CLEAN_TEST_PYTHON(TestXdmfHDF5Writer
+  hdf5WriterPythonTest.h5)
+CLEAN_TEST_PYTHON(TestXdmfRead
+  TestXdmfRead.xmf
+  TestXdmfRead.h5)
+CLEAN_TEST_PYTHON(TestXdmfSet)
+CLEAN_TEST_PYTHON(TestXdmfWriter
+  output.h5
+  output.xmf)
+CLEAN_TEST_PYTHON(TestXdmfXPointerReference
+  duplicateXpointer.xmf
+  duplicateXpointer.h5
+  duplicateXpointer2.xmf
+  duplicateXpointer2.h5)
+CLEAN_TEST_PYTHON(ReadTypeTest
+  typeTest.h5
+  typeTest.xmf)
+
+
+# Add a custom target for all python tests
+# Note: ${TARGETS} is set in ADD_TEST_PYTHON
+#IF(EXISTS Python_Core_Test_target)
+#	SET(Python_Core_Test_target Python_Core_Test_target)
+#ENDIF(EXISTS Python_Core_Test_target)
+
+#GET_PROPERTY(targets GLOBAL PROPERTY PYTHON_TEST_TARGETS)
+#ADD_CUSTOM_TARGET(Python_ALLTEST ALL DEPENDS ${Python_Core_Test_target} ${targets})
+CREATE_TARGET_TEST_PYTHON()
diff --git a/tests/Python/ReadArray.py b/tests/Python/ReadArray.py
new file mode 100644
index 0000000..afd0b72
--- /dev/null
+++ b/tests/Python/ReadArray.py
@@ -0,0 +1,76 @@
+from Xdmf import *
+
+
+def maximum(values):
+	values = ArrayVector(values)#need to cast to the right data type
+        if values[0].getArrayType() == XdmfArrayType.String():
+                returnArray = XdmfArray.New()
+                returnArray.pushBackAsString(values[0].getValueAsString(0))
+                return returnArray;
+        else:
+                maxVal = values[0].getValueAsFloat64(0)
+                for i in range (0, values.size()):
+                        for j in range (0, values[i].getSize()):
+                                if maxVal < values[i].getValueAsFloat64(j):
+                                        maxVal = values[i].getValueAsFloat64(j)
+                returnArray = XdmfArray.New()
+                returnArray.pushBackAsFloat64(maxVal)
+                return returnArray
+
+def prepend(val1, val2):
+	val1 = XdmfArray.XdmfArrayPtr(val1)#need to cast to the right data type
+	val2 = XdmfArray.XdmfArrayPtr(val2)#had to write a custom casting method to integrate it properly
+	returnArray = XdmfArray.New()
+	returnArray.insert(0, val2, 0, val2.getSize())
+	returnArray.insert(val2.getSize(), val1, 0, val1.getSize())
+	return returnArray
+
+if __name__ == "__main__":
+	#functions are passed as callable pyobjects
+	XdmfFunction.addFunction("MAX", maximum)
+	functionVector = XdmfFunction.getSupportedFunctions()
+	for i in range (0, functionVector.size()):
+		print functionVector[i]
+	XdmfFunction.addOperation("@", prepend, 2)
+	print XdmfFunction.getSupportedOperations()
+        testVector = ArrayVector()
+	testArray = XdmfArray.New()
+	testArray.pushBackAsInt32(10)
+	testArray.pushBackAsInt32(9)
+	testVector.push_back(testArray)
+	print "before evaluating function"
+	resultArray = XdmfFunction.evaluateFunction(testVector, "MAX")
+	print type(resultArray)
+	print "after function is evaulated"
+	print resultArray.getValuesString()
+	print "before evaluating function"
+	resultArray = XdmfFunction.evaluateFunction(testVector, "AVE")
+	print type(resultArray)
+	print "after function is evaulated"
+	print resultArray.getValuesString()
+	testArray2 = XdmfArray.New()
+	testArray2.pushBackAsInt32(1)
+	testArray2.pushBackAsInt32(2)
+	print "before evaluating Operation"
+	resultArray = XdmfFunction.evaluateOperation(testArray, testArray2, "|")
+	print type(resultArray)
+	print "after evaluationg Operation"
+	print resultArray.getValuesString()
+	resultArray = XdmfFunction.evaluateOperation(testArray, testArray2, "@")
+	print type(resultArray)
+	print "after evaluationg Operation"
+	print resultArray.getValuesString()
+	print "before evaluating expression"
+	testMap = ArrayMap()
+	testMap["A"] = testArray
+	testMap["B"] = testArray2
+	testArray3 = XdmfArray.New()
+	testArray3.pushBackAsInt32(5)
+	testArray3.pushBackAsInt32(5)
+	testArray3.pushBackAsInt32(5)
+	testArray3.pushBackAsInt32(5)
+	testMap["C"] = testArray3
+	resultArray = XdmfFunction.evaluateExpression("A|B#C", testMap)
+	print type(resultArray)
+	print resultArray.getValuesString()
+	print "after evaluating expression"
diff --git a/tests/Python/ReadTypeTest.py b/tests/Python/ReadTypeTest.py
new file mode 100644
index 0000000..bbee432
--- /dev/null
+++ b/tests/Python/ReadTypeTest.py
@@ -0,0 +1,28 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+	testDomain = XdmfDomain.New()
+	testCollection1 = XdmfGridCollection.New()
+	testCollection2 = XdmfGridCollection.New()
+	testCollection3 = XdmfGridCollection.New()
+
+	testCollection2.insert(testCollection3)
+	testCollection1.insert(testCollection2)
+	testDomain.insert(testCollection1)
+
+	testWriter = XdmfWriter.New("typeTest.xmf")
+
+	testDomain.accept(testWriter)
+
+	readXPath = "/Xdmf/Domain/Grid"
+        testReader = XdmfReader.New()
+
+	readVector = testReader.read("typeTest.xmf", readXPath)
+
+	print type(readVector)
+	print type(readVector[0])
+
+        print str(readVector[0]) + " ?= " + str(XdmfGridCollection)
+
+	assert(type(readVector[0]) == XdmfGridCollection)
diff --git a/tests/Python/SplitTime.py b/tests/Python/SplitTime.py
new file mode 100644
index 0000000..ec68dd9
--- /dev/null
+++ b/tests/Python/SplitTime.py
@@ -0,0 +1,41 @@
+from Xdmf import *
+import XdmfCore
+import timeit
+import os
+import time
+
+numberArrays = 10000
+arraySize = 100
+
+h5file = os.getcwd() + "/timing.h5"
+xmffile = os.getcwd() + "/timing.xmf"
+
+class TimedWrite():
+    def __init__(self):
+        self.domain = XdmfDomain.New()
+        grid = XdmfUnstructuredGrid.New()
+        self.domain.insert(grid)
+        dimensionArray = UInt32Vector()
+	dimensionArray.push_back(arraySize)
+	dimensionArray.push_back(arraySize)
+        for i in range(0, numberArrays):
+            attribute = XdmfAttribute.New()
+            attribute.resizeAsFloat64(dimensionArray)
+            grid.insert(attribute)
+
+        hdf5Writer = XdmfHDF5Writer.New(h5file)
+        hdf5Writer.setFileSizeLimit(10000)
+        self.writer = XdmfWriter.New(xmffile,
+                                     hdf5Writer)
+	self.writer.setLightDataLimit(10)
+
+    def write(self):
+        self.domain.accept(self.writer)
+   
+if __name__ == "__main__":
+    timedWrite = TimedWrite()
+    startclock = time.clock()
+    print timeit.Timer(timedWrite.write).timeit(1)
+    print (time.clock() - startclock)
+    os.remove(xmffile)
+    os.remove(h5file)
diff --git a/tests/Python/TestXdmfEquals.py b/tests/Python/TestXdmfEquals.py
new file mode 100644
index 0000000..a4d4ff8
--- /dev/null
+++ b/tests/Python/TestXdmfEquals.py
@@ -0,0 +1,59 @@
+from XdmfCore import *
+from Xdmf import *
+
+if __name__ == "__main__":
+
+    xac1 = XdmfAttributeCenter.Grid()
+    xac2 = XdmfAttributeCenter.Grid()
+    xac3 = XdmfAttributeCenter.Cell()
+
+    print "XdmfAttributeCenter True Check"
+    assert xac1 == xac2
+    print "XdmfAttributeCenter False Check"
+    assert not xac1 == xac3
+
+    xat1 = XdmfAttributeType.Scalar()
+    xat2 = XdmfAttributeType.Scalar()
+    xat3 = XdmfAttributeType.Tensor()
+
+    print "XdmfAttributeType True Check"
+    assert xat1 == xat2
+    print "XdmfAttributeType False Check"
+    assert not xat1 == xat3
+
+    xgt1 = XdmfGeometryType.XYZ()
+    xgt2 = XdmfGeometryType.XYZ()
+    xgt3 = XdmfGeometryType.XY()
+
+    print "XdmfGeometryType True Check"
+    assert xgt1 == xgt2
+    print "XdmfGeometryType False Check"
+    assert not xgt1 == xgt3
+
+    xgct1 = XdmfGridCollectionType.Spatial()
+    xgct2 = XdmfGridCollectionType.Spatial()
+    xgct3 = XdmfGridCollectionType.Temporal()
+
+    print "XdmfGridCollectionType True Check"
+    assert xgct1 == xgct2
+    print "XdmfGridCollectionType False Check"
+    assert not xgct1 == xgct3
+
+    xst1 = XdmfSetType.Node()
+    xst2 = XdmfSetType.Node()
+    xst3 = XdmfSetType.Face()
+
+    print "XdmfSetType True Check"
+    assert xst1 == xst2
+    print "XdmfSetType False Check"
+    assert not xst1 == xst3
+
+    xtt1 = XdmfTopologyType.Polyvertex()
+    xtt2 = XdmfTopologyType.Polyvertex()
+    xtt3 = XdmfTopologyType.Polyline(0)
+
+    print "XdmfTopologyType True Check"
+    assert xtt1 == xtt2
+    print "XdmfTopologyType False Check"
+    assert not xtt1 == xtt3
+
diff --git a/tests/Python/TestXdmfFunction.py b/tests/Python/TestXdmfFunction.py
new file mode 100644
index 0000000..b19a5f8
--- /dev/null
+++ b/tests/Python/TestXdmfFunction.py
@@ -0,0 +1,84 @@
+from Xdmf import *
+
+
+def maximum(values):
+	# Need to cast to the right data type
+	values = ArrayVector(values)
+        if values[0].getArrayType() == XdmfArrayType.String():
+                returnArray = XdmfArray.New()
+                returnArray.pushBackAsString(values[0].getValueAsString(0))
+                return returnArray;
+        else:
+                maxVal = values[0].getValueAsFloat64(0)
+                for i in range (0, values.size()):
+                        for j in range (0, values[i].getSize()):
+                                if maxVal < values[i].getValueAsFloat64(j):
+                                        maxVal = values[i].getValueAsFloat64(j)
+                returnArray = XdmfArray.New()
+                returnArray.pushBackAsFloat64(maxVal)
+                return returnArray
+
+def prepend(val1, val2):
+	# Need to cast to the right data type
+	# Had to write a custom casting method to integrate it properly
+	val1 = XdmfArray.XdmfArrayPtr(val1)
+	val2 = XdmfArray.XdmfArrayPtr(val2)
+	returnArray = XdmfArray.New()
+	returnArray.insert(0, val2, 0, val2.getSize())
+	returnArray.insert(val2.getSize(), val1, 0, val1.getSize())
+	return returnArray
+
+if __name__ == "__main__":
+	#functions are passed as callable pyobjects
+	XdmfFunction.addFunction("MAX", maximum)
+	functionVector = XdmfFunction.getSupportedFunctions()
+	for i in functionVector:
+		print i
+	XdmfFunction.addOperation("@", prepend, 2)
+	print XdmfFunction.getSupportedOperations()
+        testVector = ArrayVector()
+	testArray = XdmfArray.New()
+	testArray.pushBackAsInt32(10)
+	testArray.pushBackAsInt32(9)
+	testVector.push_back(testArray)
+	print "before evaluating function"
+	resultArray = XdmfFunction.evaluateFunction(testVector, "MAX")
+	print type(resultArray)
+	print "after function is evaulated"
+	print resultArray.getValuesString()
+	assert resultArray.getValuesString() == "10"
+	print "before evaluating function"
+	resultArray = XdmfFunction.evaluateFunction(testVector, "AVE")
+	print type(resultArray)
+	print "after function is evaulated"
+	print resultArray.getValuesString() + " ?= 9.5"
+	assert resultArray.getValuesString() == "9.5"
+	testArray2 = XdmfArray.New()
+	testArray2.pushBackAsInt32(1)
+	testArray2.pushBackAsInt32(2)
+	print "before evaluating Operation"
+	resultArray = XdmfFunction.evaluateOperation(testArray, testArray2, "|")
+	print type(resultArray)
+	print "after evaluationg Operation"
+	print resultArray.getValuesString() + " ?= 10 9 1 2"
+	assert resultArray.getValuesString() == "10 9 1 2"
+	resultArray = XdmfFunction.evaluateOperation(testArray, testArray2, "@")
+	print type(resultArray)
+	print "after evaluationg Operation"
+	print resultArray.getValuesString() + " ?= 1 2 10 9"
+	assert resultArray.getValuesString() == "1 2 10 9"
+	print "before evaluating expression"
+	testMap = ArrayMap()
+	testMap["A"] = testArray
+	testMap["B"] = testArray2
+	testArray3 = XdmfArray.New()
+	testArray3.pushBackAsInt32(5)
+	testArray3.pushBackAsInt32(5)
+	testArray3.pushBackAsInt32(5)
+	testArray3.pushBackAsInt32(5)
+	testMap["C"] = testArray3
+	resultArray = XdmfFunction.evaluateExpression("A|B#C", testMap)
+	print type(resultArray)
+	print resultArray.getValuesString() + " ?= 10 5 9 5 1 5 2 5"
+	assert resultArray.getValuesString() == "10 5 9 5 1 5 2 5"
+	print "after evaluating expression"
diff --git a/tests/Python/TestXdmfFunctionRead.py b/tests/Python/TestXdmfFunctionRead.py
new file mode 100644
index 0000000..b62fc03
--- /dev/null
+++ b/tests/Python/TestXdmfFunctionRead.py
@@ -0,0 +1,82 @@
+from Xdmf import *
+
+def maximum(values):
+	# Need to cast to the right data type
+	values = ArrayVector(values)
+	if values[0].getArrayType() == XdmfArrayType.String():
+		returnArray = XdmfArray.New()
+		returnArray.pushBackAsString(values[0].getValueAsString(0))
+		return returnArray;
+	else:
+		maxVal = values[0].getValueAsFloat64(0)
+		for i in range (0, values.size()):
+			for j in range (0, values[i].getSize()):
+				if maxVal < values[i].getValueAsFloat64(j):
+					maxVal = values[i].getValueAsFloat64(j)
+		returnArray = XdmfArray.New()
+		returnArray.pushBackAsFloat64(maxVal)
+		return returnArray
+
+def prepend(val1, val2):
+	# Need to cast to the right data type
+	# Had to write a custom casting method to integrate it properly
+	val1 = XdmfArray.XdmfArrayPtr(val1)
+	val2 = XdmfArray.XdmfArrayPtr(val2)
+	returnArray = XdmfArray.New()
+	returnArray.insert(0, val2, 0, val2.getSize())
+	returnArray.insert(val2.getSize(), val1, 0, val1.getSize())
+	return returnArray
+
+if __name__ == "__main__":
+	functionExpression = "MAX(A,B)@(A#B)"
+
+	numOperations = XdmfFunction.addOperation('@', prepend, 2)
+	numFunctions = XdmfFunction.addFunction("MAX", maximum)
+
+	functionVariables = ArrayMap()
+
+	variable1 = XdmfArray.New()
+
+	for i in range (0, 15):
+		variable1.pushBackAsInt32(i*3)
+
+	functionVariables["A"] = variable1
+
+	variable2 = XdmfArray.New()
+
+	for i in range (0, 15):
+		variable2.pushBackAsInt32(i*5)
+
+	functionVariables["B"] = variable2
+
+	testFunction = XdmfFunction.New(functionExpression, functionVariables)
+
+	functionHolder = XdmfAttribute.New()
+
+	functionHolder.setReference(testFunction)
+
+	functionHolder.setReadMode(XdmfArray.Reference)
+
+	functionWriter = XdmfWriter.New("function.xmf")
+
+	functionHolder.accept(functionWriter)
+
+	functionHolder.readReference()
+
+	print functionHolder.getValuesString()
+
+	functionReader = XdmfReader.New()
+
+	readItem = functionReader.read("function.xmf")
+
+        print readItem.getItemTag() + " ?= Attribute"
+
+	assert readItem.getItemTag() == "Attribute"
+
+	readFunctionHolder = readItem
+
+	readFunctionHolder.readReference()
+
+        print readFunctionHolder.getValuesString() + " ?= " + functionHolder.getValuesString()
+
+	assert readFunctionHolder.getValuesString() == functionHolder.getValuesString()
diff --git a/tests/Python/TestXdmfHDF5Writer.py b/tests/Python/TestXdmfHDF5Writer.py
new file mode 100644
index 0000000..96e4e49
--- /dev/null
+++ b/tests/Python/TestXdmfHDF5Writer.py
@@ -0,0 +1,39 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+    writer = XdmfHDF5Writer.New("hdf5WriterPythonTest.h5")
+
+    grid = XdmfUnstructuredGrid.New()
+    grid.setName("test")
+    points = [0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1,
+              1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1,
+              0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1]
+
+    grid.getGeometry().setType(XdmfGeometryType.XYZ())
+    grid.getGeometry().insertAsFloat64(0, points)
+
+    connectivity = [0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10]
+    grid.getTopology().setType(XdmfTopologyType.Hexahedron())
+    grid.getTopology().insertAsInt32(0, connectivity)
+
+    nodalAttribute = XdmfAttribute.New()
+    nodalAttribute.setName("Nodal Attribute")
+    nodalAttribute.setType(XdmfAttributeType.Scalar())
+    nodalAttribute.setCenter(XdmfAttributeCenter.Node())
+    nodeVals = [100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600, 700]
+    nodalAttribute.insertAsFloat64(0, nodeVals)
+
+    cellAttribute = XdmfAttribute.New()
+    cellAttribute.setName("Cell Attribute")
+    cellAttribute.setType(XdmfAttributeType.Scalar())
+    cellAttribute.setCenter(XdmfAttributeCenter.Cell())
+    cellVals = [100, 200]
+    cellAttribute.insertAsFloat64(0, cellVals)
+
+    grid.insert(nodalAttribute)
+    grid.insert(cellAttribute)
+
+    domain = XdmfDomain.New()
+    domain.insert(grid)
+    domain.accept(writer)
diff --git a/tests/Python/TestXdmfRead.py b/tests/Python/TestXdmfRead.py
new file mode 100644
index 0000000..3a01eef
--- /dev/null
+++ b/tests/Python/TestXdmfRead.py
@@ -0,0 +1,58 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+    fileName ="TestXdmfRead.xmf"
+
+    # create a simple empty file
+    domain = XdmfDomain.New()
+    collection = XdmfGridCollection.New()
+    grid = XdmfUnstructuredGrid.New()
+    attribute1 = XdmfAttribute.New()
+    attribute2 = XdmfAttribute.New()
+    information = XdmfInformation.New()
+
+    domain.insert(collection)
+    collection.insert(grid)
+    grid.insert(attribute1)
+    grid.insert(attribute2)
+    grid.insert(information)
+    
+    writer = XdmfWriter.New(fileName)
+    domain.accept(writer)
+
+    # read file using XPaths and verify downcasts to appropriate XdmfItems
+    reader = XdmfReader.New()
+
+    domain = reader.read(fileName, "/Xdmf/Domain")
+    print str(len(domain)) + " ?= " + str(1)
+    print "? " + str(isinstance(domain[0], XdmfDomain))
+    assert(len(domain) == 1)
+    assert(isinstance(domain[0], XdmfDomain))
+
+    collection = reader.read(fileName, "/Xdmf/Domain/Grid")
+    print str(len(collection)) + " ?= " + str(1)
+    print "? " + str(isinstance(collection[0], XdmfGridCollection))
+    assert(len(collection) == 1)
+    assert(isinstance(collection[0], XdmfGridCollection))
+    
+    grid = reader.read(fileName, "/Xdmf/Domain/Grid/Grid")
+    print str(len(grid)) + " ?= " + str(1)
+    print "? " + str(isinstance(grid[0], XdmfUnstructuredGrid))
+    assert(len(grid) == 1)
+    assert(isinstance(grid[0], XdmfUnstructuredGrid))
+
+    attributes = reader.read(fileName, "/Xdmf/Domain/Grid/Grid/Attribute")
+    print str(len(attributes)) + " ?= " + str(2)
+    print "? " + str(isinstance(attributes[0], XdmfAttribute))
+    print "? " + str(isinstance(attributes[1], XdmfAttribute))
+    assert(len(attributes) == 2)
+    assert(isinstance(attributes[0], XdmfAttribute))
+    assert(isinstance(attributes[1], XdmfAttribute))
+
+    information = reader.read(fileName, "/Xdmf/Domain/Grid/Grid/Information")
+    print str(len(information)) + " ?= " + str(1)
+    print "? " + str(isinstance(information[0], XdmfInformation))
+    assert(len(information) == 1)
+    assert(isinstance(information[0], XdmfInformation))
+
diff --git a/tests/Python/TestXdmfSet.py b/tests/Python/TestXdmfSet.py
new file mode 100644
index 0000000..d1cbfd2
--- /dev/null
+++ b/tests/Python/TestXdmfSet.py
@@ -0,0 +1,24 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+    set = XdmfSet.New()
+    print set.getName() + " ?= "
+    print "?! " + str(set.isInitialized())
+    assert(set.getName() == "")
+    assert(not set.isInitialized())
+    set.setName("foo")
+    print set.getName() + " ?= foo"
+    print str(set.getType()) + " ?= " + str(XdmfSetType.NoSetType())
+    assert(set.getName() == "foo")
+    assert(set.getType() == XdmfSetType.NoSetType())
+    set.setType(XdmfSetType.Node())
+    print str(set.getType()) + " ?= " + str(XdmfSetType.Node())
+    print str(set.getSize()) + " ?= " + str(0)
+    assert(set.getType() == XdmfSetType.Node())
+    assert(set.getSize() == 0)
+    print type(1).__name__
+    set.insertValueAsInt32(0, 1)
+    print str(set.getSize()) + " ?= " + str(1)
+    assert(set.getSize() == 1)
+
diff --git a/tests/Python/TestXdmfWriter.py b/tests/Python/TestXdmfWriter.py
new file mode 100644
index 0000000..b2441aa
--- /dev/null
+++ b/tests/Python/TestXdmfWriter.py
@@ -0,0 +1,163 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+    writer = XdmfWriter.New("output.xmf")
+    writer.setLightDataLimit(10)
+
+    heavyFile = "testoutput.h5"
+    replaceFile = True
+    exampleHeavyWriter = XdmfHDF5Writer.New(heavyFile, replaceFile)
+    exampleWriter = XdmfWriter.New("testoutput.xmf", exampleHeavyWriter)
+
+    grid = XdmfUnstructuredGrid.New()
+    grid.setName("test")
+    points = [0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1,
+              1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1,
+              0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1]
+
+    testArray = XdmfArray.New()
+
+    dimensionVector = UInt32Vector()
+    dimensionVector.push_back(3)
+    dimensionVector.push_back(12)
+
+    testArray.initialize(XdmfArrayType.Float64(), dimensionVector)
+#    testArray.initialize(XdmfArrayType.Float64(), 36)
+
+    testVals = [float(piece) for piece in testArray.getValuesString().split()]
+    print testVals
+    print "These values are not exact because of the way that python handles floats"
+
+    testArray.insertAsFloat64(0, points)
+
+    arrayDimensions = testArray.getDimensions()
+
+    for val in arrayDimensions:
+      print val
+
+    testVals = [float(piece) for piece in testArray.getValuesString().split()]
+    print testVals
+    print "These values are not exact because of the way that python handles floats"
+
+    grid.getGeometry().setType(XdmfGeometryType.XYZ())
+    grid.getGeometry().insert(0, testArray, 0, 36, 1, 1);
+# or insert points directly
+#    grid.getGeometry().insertAsFloat64(0, points)
+
+    connectivity = [0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10]
+    grid.getTopology().setType(XdmfTopologyType.Hexahedron())
+    grid.getTopology().insertAsInt32(0, connectivity)
+
+    nodalAttribute = XdmfAttribute.New()
+    nodalAttribute.setName("Nodal Attribute")
+    nodalAttribute.setType(XdmfAttributeType.Scalar())
+    nodalAttribute.setCenter(XdmfAttributeCenter.Node())
+    nodeVals = [100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600, 700]
+    nodalAttribute.insertAsFloat64(0, nodeVals)
+
+    cellAttribute = XdmfAttribute.New()
+    cellAttribute.setName("Cell Attribute")
+    cellAttribute.setType(XdmfAttributeType.Scalar())
+    cellAttribute.setCenter(XdmfAttributeCenter.Cell())
+    cellVals = [100, 200]
+    cellAttribute.insertAsFloat64(0, cellVals)
+
+    map1Attribute = XdmfAttribute.New()
+    map1Attribute.setName("Test Attribute")
+    map1Attribute.setType(XdmfAttributeType.Scalar())
+    map1Attribute.setCenter(XdmfAttributeCenter.Node())
+    map1Vals = [1,2,3,4,5,7,9]
+    map1Attribute.insertAsInt32(0, map1Vals)
+
+    map2Attribute = XdmfAttribute.New()
+    map2Attribute.setName("Test Attribute")
+    map2Attribute.setType(XdmfAttributeType.Scalar())
+    map2Attribute.setCenter(XdmfAttributeCenter.Node())
+    map2Vals = [9,8,7,4,3]
+    map2Attribute.insertAsInt32(0, map2Vals)
+
+    testVector = AttributeVector()
+    testVector.push_back(map1Attribute)
+    testVector.push_back(map2Attribute)
+
+    testMap = XdmfMap.New(testVector)
+
+    taskIDMap = testMap[0].getMap()
+    nodeIDMap = taskIDMap[1]
+
+    print type(taskIDMap)
+
+    i = 0
+    for val in taskIDMap:
+      print val
+      i = i + 1
+      if i == taskIDMap.size():
+        break
+
+    i = 0
+    for val in nodeIDMap:
+      print val
+      i = i + 1
+      if i == nodeIDMap.size():
+        break
+
+    for val in nodeIDMap[3]:
+      print val
+
+    newTaskMap = XdmfMapMap()
+
+    newNodeIdMap = XdmfMapNodeIdMap()
+
+    newNodeIdMap[0] = (1,)
+    newNodeIdMap[1] = (5,)
+    newNodeIdMap[2] = (3,)
+    newNodeIdMap[3] = (6,)
+    newNodeIdMap[4] = (2,)
+
+    newTaskMap[1] = newNodeIdMap
+
+    testSetMap = XdmfMap.New()
+    testSetMap.setMap(newTaskMap)
+
+    grid.insert(nodalAttribute)
+    grid.insert(cellAttribute)
+    grid.insert(testSetMap)
+    for insertedMap in testMap:
+      grid.insert(insertedMap)
+
+
+    xPoints = XdmfArray.New()
+    xPoints.pushBackAsInt32(1)
+    xPoints.pushBackAsInt32(2)
+    xPoints.pushBackAsInt32(3)
+    xPoints.pushBackAsInt32(4)
+    xPoints.pushBackAsInt32(5)
+
+    yPoints = XdmfArray.New()
+    yPoints.pushBackAsInt32(1)
+    yPoints.pushBackAsInt32(2)
+    yPoints.pushBackAsInt32(3)
+    yPoints.pushBackAsInt32(4)
+    yPoints.pushBackAsInt32(5)
+
+    zPoints = XdmfArray.New()
+    zPoints.pushBackAsInt32(1)
+    zPoints.pushBackAsInt32(2)
+    zPoints.pushBackAsInt32(3)
+    zPoints.pushBackAsInt32(4)
+    zPoints.pushBackAsInt32(5)
+
+    arrayVector = ArrayVector()
+    arrayVector.push_back(xPoints)
+    arrayVector.push_back(yPoints)
+    arrayVector.push_back(zPoints)
+
+    rectGrid = XdmfRectilinearGrid.New(arrayVector)
+
+
+    domain = XdmfDomain.New()
+    domain.insert(grid)
+    domain.insert(rectGrid)
+    domain.accept(writer)
+    domain.accept(exampleWriter)
diff --git a/tests/Python/TestXdmfXPointerReference.py b/tests/Python/TestXdmfXPointerReference.py
new file mode 100644
index 0000000..e29c9f8
--- /dev/null
+++ b/tests/Python/TestXdmfXPointerReference.py
@@ -0,0 +1,47 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+
+        reader = XdmfReader.New()
+
+        domain = XdmfDomain.New()
+
+        collection1 = XdmfGridCollection.New()
+        collection2 = XdmfGridCollection.New()
+
+        unstructuredGrid = XdmfUnstructuredGrid.New()
+
+        collection1.insert(unstructuredGrid)
+        collection2.insert(unstructuredGrid)
+        domain.insert(collection1)
+        domain.insert(collection2)
+
+        writer = XdmfWriter.New("duplicateXpointer.xmf")
+
+        domain.accept(writer)
+
+        readDomain = reader.read("duplicateXpointer.xmf")
+
+        print str(readDomain.getGridCollection(0).getUnstructuredGrid(0)) + "\n?=\n" + str(readDomain.getGridCollection(1).getUnstructuredGrid(0))
+
+        assert(readDomain.getGridCollection(0).getUnstructuredGrid(0) == readDomain.getGridCollection(1).getUnstructuredGrid(0))
+
+        readDomain.getGridCollection(0).getUnstructuredGrid(0).setName("Test Grid")
+
+        time = XdmfTime.New(5.5)
+
+        readDomain.getGridCollection(1).getUnstructuredGrid(0).setTime(time)
+
+        writer2 = XdmfWriter.New("duplicateXpointer2.xmf")
+
+        readDomain.accept(writer2)
+
+        readDomain2 = reader.read("duplicateXpointer2.xmf")
+
+        print readDomain2.getGridCollection(1).getUnstructuredGrid(0).getName() + " ?= Test Grid"
+
+        print str(readDomain2.getGridCollection(0).getUnstructuredGrid(0).getTime().getValue()) + " ?= " + str(5.5)
+
+        assert(readDomain2.getGridCollection(1).getUnstructuredGrid(0).getName() =="Test Grid")
+
+        assert(readDomain2.getGridCollection(0).getUnstructuredGrid(0).getTime().getValue() == 5.5)
diff --git a/tests/Python/WriteArray.py b/tests/Python/WriteArray.py
new file mode 100644
index 0000000..1a5ed8a
--- /dev/null
+++ b/tests/Python/WriteArray.py
@@ -0,0 +1,15 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+	primaryDomain = XdmfDomain.New()
+	testGrid = XdmfUnstructuredGrid.New()
+	primaryDomain.insert(testGrid)
+	testGeometry = XdmfGeometry.New()
+	for i in range (0, 11):
+		testGeometry.pushBackAsInt32(i);
+	testGrid.setGeometry(testGeometry)
+	testTopology = XdmfTopology.New()
+	testGrid.setTopology(testTopology)
+
+	arrayWriter = XdmfWriter.New("array.xmf")
+	primaryDomain.accept(arrayWriter)
diff --git a/tests/Python/WriteTime.py b/tests/Python/WriteTime.py
new file mode 100644
index 0000000..e6359fc
--- /dev/null
+++ b/tests/Python/WriteTime.py
@@ -0,0 +1,93 @@
+from Xdmf import *
+
+import timeit
+import time
+import os
+
+h5file = os.getcwd() + "/timestamptest.h5"
+xmffile = os.getcwd() + "/timestamptest.xmf"
+
+if __name__ == "__main__":
+
+	#for later use in determining actual time
+	#    print timeit.Timer(timedWrite.write).timeit(1)
+
+        exampleHeavyWriter = XdmfHDF5Writer.New(h5file)
+
+        #possible options
+        exampleHeavyWriter.setReleaseData(True)
+
+        exampleWriter = XdmfWriter.New(xmffile, exampleHeavyWriter)
+        exampleWriter.setLightDataLimit(10)
+
+
+	primaryDomain = XdmfDomain.New()
+
+	numNodes = 30000
+	numAttrib = 10
+	gridsPerTimestamp = 10
+	numTimestamps = 100
+
+	#for 100 time steps
+	#each time step is a grid collection
+	#base structue is a spacial grid collection full of temporal grid collections
+
+	primaryCollection = XdmfGridCollection.New()
+
+	primaryDomain.insert(primaryCollection)
+
+	startclock = time.clock()
+
+	for i in range(numTimestamps):
+		timestampGrid = XdmfGridCollection.New()
+		timestampTime = XdmfTime.New(i)
+		timestampGrid.setTime(timestampTime)
+		#each time stamp has 10 grids
+		for j in range(gridsPerTimestamp):
+			sectionGrid = XdmfUnstructuredGrid.New()
+			sectionTime = XdmfTime.New(i)
+			sectionGrid.setTime(sectionTime)
+			#each grid has one topo, one geo, and 10 attrib
+			sectionGeometry = XdmfGeometry.New()
+			sectionGeometry.setType(XdmfGeometryType.XYZ())
+			sectionTopology = XdmfTopology.New()
+			sectionTopology.setType(XdmfTopologyType.Triangle())
+			#Fill each with 30,000 values
+			#for k in range(numNodes):
+			#	sectionGeometry.pushBackAsFloat32(k)
+			#	sectionTopology.pushBackAsFloat32(k)
+			sectionGeometry.resizeAsFloat32(30000)
+			sectionTopology.resizeAsFloat32(30000)
+			sectionGrid.setGeometry(sectionGeometry)
+			sectionGrid.setTopology(sectionTopology)
+			for k in range(numAttrib):
+				sectionAttribute = XdmfAttribute.New()
+				#for l in range(numNodes):
+				#	sectionAttribute.pushBackAsFloat32(l)
+				sectionAttribute.resizeAsFloat32(30000)
+				sectionGrid.insert(sectionAttribute)
+			timestampGrid.insert(sectionGrid)
+			#exampleHeavyWriter.openFile()
+			#sectionGrid.accept(exampleHeavyWriter)
+			#exampleHeavyWriter.closeFile()
+		primaryCollection.insert(timestampGrid)
+		writeclock = time.clock()
+		exampleHeavyWriter.openFile()
+		#primaryDomain.accept(exampleHeavyWriter)
+		if i % 10 == 9:
+			primaryDomain.accept(exampleWriter)
+		else:
+			timestampGrid.accept(exampleHeavyWriter)
+		exampleHeavyWriter.closeFile()
+		print "iteration " + str(i) + " Time = " + str(time.clock() - writeclock)
+
+
+	exampleHeavyWriter.openFile()
+	primaryDomain.accept(exampleWriter)
+
+	exampleHeavyWriter.closeFile()
+
+	print (time.clock() - startclock)
+
+	os.remove(xmffile)
+	os.remove(h5file)
diff --git a/tests/Python/XdmfExampleWrite.py b/tests/Python/XdmfExampleWrite.py
new file mode 100644
index 0000000..74341e8
--- /dev/null
+++ b/tests/Python/XdmfExampleWrite.py
@@ -0,0 +1,106 @@
+from Xdmf import *
+
+if __name__ == "__main__":
+	primaryDomain = XdmfDomain.New()
+
+	gridHolder = XdmfGridCollection.New()
+	gridHolder.setType(XdmfGridCollectionType.Spatial())
+	holderInfo = XdmfInformation.New("Grid Collection 1", "This is the main grid collection")
+	gridHolder.insert(holderInfo)
+
+
+	ungrid = XdmfUnstructuredGrid.New()
+	ungrid.setName("Unstructured Grid Example")
+	untime = XdmfTime.New(5.0)
+	untimeinfo = XdmfInformation.New("Time", "This is the time for the Unstructured Grid")
+	untime.insert(untimeinfo)
+	ungrid.setTime(untime)
+	unglobalID = XdmfAttribute.New()
+	unglobalID.setType(XdmfAttributeType.GlobalId())
+	unglobalID.setCenter(XdmfAttributeCenter.Node())
+	unglobalID.setName("Global Node Equivalencies")
+	task1globalnodes = [1, 4, 5, 7, 3, 6]
+	unglobalID.insertAsInt32(0, task1globalnodes)
+	unglobalIDinfo = XdmfInformation.New("Global Nodes", "This is the global nodes that accociate with the local nodes")
+	ungrid.insert(unglobalID)
+	unset = XdmfSet.New()
+	unsetinfo = XdmfInformation.New("Data Set", "This is a set of arbitrary data")
+	unset.insert(unsetinfo)
+	unset.setName("Unstructured Grid's Set")
+	unset.setType(XdmfSetType.Node())
+	unsetattribute = XdmfAttribute.New()
+	unsetattribute.setType(XdmfAttributeType.Scalar())
+	unsetattribute.setCenter(XdmfAttributeCenter.Node())
+	unsetattribute.setName("The Set's attribute")
+	unsetattribdata = [1.9, 2.8, 3.7, 4.6, 5.5, 6.4, 7.3, 8.2, 9.1]
+	unsetattribute.insertAsFloat64(0, unsetattribdata)
+	unset.insert(unsetattribute)
+	unsetdata = [5.1, 4.2, 3.3, 2.4, 1.5]
+	unset.insertAsFloat64(0, unsetdata)
+	ungrid.insert(unset)
+	ungeometry = XdmfGeometry.New()
+	ungeometry.setType(XdmfGeometryType.XYZ())
+	ungeometry.setName("Unstructured Geometry")
+	ungeopoints = [0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1, 1.1, 1.1,
+		1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1, 0.1, -1.1, 3.1,
+		0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1, -1.1, 3.1, 2.1, -2.1]
+	ungeometry.insertAsFloat64(0, ungeopoints)
+	ungeometryinfo = XdmfInformation.New("Geometry", "This is the geometry associated with the unstructured grid")
+	ungeometry.insert(ungeometryinfo)
+	ungrid.setGeometry(ungeometry)
+	untopology = XdmfTopology.New()
+	untopology.setType(XdmfTopologyType.Hexahedron())
+	untopology.setName("Unstructured Topology")
+	untopovalues = [0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10]
+	untopology.insertAsInt32(0, untopovalues)
+	untopologyinfo = XdmfInformation.New("Topology", "This is the topology associated with the unstructured grid")
+	ungrid.setTopology(untopology)
+
+
+	curvdimensions = XdmfArray.New()
+	curvdimensions.pushBackAsInt32(12)
+	curvdimensions.pushBackAsInt32(12)
+	curvdimensions.pushBackAsInt32(12)
+	curvgrid = XdmfCurvilinearGrid.New(curvdimensions)
+	curvtime = XdmfTime.New(5.0)
+	curvgrid.setTime(curvtime)
+	curvglobalID = XdmfAttribute.New()
+	curvglobalID.setType(XdmfAttributeType.GlobalId())
+	curvglobalID.setCenter(XdmfAttributeCenter.Node())
+	curvglobalID.setName("Global Node Equivalencies")
+	task2globalnodes = [7, 3, 8, 2, 5, 1]
+	curvglobalID.insertAsInt32(0, task1globalnodes)
+	curvgrid.insert(curvglobalID)
+	curvgeometry = XdmfGeometry.New()
+	curvgeometry.setType(XdmfGeometryType.XYZ())
+	curvgeometry.setName("Curvilinear Geometry")
+	curvgeopoints = [1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1, 2.1,
+		2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1, 4.1,
+		1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1]
+	curvgeometry.insertAsFloat64(0, curvgeopoints)
+	curvgrid.setGeometry(curvgeometry)
+
+
+	rectXcoordinates = [1.1, 1.1, 2.1, 2.1, 1.1, 2.1, 4.1, 1.1, 3.1, 1.1, 2.1, 2.1]
+	rectYcoordinates = [2.1, 2.1, 2.1, 4.1, 3.1, 3.1, 1.1, 1.1, 0.1, 2.1, 1.1, 0.1]
+	rectZcoordinates = [4.1, 1.1, -1.1, 1.1, 2.1, 0.1, 1.1, 2.1, -0.1, 4.1, 3.1, -1.1]
+	rectXarray = XdmfArray.New()
+	rectXarray.insertAsFloat64(0, rectXcoordinates)
+	rectYarray = XdmfArray.New()
+	rectYarray.insertAsFloat64(0, rectYcoordinates)
+	rectZarray = XdmfArray.New()
+	rectZarray.insertAsFloat64(0, rectZcoordinates)
+	coordinatecontainer = ArrayVector()
+	coordinatecontainer.push_back(rectXarray)
+	coordinatecontainer.push_back(rectYarray)
+	coordinatecontainer.push_back(rectZarray)
+	rectgrid = XdmfRectilinearGrid.New(coordinatecontainer)
+	rectglobalID = XdmfAttribute.New()
+	rectglobalID.setType(XdmfAttributeType.GlobalId())
+	rectglobalID.setCenter(XdmfAttributeCenter.Node())
+	rectglobalID.setName("Global Node Equivalencies")
+	task3globalnodes = [2, 7, 9, 0, 8, 6]
+	rectglobalID.insertAsInt32(0, task3globalnodes)
+	recttime = XdmfTime.New(5.0)
+	rectgrid.setTime(recttime)
+	rectgrid.insert(rectglobalID)
diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt
new file mode 100644
index 0000000..98fea26
--- /dev/null
+++ b/utils/CMakeLists.txt
@@ -0,0 +1,178 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+
+option(XDMF_BUILD_EXODUS_IO OFF)
+option(XDMF_BUILD_PARTITIONER OFF)
+option(XDMF_BUILD_FORTRAN OFF)
+option(XDMF_BUILD_DSM OFF)
+
+
+set(XdmfUtilsSources
+  XdmfDiff
+  XdmfGeometryConverter
+  XdmfTopologyConverter
+  XdmfUtils)
+set(XdmfUtilsLinkLibraries Xdmf)
+
+if(XDMF_BUILD_FORTRAN)
+  set(XdmfUtilsSources ${XdmfUtilsSources} XdmfFortran)
+  enable_language (Fortran)
+  if (XDMF_BUILD_DSM)
+    # gcc doesn't automatically link to the fortran mpi libraries
+    STRING(REGEX MATCH "gfortran" IS_GFORTRAN "${CMAKE_Fortran_COMPILER}")
+    if (NOT "${IS_GFORTRAN}" STREQUAL "")
+      EXECUTE_PROCESS(
+        COMMAND ${MPIEXEC} --version
+        OUTPUT_VARIABLE MPI_TYPE_OUTPUT
+        ERROR_VARIABLE MPI_TYPE_ERROR
+      )
+      if (NOT "${MPI_TYPE_ERROR}" STREQUAL "")
+        STRING(REGEX MATCH "Open" IS_OPENMPI "${MPI_TYPE_ERROR}")
+      elseif (NOT "${MPI_TYPE_OUTPUT}" STREQUAL "")
+        STRING(REGEX MATCH "Open" IS_OPENMPI "${MPI_TYPE_OUTPUT}")
+      endif ()
+      IF (NOT "${IS_OPENMPI}" STREQUAL "")
+        if (NOT "${MPI_TYPE_ERROR}" STREQUAL "")
+          STRING(REGEX MATCH "[0-9]+[.][0-9]+[.][0-9]+" MPI_VERSION "${MPI_TYPE_ERROR}")
+        elseif (NOT "${MPI_TYPE_OUTPUT}" STREQUAL "")
+          STRING(REGEX MATCH "[0-9]+[.][0-9]+[.][0-9]+" MPI_VERSION "${MPI_TYPE_OUTPUT}")
+        endif ()
+        if (NOT "${MPI_VERSION}" STREQUAL "")
+          STRING(REGEX MATCH "^[0-9]+" MPI_VERSION_MAJOR "${MPI_VERSION}")
+          STRING(REGEX MATCH "[0-9]+[.][0-9]+$" MPI_VERSION_CUT "${MPI_VERSION}")
+          STRING(REGEX MATCH "^[0-9]+" MPI_VERSION_MINOR "${MPI_VERSION_CUT}")
+          if (("${MPI_VERSION_MAJOR}" EQUAL 1) OR ("${MPI_VERSION_MAJOR}" LESS 1))
+            if ("${MPI_VERSION_MAJOR}" EQUAL 1)
+              if ("${MPI_VERSION_MINOR}" LESS 8)
+                # Minor version is less than 1.8
+                set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -lmpi_f90")
+              else ("${MPI_VERSION_MINOR}" LESS 8)
+                # Version is 1.8.0 or greater
+                set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -lmpi_mpifh")
+              endif ("${MPI_VERSION_MINOR}" LESS 8)
+            else ("${MPI_VERSION_MAJOR}" EQUAL 1)
+              # Major version is less than 1
+              set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -lmpi_f90")
+            endif ("${MPI_VERSION_MAJOR}" EQUAL 1)
+          else (("${MPI_VERSION_MAJOR}" EQUAL 1) OR ("${MPI_VERSION_MAJOR}" LESS 1))
+            # Major version is greater than 1
+            set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -lmpi_mpifh")
+          endif (("${MPI_VERSION_MAJOR}" EQUAL 1) OR ("${MPI_VERSION_MAJOR}" LESS 1))
+        endif (NOT "${MPI_VERSION}" STREQUAL "")
+      ENDIF (NOT "${IS_OPENMPI}" STREQUAL "")
+    endif (NOT "${IS_GFORTRAN}" STREQUAL "")
+  endif (XDMF_BUILD_DSM)
+endif(XDMF_BUILD_FORTRAN)
+
+if (XDMF_BUILD_DSM)
+  add_definitions(-DXDMF_BUILD_DSM)
+endif (XDMF_BUILD_DSM)
+
+if(XDMF_BUILD_EXODUS_IO)
+  set(XDMF_SWIG_FLAGS ${XDMF_SWIG_FLAGS} -DXDMF_BUILD_EXODUS_IO)
+  find_package(Exodus REQUIRED)
+  if(EXODUS_FOUND)
+    include_directories(${EXODUS_INCLUDE_DIR} ${NetCDF_INCLUDE_DIR})
+  endif(EXODUS_FOUND)
+  set(XdmfUtilsSources ${XdmfUtilsSources} XdmfExodusReader XdmfExodusWriter)
+  set(XdmfUtilsExecutables ${XdmfUtilsExecutables} XdmfExodusConverter)
+  set(XdmfUtilsLinkLibraries
+    ${XdmfUtilsLinkLibraries}
+    ${EXODUS_LIBRARIES}
+    ${NetCDF_LIBRARIES})
+endif(XDMF_BUILD_EXODUS_IO)
+
+if(XDMF_BUILD_PARTITIONER)
+  set(XDMF_SWIG_FLAGS ${XDMF_SWIG_FLAGS} -DXDMF_BUILD_PARTITIONER)
+  find_package(Metis REQUIRED)
+  if(METIS_FOUND)
+    include_directories(${METIS_INCLUDE_DIR})
+  endif(METIS_FOUND)
+  set(XdmfUtilsExecutables ${XdmfUtilsExecutables} XdmfPartitioner)
+  set(XdmfUtilsSources ${XdmfUtilsSources} XdmfPartitioner)
+  set(XdmfUtilsLinkLibraries ${XdmfUtilsLinkLibraries} ${METIS_LIBRARIES})
+endif(XDMF_BUILD_PARTITIONER)
+
+add_library(XdmfUtilsObjects OBJECT ${XdmfUtilsSources})
+add_library(XdmfUtils $<TARGET_OBJECTS:XdmfUtilsObjects>)
+if (BUILD_SHARED_LIBS)
+  add_library(XdmfUtils_Static STATIC $<TARGET_OBJECTS:XdmfUtilsObjects>)
+  if (UNIX)
+    set_target_properties(XdmfUtils_Static PROPERTIES
+      OUTPUT_NAME "XdmfUtils")
+  endif (UNIX)
+endif (BUILD_SHARED_LIBS)
+target_link_libraries(XdmfUtils ${XdmfUtilsLinkLibraries})
+if (BUILD_SHARED_LIBS)
+  target_link_libraries(XdmfUtils_Static ${XdmfUtilsLinkLibraries})
+endif (BUILD_SHARED_LIBS)
+
+if(WIN32)
+  set_target_properties(${executable} PROPERTIES
+      DEFINE_SYMBOL XdmfUtils_EXPORTS
+	  PREFIX ../
+	  IMPORT_PREFIX ../
+	  RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+	  LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+	  ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+endif(WIN32)
+
+foreach(executable ${XdmfUtilsExecutables})
+  add_executable(${executable} ${executable})
+  set_target_properties(${executable} PROPERTIES COMPILE_FLAGS -DBUILD_EXE)
+  target_link_libraries(${executable} XdmfUtils)
+
+  if(WIN32)
+	  set_target_properties(${executable} PROPERTIES
+	      DEFINE_SYMBOL XdmfUtils_EXPORTS)
+      if(NOT MSVC10)
+    	  set_target_properties(${executable} PROPERTIES
+	    	  PREFIX ../
+		      IMPORT_PREFIX ../
+		      RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+		      LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}
+		      ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
+      endif(NOT MSVC10)
+  endif(WIN32)
+
+endforeach(executable ${XdmfUtilsExecutables})
+
+if(XDMF_BUILD_TESTING)
+  add_subdirectory(tests)
+endif(XDMF_BUILD_TESTING)
+
+if(XDMF_WRAP_JAVA)
+  XDMF_SWIG_JAVA(XdmfUtils Compiled_Xdmf_Jar)
+endif(XDMF_WRAP_JAVA)
+
+
+if(XDMF_WRAP_PYTHON)
+  if (NOT BUILD_SHARED_LIBS)
+    message(FATAL_ERROR "Python Wrappers do not function"
+                        " properly without shared libraries")
+  endif (NOT BUILD_SHARED_LIBS)
+  XDMF_SWIG_PYTHON(XdmfUtils Xdmf)
+endif(XDMF_WRAP_PYTHON)
+
+foreach(source ${XdmfUtilsSources})
+  set(XdmfUtilsHeaders ${XdmfUtilsHeaders} ${source}.hpp)
+endforeach(source ${XdmfUtilsSources})
+
+if(XDMF_BUILD_FORTRAN)
+  set(XdmfUtilsHeaders ${XdmfUtilsHeaders} Xdmf.f)
+endif(XDMF_BUILD_FORTRAN)
+
+install(FILES ${XdmfUtilsHeaders} DESTINATION include)
+install(TARGETS XdmfUtils 
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib)
+if (BUILD_SHARED_LIBS)
+install(TARGETS XdmfUtils_Static
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib)
+endif (BUILD_SHARED_LIBS)
+install(TARGETS ${XdmfUtilsExecutables} 
+    RUNTIME DESTINATION bin
+    LIBRARY DESTINATION lib
+    ARCHIVE DESTINATION lib)
diff --git a/utils/Xdmf.f b/utils/Xdmf.f
new file mode 100644
index 0000000..508a762
--- /dev/null
+++ b/utils/Xdmf.f
@@ -0,0 +1,203 @@
+! Function Return Types
+        integer xdmfaddattribute
+        integer xdmfaddinformation
+        integer xdmfsetgeometry
+        integer xdmfsettopology
+        integer xdmfsetdimensions
+        integer xdmfsetorigin
+        integer xdmfsetbrick
+        integer xdmfstoremap
+        integer xdmfaddcoordinate
+        integer xdmfaddset
+        integer xdmfgetmaxopenedfiles
+        integer xdmfaddfunctionasattribute
+        integer xdmfsetfunctionasgeometry
+        integer xdmfsetfunctionastopology
+        integer xdmfaddfunctionascoordinate
+        integer xdmfaddfunctionasset
+        integer xdmfaddsubsetasattribute
+        integer xdmfsetsubsetasgeometry
+        integer xdmfsetsubsetastopology
+        integer xdmfaddsubsetascoordinate
+        integer xdmfaddsubsetasset
+
+! Array Type
+        integer XDMF_ARRAY_TYPE_INT8
+        integer XDMF_ARRAY_TYPE_INT16
+        integer XDMF_ARRAY_TYPE_INT32
+        integer XDMF_ARRAY_TYPE_INT64
+        integer XDMF_ARRAY_TYPE_UINT8
+        integer XDMF_ARRAY_TYPE_UINT16
+        integer XDMF_ARRAY_TYPE_UINT32
+        integer XDMF_ARRAY_TYPE_FLOAT32
+        integer XDMF_ARRAY_TYPE_FLOAT64
+
+! Attribute Center
+        integer XDMF_ATTRIBUTE_CENTER_GRID
+        integer XDMF_ATTRIBUTE_CENTER_CELL
+        integer XDMF_ATTRIBUTE_CENTER_FACE
+        integer XDMF_ATTRIBUTE_CENTER_EDGE
+        integer XDMF_ATTRIBUTE_CENTER_NODE
+
+! Attribute Type
+        integer XDMF_ATTRIBUTE_TYPE_SCALAR
+        integer XDMF_ATTRIBUTE_TYPE_VECTOR
+        integer XDMF_ATTRIBUTE_TYPE_TENSOR
+        integer XDMF_ATTRIBUTE_TYPE_MATRIX
+        integer XDMF_ATTRIBUTE_TYPE_TENSOR6
+        integer XDMF_ATTRIBUTE_TYPE_GLOBALID
+        integer XDMF_ATTRIBUTE_TYPE_NOTYPE
+
+! Geometry Type
+        integer XDMF_GEOMETRY_TYPE_XYZ
+        integer XDMF_GEOMETRY_TYPE_XY
+        integer XDMF_GEOMETRY_TYPE_POLAR
+        integer XDMF_GEOMETRY_TYPE_SPHERICAL
+
+! Grid Collection Type
+        integer XDMF_GRID_COLLECTION_TYPE_SPATIAL
+        integer XDMF_GRID_COLLECTION_TYPE_TEMPORAL
+
+! Topology Type
+        integer XDMF_TOPOLOGY_TYPE_POLYVERTEX
+        integer XDMF_TOPOLOGY_TYPE_POLYLINE
+        integer XDMF_TOPOLOGY_TYPE_POLYGON
+        integer XDMF_TOPOLOGY_TYPE_POLYHEDRON
+        integer XDMF_TOPOLOGY_TYPE_TRIANGLE
+        integer XDMF_TOPOLOGY_TYPE_QUADRILATERAL
+        integer XDMF_TOPOLOGY_TYPE_TETRAHEDRON
+        integer XDMF_TOPOLOGY_TYPE_PYRAMID
+        integer XDMF_TOPOLOGY_TYPE_WEDGE
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON
+        integer XDMF_TOPOLOGY_TYPE_EDGE_3
+        integer XDMF_TOPOLOGY_TYPE_TRIANGLE_6
+        integer XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8
+        integer XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9
+        integer XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10
+        integer XDMF_TOPOLOGY_TYPE_PYRAMID_13
+        integer XDMF_TOPOLOGY_TYPE_WEDGE_15
+        integer XDMF_TOPOLOGY_TYPE_WEDGE_18
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000
+        integer XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331
+        integer XDMF_TOPOLOGY_TYPE_MIXED
+
+! Set Type
+        integer XDMF_SET_TYPE_NODE
+        integer XDMF_SET_TYPE_CELL
+        integer XDMF_SET_TYPE_FACE
+        integer XDMF_SET_TYPE_EDGE
+
+! Grid Type
+        integer XDMF_GRID_TYPE_CURVILINEAR
+        integer XDMF_GRID_TYPE_RECTILINEAR
+        integer XDMF_GRID_TYPE_REGULAR
+        integer XDMF_GRID_TYPE_UNSTRUCTURED
+
+! Binary Endian
+        integer XDMF_BINARY_ENDIAN_NATIVE
+        integer XDMF_BINARY_ENDIAN_LITTLE
+        integer XDMF_BINARY_ENDIAN_BIG
+
+!------------------------------------------------------
+
+        parameter (XDMF_ARRAY_TYPE_INT8    = 0)
+        parameter (XDMF_ARRAY_TYPE_INT16   = 1)
+        parameter (XDMF_ARRAY_TYPE_INT32   = 2)
+        parameter (XDMF_ARRAY_TYPE_INT64   = 3)
+        parameter (XDMF_ARRAY_TYPE_UINT8   = 4)
+        parameter (XDMF_ARRAY_TYPE_UINT16  = 5)
+        parameter (XDMF_ARRAY_TYPE_UINT32  = 6)
+        parameter (XDMF_ARRAY_TYPE_FLOAT32 = 7)
+        parameter (XDMF_ARRAY_TYPE_FLOAT64 = 8)
+
+        parameter (XDMF_ATTRIBUTE_CENTER_GRID = 100)
+        parameter (XDMF_ATTRIBUTE_CENTER_CELL = 101)
+        parameter (XDMF_ATTRIBUTE_CENTER_FACE = 102)
+        parameter (XDMF_ATTRIBUTE_CENTER_EDGE = 103)
+        parameter (XDMF_ATTRIBUTE_CENTER_NODE = 104)
+
+        parameter (XDMF_ATTRIBUTE_TYPE_SCALAR   = 200)
+        parameter (XDMF_ATTRIBUTE_TYPE_VECTOR   = 201)
+        parameter (XDMF_ATTRIBUTE_TYPE_TENSOR   = 202)
+        parameter (XDMF_ATTRIBUTE_TYPE_MATRIX   = 203)
+        parameter (XDMF_ATTRIBUTE_TYPE_TENSOR6  = 204)
+        parameter (XDMF_ATTRIBUTE_TYPE_GLOBALID = 205)
+        parameter (XDMF_ATTRIBUTE_TYPE_NOTYPE   = 206)
+
+        parameter (XDMF_GEOMETRY_TYPE_XYZ       = 301)
+        parameter (XDMF_GEOMETRY_TYPE_XY        = 302)
+        parameter (XDMF_GEOMETRY_TYPE_POLAR     = 303)
+        parameter (XDMF_GEOMETRY_TYPE_SPHERICAL = 304)
+
+        parameter (XDMF_GRID_COLLECTION_TYPE_SPATIAL  = 400)
+        parameter (XDMF_GRID_COLLECTION_TYPE_TEMPORAL = 401)
+
+        parameter (XDMF_TOPOLOGY_TYPE_POLYVERTEX               = 500)
+        parameter (XDMF_TOPOLOGY_TYPE_POLYLINE                 = 501)
+        parameter (XDMF_TOPOLOGY_TYPE_POLYGON                  = 502)
+        parameter (XDMF_TOPOLOGY_TYPE_POLYHEDRON               = 503)
+        parameter (XDMF_TOPOLOGY_TYPE_TRIANGLE                 = 504)
+        parameter (XDMF_TOPOLOGY_TYPE_QUADRILATERAL            = 505)
+        parameter (XDMF_TOPOLOGY_TYPE_TETRAHEDRON              = 506)
+        parameter (XDMF_TOPOLOGY_TYPE_PYRAMID                  = 507)
+        parameter (XDMF_TOPOLOGY_TYPE_WEDGE                    = 508)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON               = 509)
+        parameter (XDMF_TOPOLOGY_TYPE_EDGE_3                   = 510)
+        parameter (XDMF_TOPOLOGY_TYPE_TRIANGLE_6               = 511)
+        parameter (XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8          = 512)
+        parameter (XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9          = 513)
+        parameter (XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10           = 514)
+        parameter (XDMF_TOPOLOGY_TYPE_PYRAMID_13               = 515)
+        parameter (XDMF_TOPOLOGY_TYPE_WEDGE_15                 = 516)
+        parameter (XDMF_TOPOLOGY_TYPE_WEDGE_18                 = 517)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20            = 518)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24            = 519)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27            = 520)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64            = 521)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125           = 522)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216           = 523)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343           = 524)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512           = 525)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729           = 526)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000          = 527)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331          = 528)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64   = 529)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125  = 530)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216  = 531)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343  = 532)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512  = 533)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729  = 534)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000 = 535)
+        parameter (XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331 = 536)
+        parameter (XDMF_TOPOLOGY_TYPE_MIXED                    = 537)
+
+        parameter (XDMF_SET_TYPE_NODE = 601)
+        parameter (XDMF_SET_TYPE_CELL = 602)
+        parameter (XDMF_SET_TYPE_FACE = 603)
+        parameter (XDMF_SET_TYPE_EDGE = 604)
+
+        parameter (XDMF_GRID_TYPE_CURVILINEAR   = 701)
+        parameter (XDMF_GRID_TYPE_RECTILINEAR   = 702)
+        parameter (XDMF_GRID_TYPE_REGULAR       = 703)
+        parameter (XDMF_GRID_TYPE_UNSTRUCTURED  = 704)
+
+        parameter (XDMF_BINARY_ENDIAN_NATIVE = 801)
+        parameter (XDMF_BINARY_ENDIAN_LITTLE = 802)
+        parameter (XDMF_BINARY_ENDIAN_BIG    = 803)
diff --git a/utils/XdmfDiff.cpp b/utils/XdmfDiff.cpp
new file mode 100644
index 0000000..ff61fb7
--- /dev/null
+++ b/utils/XdmfDiff.cpp
@@ -0,0 +1,333 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDiff.cpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cmath>
+#include <iomanip>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfDiff.hpp"
+#include "XdmfError.hpp"
+#include "XdmfVisitor.hpp"
+
+//
+// local methods
+//
+namespace {
+
+  /**
+   * @brief Internal class that traverses all items in xdmf hierarchy and
+   * adds them to mItems.
+   */
+  class XdmfDiffVisitor : public XdmfVisitor {
+
+  public:
+
+    static shared_ptr<XdmfDiffVisitor>
+    New()
+    {
+      shared_ptr<XdmfDiffVisitor> p(new XdmfDiffVisitor());
+      return p;
+    };
+
+    ~XdmfDiffVisitor()
+    {
+    };
+
+    void
+    visit(XdmfItem & item,
+          const shared_ptr<XdmfBaseVisitor> visitor)
+    {
+      mItems.push_back(&item);
+      item.traverse(visitor);
+    }
+
+    std::vector<XdmfItem *> mItems;
+
+  protected:
+
+    XdmfDiffVisitor()
+    {
+    }
+
+  };
+
+  template <typename T>
+  void 
+  diffArrays(XdmfArray * array1,
+             XdmfArray * array2,
+             const double absoluteTolerance,
+             bool & returnValue) {
+    bool releaseArray1 = false;
+    if(!array1->isInitialized()) {
+      array1->read();
+      releaseArray1 = true;
+    }
+    bool releaseArray2 = false;
+    if(!array2->isInitialized()) {
+      array2->read();
+      releaseArray2 = true;
+    }
+
+    const unsigned int size = array1->getSize();
+    for(unsigned int i=0; i<size; ++i) {
+      const T array1Value = array1->getValue<T>(i);
+      const T array2Value = array2->getValue<T>(i);
+      const T difference =
+        static_cast<T>(array1Value > array2Value ?
+                         array1Value-array2Value : array2Value-array1Value);
+
+      if(difference > absoluteTolerance) {
+        std::cout << "At Index " << i << " | Expected: "
+                  << array1Value << " | Got: " << array2Value << std::endl;
+        returnValue = false;
+      }
+    }
+
+    if(releaseArray1) {
+      array1->release();
+    }
+    if(releaseArray2) {
+      array2->release();
+    }
+  }
+
+}
+
+shared_ptr<XdmfDiff>
+XdmfDiff::New()
+{
+  shared_ptr<XdmfDiff> p(new XdmfDiff());
+  return p;
+}
+
+XdmfDiff::XdmfDiff() :
+  mAbsoluteTolerance(0.0)
+{
+}
+
+XdmfDiff::XdmfDiff(const XdmfDiff &diffRef) :
+  mAbsoluteTolerance(diffRef.mAbsoluteTolerance)
+{
+}
+
+XdmfDiff::~XdmfDiff()
+{
+}
+
+bool
+XdmfDiff::compare(const shared_ptr<XdmfItem> item1,
+                  const shared_ptr<XdmfItem> item2) const
+{
+
+  bool returnValue = true;
+
+  shared_ptr<XdmfDiffVisitor> diffVisitor1 = XdmfDiffVisitor::New();
+  shared_ptr<XdmfDiffVisitor> diffVisitor2 = XdmfDiffVisitor::New();
+
+  item1->accept(diffVisitor1);
+  item2->accept(diffVisitor2);
+
+  assert(diffVisitor1->mItems.size() == diffVisitor2->mItems.size());
+
+  for(std::vector<XdmfItem *>::size_type i=0;
+      i<diffVisitor1->mItems.size();
+      ++i) {
+
+    XdmfItem * item1 = diffVisitor1->mItems[i];
+    XdmfItem * item2 = diffVisitor2->mItems[i];
+
+    // compare item tags
+    const std::string itemTag1 = item1->getItemTag();
+    const std::string itemTag2 = item2->getItemTag();
+
+    if(itemTag1.compare(itemTag2) != 0) {
+      std::cout << "Error: Expected " << itemTag1 << " and got " << itemTag2
+                << ". The files are not structured the same" << std::endl;
+      return false;
+    }
+
+    // compare item properties
+    const std::map<std::string, std::string> itemProperties1 =
+      item1->getItemProperties();
+    const std::map<std::string, std::string> itemProperties2 =
+      item2->getItemProperties();
+
+    assert(itemProperties1.size() == itemProperties2.size());
+
+    for(std::map<std::string, std::string>::const_iterator iter1 =
+          itemProperties1.begin();
+        iter1 != itemProperties1.end();
+        ++iter1) {
+      const std::string & key = iter1->first;
+      const std::map<std::string, std::string>::const_iterator iter2 =
+        itemProperties2.find(key);
+      if(iter2 == itemProperties2.end()) {
+        std::cout << "Error: Expected " << key << " and did not find corresponding key "
+                  << "files are not structured the same" << std::endl;
+        assert(false);
+      }
+      const std::string & value1 = iter1->second;
+      const std::string & value2 = iter2->second;
+      if(value1.compare(value2) != 0) {
+        std::cout << "Error: For: " << itemTag1 << " | Key: " << key
+                  << "Expected: " << value1 << " | Got: " << value2
+                  << std::endl;
+        returnValue = false;
+      }
+    }
+
+    // compare array values
+    XdmfArray * array1 = dynamic_cast<XdmfArray *>(item1);
+
+    if(array1) {
+      XdmfArray * array2 = dynamic_cast<XdmfArray *>(item2);
+      if(array1->getSize() != array2->getSize()) {
+        std::cout << "Error: For: " << itemTag1
+                  << " Different number of values stored. Expected: "
+                  << array1->getSize() << " | Got: " << array2->getSize()
+                  << std::endl;
+        returnValue = false;
+      }
+      const shared_ptr<const XdmfArrayType> arrayType =
+        array1->getArrayType();
+      if(arrayType != array2->getArrayType()) {
+        std::cout << "Error: For: " << itemTag1
+                  << " Different type of values stored. Expected: "
+                  << arrayType->getName() << " | Got: "
+                  << array2->getArrayType()->getName() << std::endl;
+        returnValue = false;
+      }
+      if(arrayType == XdmfArrayType::Int8()) {
+        diffArrays<char>(array1, 
+                         array2, 
+                         mAbsoluteTolerance, 
+                         returnValue);
+      }
+      else if(arrayType == XdmfArrayType::Int16()) {
+        diffArrays<short>(array1, 
+                          array2, 
+                          mAbsoluteTolerance,
+                          returnValue);
+      }
+      else if(arrayType == XdmfArrayType::Int32()) {
+        diffArrays<int>(array1, 
+                        array2, 
+                        mAbsoluteTolerance,
+                        returnValue);
+      }
+      else if(arrayType == XdmfArrayType::Int64()) {
+        diffArrays<long>(array1, 
+                         array2, 
+                         mAbsoluteTolerance, 
+                         returnValue);
+      }
+      else if(arrayType == XdmfArrayType::UInt8()) {
+        diffArrays<unsigned char>(array1, 
+                                  array2, 
+                                  mAbsoluteTolerance,
+                                  returnValue);
+      }
+      else if(arrayType == XdmfArrayType::UInt16()) {
+        diffArrays<unsigned short>(array1, 
+                                   array2, 
+                                   mAbsoluteTolerance,
+                                   returnValue);
+      }
+      else if(arrayType == XdmfArrayType::UInt32()) {
+        diffArrays<unsigned int>(array1, 
+                                 array2, 
+                                 mAbsoluteTolerance,
+                                 returnValue);
+      }
+      else if(arrayType == XdmfArrayType::Float32()) {
+        diffArrays<float>(array1, 
+                          array2, 
+                          mAbsoluteTolerance,
+                          returnValue);
+      }
+      else if(arrayType == XdmfArrayType::Float64()) {
+        std::cout << std::setprecision(15);
+        diffArrays<double>(array1, 
+                           array2, 
+                           mAbsoluteTolerance,
+                           returnValue);
+      }
+      else {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Array Types match, but type is not supported.");
+      }
+    }
+  }
+  return returnValue;
+}
+
+double
+XdmfDiff::getAbsoluteTolerance() const
+{
+  return mAbsoluteTolerance;
+}
+
+void
+XdmfDiff::setAbsoluteTolerance(const double absoluteTolerance)
+{
+  mAbsoluteTolerance = absoluteTolerance;
+}
+
+// C Wrappers
+
+XDMFDIFF *
+XdmfDiffNew()
+{
+  shared_ptr<XdmfDiff> generatedDiff = XdmfDiff::New();
+  return (XDMFDIFF *)((void *)(new XdmfDiff(*generatedDiff.get())));
+}
+
+int
+XdmfDiffCompare(XDMFDIFF * diff, XDMFITEM * item1, XDMFITEM * item2)
+{
+  shared_ptr<XdmfItem> tempItem1 = shared_ptr<XdmfItem>((XdmfItem *)item1, XdmfNullDeleter());
+  shared_ptr<XdmfItem> tempItem2 = shared_ptr<XdmfItem>((XdmfItem *)item2, XdmfNullDeleter());
+  return ((XdmfDiff *)diff)->compare(tempItem1, tempItem2);
+}
+
+double
+XdmfDiffGetAbsoluteTolerance(XDMFDIFF * diff)
+{
+  return ((XdmfDiff *)diff)->getAbsoluteTolerance();
+}
+
+void
+XdmfDiffSetAbsoluteTolerance(XDMFDIFF * diff, double tolerance)
+{
+  ((XdmfDiff *)diff)->setAbsoluteTolerance(tolerance);
+}
+
+void
+XdmfDiffFree(XDMFDIFF * diff)
+{
+  if (diff != NULL) {
+    delete ((XdmfDiff *)diff);
+    diff = NULL;
+  }
+}
diff --git a/utils/XdmfDiff.hpp b/utils/XdmfDiff.hpp
new file mode 100644
index 0000000..cf8922a
--- /dev/null
+++ b/utils/XdmfDiff.hpp
@@ -0,0 +1,127 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfDiff.hpp                                                        */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFDIFF_HPP_
+#define XDMFDIFF_HPP_
+
+// C Compatible Includes
+#include "XdmfUtils.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfItem;
+
+// Includes
+#include <string>
+#include "XdmfUtils.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Compare differences between data stored in two Xdmf
+ * structures.
+ */
+class XDMFUTILS_EXPORT XdmfDiff {
+
+public:
+
+  /**
+   * Create a new XdmfDiff.
+   *
+   * @return constructed XdmfDiff.
+   */
+  static shared_ptr<XdmfDiff> New();
+
+  virtual ~XdmfDiff();
+
+  /**
+   * Compare the contents of two Xdmf structures.
+   *
+   * @param item1 an Xdmf structure to compare.
+   * @param item2 an Xdmf structure to compare.
+   *
+   * @return true if the Xdmf structures are equivalent.
+   */
+  bool
+  compare(const shared_ptr<XdmfItem> item1,
+          const shared_ptr<XdmfItem> item2) const;
+
+  /**
+   * Get the absolute tolerance used for comparing values between Xdmf
+   * structures.
+   *
+   * @return double the absolute tolerance.
+   */
+  double
+  getAbsoluteTolerance() const;
+
+  /**
+   * Set the absolute tolerance for comparing values between Xdmf
+   * structures.
+   *
+   * @param absoluteTolerance the absolute tolerance to set.
+   */
+  void
+  setAbsoluteTolerance(const double absoluteTolerance);
+
+  XdmfDiff(const XdmfDiff &);
+
+protected:
+
+  XdmfDiff();
+
+private:
+
+  void operator=(const XdmfDiff &);  // Not implemented.
+
+  double mAbsoluteTolerance;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFDIFF; // Simply as a typedef to ensure correct typing
+typedef struct XDMFDIFF XDMFDIFF;
+
+XDMFUTILS_EXPORT XDMFDIFF * XdmfDiffNew();
+
+XDMFUTILS_EXPORT int XdmfDiffCompare(XDMFDIFF * diff, XDMFITEM * item1, XDMFITEM * item2);
+
+XDMFUTILS_EXPORT double XdmfDiffGetAbsoluteTolerance(XDMFDIFF * diff);
+
+XDMFUTILS_EXPORT void XdmfDiffSetAbsoluteTolerance(XDMFDIFF * diff, double tolerance);
+
+XDMFUTILS_EXPORT void XdmfDiffFree(XDMFDIFF * diff);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFDIFF_HPP_ */
+
diff --git a/utils/XdmfExodusConverter.cpp b/utils/XdmfExodusConverter.cpp
new file mode 100644
index 0000000..70855e7
--- /dev/null
+++ b/utils/XdmfExodusConverter.cpp
@@ -0,0 +1,181 @@
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+#include <exodusII.h>
+#include "XdmfDomain.hpp"
+#include "XdmfError.hpp"
+#include "XdmfExodusReader.hpp"
+#include "XdmfExodusWriter.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfWriter.hpp"
+
+namespace {
+
+  //
+  // print usage
+  //
+  inline void
+  printUsage(const char * programName)
+  {
+
+    std::cerr << "usage: " << programName << " "
+              << "<input file> [output file]"
+              << std::endl;
+
+    //
+    //
+    //
+    return;
+
+  }
+
+  //
+  // process command line
+  //
+  void
+  processCommandLine(std::string                  & inputFileName,
+                     std::string                  & outputFileName,
+                     int                            ac,
+                     char                         * av[])
+  {
+
+    int c;
+    bool errorFlag = false;
+
+    while( (c=getopt(ac, av, "")) != -1 )
+      switch(c){
+      case '?':
+        errorFlag = true;
+        break;
+      }
+    
+    if (optind >= ac)
+      errorFlag = true;
+    else {
+      inputFileName = av[optind];
+      ++optind;
+    }
+
+    if (optind < ac) {
+      outputFileName = av[optind];
+      ++optind;
+    }
+
+    //
+    // check errorFlag
+    //
+    if (errorFlag == true) {
+      printUsage(av[0]);
+      std::exit(EXIT_FAILURE);
+    }
+
+  }
+
+}
+
+/**
+ * XdmfExodusConverter is a command line utility for converting
+ * between Xdmf and Exodus files. If given an Xdmf file, the tool
+ * converts the file to Exodus and if given a path to an Exodus file,
+ * the tool converts the file to Xdmf.
+ *
+ * Usage:
+ *     XdmfExodusConverter <path-of-file-to-convert> 
+ *                         (Optional: <path-to-output-file>)
+ *
+ */
+int main(int argc, char* argv[])
+{
+
+  std::string inputFileName = "";
+  std::string outputFileName = "";
+
+  processCommandLine(inputFileName,
+                     outputFileName,
+                     argc,
+                     argv);
+
+  FILE * refFile = fopen(inputFileName.c_str(), "r");
+  if (refFile) {
+    // Success
+    fclose(refFile);
+  }
+  else {
+    std::cout << "Cannot open file: " << argv[1] << std::endl;
+    return 1;
+  }
+
+  std::string meshName;
+  if(outputFileName.compare("") == 0) {
+    meshName = inputFileName;
+  }
+  else {
+    meshName = outputFileName;
+  }
+
+  if(meshName.find_last_of("/\\") != std::string::npos) {
+    meshName = meshName.substr(meshName.find_last_of("/\\") + 1,
+                               meshName.length());
+  }
+
+  if (meshName.rfind(".") != std::string::npos) {
+    meshName = meshName.substr(0, meshName.rfind("."));
+  }
+
+  int CPU_word_size = sizeof(double);
+  int IO_word_size = 0; // Get from file
+  float version;
+  const int exodusHandle = 
+    ex_open(argv[1], EX_READ, &CPU_word_size, &IO_word_size, &version);
+  if(exodusHandle < 0) {
+    // Xdmf to Exodus
+    shared_ptr<XdmfReader> reader = XdmfReader::New();
+    shared_ptr<XdmfDomain> domain = 
+      shared_dynamic_cast<XdmfDomain>(reader->read(inputFileName));
+    std::stringstream exodusFileName;
+    exodusFileName << meshName << ".exo";
+    shared_ptr<XdmfExodusWriter> writer = XdmfExodusWriter::New();
+    if(domain->getNumberUnstructuredGrids() == 1) {
+      const shared_ptr<XdmfUnstructuredGrid> grid = 
+        domain->getUnstructuredGrid(0);
+      writer->write(exodusFileName.str(),
+                    grid);
+      std::cout << "Wrote: " << exodusFileName.str() << std::endl;
+    }
+    else if(domain->getNumberGridCollections() == 1) {
+      const shared_ptr<XdmfGridCollection> grid = 
+        domain->getGridCollection(0);
+      writer->write(exodusFileName.str(),
+                    grid);
+      std::cout << "Wrote: " << exodusFileName.str() << std::endl;
+    }
+    else {
+      XdmfError::message(XdmfError::FATAL,
+                         "Cannot find grid in Xdmf file to convert to "
+                         "exodus.");
+    }
+  }
+  else {
+    // Exodus to Xdmf
+    std::stringstream heavyFileName;
+    heavyFileName << meshName << ".h5";
+    shared_ptr<XdmfHDF5Writer> heavyDataWriter =
+      XdmfHDF5Writer::New(heavyFileName.str());
+    heavyDataWriter->setReleaseData(true);
+    shared_ptr<XdmfExodusReader> exodusReader = XdmfExodusReader::New();
+    shared_ptr<XdmfUnstructuredGrid> readGrid = 
+      exodusReader->read(inputFileName,
+                         heavyDataWriter);
+    shared_ptr<XdmfDomain> newDomain = XdmfDomain::New();
+    newDomain->insert(readGrid);
+    std::stringstream xmlFileName;
+    xmlFileName << meshName << ".xmf";
+    shared_ptr<XdmfWriter> writer = XdmfWriter::New(xmlFileName.str(),
+                                                    heavyDataWriter);
+    newDomain->accept(writer);
+    std::cout << "Wrote: " << xmlFileName.str() << std::endl;
+  }
+
+}
diff --git a/utils/XdmfExodusReader.cpp b/utils/XdmfExodusReader.cpp
new file mode 100644
index 0000000..1546547
--- /dev/null
+++ b/utils/XdmfExodusReader.cpp
@@ -0,0 +1,698 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfExodusReader.cpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <exodusII.h>
+#include <cstring>
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfExodusReader.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfError.hpp"
+
+//
+// local methods
+//
+namespace {
+
+  /**
+   * Convert exodus topology type to xdmf topology type.
+   *
+   * @param exodusTopologyType a string containing the name of the exodus
+   * topology type.
+   * @param pointsPerCell the number of points per cell for the exodus
+   * topology type.
+   *
+   * @return the equivalent XdmfTopologyType. If no equivalent is found,
+   * XdmfTopologyType::NoTopologyType() is returned.
+   */
+  shared_ptr<const XdmfTopologyType>
+  exodusToXdmfTopologyType(std::string exodusTopologyType,
+                           const int pointsPerCell)
+  {
+    // Convert exodusTopologyType to uppercase
+    std::transform(exodusTopologyType.begin(),
+                   exodusTopologyType.end(),
+                   exodusTopologyType.begin(),
+                   toupper);
+
+    // First check for quadratic elements then look for linear elements
+    if (exodusTopologyType.substr(0,3).compare("TRI") == 0 &&
+        pointsPerCell == 6) {
+      return XdmfTopologyType::Triangle_6();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("SHE") == 0 &&
+             pointsPerCell == 8) {
+      return XdmfTopologyType::Quadrilateral_8();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("SHE") == 0 &&
+             pointsPerCell == 9) {
+      return XdmfTopologyType::Quadrilateral_9();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("TET") == 0 &&
+             pointsPerCell == 10) {
+      return XdmfTopologyType::Tetrahedron_10();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("TET") == 0 &&
+             pointsPerCell == 11) {
+      // VTK_QUADRATIC_TETRA with 11 points
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("WED") == 0 &&
+             pointsPerCell == 15) {
+      return XdmfTopologyType::Wedge_15();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("WED") == 0 &&
+             pointsPerCell == 18) {
+      return XdmfTopologyType::Wedge_18();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("HEX") == 0 &&
+             pointsPerCell == 20) {
+      return XdmfTopologyType::Hexahedron_20();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("HEX") == 0 &&
+             pointsPerCell == 21) {
+      // VTK_QUADRATIC_HEXAHEDRON with 21 points
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("HEX") == 0 &&
+             pointsPerCell == 27) {
+      return XdmfTopologyType::Hexahedron_27();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("QUA") == 0 &&
+             pointsPerCell == 8) {
+      return XdmfTopologyType::Quadrilateral_8();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("QUA") == 0 &&
+             pointsPerCell == 9) {
+      return XdmfTopologyType::Quadrilateral_9();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("TRU") == 0 &&
+             pointsPerCell == 3) {
+      return XdmfTopologyType::Edge_3();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("BEA") == 0 &&
+             pointsPerCell == 3) {
+      return XdmfTopologyType::Edge_3();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("BAR") == 0 &&
+             pointsPerCell == 3) {
+      return XdmfTopologyType::Edge_3();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("EDG") == 0 &&
+             pointsPerCell == 3) {
+      return XdmfTopologyType::Edge_3();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("CIR") == 0) {
+      // VTK_VERTEX;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("SPH") == 0) {
+      // VTK_VERTEX;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("BAR") == 0) {
+      // VTK_LINE;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("TRU") == 0) {
+      // VTK_LINE;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("BEA") == 0) {
+      // VTK_LINE;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("EDG") == 0) {
+      // VTK_LINE;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("TRI") == 0) {
+      return XdmfTopologyType::Triangle();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("QUA") == 0) {
+      return XdmfTopologyType::Quadrilateral();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("TET") == 0) {
+      return XdmfTopologyType::Tetrahedron();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("PYR") == 0) {
+      return XdmfTopologyType::Pyramid();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("WED") == 0) {
+      return XdmfTopologyType::Wedge();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("HEX") == 0) {
+      return XdmfTopologyType::Hexahedron();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("SHE") == 0 &&
+             pointsPerCell == 3) {
+      return XdmfTopologyType::Triangle();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("SHE") == 0 &&
+             pointsPerCell == 4) {
+      return XdmfTopologyType::Quadrilateral();
+    }
+    else if (exodusTopologyType.substr(0,8).compare("STRAIGHT") == 0 &&
+             pointsPerCell == 2) {
+      // VTK_LINE;
+      // Currently unsupported in Xdmf
+      return XdmfTopologyType::NoTopologyType();
+    }
+    else if (exodusTopologyType.substr(0,3).compare("SUP") == 0) {
+      return XdmfTopologyType::Polyvertex();
+    }
+    return XdmfTopologyType::NoTopologyType();
+  }
+}
+
+shared_ptr<XdmfExodusReader>
+XdmfExodusReader::New()
+{
+  shared_ptr<XdmfExodusReader> p(new XdmfExodusReader());
+  return p;
+}
+
+XdmfExodusReader::XdmfExodusReader()
+{
+}
+
+XdmfExodusReader::~XdmfExodusReader()
+{
+}
+
+shared_ptr<XdmfUnstructuredGrid>
+XdmfExodusReader::read(const std::string & fileName,
+                       const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) const
+{
+  if(heavyDataWriter) {
+    heavyDataWriter->openFile();
+  }
+
+  shared_ptr<XdmfUnstructuredGrid> toReturn = XdmfUnstructuredGrid::New();
+
+  // Read Exodus II file to XdmfGridUnstructured via Exodus II API
+  float version;
+  int CPU_word_size = sizeof(double);
+  int IO_word_size = 0; // Get from file
+  int exodusHandle = ex_open(fileName.c_str(),
+                             EX_READ,
+                             &CPU_word_size,
+                             &IO_word_size,
+                             &version);
+
+  if(exodusHandle < 0) {
+    // Invalid fileName
+    XdmfError::message(XdmfError::FATAL, "Invalid fileName: " + fileName + 
+                       " in XdmfExodusReader::read");
+  }
+
+  char * title = new char[MAX_LINE_LENGTH+1];
+  int num_dim, num_nodes, num_elem, num_elem_blk, num_node_sets, num_side_sets;
+  ex_get_init (exodusHandle,
+               title,
+               &num_dim,
+               &num_nodes,
+               &num_elem,
+               &num_elem_blk,
+               &num_node_sets,
+               &num_side_sets);
+  toReturn->setName(title);
+  delete [] title;
+
+  /*
+    cout << "Title: " << title <<
+    "\nNum Dim: " << num_dim <<
+    "\nNum Nodes: " << num_nodes <<
+    "\nNum Elem: " << num_elem <<
+    "\nNum Elem Blk: " << num_elem_blk <<
+    "\nNum Node Sets: " << num_node_sets <<
+    "\nNum Side Sets: " << num_side_sets << endl;
+  */
+
+  // Read geometry values
+  double * x = new double[num_nodes];
+  double * y = new double[num_nodes];
+  double * z = new double[num_nodes];
+
+  ex_get_coord(exodusHandle, x, y, z);
+
+  // In the future we may want to do XDMF_GEOMETRY_X_Y_Z?
+  if(num_dim == 3) {
+    toReturn->getGeometry()->setType(XdmfGeometryType::XYZ());
+  }
+  else if(num_dim == 2) {
+    toReturn->getGeometry()->setType(XdmfGeometryType::XY());
+  }
+  else {
+    // Xdmf does not support geometries with less than 2 dimensions
+    std::ostringstream oss;
+    oss << "Xdmf does not support geometries with less than 2 dimensions -- num_dim: " << num_dim << "-- in XdmfExodusReader::read";
+    XdmfError::message(XdmfError::FATAL, oss.str());
+  }
+
+  toReturn->getGeometry()->initialize(XdmfArrayType::Float64());
+  toReturn->getGeometry()->reserve(num_nodes * num_dim);
+  for(int i=0; i<num_nodes; ++i) {
+    toReturn->getGeometry()->pushBack(x[i]);
+    toReturn->getGeometry()->pushBack(y[i]);
+    if(num_dim == 3) {
+      toReturn->getGeometry()->pushBack(z[i]);
+    }
+  }
+  delete [] x;
+  delete [] y;
+  delete [] z;
+
+  if(heavyDataWriter) {
+    toReturn->getGeometry()->accept(heavyDataWriter);
+    toReturn->getGeometry()->release();
+  }
+
+  int * blockIds = new int[num_elem_blk];
+  ex_get_elem_blk_ids(exodusHandle, blockIds);
+
+  int * numElemsInBlock = new int[num_elem_blk];
+  int * numNodesPerElemInBlock = new int[num_elem_blk];
+  int * numElemAttrInBlock = new int[num_elem_blk];
+  std::vector<shared_ptr<const XdmfTopologyType> > topologyTypes;
+  topologyTypes.reserve(num_elem_blk);
+  int totalNumElem = 0;
+  int totalConns = 0;
+  for(int i=0; i<num_elem_blk; ++i) {
+    char * elem_type = new char[MAX_STR_LENGTH+1];
+    int num_nodes_per_elem, num_elem_this_blk, num_attr;
+    ex_get_elem_block(exodusHandle,
+                      blockIds[i],
+                      elem_type,
+                      &num_elem_this_blk,
+                      &num_nodes_per_elem,
+                      &num_attr);
+
+    /*
+      cout << "Block Id: " << blockIds[j] <<
+      "\nElem Type: " << elem_type <<
+      "\nNum Elem in Blk: " << num_elem_this_blk <<
+      "\nNum Nodes per Elem: " << num_nodes_per_elem <<
+      "\nNum Attr: " << num_attr << endl;
+    */
+
+    numElemsInBlock[i] = num_elem_this_blk;
+    numNodesPerElemInBlock[i] = num_nodes_per_elem;
+    numElemAttrInBlock[i] = num_attr;
+    const shared_ptr<const XdmfTopologyType> topologyType =
+      exodusToXdmfTopologyType(elem_type, num_nodes_per_elem);
+    topologyTypes.push_back(topologyType);
+    totalNumElem += num_elem_this_blk;
+    totalConns += num_elem_this_blk * num_nodes_per_elem;
+    delete [] elem_type;
+  }
+
+  if(topologyTypes.size() > 0) {
+    toReturn->getTopology()->setType(topologyTypes[0]);
+    if(topologyTypes.size() > 1) {
+      for(std::vector<shared_ptr<const XdmfTopologyType> >::const_iterator
+            iter = topologyTypes.begin() + 1;
+          iter != topologyTypes.end();
+          ++iter) {
+        // Cannot be mixed topology!
+        if(toReturn->getTopology()->getType() != *iter) {
+          XdmfError::message(XdmfError::FATAL, 
+                             "Requested mix of topology types -- "+ 
+                             toReturn->getTopology()->getType()->getName() +
+                             " and " + (*iter)->getName() + 
+                             " in XdmfExodusReader::read");
+        }
+      }
+    }
+  }
+
+  topologyTypes.clear();
+
+  toReturn->getTopology()->initialize(XdmfArrayType::Int32(), totalConns);
+  int * connectivityPointer =
+    (int *)toReturn->getTopology()->getValuesInternal();
+  // Read connectivity from element blocks
+  int elemIndex = 0;
+  for(int i=0; i<num_elem_blk; ++i) {
+    ex_get_elem_conn(exodusHandle,
+                     blockIds[i],
+                     connectivityPointer + elemIndex);
+    elemIndex += numElemsInBlock[i] * numNodesPerElemInBlock[i];
+  }
+
+  // This is taken from VTK's vtkExodusIIReader and adapted to fit Xdmf
+  // element types, which have the same ordering as VTK.
+  if(toReturn->getTopology()->getType() == XdmfTopologyType::Hexahedron_20() ||
+     toReturn->getTopology()->getType() == XdmfTopologyType::Hexahedron_27()) {
+    int * ptr = connectivityPointer;
+    int itmp[4];
+
+    // Exodus Node ordering does not match Xdmf, we must convert.
+    for(int i=0; i<totalNumElem; ++i) {
+      ptr += 12;
+
+      for(unsigned int j=0; j<4; ++j, ++ptr) {
+        itmp[j] = *ptr;
+        *ptr = ptr[4];
+      }
+
+      for(unsigned int j=0; j<4; ++j, ++ptr) {
+        *ptr = itmp[j];
+      }
+
+      if(toReturn->getTopology()->getType() == XdmfTopologyType::Hexahedron_27()) {
+        for(unsigned int j=0; j<4; ++j, ++ptr) {
+          itmp[j] = *ptr;
+          *ptr = ptr[3];
+        }
+        *(ptr++) = itmp[1];
+        *(ptr++) = itmp[2];
+        *(ptr++) = itmp[0];
+      }
+    }
+  }
+  else if(toReturn->getTopology()->getType() == XdmfTopologyType::Wedge_15() ||
+          toReturn->getTopology()->getType() == XdmfTopologyType::Wedge_18()) {
+    int * ptr = connectivityPointer;
+    int itmp[3];
+
+    // Exodus Node ordering does not match Xdmf, we must convert.
+    for (int i=0; i<totalNumElem; i++) {
+      ptr += 9;
+
+      for(unsigned int j=0; j<3; ++j, ++ptr) {
+        itmp[j] = *ptr;
+        *ptr = ptr[3];
+      }
+
+      for(unsigned int j=0; j<3; ++j, ++ptr) {
+        *ptr = itmp[j];
+      }
+
+      if(toReturn->getTopology()->getType() == XdmfTopologyType::Wedge_18()) {
+        itmp[0] = *(ptr);
+        itmp[1] = *(ptr+1);
+        itmp[2] = *(ptr+2);
+        *(ptr++) = itmp[1];
+        *(ptr++) = itmp[2];
+        *(ptr++) = itmp[0];
+      }
+    }
+  }
+
+  // Subtract all node ids by 1 since exodus indices start at 1
+  for(int i=0; i<totalConns; ++i) {
+    connectivityPointer[i]--;
+  }
+
+  if(heavyDataWriter) {
+    toReturn->getTopology()->accept(heavyDataWriter);
+    toReturn->getTopology()->release();
+  }
+
+  shared_ptr<XdmfAttribute> globalIds = XdmfAttribute::New();
+  globalIds->setName("GlobalNodeId");
+  globalIds->setCenter(XdmfAttributeCenter::Node());
+  globalIds->setType(XdmfAttributeType::GlobalId());
+  globalIds->initialize(XdmfArrayType::Int32(), num_nodes);
+  int * globalIdsPointer = (int*)globalIds->getValuesInternal();
+
+  ex_get_node_num_map(exodusHandle, globalIdsPointer);
+
+  // Subtract all node ids by 1 since exodus indices start at 1
+  for(int i=0; i<num_nodes; ++i) {
+    globalIdsPointer[i]--;
+  }
+
+  toReturn->insert(globalIds);
+
+  if(heavyDataWriter) {
+    globalIds->accept(heavyDataWriter);
+    globalIds->release();
+  }
+
+  // Read node sets
+  int * nodeSetIds = new int[num_node_sets];
+  ex_get_node_set_ids(exodusHandle, nodeSetIds);
+
+  char * node_set_names[num_node_sets];
+  for (int i=0; i<num_node_sets; ++i) {
+    node_set_names[i] = new char[MAX_STR_LENGTH+1];
+  }
+  ex_get_names(exodusHandle, EX_NODE_SET, node_set_names);
+
+  for (int i=0; i<num_node_sets; ++i) {
+    int num_nodes_in_set, num_df_in_set;
+    ex_get_node_set_param(exodusHandle,
+                          nodeSetIds[i],
+                          &num_nodes_in_set,
+                          &num_df_in_set);
+
+    /*
+      cout << "Node Set Id: " << nodeSetIds[j] <<
+      "\nNode Set Name: " << node_set_names[j] <<
+      "\nNum Nodes in Set: "<< num_nodes_in_set <<
+      "\nNum Distrub Factors: " << num_df_in_set << endl;
+    */
+
+    if (num_nodes_in_set > 0) {
+      shared_ptr<XdmfSet> set = XdmfSet::New();
+      set->setName(node_set_names[i]);
+      set->setType(XdmfSetType::Node());
+      set->initialize(XdmfArrayType::Int32(), num_nodes_in_set);
+      int * setPointer = (int*)set->getValuesInternal();
+      ex_get_node_set(exodusHandle, nodeSetIds[i], setPointer);
+
+      // Subtract all node ids by 1 since exodus indices start at 1
+      for(int j=0; j<num_nodes_in_set; ++j) {
+        setPointer[j]--;
+      }
+
+      toReturn->insert(set);
+
+      if(heavyDataWriter) {
+        set->accept(heavyDataWriter);
+        set->release();
+      }
+    }
+    delete [] node_set_names[i];
+  }
+  delete [] nodeSetIds;
+
+  // Read result variables (attributes)
+  int num_global_vars, num_nodal_vars, num_elem_vars;
+  ex_get_var_param(exodusHandle, "g", &num_global_vars);
+  ex_get_var_param(exodusHandle, "n", &num_nodal_vars);
+  ex_get_var_param(exodusHandle, "e", &num_elem_vars);
+
+  /*
+    cout << "Num Global Vars: " << num_global_vars <<
+    "\nNum Nodal Vars: " << num_nodal_vars <<
+    "\nNum Elem Vars: " << num_elem_vars << endl;
+  */
+
+  char * global_var_names[num_global_vars];
+  char * nodal_var_names[num_nodal_vars];
+  char * elem_var_names[num_elem_vars];
+  for (int j=0; j<num_global_vars; j++) {
+    global_var_names[j] = new char[MAX_STR_LENGTH+1];
+  }
+  for (int j=0; j<num_nodal_vars; j++) {
+    nodal_var_names[j] = new char[MAX_STR_LENGTH+1];
+  }
+  for (int j=0; j<num_elem_vars; j++) {
+    elem_var_names[j] = new char[MAX_STR_LENGTH+1];
+  }
+  ex_get_var_names(exodusHandle, "g", num_global_vars, global_var_names);
+  ex_get_var_names(exodusHandle, "n", num_nodal_vars, nodal_var_names);
+  ex_get_var_names(exodusHandle, "e", num_elem_vars, elem_var_names);
+
+  /*
+    cout << "Global Vars Names: " << endl;
+    for (int j=0; j<num_global_vars; j++)
+    {
+    cout << global_var_names[j] << endl;
+    }
+    cout << "Nodal Vars Names: " << endl;
+    for (int j=0; j<num_nodal_vars; j++)
+    {
+    cout << nodal_var_names[j] << endl;
+    }
+    cout << "Elem Vars Names: " << endl;
+    for (int j=0; j<num_elem_vars; j++)
+    {
+    cout << elem_var_names[j] << endl;
+    }
+  */
+
+  // Get variable data
+  // TODO: do this for all timesteps?
+
+  // Global variable data
+  double * global_var_vals = new double[num_global_vars];
+  ex_get_glob_vars(exodusHandle, 1, num_global_vars, global_var_vals);
+  for (int i=0; i<num_global_vars; ++i) {
+    // Write global attribute to xdmf
+    shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+    attribute->setName(global_var_names[i]);
+    attribute->setCenter(XdmfAttributeCenter::Grid());
+    attribute->setType(XdmfAttributeType::Scalar());
+    attribute->initialize(XdmfArrayType::Float64());
+    attribute->pushBack(global_var_vals[i]);
+    toReturn->insert(attribute);
+    if(heavyDataWriter) {
+      attribute->accept(heavyDataWriter);
+      attribute->release();
+    }
+    delete [] global_var_names[i];
+  }
+  delete [] global_var_vals;
+
+  // Nodal variable data
+  for (int i=0; i<num_nodal_vars; ++i) {
+    // The strcmp with "GlobalNodeId" is meant to prevent errors from occuring
+    // when a nodal variable is named GlobalNodeId. A GlobalNodeId attribute
+    // was added before when adding the nodal map which means that this
+    // attribute should be ignored... This will probably only occur when doing
+    // repeated conversions --- i.e. Xdmf to Exodus to Xdmf to Exodus...
+    if (strcmp(nodal_var_names[i], "GlobalNodeId") != 0) {
+      shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+      attribute->setName(nodal_var_names[i]);
+      attribute->setCenter(XdmfAttributeCenter::Node());
+      attribute->setType(XdmfAttributeType::Scalar());
+      attribute->initialize(XdmfArrayType::Float64(), num_nodes);
+      ex_get_nodal_var(exodusHandle,
+                       1,
+                       i+1,
+                       num_nodes,
+                       (double*)attribute->getValuesInternal());
+      toReturn->insert(attribute);
+      if(heavyDataWriter) {
+        attribute->accept(heavyDataWriter);
+        attribute->release();
+      }
+      delete [] nodal_var_names[i];
+    }
+  }
+
+  // Element variable data
+  for (int i=0; i<num_elem_vars; ++i) {
+    shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+    attribute->setName(elem_var_names[i]);
+    attribute->setCenter(XdmfAttributeCenter::Cell());
+    attribute->setType(XdmfAttributeType::Scalar());
+    attribute->initialize(XdmfArrayType::Float64(), totalNumElem);
+    elemIndex = 0;
+    for (int j=0; j<num_elem_blk; ++j) {
+      ex_get_elem_var(exodusHandle,
+                      1,
+                      i+1,
+                      blockIds[j],
+                      numElemsInBlock[j],
+                      (double*)attribute->getValuesInternal() + elemIndex);
+      elemIndex += numElemsInBlock[j];
+    }
+    toReturn->insert(attribute);
+    if(heavyDataWriter) {
+      attribute->accept(heavyDataWriter);
+      attribute->release();
+    }
+    delete [] elem_var_names[i];
+  }
+
+  ex_close(exodusHandle);
+
+  // add block information as sets
+  unsigned int elementId = 0;
+  for(int i=0; i<num_elem_blk; ++i) {
+    const int numberElementsInBlock = numElemsInBlock[i];
+    shared_ptr<XdmfSet> set = XdmfSet::New();
+    std::stringstream setName;
+    setName << "Block " << i;
+    set->setName(setName.str());
+    set->setType(XdmfSetType::Cell());
+    set->initialize(XdmfArrayType::Int32(), numberElementsInBlock);
+    for(int j=0; j<numberElementsInBlock; ++j) {
+      set->insert(j, elementId++);
+    }
+    toReturn->insert(set);
+    if(heavyDataWriter) {
+      set->accept(heavyDataWriter);
+      set->release();
+    }
+  }
+
+  delete [] blockIds;
+  delete [] numElemsInBlock;
+  delete [] numNodesPerElemInBlock;
+  delete [] numElemAttrInBlock;
+  
+
+  if(heavyDataWriter) {
+    heavyDataWriter->closeFile();
+  }
+
+  return toReturn;
+}
+
+// C Wrappers
+
+XDMFEXODUSREADER *
+XdmfExodusReaderNew()
+{
+  shared_ptr<XdmfExodusReader> generatedReader = XdmfExodusReader::New();
+  return (XDMFEXODUSREADER *)((void *)(new XdmfExodusReader(*generatedReader.get())));
+}
+
+XDMFUNSTRUCTUREDGRID *
+XdmfExodusReaderRead(XDMFEXODUSREADER * reader, char * fileName, XDMFHEAVYDATAWRITER * heavyDataWriter)
+{
+  shared_ptr<XdmfHeavyDataWriter> tempWriter = shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *)heavyDataWriter, XdmfNullDeleter());
+  return (XDMFUNSTRUCTUREDGRID)((void *)(new XdmfUnstructuredGrid(*((((XdmfExodusReader *)reader)->read(fileName, tempWriter)).get()))));
+}
+
+void
+XdmfExodusReaderFree(XDMFEXODUSREADER * reader)
+{
+  if (reader != NULL) {
+    delete ((XdmfExodusReader *)reader);
+    reader = NULL;
+  }
+}
diff --git a/utils/XdmfExodusReader.hpp b/utils/XdmfExodusReader.hpp
new file mode 100644
index 0000000..dbeeb36
--- /dev/null
+++ b/utils/XdmfExodusReader.hpp
@@ -0,0 +1,102 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfExodusReader.hpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFEXODUSREADER_HPP_
+#define XDMFEXODUSREADER_HPP_
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfHeavyDataWriter;
+class XdmfUnstructuredGrid;
+
+// Includes
+#include <string>
+#include "XdmfUtils.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Reads an ExodusII file from disk into an Xdmf structure in
+ * memory.
+ */
+class XDMFUTILS_EXPORT XdmfExodusReader {
+
+public:
+
+  /**
+   * Create a new XdmfExodusReader.
+   *
+   * @return constructed XdmfExodusReader.
+   */
+  static shared_ptr<XdmfExodusReader> New();
+
+  virtual ~XdmfExodusReader();
+
+  /**
+   * Read the contents of an ExodusII file from disk into an Xdmf
+   * structure in memory.
+   *
+   * @param fileName containing the path of the exodus file to read.
+   * @param heavyDataWriter an XdmfHeavyDataWriter to write the mesh to. If no
+   * heavyDataWriter is specified, all mesh data will remain in memory.
+   *
+   * @return an unstructured grid containing the mesh stored in the ExodusII
+   * file.
+   */
+  shared_ptr<XdmfUnstructuredGrid>
+  read(const std::string & fileName,
+       const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter = shared_ptr<XdmfHeavyDataWriter>()) const;
+
+protected:
+
+  XdmfExodusReader();
+
+private:
+
+  XdmfExodusReader(const XdmfExodusReader &);  // Not implemented.
+  void operator=(const XdmfExodusReader &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFEXODUSREADER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFEXODUSREADER XDMFEXODUSREADER;
+
+XDMFUTILS_EXPORT XDMFEXODUSREADER * XdmfExodusReaderNew();
+
+XDMFUTILS_EXPORT XDMFUNSTRUCTUREDGRID * XdmfExodusReaderRead(XDMFEXODUSREADER * reader, char * fileName, XDMFHEAVYDATAWRITER * heavyDataWriter);
+
+XDMFUTILS_EXPORT void XdmfExodusReaderFree(XDMFEXODUSREADER * reader);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFEXODUSREADER_HPP_ */
diff --git a/utils/XdmfExodusWriter.cpp b/utils/XdmfExodusWriter.cpp
new file mode 100644
index 0000000..dae9769
--- /dev/null
+++ b/utils/XdmfExodusWriter.cpp
@@ -0,0 +1,964 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfExodusWriter.cpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cstring>
+#include <exodusII.h>
+#include <set>
+#include <sstream>
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfExodusWriter.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfPartitioner.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfError.hpp"
+
+#include <iostream>
+
+//
+// local methods
+//
+namespace {
+
+  /**
+   * Constructs attribute names for ExodusII files since exodus cannot
+   * store vectors. Also handles the exodus MAX_STR_LENGTH limitation.
+   *
+   * @param attributeName the attribute name in Xdmf.
+   * @param names a vector of names to add the constructed attribute names to.
+   * @param numComponents the number of components in the attribute
+   * (e.g. for an xyz vector this is 3)
+   */
+  void
+  constructAttributeNames(std::string attributeName,
+                          std::vector<std::string> & names,
+                          const int numComponents)
+  {
+    if(numComponents == 1) {
+      if(attributeName.length() > MAX_STR_LENGTH) {
+        attributeName = attributeName.substr(0, MAX_STR_LENGTH);
+      }
+      names.push_back(attributeName);
+    }
+    else if(numComponents > 1) {
+      int numComponentDigits = int(numComponents / 10);
+      if(attributeName.length() + numComponentDigits > MAX_STR_LENGTH) {
+        attributeName =
+          attributeName.substr(0,
+                               MAX_STR_LENGTH - numComponentDigits);
+      }
+      for(int i=0; i<numComponents; ++i) {
+        std::stringstream toAdd;
+        toAdd << attributeName << "-" << i+1;
+        names.push_back(toAdd.str());
+      }
+    }
+  }
+
+  /**
+   * Converts xdmf topology types to equivalent exodus topology types.
+   *
+   * @param topologyType an xdmf topology type to convert to the equivalent
+   * exodus topology type.
+   *
+   * @return string containing the name of the equivalent exodus topology type.
+   */
+  std::string
+  xdmfToExodusTopologyType(shared_ptr<const XdmfTopologyType> topologyType)
+  {
+    if(topologyType == XdmfTopologyType::Polyvertex()) {
+      return "SUP";
+    }
+    else if(topologyType == XdmfTopologyType::Triangle() ||
+            topologyType == XdmfTopologyType::Triangle_6()) {
+      return "TRIANGLE";
+    }
+    else if(topologyType == XdmfTopologyType::Quadrilateral() ||
+            topologyType == XdmfTopologyType::Quadrilateral_8() ||
+            topologyType == XdmfTopologyType::Quadrilateral_9()) {
+      return "QUAD";
+    }
+    else if(topologyType == XdmfTopologyType::Tetrahedron() ||
+            topologyType == XdmfTopologyType::Tetrahedron_10()) {
+      return "TETRA";
+    }
+    else if(topologyType == XdmfTopologyType::Pyramid() ||
+            topologyType == XdmfTopologyType::Pyramid_13()) {
+      return "PYRAMID";
+    }
+    else if(topologyType == XdmfTopologyType::Wedge() ||
+            topologyType == XdmfTopologyType::Wedge_15() ||
+            topologyType == XdmfTopologyType::Wedge_18()) {
+      return "WEDGE";
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron() ||
+            topologyType == XdmfTopologyType::Hexahedron_20() ||
+            topologyType == XdmfTopologyType::Hexahedron_24() ||
+            topologyType == XdmfTopologyType::Hexahedron_27()) {
+      return "HEX";
+    }
+    else if(topologyType == XdmfTopologyType::Edge_3()) {
+      return "EDGE";
+    }
+    XdmfError::message(XdmfError::FATAL, 
+                       "Topology type not supported by ExodusII");
+    return "";
+  }
+
+  /**
+   * Pull general information from grid in order to initialize exodus
+   * file.
+   */
+  void
+  getGridInformation(const shared_ptr<XdmfUnstructuredGrid> grid,
+                     int & num_dim,
+                     int & num_nodes,
+                     int & num_elem,
+                     int & num_elem_blk,
+                     std::vector<int> & elem_blk_ids,
+                     std::vector<char *> & elem_type,
+                     std::vector<int> & num_elem_this_blk,
+                     std::vector<int> & num_nodes_per_elem,
+                     std::vector<int> & num_attr,
+                     int & num_node_sets,
+                     std::vector<shared_ptr<XdmfSet> > & blocks)
+  {
+
+    // get topology
+    const shared_ptr<XdmfTopology> topology = grid->getTopology();
+    const shared_ptr<const XdmfTopologyType> topologyType = 
+      topology->getType();
+    const int numberElements = topology->getNumberElements();
+    const int nodesPerElement = topologyType->getNodesPerElement();
+
+    // get geometry
+    const shared_ptr<XdmfGeometry> geometry = grid->getGeometry();
+    const shared_ptr<const XdmfGeometryType> geometryType = 
+      geometry->getType();
+    const int numberNodes = geometry->getNumberPoints();
+
+    num_dim = geometryType->getDimensions();
+    num_nodes = numberNodes;
+    num_elem = numberElements;
+
+    std::cout << num_dim << std::endl;
+
+    // get exodus topology type
+    const std::string exodusTopologyType = 
+      xdmfToExodusTopologyType(topologyType);
+     
+    // search for blocks in file
+    int elementBlockId = 10;
+    for(unsigned int i=0; i<grid->getNumberSets(); ++i) {
+      shared_ptr<XdmfSet> set = grid->getSet(i);
+      if(set->getType() == XdmfSetType::Cell()) {
+        if(set->getName().find("Block") == 0) {
+          ++num_elem_blk;
+          blocks.push_back(set);
+          elem_blk_ids.push_back(elementBlockId++);
+          char * cellTypeCStr = new char[exodusTopologyType.size() + 1];
+          strcpy(cellTypeCStr, exodusTopologyType.c_str());
+          elem_type.push_back(cellTypeCStr);   
+          num_elem_this_blk.push_back(set->getSize());
+          num_nodes_per_elem.push_back(nodesPerElement);
+          num_attr.push_back(0);
+        }
+      }
+      else if(set->getType() == XdmfSetType::Node()) {
+        ++num_node_sets;
+      }
+    }
+
+    // adjust for case where there are no blocks found in the xdmf file
+    if(blocks.size() == 0) {
+      num_elem_blk = 1;
+      elem_blk_ids.push_back(elementBlockId);
+      elem_blk_ids.push_back(elementBlockId++);
+      char * cellTypeCStr = new char[exodusTopologyType.size() + 1];
+      strcpy(cellTypeCStr, exodusTopologyType.c_str());
+      elem_type.push_back(cellTypeCStr);   
+      num_elem_this_blk.push_back(numberElements);
+      num_nodes_per_elem.push_back(nodesPerElement);
+      num_attr.push_back(0);
+    }
+    
+  }
+
+  /**
+   * Convert between Xdmf and Exodus topology numberings
+   */
+  void
+  convertXdmfToExodusTopology(int * elem_connectivity,
+                              const shared_ptr<const XdmfTopologyType> topType,
+                              int num_elem)
+  {
+    if(topType == XdmfTopologyType::Hexahedron_20() ||
+       topType == XdmfTopologyType::Hexahedron_27()) {
+      int * ptr = elem_connectivity;
+      int itmp[4];
+      
+      for(int i=0; i<num_elem; ++i) {
+        ptr += 12;
+        
+        for (unsigned int j=0; j<4; ++j, ++ptr) {
+          itmp[j] = *ptr;
+          *ptr = ptr[4];
+        }
+        
+        for(unsigned int j=0; j<4; ++j, ++ptr) {
+          *ptr = itmp[j];
+        }
+        
+        if(topType == XdmfTopologyType::Hexahedron_27()) {
+          itmp[0] = *ptr;
+          *ptr = ptr[6];
+          ptr++;
+          itmp[1] = *ptr;
+          *ptr = ptr[3];
+          ptr++;
+          itmp[2] = *ptr;
+          *ptr = ptr[3];
+          ptr++;
+          itmp[3] = *ptr;
+          for (unsigned int j=0; j<4; ++j, ++ptr) {
+            *ptr = itmp[j];
+          }
+        }
+      }
+    }
+    else if(topType == XdmfTopologyType::Wedge_15() ||
+            topType == XdmfTopologyType::Wedge_18()) {
+      int * ptr = elem_connectivity;
+      int itmp[3];
+      
+      for(int i=0; i<num_elem; ++i) {
+        ptr += 9;
+        
+        for(unsigned int j=0; j<3; ++j, ++ptr) {
+          itmp[j] = *ptr;
+          *ptr = ptr[3];
+        }
+        
+        for(unsigned int j=0; j<3; ++j, ++ptr) {
+          *ptr = itmp[j];
+        }
+        
+        if(topType == XdmfTopologyType::Wedge_18()) {
+          itmp[0] = *(ptr);
+          itmp[1] = *(ptr+1);
+          itmp[2] = *(ptr+2);
+          *(ptr++) = itmp[2];
+          *(ptr++) = itmp[0];
+          *(ptr++) = itmp[1];
+        }
+      }
+    }
+  }
+
+  /**
+   * Write sets from grid to exodus file.
+   */
+  void
+  writeSets(int exodusHandle,
+            const shared_ptr<XdmfUnstructuredGrid> grid)
+  {
+    const unsigned int numberSets = grid->getNumberSets();
+    const int setId = 20;
+    
+    std::vector<int> values;
+
+    for(unsigned int i=0; i<numberSets; ++i) {
+      const shared_ptr<XdmfSet> set = grid->getSet(i);
+
+      if(set->getType() == XdmfSetType::Node()) {
+
+        bool releaseSet = false;
+        if(!set->isInitialized()) {
+          set->read();
+          releaseSet = true;
+        }
+        
+        std::string name = set->getName();
+        if(name.size() > MAX_STR_LENGTH) {
+          name = name.substr(0, MAX_STR_LENGTH);
+        }
+        
+        const unsigned int setSize = set->getSize();
+        values.resize(setSize);
+        for(unsigned int k=0; k<setSize; ++k) {
+          // Add 1 to xdmf ids because exodus ids begin at 1
+          values[k] = set->getValue<int>(k) + 1;
+        }
+      
+        /*
+          if(set->getType() == XdmfSetType::Cell()) {
+          ex_put_side_set_param(exodusHandle, setId + i, setSize, 0);
+          ex_put_side_set(exodusHandle, setId + i, &(values[0]), NULL);
+          ex_put_name(exodusHandle, EX_SIDE_SET, setId + i, name.c_str());
+          }
+        */
+
+        
+        ex_put_node_set_param(exodusHandle, setId + i, setSize, 0);
+        ex_put_node_set(exodusHandle, setId + i, &(values[0]));
+        ex_put_name(exodusHandle, EX_NODE_SET, setId + i, name.c_str());
+
+        if(releaseSet) {
+          set->release();
+        }
+      }
+    }
+  }
+
+}
+
+shared_ptr<XdmfExodusWriter>
+XdmfExodusWriter::New()
+{
+  shared_ptr<XdmfExodusWriter> p(new XdmfExodusWriter());
+  return p;
+}
+
+XdmfExodusWriter::XdmfExodusWriter()
+{
+}
+
+XdmfExodusWriter::~XdmfExodusWriter()
+{
+}
+
+void
+XdmfExodusWriter::write(const std::string & filePath,
+                        const shared_ptr<XdmfUnstructuredGrid> gridToWrite) const
+{
+
+  // add this grid to a simple grid collection and write
+  shared_ptr<XdmfGridCollection> collection = XdmfGridCollection::New();
+  collection->setName(gridToWrite->getName());
+  collection->setType(XdmfGridCollectionType::Temporal());
+  collection->insert(gridToWrite);
+  return write(filePath,
+               collection);
+
+}
+
+void
+XdmfExodusWriter::write(const std::string & filePath,
+                        const shared_ptr<XdmfGridCollection> grid) const
+{
+
+  int error;
+  ex_opts(EX_VERBOSE);
+
+  // open exodus file
+  int wordSize = 8;
+  int storeSize = 8;
+  int exodusHandle = ex_create(filePath.c_str(),
+                               EX_CLOBBER,
+                               &wordSize,
+                               &storeSize);
+
+  // initialize exodus file
+  std::string title = grid->getName();
+  if(title.size() > MAX_STR_LENGTH) {
+    title = title.substr(0, MAX_STR_LENGTH);
+  }
+
+  // determine type of collections present
+  bool isSpatial = false;
+  bool isTemporal = false;
+  shared_ptr<XdmfGridCollection> gridCollection = grid;
+
+  if(grid->getType() == XdmfGridCollectionType::Temporal()) {
+    isTemporal = true;
+    if(grid->getNumberGridCollections() != 0) {
+      gridCollection = grid->getGridCollection(0);
+      if(gridCollection->getType() == XdmfGridCollectionType::Spatial()) {
+        isSpatial = true;
+      }
+    }
+  }
+  else if(grid->getType() == XdmfGridCollectionType::Spatial()) {
+    isSpatial = true;
+  }
+
+  int num_dim = 0;
+  int num_nodes = 0;
+  int num_elem = 0;
+  int num_elem_blk = 0;
+  int num_node_sets = 0;
+  int num_side_sets = 0;
+
+  std::vector<int> elem_blk_ids;
+  std::vector<char *> elem_type;
+  std::vector<int> num_elem_this_blk;
+  std::vector<int> num_nodes_per_elem;
+  std::vector<int> num_attr;
+  std::vector<shared_ptr<XdmfAttribute> > globalNodeIds;
+ 
+  // initialize file
+
+  shared_ptr<XdmfUnstructuredGrid> unstructuredGrid;
+    
+  if(isSpatial) {
+        
+    // unpartition grid as exodus does not store partitioning information
+    shared_ptr<XdmfPartitioner> partitioner = XdmfPartitioner::New();
+    unstructuredGrid = partitioner->unpartition(gridCollection);
+
+  }
+  else {
+
+    // get first unstructured grid from temporal collection
+    unstructuredGrid = gridCollection->getUnstructuredGrid(0);
+    
+  }
+
+  std::vector<shared_ptr<XdmfSet> > blocks;
+  getGridInformation(unstructuredGrid,
+                     num_dim,
+                     num_nodes,
+                     num_elem,
+                     num_elem_blk,
+                     elem_blk_ids,
+                     elem_type,
+                     num_elem_this_blk,
+                     num_nodes_per_elem,
+                     num_attr,
+                     num_node_sets,
+                     blocks);
+
+  /*
+  std::cout << "num_dim: " << num_dim << std::endl;
+  std::cout << "num_nodes: " << num_nodes << std::endl;
+  std::cout << "num_elem: " << num_elem << std::endl;
+  std::cout << "num_elem_blk: " << num_elem_blk << std::endl;
+  std::cout << "num_node_sets: " << num_node_sets << std::endl;
+  std::cout << "num_side_sets: " << num_side_sets << std::endl;
+  */
+
+  error = ex_put_init(exodusHandle,
+                      title.c_str(),
+                      num_dim,
+                      num_nodes,
+                      num_elem,
+                      num_elem_blk,
+                      num_node_sets,
+                      num_side_sets);
+  
+  if(error != 0) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error initializing exodus file.");
+  }
+ 
+  const int define_maps  = 0;
+  error = ex_put_concat_elem_block(exodusHandle, 
+                                   &(elem_blk_ids[0]), 
+                                   &(elem_type[0]), 
+                                   &(num_elem_this_blk[0]), 
+                                   &(num_nodes_per_elem[0]),
+                                   &(num_attr[0]), 
+                                   define_maps);
+  
+  if(error != 0) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error initializing element blocks in exodus file");
+    return;
+  }
+
+  for(int i=0; i<num_elem_blk; ++i) {
+    delete [] elem_type[i];
+  }
+
+  /*
+  std::cout << "End Init" << std::endl;
+  */
+
+  // write geometry
+
+  double * x = new double[num_nodes];
+  double * y = new double[num_nodes];
+  double * z = NULL;
+
+  if(num_dim == 3) {
+    z = new double[num_nodes];
+  }
+   
+  // get geometry
+  shared_ptr<XdmfGeometry> geometry = unstructuredGrid->getGeometry();
+  bool releaseGeometry = false;
+  if(!geometry->isInitialized()) {
+    geometry->read();
+    releaseGeometry = true;
+  }
+  
+  // read nodal positions
+  geometry->getValues(0, x, num_nodes, num_dim);
+  geometry->getValues(1, y, num_nodes, num_dim);
+  if(num_dim == 3) {
+    geometry->getValues(2, z, num_nodes, num_dim);
+  }
+    
+  // release data
+  if(releaseGeometry) {
+    geometry->release();
+  }
+
+  error = ex_put_coord(exodusHandle, x ,y ,z);
+
+  delete [] x;
+  delete [] y;
+  delete [] z;
+
+  /*
+  std::cout << "End Geometry" << std::endl;
+  */
+
+  // write topology
+  shared_ptr<XdmfTopology> topology = unstructuredGrid->getTopology();
+  shared_ptr<const XdmfTopologyType> topologyType = topology->getType();
+  const int nodesPerElement = topologyType->getNodesPerElement();
+  bool releaseTopology = false;
+  if(!topology->isInitialized()) {
+    topology->read();
+    releaseTopology = true;
+  }
+    
+  if(blocks.size() > 0) {
+
+    // if blocks, write topology to blocks
+    for(unsigned int i=0; i<blocks.size(); ++i) {
+      
+      shared_ptr<XdmfSet> & set = blocks[i];
+      
+      bool releaseSet = false;
+      if(!set->isInitialized()) {
+        set->read();
+        releaseSet = true;
+      }
+      
+      const unsigned int connectivitySize = set->getSize() * nodesPerElement;
+      int * elem_connectivity = new int[connectivitySize];      
+      int offset = 0;
+      for(unsigned int j=0; j<set->getSize(); ++j) {
+        const int elementId = set->getValue<int>(j);
+        const int topologyOffset = elementId * nodesPerElement;
+        for(int k=0; k<nodesPerElement; ++k) {
+          elem_connectivity[offset] = 
+            topology->getValue<int>(topologyOffset + k) + 1;
+          ++offset;
+        }
+      }
+      
+      if(releaseSet) {
+        set->release();
+      }
+      
+      convertXdmfToExodusTopology(elem_connectivity,
+                                  topologyType,
+                                  num_elem);
+      
+      ex_put_elem_conn(exodusHandle, 
+                       elem_blk_ids[i], 
+                       elem_connectivity);
+      
+      delete [] elem_connectivity;
+      
+    }
+  }
+  else {
+    
+    // write to single block
+    const unsigned int connectivitySize = topology->getSize();
+    int * elem_connectivity = new int[connectivitySize];
+    for(unsigned int i=0; i<connectivitySize; ++i) {
+      elem_connectivity[i] = topology->getValue<int>(i) + 1;
+    }
+    if(releaseTopology) {
+      topology->release();
+    }
+    convertXdmfToExodusTopology(elem_connectivity,
+                                topologyType,
+                                num_elem);
+    ex_put_elem_conn(exodusHandle, 
+                     elem_blk_ids[0], 
+                     elem_connectivity);
+
+    delete [] elem_connectivity;
+  }
+    
+  if(releaseTopology) {
+    topology->release();
+  }
+
+  /*
+  std::cout << "End Topology" << std::endl;
+  */
+
+  // write attributes
+  int numGlobalAttributes = 0;
+  int numNodalAttributes = 0;
+  int numElementAttributes = 0;
+
+  std::vector<unsigned int> globalComponents;
+  std::vector<unsigned int> nodalComponents;
+  std::vector<unsigned int> elementComponents;
+  std::vector<std::string> globalAttributeNames;
+  std::vector<std::string> nodalAttributeNames;
+  std::vector<std::string> elementAttributeNames;
+
+  const unsigned int numberAttributes = 
+    unstructuredGrid->getNumberAttributes();
+
+  for(unsigned int i=0; i<numberAttributes; ++i) {
+
+    const shared_ptr<XdmfAttribute> attribute = 
+      unstructuredGrid->getAttribute(i);
+    const unsigned int numberElements = 
+      unstructuredGrid->getTopology()->getNumberElements();
+    const unsigned int numberPoints = 
+      unstructuredGrid->getGeometry()->getNumberPoints();
+
+    const shared_ptr<const XdmfAttributeCenter> attributeCenter =
+      attribute->getCenter();
+
+    if(attributeCenter == XdmfAttributeCenter::Grid()) {
+      const int numComponents = attribute->getSize();
+      globalComponents.push_back(numComponents);
+      numGlobalAttributes += numComponents;
+      constructAttributeNames(attribute->getName(),
+                              globalAttributeNames,
+                              numComponents);
+    }
+    else if(attributeCenter == XdmfAttributeCenter::Node()) {
+      const int numComponents = attribute->getSize() / numberPoints;
+      nodalComponents.push_back(numComponents);
+      numNodalAttributes += numComponents;
+      constructAttributeNames(attribute->getName(),
+                              nodalAttributeNames,
+                              numComponents);
+    }
+    else if(attributeCenter == XdmfAttributeCenter::Cell()) {
+      const int numComponents = attribute->getSize() / numberElements;
+      elementComponents.push_back(numComponents);
+      numElementAttributes += numComponents;
+      constructAttributeNames(attribute->getName(),
+                              elementAttributeNames,
+                              numComponents);
+    }
+
+  }
+
+  if(numGlobalAttributes > 0) {
+    ex_put_var_param(exodusHandle, "g", numGlobalAttributes);
+  }
+  if(numNodalAttributes > 0) {
+    ex_put_var_param(exodusHandle, "n", numNodalAttributes);
+  }
+  if(numElementAttributes > 0) {
+    ex_put_var_param(exodusHandle, "e", numElementAttributes);
+  }
+
+  /*
+  std::cout << "Done attribute params" << std::endl;
+  */
+
+  char ** globalNames = new char*[numGlobalAttributes];
+  char ** nodalNames = new char*[numNodalAttributes];
+  char ** elementNames = new char*[numElementAttributes];
+
+  for(int i=0; i<numGlobalAttributes; ++i) {
+    globalNames[i] = (char*)globalAttributeNames[i].c_str();
+  }
+
+  for(int i=0; i<numNodalAttributes; ++i) {
+    nodalNames[i] = (char*)nodalAttributeNames[i].c_str();
+  }
+
+  for(int i=0; i<numElementAttributes; ++i) {
+    elementNames[i] = (char*)elementAttributeNames[i].c_str();
+  }
+
+  if(numGlobalAttributes > 0) {
+    ex_put_var_names(exodusHandle, "g", numGlobalAttributes, globalNames);
+  }
+  if(numNodalAttributes > 0) {
+    ex_put_var_names(exodusHandle, "n", numNodalAttributes, nodalNames);
+  }
+  if(numElementAttributes > 0) {
+    ex_put_var_names(exodusHandle, "e", numElementAttributes, elementNames);
+  }
+
+  delete [] globalNames;
+  delete [] nodalNames;
+  delete [] elementNames;
+
+  /*
+  std::cout << "Done attribute names" << std::endl;
+  */
+
+  if(numElementAttributes > 0) {
+    const int numTruthTableValues = num_elem_blk * numElementAttributes;
+    int * truthTable = new int[numTruthTableValues];
+    for(int i=0; i<numTruthTableValues; ++i) {
+      truthTable[i] = 1;
+    }
+    ex_put_elem_var_tab(exodusHandle, 
+                        num_elem_blk, 
+                        numElementAttributes, 
+                        truthTable);
+    delete [] truthTable;
+  }
+
+  /*
+  std::cout << "Done truth table" << std::endl;
+  */
+
+  unsigned int numTemporalGrids = 1;
+  if(isTemporal) {
+    if(grid->getNumberUnstructuredGrids() == 0) {
+      numTemporalGrids = grid->getNumberGridCollections();
+    }
+    else {
+      numTemporalGrids = grid->getNumberUnstructuredGrids();
+    }
+  }
+
+  // only write for first timestep
+  writeSets(exodusHandle,
+            unstructuredGrid);
+
+  /*
+  std::cout << "Done Sets" << std::endl;
+  */
+
+  for(unsigned int i=0; i<numTemporalGrids; ++i) {
+
+    // get appropriate grid
+    if(isTemporal) {
+      if(isSpatial) {
+        // we already unpartitioned the first timestep, avoid doing it again
+        if(i != 0) {
+          // unpartition spatial partitioning
+          std::cout << "unpartition" << std::endl;
+          gridCollection = grid->getGridCollection(i);
+          shared_ptr<XdmfPartitioner> partitioner = XdmfPartitioner::New();
+          unstructuredGrid = partitioner->unpartition(gridCollection);
+        }
+      }
+      else {
+        unstructuredGrid = grid->getUnstructuredGrid(i);
+      }
+    }
+
+    double * globalAttributeVals = new double[numGlobalAttributes];
+
+    unsigned int globalIndex = 0;
+    unsigned int globalComponentIndex = 0;
+    unsigned int nodalIndex = 0;
+    unsigned int nodalComponentIndex = 0;
+    unsigned int elementIndex = 0;
+    unsigned int elementComponentIndex = 0;
+    
+    std::vector<double> elementArray;
+
+    for(unsigned int j=0; j<numberAttributes; ++j) {
+      
+      shared_ptr<XdmfAttribute> attribute = unstructuredGrid->getAttribute(j);
+      shared_ptr<const XdmfAttributeCenter> attributeCenter = 
+        attribute->getCenter();
+
+      /*
+      std::cout << attribute->getName() << std::endl;
+      */
+
+      bool releaseAttribute = false;
+      if(!attribute->isInitialized()) {
+        attribute->read();
+        releaseAttribute = true;
+      }
+
+      if(attribute->getCenter() == XdmfAttributeCenter::Grid()) {
+        for(unsigned int k=0; k<globalComponents[globalComponentIndex]; ++k) {
+          attribute->getValues(k, 
+                               globalAttributeVals + globalIndex, 
+                               1);
+          globalIndex++;
+        }
+        globalComponentIndex++;
+      }
+      else if(attribute->getCenter() == XdmfAttributeCenter::Node()) {
+        for(unsigned int k=0; k<nodalComponents[nodalComponentIndex]; ++k) {
+          double * nodalValues = new double[num_nodes];
+          attribute->getValues(k,
+                               nodalValues,
+                               num_nodes,
+                               nodalComponents[nodalComponentIndex]);
+          ex_put_nodal_var(exodusHandle,
+                           i+1,
+                           nodalIndex+1,
+                           num_nodes,
+                           nodalValues);
+          ex_update(exodusHandle);
+          delete [] nodalValues;
+          nodalIndex++;
+        }
+        nodalComponentIndex++;
+      }
+      else if(attribute->getCenter() == XdmfAttributeCenter::Cell()) {
+        if(blocks.size() > 0) {
+          for(unsigned int k=0; k<blocks.size(); ++k) {
+            
+            const shared_ptr<XdmfSet> & set = blocks[k];
+            const int num_elem_in_blk = set->getSize();
+            
+            bool releaseSet = false;
+            if(!set->isInitialized()) {
+              set->read();
+              releaseSet = true;
+            }
+            
+            double * elementValues = new double[num_elem_in_blk];
+            
+            // loop over components
+            const int numberComponents = 
+              elementComponents[elementComponentIndex];
+            
+            for(int l=0; l<numberComponents; ++l) {
+              for(int m=0; m<num_elem_in_blk; ++m) {
+                const int elementId = set->getValue<int>(m);
+                elementValues[m] = 
+                  attribute->getValue<double>(numberComponents*elementId + l);
+              }
+              ex_put_elem_var(exodusHandle,
+                              i+1,
+                              elementIndex+l+1,
+                              elem_blk_ids[k],
+                              num_elem_in_blk,
+                              elementValues);
+              ex_update(exodusHandle);
+            }        
+            
+            delete [] elementValues;
+            
+            if(releaseSet) {
+              set->release();
+            }
+          }
+          elementIndex += elementComponents[elementComponentIndex];
+          elementComponentIndex++;
+        }
+        else {
+          for(unsigned int k=0; 
+              k<elementComponents[elementComponentIndex]; ++k) {
+            double * elementValues = new double[num_elem];
+            attribute->getValues(k,
+                                 elementValues,
+                                 num_elem,
+                                 elementComponents[elementComponentIndex]);
+            ex_put_elem_var(exodusHandle,
+                            i+1,
+                            elementIndex+1,
+                            elem_blk_ids[0], 
+                            num_elem,
+                            elementValues);
+            ex_update(exodusHandle);
+            delete [] elementValues;
+            elementIndex++;
+          }
+          elementComponentIndex++;
+        }
+      }
+      if(releaseAttribute) {
+        attribute->release();
+      }
+    }
+    if(numGlobalAttributes > 0) {
+      ex_put_glob_vars(exodusHandle,
+                       i+1,
+                       numGlobalAttributes,
+                       globalAttributeVals);
+    }
+    ex_update(exodusHandle);
+    delete [] globalAttributeVals;
+
+  }
+
+  /*
+  std::cout << "Done Attributes" << std::endl;
+  */
+
+  // close exodus file
+  ex_close(exodusHandle);
+
+}
+
+// C Wrappers
+
+XDMFEXODUSWRITER *
+XdmfExodusWriterNew()
+{
+  shared_ptr<XdmfExodusWriter> generatedWriter = XdmfExodusWriter::New();
+  return (XDMFEXODUSWRITER *)((void *)(new XdmfExodusWriter(*generatedWriter.get())));
+}
+
+void
+XdmfExodusWriterWriteGrid(XDMFEXODUSWRITER * writer,
+                          char * filePath,
+                          XDMFUNSTRUCTUREDGRID * grid,
+                          int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfUnstructuredGrid> tempGrid = shared_ptr<XdmfUnstructuredGrid>((XdmfUnstructuredGrid *)grid, XdmfNullDeleter());
+  ((XdmfExodusWriter *)writer)->write(std::string(filePath), tempGrid);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfExodusWriterWriteGridCollection(XDMFEXODUSWRITER * writer,
+                                    char * filePath,
+                                    XDMFGRIDCOLLECTION * grid,
+                                    int * status)
+{
+  XDMF_ERROR_WRAP_START(status)
+  shared_ptr<XdmfGridCollection> tempGrid = shared_ptr<XdmfGridCollection>((XdmfGridCollection *)grid, XdmfNullDeleter());
+  ((XdmfExodusWriter *)writer)->write(std::string(filePath), tempGrid);
+  XDMF_ERROR_WRAP_END(status)
+}
+
+void
+XdmfExodusWriterFree(XDMFEXODUSWRITER * writer)
+{
+  if (writer != NULL) {
+    delete ((XdmfExodusWriter *)writer);
+    writer = NULL;
+  }
+}
diff --git a/utils/XdmfExodusWriter.hpp b/utils/XdmfExodusWriter.hpp
new file mode 100644
index 0000000..9683b23
--- /dev/null
+++ b/utils/XdmfExodusWriter.hpp
@@ -0,0 +1,116 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfExodusWriter.hpp                                                */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFEXODUSWRITER_HPP_
+#define XDMFEXODUSWRITER_HPP_
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfGridCollection;
+class XdmfUnstructuredGrid;
+
+// Includes
+#include <string>
+#include "XdmfUtils.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Writes an Xdmf structure in memory to an ExodusII file on
+ * disk.
+ */
+class XDMFUTILS_EXPORT XdmfExodusWriter {
+
+public:
+
+  /**
+   * Create a new XdmfExodusReader.
+   *
+   * @return constructed XdmfExodusReader.
+   */
+  static shared_ptr<XdmfExodusWriter> New();
+
+  virtual ~XdmfExodusWriter();
+
+  /**
+   * Write an XdmfUnstructuredGrid to an ExodusII file.
+   *
+   * @param filePath of the ExodusII file to write.
+   * @param grid an XdmfUnstructuredGrid to write to ExodusII file
+   * format.
+   */
+  void write(const std::string & filePath,
+             const shared_ptr<XdmfUnstructuredGrid> grid) const;
+
+  /**
+   * Write an XdmfGridCollection to an ExodusII file.
+   *
+   * @param filePath of the ExodusII file to write.
+   * @param grid an XdmfGridCollection to write to ExodusII file
+   * format.
+   */
+  void write(const std::string & filePath,
+             const shared_ptr<XdmfGridCollection> grid) const;
+
+
+protected:
+
+  XdmfExodusWriter();
+
+private:
+
+  XdmfExodusWriter(const XdmfExodusWriter &);  // Not implemented.
+  void operator=(const XdmfExodusWriter &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFEXODUSWRITER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFEXODUSWRITER XDMFEXODUSWRITER;
+
+XDMFUTILS_EXPORT XDMFEXODUSWRITER * XdmfExodusWriterNew();
+
+XDMFUTILS_EXPORT void XdmfExodusWriterWriteGrid(XDMFEXODUSWRITER * writer,
+                                                char * filePath,
+                                                XDMFUNSTRUCTUREDGRID * grid,
+                                                int * status);
+
+XDMFUTILS_EXPORT void XdmfExodusWriterWriteGridCollection(XDMFEXODUSWRITER * writer,
+                                                          char * filePath,
+                                                          XDMFGRIDCOLLECTION * grid,
+                                                          int * status);
+
+XDMFUTILS_EXPORT void XdmfExodusWriterFree(XDMFEXODUSWRITER * writer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFEXODUSWRITER_HPP_ */
diff --git a/utils/XdmfFortran.cpp b/utils/XdmfFortran.cpp
new file mode 100644
index 0000000..51018a0
--- /dev/null
+++ b/utils/XdmfFortran.cpp
@@ -0,0 +1,13022 @@
+
+/*******************************************************************/
+/*                               XDMF                              */
+/*                   eXtensible Data Model and Format              */
+/*                                                                 */
+/*  Id : Id  */
+/*  Date : $Date$ */
+/*  Version : $Revision$ */
+/*                                                                 */
+/*  Author:                                                        */
+/*     John Vines                                                  */
+/*     john.m.vines at us.army.mil                                    */
+/*     US Army Research Laboratory                                 */
+/*     Aberdeen Proving Ground, MD                                 */
+/*                                                                 */
+/*     Copyright @ 2009 US Army Research Laboratory                */
+/*     All Rights Reserved                                         */
+/*     See Copyright.txt or http://www.arl.hpc.mil/ice for details */
+/*                                                                 */
+/*     This software is distributed WITHOUT ANY WARRANTY; without  */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS     */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice   */
+/*     for more information.                                       */
+/*                                                                 */
+/*******************************************************************/
+#include <sys/stat.h>
+
+#include "XdmfFortran.hpp"
+
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfBinaryController.hpp"
+#include "XdmfDomain.hpp"
+#include "XdmfError.hpp"
+#include "XdmfFunction.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGrid.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfGridController.hpp"
+#include "XdmfInformation.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfTime.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfSubset.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfCurvilinearGrid.hpp"
+#include "XdmfRectilinearGrid.hpp"
+#include "XdmfRegularGrid.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfHDF5Controller.hpp"
+#include "string.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#ifdef XDMF_BUILD_DSM
+  #include <mpi.h>
+  #include "XdmfHDF5WriterDSM.hpp"
+  #include "XdmfHDF5ControllerDSM.hpp"
+#endif
+
+template <typename T>
+void
+XdmfFortran::insertElements(const T grid,
+                            std::vector<shared_ptr<XdmfAttribute> > & mAttributes,
+                            std::vector<shared_ptr<XdmfInformation> > & mInformations,
+                            std::vector<shared_ptr<XdmfSet> > & mSets,
+                            std::vector<shared_ptr<XdmfMap> > & mMaps,
+                            shared_ptr<XdmfTime> mTime,
+                            shared_ptr<XdmfDomain> mDomain,
+                            std::stack<shared_ptr<XdmfGridCollection> > & mGridCollections)
+{
+  for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+        mAttributes.begin();
+      iter != mAttributes.end();
+      ++iter) {
+    grid->insert(*iter);
+  }
+
+  mAttributes.clear();
+
+  for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin();
+      iter != mInformations.end();
+      ++iter) {
+    grid->insert(*iter);
+  }
+
+  mInformations.clear();
+
+  for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+        mSets.begin();
+      iter != mSets.end();
+      ++iter) {
+    grid->insert(*iter);
+  }
+
+  mSets.clear();
+
+  for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+        mMaps.begin();
+      iter != mMaps.end();
+      ++iter) {
+    grid->insert(*iter);
+  }
+
+  mMaps.clear();
+
+  if(mTime) {
+    grid->setTime(mTime);
+  }
+
+  if(mGridCollections.empty()) {
+    mDomain->insert(grid);
+  }
+  else {
+    mGridCollections.top()->insert(grid);
+  }
+}
+
+// read values from an xdmf array for a number type
+void
+XdmfFortran::readFromArray(shared_ptr<XdmfArray> array,
+                           const int arrayType,
+                           void * const values,
+                           const unsigned int numValues,
+                           const unsigned int startIndex,
+                           const unsigned int arrayStride,
+                           const unsigned int valuesStride)
+{
+  if (!array->isInitialized()) {
+    array->read();
+  }
+  switch(arrayType) {
+  case XDMF_ARRAY_TYPE_INT8:
+    array->getValues(startIndex,
+                     static_cast<char *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_INT16:
+    array->getValues(startIndex,
+                     static_cast<short *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_INT32:
+    array->getValues(startIndex,
+                     static_cast<int *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_INT64:
+    array->getValues(startIndex,
+                     static_cast<long *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_UINT8:
+    array->getValues(startIndex,
+                     static_cast<unsigned char *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_UINT16:
+    array->getValues(startIndex,
+                     static_cast<unsigned short *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_UINT32:
+    array->getValues(startIndex,
+                     static_cast<unsigned int *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_FLOAT32:
+    array->getValues(startIndex,
+                     static_cast<float *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  case XDMF_ARRAY_TYPE_FLOAT64:
+    array->getValues(startIndex,
+                     static_cast<double *>(values),
+                     numValues,
+                     arrayStride,
+                     valuesStride);
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid array number type");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+// write values to xdmf array for a number type
+void
+XdmfFortran::writeToArray(shared_ptr<XdmfArray> array,
+                          const unsigned int numValues,
+                          const int arrayType,
+                          const void * const values,
+                          const unsigned int offset,
+                          const unsigned int arrayStride,
+                          const unsigned int valueStride)
+{
+  switch(arrayType) {
+  case XDMF_ARRAY_TYPE_INT8:
+    array->insert(offset,
+                  static_cast<const char *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_INT16:
+    array->insert(offset,
+                  static_cast<const short *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_INT32:
+    array->insert(offset,
+                  static_cast<const int *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_INT64:
+    array->insert(offset,
+                  static_cast<const long *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_UINT8:
+    array->insert(offset,
+                  static_cast<const unsigned char *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_UINT16:
+    array->insert(offset,
+                  static_cast<const unsigned short *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_UINT32:
+    array->insert(offset,
+                  static_cast<const unsigned int *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_FLOAT32:
+    array->insert(offset,
+                  static_cast<const float *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  case XDMF_ARRAY_TYPE_FLOAT64:
+    array->insert(offset,
+                  static_cast<const double *>(values),
+                  numValues,
+                  arrayStride,
+                  valueStride);
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid array type");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+
+
+XdmfFortran::XdmfFortran() :
+  mDomain(XdmfDomain::New()),
+  mGeometry(shared_ptr<XdmfGeometry>()),
+  mTime(shared_ptr<XdmfTime>()),
+  mTopology(shared_ptr<XdmfTopology>()),
+  mBrick(shared_ptr<XdmfArray>()),
+  mOrigin(shared_ptr<XdmfArray>()),
+  mDimensions(shared_ptr<XdmfArray>()),
+  mHeavyDataWriter(shared_ptr<XdmfHeavyDataWriter>()),
+  mDSMWriter(shared_ptr<XdmfHDF5WriterDSM>()),
+  mSubsetReference(shared_ptr<XdmfArray>()),
+  mMaxFileSize(0),
+  mAllowSetSplitting(false)
+{
+}
+
+XdmfFortran::~XdmfFortran()
+{
+}
+
+int
+XdmfFortran::addAttribute(const char * const name,
+                          const int attributeCenter,
+                          const int attributeType,
+                          const unsigned int numValues,
+                          const int arrayType,
+                          const void * const values)
+{
+  shared_ptr<XdmfAttribute> currAttribute = XdmfAttribute::New();
+  currAttribute->setName(name);
+
+  switch(attributeCenter) {
+  case XDMF_ATTRIBUTE_CENTER_GRID:
+    currAttribute->setCenter(XdmfAttributeCenter::Grid());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_CELL:
+    currAttribute->setCenter(XdmfAttributeCenter::Cell());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_FACE:
+    currAttribute->setCenter(XdmfAttributeCenter::Face());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_EDGE:
+    currAttribute->setCenter(XdmfAttributeCenter::Edge());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_NODE:
+    currAttribute->setCenter(XdmfAttributeCenter::Node());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid attribute center");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+   
+  switch(attributeType) {
+  case XDMF_ATTRIBUTE_TYPE_SCALAR:
+    currAttribute->setType(XdmfAttributeType::Scalar());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_VECTOR:
+    currAttribute->setType(XdmfAttributeType::Vector());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_TENSOR:
+    currAttribute->setType(XdmfAttributeType::Tensor());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_MATRIX:
+    currAttribute->setType(XdmfAttributeType::Matrix());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_TENSOR6:
+    currAttribute->setType(XdmfAttributeType::Tensor6());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_GLOBALID:
+    currAttribute->setType(XdmfAttributeType::GlobalId());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid attribute type");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin(); 
+      iter != mInformations.end();
+      ++iter) {
+    currAttribute->insert(*iter);
+  }
+  mInformations.clear();
+
+
+  // insert values into attribute
+  writeToArray(currAttribute,
+               numValues,
+               arrayType,
+               values);
+
+  mAttributes.push_back(currAttribute);
+
+  const int id = mPreviousAttributes.size();
+  mPreviousAttributes.push_back(currAttribute);
+  return id;
+}
+
+void
+XdmfFortran::clearAttributeHeavyData(const int index)
+{
+  if (index < mAttributes.size()) {
+    while (mAttributes[index]->getNumberHeavyDataControllers() > 0) {
+      mAttributes[index]->removeHeavyDataController(0);
+    }
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Index out of range.");
+  }
+}
+
+void
+XdmfFortran::setAttributeHDF5(const int index,
+                              const char * hdf5File,
+                              const char * hdf5Dataset,
+                              const unsigned int start,
+                              const unsigned int stride,
+                              const unsigned int numValues,
+                              const unsigned int dataspace)
+{
+  if (index < mAttributes.size()) {
+    // create HDF5 link
+    shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                           std::string(hdf5Dataset),
+                                                                           mAttributes[index]->getArrayType(),
+                                                                           std::vector<unsigned int>(1, start),
+                                                                           std::vector<unsigned int>(1, stride),
+                                                                           std::vector<unsigned int>(1, numValues),
+                                                                           std::vector<unsigned int>(1, dataspace));
+    while (mAttributes[index]->getNumberHeavyDataControllers() > 0) {
+      mAttributes[index]->removeHeavyDataController(0);
+    }
+
+    mAttributes[index]->insert(newController);
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Index out of range.");
+  }
+}
+
+void
+XdmfFortran::setAttributeBinary(const int index,
+                                const char * binFile,
+                                const int endian,
+                                const unsigned int seek,
+                                const unsigned int start,
+                                const unsigned int stride,
+                                const unsigned int numValues,
+                                const unsigned int dataspace)
+{
+  if (index < mAttributes.size()) {
+    // create Binary link
+    XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+    switch (endian) {
+      case XDMF_BINARY_ENDIAN_NATIVE:
+        newEndian = XdmfBinaryController::NATIVE;
+        break;
+      case XDMF_BINARY_ENDIAN_LITTLE:
+        newEndian = XdmfBinaryController::LITTLE;
+        break;
+      case XDMF_BINARY_ENDIAN_BIG:
+        newEndian = XdmfBinaryController::BIG;
+        break;
+      default:
+        break;
+    }
+    shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                               mAttributes[index]->getArrayType(),
+                                                                               newEndian,
+                                                                               seek,
+                                                                               std::vector<unsigned int>(1, start),
+                                                                               std::vector<unsigned int>(1, stride),
+                                                                               std::vector<unsigned int>(1, numValues),
+                                                                               std::vector<unsigned int>(1, dataspace));
+
+    while (mAttributes[index]->getNumberHeavyDataControllers() > 0) {
+      mAttributes[index]->removeHeavyDataController(0);
+    }
+
+    mAttributes[index]->insert(newController);
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Index out of range.");
+  }
+}
+
+// unstructured version
+void 
+XdmfFortran::addGrid(const char * const name, const bool writeToHDF5)
+{
+  const shared_ptr<XdmfUnstructuredGrid> grid = XdmfUnstructuredGrid::New();
+  grid->setName(name);
+
+  if(mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                       "Must set geometry before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  if(mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set topology before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  
+  grid->setGeometry(mGeometry);
+  grid->setTopology(mTopology);
+
+  insertElements(grid,
+                 mAttributes,
+                 mInformations,
+                 mSets,
+                 mMaps,
+                 mTime,
+                 mDomain,
+                 mGridCollections);
+  if (writeToHDF5 && mHeavyDataWriter != NULL) {
+    mHeavyDataWriter->openFile();
+    grid->accept(mHeavyDataWriter);
+    mHeavyDataWriter->closeFile();
+  }
+}
+
+void
+XdmfFortran::addGridCurvilinear(const char * const name,
+                                const bool writeToHDF5)
+{
+  if(mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set dimensions before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  const shared_ptr<XdmfCurvilinearGrid> grid =
+    XdmfCurvilinearGrid::New(mDimensions);
+  grid->setName(name);
+
+  if(mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set geometry before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  grid->setGeometry(mGeometry);
+
+  insertElements(grid,
+                 mAttributes,
+                 mInformations,
+                 mSets,
+                 mMaps,
+                 mTime,
+                 mDomain,
+                 mGridCollections);
+  if (writeToHDF5 && mHeavyDataWriter != NULL) {
+    mHeavyDataWriter->openFile();
+    grid->accept(mHeavyDataWriter);
+    mHeavyDataWriter->closeFile();
+  }
+}
+
+void
+XdmfFortran::addGridRectilinear(const char * const name,
+                                const bool writeToHDF5)
+{
+  if(mCoordinates.empty()) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set Coordinates before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  const shared_ptr<XdmfRectilinearGrid> grid =
+    XdmfRectilinearGrid::New(mCoordinates);
+  mCoordinates.clear();
+  grid->setName(name);
+
+  insertElements(grid,
+                 mAttributes,
+                 mInformations,
+                 mSets,
+                 mMaps,
+                 mTime,
+                 mDomain,
+                 mGridCollections);
+  if (writeToHDF5 && mHeavyDataWriter != NULL) {
+    mHeavyDataWriter->openFile();
+    grid->accept(mHeavyDataWriter);
+    mHeavyDataWriter->closeFile();
+  }
+}
+
+void
+XdmfFortran::addGridRegular(const char * const name,
+                            const bool writeToHDF5)
+{
+  if(mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set brick size before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  if(mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set dimensions before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  if(mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set origin before adding grid.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  const shared_ptr<XdmfRegularGrid> grid =
+    XdmfRegularGrid::New(mBrick, mDimensions, mOrigin);
+  grid->setName(name);
+
+  insertElements(grid,
+                 mAttributes,
+                 mInformations,
+                 mSets,
+                 mMaps,
+                 mTime,
+                 mDomain,
+                 mGridCollections);
+  if (writeToHDF5 && mHeavyDataWriter != NULL) {
+    mHeavyDataWriter->openFile();
+    grid->accept(mHeavyDataWriter);
+    mHeavyDataWriter->closeFile();
+  }
+}
+
+
+
+void 
+XdmfFortran::addGridCollection(const char * const name,
+                               const int gridCollectionType)
+{
+  const shared_ptr<XdmfGridCollection> gridCollection = 
+    XdmfGridCollection::New();
+  gridCollection->setName(name);
+
+  switch(gridCollectionType) {
+  case XDMF_GRID_COLLECTION_TYPE_SPATIAL:
+    gridCollection->setType(XdmfGridCollectionType::Spatial());
+    break;
+  case XDMF_GRID_COLLECTION_TYPE_TEMPORAL:
+    gridCollection->setType(XdmfGridCollectionType::Temporal());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid grid collection type");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  insertElements(gridCollection,
+                 mAttributes,
+                 mInformations,
+                 mSets,
+                 mMaps,
+                 mTime,
+                 mDomain,
+                 mGridCollections);
+
+  mGridCollections.push(gridCollection);
+}
+
+void
+XdmfFortran::addGridCollectionReference(const char * filePath,
+                                        const char * xmlPath)
+{
+  shared_ptr<XdmfGridCollection> gridCollection =
+    XdmfGridCollection::New();
+
+  shared_ptr<XdmfGridController> controller = XdmfGridController::New(std::string(filePath), std::string(xmlPath));
+
+  gridCollection->setGridController(controller);
+
+  if(mGridCollections.empty()) {
+    mDomain->insert(gridCollection);
+  }
+  else {
+    mGridCollections.top()->insert(gridCollection);
+  }
+}
+
+void
+XdmfFortran::addGridReference(const int gridType,
+                              const char * filePath,
+                              const char * xmlPath)
+{
+  shared_ptr<XdmfGridController> controller = XdmfGridController::New(std::string(filePath), std::string(xmlPath));
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    shared_ptr<XdmfCurvilinearGrid> grid = XdmfCurvilinearGrid::New(0, 0);
+    grid->setGridController(controller);
+    if(mGridCollections.empty()) {
+      mDomain->insert(grid);
+    }
+    else {
+      mGridCollections.top()->insert(grid);
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    shared_ptr<XdmfArray> placeholderXArray = XdmfArray::New();
+    shared_ptr<XdmfArray> placeholderYArray = XdmfArray::New();
+    shared_ptr<XdmfRectilinearGrid>grid = XdmfRectilinearGrid::New(placeholderXArray,
+                                                                   placeholderYArray);
+    grid->setGridController(controller);
+    if(mGridCollections.empty()) {
+      mDomain->insert(grid);
+    }
+    else {
+      mGridCollections.top()->insert(grid);
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    shared_ptr<XdmfRegularGrid> grid = XdmfRegularGrid::New(0, 0, 0, 0, 0, 0);
+    grid->setGridController(controller);
+    if(mGridCollections.empty()) {
+      mDomain->insert(grid);
+    }
+    else {
+      mGridCollections.top()->insert(grid);
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    shared_ptr<XdmfUnstructuredGrid> grid = XdmfUnstructuredGrid::New();
+    grid->setGridController(controller);
+    if(mGridCollections.empty()) {
+      mDomain->insert(grid);
+    }
+    else {
+      mGridCollections.top()->insert(grid);
+    }
+  }
+}
+
+int
+XdmfFortran::addInformation(const char * const key,
+                            const char * const value)
+{
+  shared_ptr<XdmfInformation> information = XdmfInformation::New();
+  information->setKey(key);
+  information->setValue(value);
+
+  mInformations.push_back(information);
+
+  const int id = mPreviousInformations.size();
+  mPreviousInformations.push_back(information);
+  return id;
+}
+
+void 
+XdmfFortran::addPreviousAttribute(const int attributeId)
+{
+  if(attributeId >= (int)mPreviousAttributes.size()) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid attribute id");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  mAttributes.push_back(mPreviousAttributes[attributeId]);
+}
+
+void 
+XdmfFortran::addPreviousInformation(const int informationId)
+{
+  if(informationId >= (int)mPreviousInformations.size()) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid information id");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  mInformations.push_back(mPreviousInformations[informationId]);
+}
+
+void 
+XdmfFortran::closeGridCollection(const bool writeToHDF5)
+{
+  if(!mGridCollections.empty()) {
+    if (writeToHDF5 && mHeavyDataWriter != NULL) {
+      mHeavyDataWriter->openFile();
+      mGridCollections.top()->accept(mHeavyDataWriter);
+      mHeavyDataWriter->closeFile();
+    }
+    mGridCollections.pop();
+  }
+}
+
+int
+XdmfFortran::setGeometry(const int geometryType, 
+                         const unsigned int numValues,
+                         const int arrayType, 
+                         const void * const pointValues)
+{
+  mGeometry = XdmfGeometry::New();
+
+  switch(geometryType) {
+  case XDMF_GEOMETRY_TYPE_XYZ:
+    mGeometry->setType(XdmfGeometryType::XYZ());
+    break;
+  case XDMF_GEOMETRY_TYPE_XY:
+    mGeometry->setType(XdmfGeometryType::XY());
+    break;
+  case XDMF_GEOMETRY_TYPE_POLAR:
+    mGeometry->setType(XdmfGeometryType::Polar());
+    break;
+  case XDMF_GEOMETRY_TYPE_SPHERICAL:
+    mGeometry->setType(XdmfGeometryType::Spherical());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid geometry type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  // insert geometry values into array
+  writeToArray(mGeometry,
+               numValues,
+               arrayType,
+               pointValues);
+
+  const int id = mPreviousGeometries.size();
+  mPreviousGeometries.push_back(mGeometry);
+  return id;
+}
+
+void
+XdmfFortran::clearGeometryHeavyData()
+{
+  if (mGeometry) {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Geometry needs to be set before hdf5 linkage can be cleared.");
+  }
+
+  while (mGeometry->getNumberHeavyDataControllers() > 0)
+  {
+    mGeometry->removeHeavyDataController(0);
+  }
+}
+
+void
+XdmfFortran::setGeometryHDF5(const char * hdf5File,
+                             const char * hdf5Dataset,
+                             const unsigned int start,
+                             const unsigned int stride,
+                             const unsigned int numValues,
+                             const unsigned int dataspace)
+{
+  if (!mGeometry) {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Geometry needs to be set before hdf5 linkage can be established");
+  }
+
+  // create HDF5 link
+  shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                         std::string(hdf5Dataset),
+                                                                         mGeometry->getArrayType(),
+                                                                         std::vector<unsigned int>(1, start),
+                                                                         std::vector<unsigned int>(1, stride),
+                                                                         std::vector<unsigned int>(1, numValues),
+                                                                         std::vector<unsigned int>(1, dataspace));
+
+  while (mGeometry->getNumberHeavyDataControllers() > 0)
+  {
+    mGeometry->removeHeavyDataController(0);
+  }
+
+  mGeometry->insert(newController);
+}
+
+void
+XdmfFortran::setGeometryBinary(const char * binFile,
+                               const int endian,
+                               const unsigned int seek,
+                               const unsigned int start,
+                               const unsigned int stride,
+                               const unsigned int numValues,
+                               const unsigned int dataspace)
+{
+  if (!mGeometry) {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Geometry needs to be set before binary linkage can be established");
+  }
+
+  XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+  switch (endian) {
+    case XDMF_BINARY_ENDIAN_NATIVE:
+      newEndian = XdmfBinaryController::NATIVE;
+      break;
+    case XDMF_BINARY_ENDIAN_LITTLE:
+      newEndian = XdmfBinaryController::LITTLE;
+      break;
+    case XDMF_BINARY_ENDIAN_BIG:
+      newEndian = XdmfBinaryController::BIG;
+      break;
+    default:
+      break;
+  }
+
+  // create Binary link
+  shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                             mGeometry->getArrayType(),
+                                                                             newEndian,
+                                                                             seek,
+                                                                             std::vector<unsigned int>(1, start),
+                                                                             std::vector<unsigned int>(1, stride),
+                                                                             std::vector<unsigned int>(1, numValues),
+                                                                             std::vector<unsigned int>(1, dataspace));
+
+  while (mGeometry->getNumberHeavyDataControllers() > 0)
+  {
+    mGeometry->removeHeavyDataController(0);
+  }
+
+  mGeometry->insert(newController);
+}
+
+void 
+XdmfFortran::setPreviousGeometry(const int geometryId)
+{
+  if(geometryId >= (int)mPreviousGeometries.size()) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid geometry id");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  mGeometry = mPreviousGeometries[geometryId];
+}
+
+void 
+XdmfFortran::setPreviousTopology(const int topologyId)
+{
+  if(topologyId >= (int)mPreviousTopologies.size()) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid topology id");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  mTopology = mPreviousTopologies[topologyId];
+}
+
+void 
+XdmfFortran::setTime(const double time)
+{
+  mTime = XdmfTime::New();
+  mTime->setValue(time);
+}
+
+int
+XdmfFortran::setTopology(const int topologyType, 
+                         const unsigned int numValues,
+                         const int arrayType,
+                         const void * const connectivityValues,
+                         const int numNodes)
+{
+  mTopology = XdmfTopology::New();
+
+  switch(topologyType) {
+  case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+    mTopology->setType(XdmfTopologyType::Polyvertex());
+    break;
+  case XDMF_TOPOLOGY_TYPE_POLYLINE:
+    mTopology->setType(XdmfTopologyType::Polyline(numNodes));
+    break;
+  case XDMF_TOPOLOGY_TYPE_POLYGON:
+    mTopology->setType(XdmfTopologyType::Polygon(numNodes));
+    break;
+  case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+    mTopology->setType(XdmfTopologyType::Triangle());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+    mTopology->setType(XdmfTopologyType::Quadrilateral());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+    mTopology->setType(XdmfTopologyType::Tetrahedron());
+    break;
+  case XDMF_TOPOLOGY_TYPE_PYRAMID:
+    mTopology->setType(XdmfTopologyType::Pyramid());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE:
+    mTopology->setType(XdmfTopologyType::Wedge());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+    mTopology->setType(XdmfTopologyType::Hexahedron());
+    break;
+  case XDMF_TOPOLOGY_TYPE_EDGE_3:
+    mTopology->setType(XdmfTopologyType::Edge_3());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+    mTopology->setType(XdmfTopologyType::Triangle_6());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+    mTopology->setType(XdmfTopologyType::Quadrilateral_8());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+    mTopology->setType(XdmfTopologyType::Quadrilateral_9());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+    mTopology->setType(XdmfTopologyType::Tetrahedron_10());
+    break;
+  case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+    mTopology->setType(XdmfTopologyType::Pyramid_13());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+    mTopology->setType(XdmfTopologyType::Wedge_15());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+    mTopology->setType(XdmfTopologyType::Wedge_18());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+    mTopology->setType(XdmfTopologyType::Hexahedron_20());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+    mTopology->setType(XdmfTopologyType::Hexahedron_24());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+    mTopology->setType(XdmfTopologyType::Hexahedron_27());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+    mTopology->setType(XdmfTopologyType::Hexahedron_64());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+    mTopology->setType(XdmfTopologyType::Hexahedron_125());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+    mTopology->setType(XdmfTopologyType::Hexahedron_216());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+    mTopology->setType(XdmfTopologyType::Hexahedron_343());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+    mTopology->setType(XdmfTopologyType::Hexahedron_512());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+    mTopology->setType(XdmfTopologyType::Hexahedron_729());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+    mTopology->setType(XdmfTopologyType::Hexahedron_1000());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+    mTopology->setType(XdmfTopologyType::Hexahedron_1331());
+    break;
+  case XDMF_TOPOLOGY_TYPE_MIXED:
+    mTopology->setType(XdmfTopologyType::Mixed());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid topology type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  // insert connectivity values into array
+  writeToArray(mTopology,
+               numValues,
+               arrayType,
+               connectivityValues);
+
+  const int id = mPreviousTopologies.size();
+  mPreviousTopologies.push_back(mTopology);
+  return id;
+}
+
+void
+XdmfFortran::clearTopologyHeavyData()
+{
+  if (mTopology) {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Topology needs to be set before hdf5 linkage can be cleared.");
+  }
+
+  while (mTopology->getNumberHeavyDataControllers() > 0)
+  {
+    mTopology->removeHeavyDataController(0);
+  }
+}
+
+void
+XdmfFortran::setTopologyHDF5(const char * hdf5File,
+                             const char * hdf5Dataset,
+                             const unsigned int start,
+                             const unsigned int stride,
+                             const unsigned int numValues,
+                             const unsigned int dataspace)
+{
+  if (!mTopology) {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Topology needs to be set before hdf5 linkage can be established.");
+  }
+
+  shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                         std::string(hdf5Dataset),
+                                                                         mTopology->getArrayType(),
+                                                                         std::vector<unsigned int>(1, start),
+                                                                         std::vector<unsigned int>(1, stride),
+                                                                         std::vector<unsigned int>(1, numValues),
+                                                                         std::vector<unsigned int>(1, dataspace));
+
+  while (mTopology->getNumberHeavyDataControllers() > 0)
+  {
+    mTopology->removeHeavyDataController(0);
+  }
+
+  mTopology->insert(newController);
+}
+
+void
+XdmfFortran::setTopologyBinary(const char * binFile,
+                               const int endian,
+                               const unsigned int seek,
+                               const unsigned int start,
+                               const unsigned int stride,
+                               const unsigned int numValues,
+                               const unsigned int dataspace)
+{
+  if (!mTopology) {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Topology needs to be set before hdf5 linkage can be established.");
+  }
+
+  XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+  switch (endian) {
+    case XDMF_BINARY_ENDIAN_NATIVE:
+      newEndian = XdmfBinaryController::NATIVE;
+      break;
+    case XDMF_BINARY_ENDIAN_LITTLE:
+      newEndian = XdmfBinaryController::LITTLE;
+      break;
+    case XDMF_BINARY_ENDIAN_BIG:
+      newEndian = XdmfBinaryController::BIG;
+      break;
+    default:
+      break;
+  }
+
+  shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                             mTopology->getArrayType(),
+                                                                             newEndian,
+                                                                             seek,
+                                                                             std::vector<unsigned int>(1, start),
+                                                                             std::vector<unsigned int>(1, stride),
+                                                                             std::vector<unsigned int>(1, numValues),
+                                                                             std::vector<unsigned int>(1, dataspace));
+
+  while (mTopology->getNumberHeavyDataControllers() > 0)
+  {
+    mTopology->removeHeavyDataController(0);
+  }
+
+  mTopology->insert(newController);
+}
+
+
+
+
+int
+XdmfFortran::retrieveNumDomainGridCollections()
+{
+  return mDomain->getNumberGridCollections();
+}
+
+int
+XdmfFortran::numGridCollectionGridCollections()
+{
+  if (!mGridCollections.empty()) {
+    return mGridCollections.top()->getNumberGridCollections();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open."); 
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveDomainTag(char * returnTag, const int tagLength)
+{
+  char * tempTag = strdup(mDomain->getItemTag().c_str());
+  memset(returnTag, 0, tagLength);
+  memcpy(returnTag, tempTag, strlen(tempTag)+1);
+  delete [] tempTag;
+}
+
+int
+XdmfFortran::retrieveDomainNumProperties()
+{
+  return mDomain->getItemProperties().size();
+}
+
+void
+XdmfFortran::retrieveDomainProperty(const int index,
+                                    char * key,
+                                    const int keyLength,
+                                    char * value,
+                                    const int valueLength)
+{
+  if (index < (int)mDomain->getItemProperties().size()) {
+    std::map<std::string, std::string>::iterator walker = mDomain->getItemProperties().begin();
+    for (int i = 0; i<index; i++) {
+      walker++;
+    }
+    char * tempKey = strdup((*walker).first.c_str());
+    memset(key, 0, keyLength);
+    memcpy(key, tempKey, strlen(tempKey)+1);
+    delete [] tempKey;
+    char * tempValue = strdup((*walker).second.c_str());
+    memset(value, 0, valueLength);
+    memcpy(value, tempValue, strlen(tempValue)+1);
+    delete [] tempValue;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveDomainPropertyByKey(char * key,
+                                         char * value,
+                                         const int valueLength)
+{
+  std::string tempString = key;
+  memset(value, 0, valueLength);
+  if ((mDomain->getItemProperties().count(tempString))>0) {
+    char * tempValue =
+      strdup(mDomain->getItemProperties()[tempString].c_str());
+    memcpy(value, tempValue, strlen(tempValue)+1);
+    delete [] tempValue;
+  }
+}
+
+void
+XdmfFortran::readDomainGridCollection(const int index)
+{
+  if ((int)mDomain->getNumberGridCollections() > index) {
+    mDomain->getGridCollection(index)->read();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeDomainGridCollection(const int index)
+{
+  if ((int)mDomain->getNumberGridCollections() > index) {
+    mDomain->removeGridCollection(index);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::openDomainGridCollection(const int index,
+                                      const int openMaps,
+                                      const int openAttributes,
+                                      const int openInformation,
+                                      const int openSets)
+{
+  if ((int)mDomain->getNumberGridCollections() > index) {
+    shared_ptr<XdmfGridCollection> openedGridCollection =
+      mDomain->getGridCollection(index);
+    int i;
+    int n;
+    if (openMaps) {
+      n = openedGridCollection->getNumberMaps();
+      shared_ptr<XdmfMap> openedMap;
+      for (i = 0; i < n; i++) {
+        openedMap = openedGridCollection->getMap(i);
+        mMaps.push_back(openedMap);
+        mPreviousMaps.push_back(openedMap);
+      }
+    }
+    if (openAttributes) {
+      n = openedGridCollection->getNumberAttributes();
+      shared_ptr<XdmfAttribute> openedAttribute;
+      for (i = 0; i < n; i++) {
+        openedAttribute = openedGridCollection->getAttribute(i);
+        mAttributes.push_back(openedAttribute);
+        mPreviousAttributes.push_back(openedAttribute);
+      }
+    }
+    if (openInformation) {
+      n = openedGridCollection->getNumberInformations();
+      shared_ptr<XdmfInformation> openedInformation;
+      for (i = 0; i < n; i++) {
+        openedInformation = openedGridCollection->getInformation(i);
+        mInformations.push_back(openedInformation);
+        mPreviousInformations.push_back(openedInformation);
+      }
+    }
+    if (openSets) {
+      n = openedGridCollection->getNumberSets();
+      shared_ptr<XdmfSet> openedSet;
+      for (i = 0; i < n; i++) {
+        openedSet = openedGridCollection->getSet(i);
+        mSets.push_back(openedSet);
+      }
+      mGridCollections.push(openedGridCollection);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::readGridCollectionGrid(const int gridType,
+                                    const int index)
+
+{
+  if (!mGridCollections.empty()) {
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        mGridCollections.top()->getCurvilinearGrid(index)->read();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        mGridCollections.top()->getRectilinearGrid(index)->read();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        mGridCollections.top()->getRegularGrid(index)->read();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        mGridCollections.top()->getUnstructuredGrid(index)->read();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+
+void
+XdmfFortran::removeGridCollectionGridCollection(const int index)
+{
+  if (!mGridCollections.empty()) {
+    if ((int)mGridCollections.top()->getNumberGridCollections() > index) {
+      mGridCollections.top()->removeGridCollection(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::openGridCollectionGridCollection(const int index,
+                                              const int openMaps,
+                                              const int openAttributes,
+                                              const int openInformation,
+                                              const int openSets)
+{
+  if (!mGridCollections.empty()) {
+    if ((int)mGridCollections.top()->getNumberGridCollections() > index) {
+      shared_ptr<XdmfGridCollection> openedGridCollection =
+        mGridCollections.top()->getGridCollection(index);
+      int i;
+      int n;
+      if (openMaps) {
+        n = openedGridCollection->getNumberMaps();
+        shared_ptr<XdmfMap> openedMap;
+        for (i = 0; i < n; i++) {
+          openedMap = openedGridCollection->getMap(i);
+          mMaps.push_back(openedMap);
+          mPreviousMaps.push_back(openedMap);
+        }
+      }
+      if (openAttributes) {
+        n = openedGridCollection->getNumberAttributes();
+        shared_ptr<XdmfAttribute> openedAttribute;
+        for (i = 0; i < n; i++) {
+          openedAttribute = openedGridCollection->getAttribute(i);
+          mAttributes.push_back(openedAttribute);
+          mPreviousAttributes.push_back(openedAttribute);
+        }
+      }
+      if (openInformation) {
+        n = openedGridCollection->getNumberInformations();
+        shared_ptr<XdmfInformation> openedInformation;
+        for (i = 0; i < n; i++) {
+          openedInformation = openedGridCollection->getInformation(i);
+          mInformations.push_back(openedInformation);
+          mPreviousInformations.push_back(openedInformation);
+        }
+      }
+      if (openSets) {
+        n = openedGridCollection->getNumberSets();
+        shared_ptr<XdmfSet> openedSet;
+        for (i = 0; i < n; i++) {
+          openedSet = openedGridCollection->getSet(i);
+          mSets.push_back(openedSet);
+        }
+        mGridCollections.push(openedGridCollection);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::readGridCollectionGridCollection(const int index)
+{
+  if (!mGridCollections.empty()) {
+    if ((int)mGridCollections.top()->getNumberGridCollections() > index) {
+      mGridCollections.top()->getGridCollection(index)->read();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionTag(char * returnTag, const int tagLength)
+{
+  if (!mGridCollections.empty()) {
+    char * tempTag = strdup(mGridCollections.top()->getItemTag().c_str());
+    memset(returnTag, 0, tagLength);
+    memcpy(returnTag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionName(char * returnName, const int nameLength)
+{
+  if (!mGridCollections.empty()) {
+    char * tempName = strdup(mGridCollections.top()->getName().c_str());
+    memset(returnName, 0, nameLength);
+    memcpy(returnName, tempName, strlen(tempName)+1);
+    delete [] tempName;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveGridCollectionNumProperties()
+{
+  if (!mGridCollections.empty()) {
+    return mGridCollections.top()->getItemProperties().size();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionProperty(const int index, char * key, const int keyLength, char * value, const int valueLength)
+{
+  if (!mGridCollections.empty()) {
+    if (index < (int)mGridCollections.top()->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mGridCollections.top()->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionPropertyByKey(char * key,
+                                                 char * value,
+                                                 const int valueLength)
+{
+  if (!mGridCollections.empty()) {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mGridCollections.top()->getItemProperties().count(tempString))>0) {
+      char * tempValue =
+        strdup(mGridCollections.top()->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: No grid collections are open.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::openDomainGrid(const int gridType,
+                            const int index,
+                            const int openMaps,
+                            const int openAttributes,
+                            const int openInformation,
+                            const int openSets)
+{
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      shared_ptr<XdmfCurvilinearGrid> openedGrid =
+        mDomain->getCurvilinearGrid(index);
+      shared_ptr<const XdmfArrayType> dataType;
+      mGeometry = openedGrid->getGeometry();
+      mDimensions = openedGrid->getDimensions();
+      mTime = openedGrid->getTime();
+      int i;
+      int n;
+      if (openAttributes) {
+        n = openedGrid->getNumberAttributes();
+        shared_ptr<XdmfAttribute> openedAttribute;
+        for (i = 0; i < n; i++) {
+          openedAttribute = openedGrid->getAttribute(i);
+          mAttributes.push_back(openedAttribute);
+          mPreviousAttributes.push_back(openedAttribute);
+        }
+      }
+      if (openMaps) {
+        n = openedGrid->getNumberMaps();
+        shared_ptr<XdmfMap> openedMap;
+        for (i = 0; i < n; i++) {
+          openedMap = openedGrid->getMap(i);
+          mMaps.push_back(openedMap);
+          mPreviousMaps.push_back(openedMap);
+        }
+      }
+      if (openInformation) {
+        n = openedGrid->getNumberInformations();
+        shared_ptr<XdmfInformation> openedInformation;
+        for (i = 0; i < n; i++) {
+          openedInformation = openedGrid->getInformation(i);
+          mInformations.push_back(openedInformation);
+          mPreviousInformations.push_back(openedInformation);
+        }
+      }
+      if (openSets) {
+        n = openedGrid->getNumberSets();
+        shared_ptr<XdmfSet> openedSet;
+        for (i = 0; i < n; i++) {
+          openedSet = openedGrid->getSet(i);
+          mSets.push_back(openedSet);
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      shared_ptr<XdmfRectilinearGrid> openedGrid =
+        mDomain->getRectilinearGrid(index);
+      shared_ptr<const XdmfArrayType> dataType;
+      mCoordinates = openedGrid->getCoordinates();
+      mTime = openedGrid->getTime();
+      int i;
+      int n;
+      if (openAttributes) {
+        n = openedGrid->getNumberAttributes();
+        shared_ptr<XdmfAttribute> openedAttribute;
+        for (i = 0; i < n; i++) {
+          openedAttribute = openedGrid->getAttribute(i);
+          mAttributes.push_back(openedAttribute);
+          mPreviousAttributes.push_back(openedAttribute);
+        }
+      }
+      if (openMaps) {
+        n = openedGrid->getNumberMaps();
+        shared_ptr<XdmfMap> openedMap;
+        for (i = 0; i < n; i++) {
+          openedMap = openedGrid->getMap(i);
+          mMaps.push_back(openedMap);
+          mPreviousMaps.push_back(openedMap);
+        }
+      }
+      if (openInformation) {
+        n = openedGrid->getNumberInformations();
+        shared_ptr<XdmfInformation> openedInformation;
+        for (i = 0; i < n; i++) {
+          openedInformation = openedGrid->getInformation(i);
+          mInformations.push_back(openedInformation);
+          mPreviousInformations.push_back(openedInformation);
+        }
+      }
+      if (openSets) {
+        n = openedGrid->getNumberSets();
+        shared_ptr<XdmfSet> openedSet;
+        for (i = 0; i < n; i++) {
+          openedSet = openedGrid->getSet(i);
+          mSets.push_back(openedSet);
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      shared_ptr<XdmfRegularGrid> openedGrid =
+        mDomain->getRegularGrid(index);
+      shared_ptr<const XdmfArrayType> dataType;
+      mTime = openedGrid->getTime();
+      mBrick = openedGrid->getBrickSize();
+      mOrigin = openedGrid->getOrigin();
+      mDimensions = openedGrid->getDimensions();
+      int i;
+      int n;
+      if (openAttributes) {
+        n = openedGrid->getNumberAttributes();
+        shared_ptr<XdmfAttribute> openedAttribute;
+        for (i = 0; i < n; i++) {
+          openedAttribute = openedGrid->getAttribute(i);
+          mAttributes.push_back(openedAttribute);
+          mPreviousAttributes.push_back(openedAttribute);
+        }
+      }
+      if (openMaps) {
+        n = openedGrid->getNumberMaps();
+        shared_ptr<XdmfMap> openedMap;
+        for (i = 0; i < n; i++) {
+          openedMap = openedGrid->getMap(i);
+          mMaps.push_back(openedMap);
+          mPreviousMaps.push_back(openedMap);
+        }
+      }
+      if (openInformation) {
+        n = openedGrid->getNumberInformations();
+        shared_ptr<XdmfInformation> openedInformation;
+        for (i = 0; i < n; i++) {
+          openedInformation = openedGrid->getInformation(i);
+          mInformations.push_back(openedInformation);
+          mPreviousInformations.push_back(openedInformation);
+        }
+      }
+      if (openSets) {
+        n = openedGrid->getNumberSets();
+        shared_ptr<XdmfSet> openedSet;
+        for (i = 0; i < n; i++) {
+          openedSet = openedGrid->getSet(i);
+          mSets.push_back(openedSet);
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      shared_ptr<XdmfUnstructuredGrid> openedGrid =
+        mDomain->getUnstructuredGrid(index);
+      mTopology = openedGrid->getTopology();
+      mGeometry = openedGrid->getGeometry();
+      mTime = openedGrid->getTime();
+      int i;
+      int n;
+      if (openAttributes) {
+        n = openedGrid->getNumberAttributes();
+        shared_ptr<XdmfAttribute> openedAttribute;
+        for (i = 0; i < n; i++) {
+          openedAttribute = openedGrid->getAttribute(i);
+          mAttributes.push_back(openedAttribute);
+          mPreviousAttributes.push_back(openedAttribute);
+        }
+      }
+      if (openMaps) {
+        n = openedGrid->getNumberMaps();
+        shared_ptr<XdmfMap> openedMap;
+        for (i = 0; i < n; i++) {
+          openedMap = openedGrid->getMap(i);
+          mMaps.push_back(openedMap);
+          mPreviousMaps.push_back(openedMap);
+        }
+      }
+      if (openInformation) {
+        n = openedGrid->getNumberInformations();
+        shared_ptr<XdmfInformation> openedInformation;
+        for (i = 0; i < n; i++) {
+          openedInformation = openedGrid->getInformation(i);
+          mInformations.push_back(openedInformation);
+          mPreviousInformations.push_back(openedInformation);
+        }
+      }
+      if (openSets) {
+        n = openedGrid->getNumberSets();
+        shared_ptr<XdmfSet> openedSet;
+        for (i = 0; i < n; i++) {
+          openedSet = openedGrid->getSet(i);
+          mSets.push_back(openedSet);
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::readDomainGrid(const int gridType,
+                            const int index)
+{
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      mDomain->getCurvilinearGrid(index)->read();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      mDomain->getRectilinearGrid(index)->read();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      mDomain->getRegularGrid(index)->read();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      mDomain->getUnstructuredGrid(index)->read();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeDomainGrid(const int gridType, const int index)
+{
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      mDomain->removeCurvilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      mDomain->removeRectilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      mDomain->removeRegularGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      mDomain->removeUnstructuredGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::replaceDomainGrid(const int gridType, const int index, char * name)
+{
+  int i;
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      if(mDimensions == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Must set dimensions before replacing grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      if(mGeometry == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set geometry before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+
+      shared_ptr<XdmfCurvilinearGrid> grid = mDomain->getCurvilinearGrid(index);
+      grid->setName(name);
+
+      grid->setGeometry(mGeometry);
+      grid->setDimensions(mDimensions);
+
+      for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+        grid->removeAttribute(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+          mAttributes.begin(); 
+          iter != mAttributes.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mAttributes.clear();
+
+      for( i=grid->getNumberInformations()-1;i>=0;i--) {
+        grid->removeInformation(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+          mInformations.begin(); 
+          iter != mInformations.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mInformations.clear();
+
+      for (i=grid->getNumberSets()-1;i>=0;i--) {
+        grid->removeSet(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+          mSets.begin(); 
+          iter != mSets.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mSets.clear();
+
+      for (i=grid->getNumberMaps()-1;i>=0;i--) {
+        grid->removeMap(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+          mMaps.begin(); 
+          iter != mMaps.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mMaps.clear();
+    
+      if(mTime) {
+        grid->setTime(mTime);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      if(mCoordinates.empty()) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set Coordinates before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+
+      shared_ptr<XdmfRectilinearGrid> grid = mDomain->getRectilinearGrid(index);
+      grid->setCoordinates(mCoordinates);
+      mCoordinates.clear();
+      for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+        grid->removeAttribute(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+          mAttributes.begin(); 
+          iter != mAttributes.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mAttributes.clear();
+
+      for (i=grid->getNumberInformations()-1;i>=0;i--) {
+        grid->removeInformation(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+          mInformations.begin(); 
+          iter != mInformations.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mInformations.clear();
+
+      for (i=grid->getNumberSets()-1;i>=0;i--) {
+        grid->removeSet(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+          mSets.begin(); 
+          iter != mSets.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mSets.clear();
+
+      for (i=grid->getNumberMaps()-1;i>=0;i--) {
+        grid->removeMap(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+          mMaps.begin(); 
+          iter != mMaps.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mMaps.clear();
+    
+      if(mTime) {
+        grid->setTime(mTime);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      if(mBrick == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set brick size before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+
+      if(mDimensions == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set dimensions before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+
+      if(mOrigin == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set origin before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+  
+      shared_ptr<XdmfRegularGrid> grid = mDomain->getRegularGrid(index);
+      grid->setOrigin(mOrigin);
+      grid->setDimensions(mDimensions);
+      grid->setBrickSize(mBrick);
+
+      for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+        grid->removeAttribute(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+          mAttributes.begin(); 
+          iter != mAttributes.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mAttributes.clear();
+
+      for (i=grid->getNumberInformations()-1;i>=0;i--) {
+        grid->removeInformation(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+          mInformations.begin(); 
+          iter != mInformations.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mInformations.clear();
+
+      for (i=grid->getNumberSets()-1;i>=0;i--) {
+        grid->removeSet(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+          mSets.begin(); 
+          iter != mSets.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mSets.clear();
+
+      for (i=grid->getNumberMaps()-1;i>=0;i--) {
+        grid->removeMap(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+          mMaps.begin(); 
+          iter != mMaps.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mMaps.clear();
+    
+      if(mTime) {
+        grid->setTime(mTime);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      if(mGeometry == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set geometry before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      if(mTopology == NULL) {
+        try {
+          XdmfError::message(XdmfError::FATAL, 
+            "Must set topology before adding grid.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+      shared_ptr<XdmfUnstructuredGrid> grid = mDomain->getUnstructuredGrid(index);
+      grid->setName(name);
+      grid->setGeometry(mGeometry);
+      grid->setTopology(mTopology);
+
+      for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+        grid->removeAttribute(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+          mAttributes.begin(); 
+          iter != mAttributes.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mAttributes.clear();
+
+      for (i=grid->getNumberInformations()-1;i>=0;i--) {
+        grid->removeInformation(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+          mInformations.begin(); 
+          iter != mInformations.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mInformations.clear();
+
+      for (i=grid->getNumberSets()-1;i>=0;i--) {
+        grid->removeSet(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+          mSets.begin(); 
+          iter != mSets.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mSets.clear();
+
+      for (i=grid->getNumberMaps()-1;i>=0;i--) {
+        grid->removeMap(0);
+      }
+
+      for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+          mMaps.begin(); 
+          iter != mMaps.end();
+          ++iter) {
+        grid->insert(*iter);
+      }
+
+      mMaps.clear();
+    
+      if(mTime) {
+        grid->setTime(mTime);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveDomainGridName(const int gridType, const int index, char * returnName, const int nameLength)
+{
+  shared_ptr<XdmfGrid> openedGrid;
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      openedGrid = mDomain->getCurvilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      openedGrid = mDomain->getRectilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      openedGrid = mDomain->getRegularGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      openedGrid = mDomain->getUnstructuredGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  char * tempName = strdup(openedGrid->getName().c_str());
+  memset(returnName, 0, nameLength);
+  memcpy(returnName, tempName, strlen(tempName)+1);
+  delete [] tempName;
+}
+
+void
+XdmfFortran::retrieveDomainGridTag(const int gridType,
+                                   const int index,
+                                   char * returnTag,
+                                   const int tagLength)
+{
+  shared_ptr<XdmfGrid> openedGrid;
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      openedGrid = mDomain->getCurvilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e)
+      {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      openedGrid = mDomain->getRectilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      openedGrid = mDomain->getRegularGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      openedGrid = mDomain->getUnstructuredGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  char * tempTag = strdup(openedGrid->getItemTag().c_str());
+  memset(returnTag, 0, tagLength);
+  memcpy(returnTag, tempTag, strlen(tempTag)+1);
+  delete [] tempTag;
+}
+
+int
+XdmfFortran::retrieveDomainGridNumProperties(const int gridType, const int index)
+{
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      return mDomain->getCurvilinearGrid(index)->getItemProperties().size();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      return mDomain->getRectilinearGrid(index)->getItemProperties().size();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      return mDomain->getRegularGrid(index)->getItemProperties().size();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      return mDomain->getUnstructuredGrid(index)->getItemProperties().size();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveDomainGridProperty(const int gridType,
+                                        const int gridIndex,
+                                        const int index,
+                                        char * key,
+                                        const int keyLength,
+                                        char * value,
+                                        const int valueLength)
+{
+  shared_ptr<XdmfGrid> openedGrid;
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      openedGrid = mDomain->getCurvilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      openedGrid = mDomain->getRectilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      openedGrid = mDomain->getRegularGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      openedGrid = mDomain->getUnstructuredGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  if (index < (int)openedGrid->getItemProperties().size()) {
+    std::map<std::string, std::string>::iterator walker =
+      openedGrid->getItemProperties().begin();
+    for (int i = 0; i<index; i++) {
+      walker++;
+    }
+    char * tempKey = strdup((*walker).first.c_str());
+    memset(key, 0, keyLength);
+    memcpy(key, tempKey, strlen(tempKey)+1);
+    delete [] tempKey;
+    char * tempValue = strdup((*walker).second.c_str());
+    memset(value, 0, valueLength);
+    memcpy(value, tempValue, strlen(tempValue)+1);
+    delete [] tempValue;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveDomainGridPropertyByKey(int gridType,
+                                             int index,
+                                             char * key,
+                                             char * value,
+                                             int valueLength)
+{
+  shared_ptr<XdmfGrid> openedGrid;
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    if (index < (int)mDomain->getNumberCurvilinearGrids()) {
+      openedGrid = mDomain->getCurvilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    if (index < (int)mDomain->getNumberRectilinearGrids()) {
+      openedGrid = mDomain->getRectilinearGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    if (index < (int)mDomain->getNumberRegularGrids()) {
+      openedGrid = mDomain->getRegularGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    if (index < (int)mDomain->getNumberUnstructuredGrids()) {
+      openedGrid = mDomain->getUnstructuredGrid(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  std::string tempString = key;
+  memset(value, 0, valueLength);
+  if ((openedGrid->getItemProperties().count(tempString))>0) {
+    char * tempValue = strdup(openedGrid->getItemProperties()[tempString].c_str());
+    memcpy(value, tempValue, strlen(tempValue)+1);
+    delete [] tempValue;
+  }
+}
+
+void
+XdmfFortran::openGridCollectionGrid(const int gridType,
+                                    const int index,
+                                    const int openMaps,
+                                    const int openAttributes,
+                                    const int openInformation,
+                                    const int openSets)
+{
+  if (!mGridCollections.empty()) {
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        shared_ptr<XdmfCurvilinearGrid> openedGrid =
+          mGridCollections.top()->getCurvilinearGrid(index);
+        shared_ptr<const XdmfArrayType> dataType;
+        mGeometry = openedGrid->getGeometry();
+        mDimensions = openedGrid->getDimensions();
+        mTime = openedGrid->getTime();
+        int i;
+        int n;
+        if (openAttributes) {
+          n = openedGrid->getNumberAttributes();
+          shared_ptr<XdmfAttribute> openedAttribute;
+          for (i = 0; i < n; i++) {
+            openedAttribute = openedGrid->getAttribute(i);
+            mAttributes.push_back(openedAttribute);
+            mPreviousAttributes.push_back(openedAttribute);
+          }
+        }
+        if (openMaps) {
+          n = openedGrid->getNumberMaps();
+          shared_ptr<XdmfMap> openedMap;
+          for (i = 0; i < n; i++) {
+            openedMap = openedGrid->getMap(i);
+            mMaps.push_back(openedMap);
+            mPreviousMaps.push_back(openedMap);
+          }
+        }
+        if (openInformation) {
+          n = openedGrid->getNumberInformations();
+          shared_ptr<XdmfInformation> openedInformation;
+          for (i = 0; i < n; i++) {
+            openedInformation = openedGrid->getInformation(i);
+            mInformations.push_back(openedInformation);
+            mPreviousInformations.push_back(openedInformation);
+          }
+        }
+        if (openSets) {
+          n = openedGrid->getNumberSets();
+          shared_ptr<XdmfSet> openedSet;
+          for (i = 0; i < n; i++) {
+            openedSet = openedGrid->getSet(i);
+            mSets.push_back(openedSet);
+          }
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        shared_ptr<XdmfRectilinearGrid> openedGrid =
+          mGridCollections.top()->getRectilinearGrid(index);
+        shared_ptr<const XdmfArrayType> dataType;
+        mCoordinates = openedGrid->getCoordinates();
+        mTime = openedGrid->getTime();
+        int i;
+        int n;
+        if (openAttributes) {
+          n = openedGrid->getNumberAttributes();
+          shared_ptr<XdmfAttribute> openedAttribute;
+          for (i = 0; i < n; i++) {
+            openedAttribute = openedGrid->getAttribute(i);
+            mAttributes.push_back(openedAttribute);
+            mPreviousAttributes.push_back(openedAttribute);
+          }
+        }
+        if (openMaps) {
+          n = openedGrid->getNumberMaps();
+          shared_ptr<XdmfMap> openedMap;
+          for (i = 0; i < n; i++) {
+            openedMap = openedGrid->getMap(i);
+            mMaps.push_back(openedMap);
+            mPreviousMaps.push_back(openedMap);
+          }
+        }
+        if (openInformation) {
+          n = openedGrid->getNumberInformations();
+          shared_ptr<XdmfInformation> openedInformation;
+          for (i = 0; i < n; i++) {
+            openedInformation = openedGrid->getInformation(i);
+            mInformations.push_back(openedInformation);
+            mPreviousInformations.push_back(openedInformation);
+          }
+        }
+        if (openSets) {
+          n = openedGrid->getNumberSets();
+          shared_ptr<XdmfSet> openedSet;
+          for (i = 0; i < n; i++) {
+            openedSet = openedGrid->getSet(i);
+            mSets.push_back(openedSet);
+          }
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        shared_ptr<XdmfRegularGrid> openedGrid =
+          mGridCollections.top()->getRegularGrid(index);
+        shared_ptr<const XdmfArrayType> dataType;
+        mTime = openedGrid->getTime();
+        mBrick = openedGrid->getBrickSize();
+        mOrigin = openedGrid->getOrigin();
+        mDimensions = openedGrid->getDimensions();
+        int i;
+        int n;
+        if (openAttributes) {
+          n = openedGrid->getNumberAttributes();
+          shared_ptr<XdmfAttribute> openedAttribute;
+          for (i = 0; i < n; i++) {
+            openedAttribute = openedGrid->getAttribute(i);
+            mAttributes.push_back(openedAttribute);
+            mPreviousAttributes.push_back(openedAttribute);
+          }
+        }
+        if (openMaps) {
+          n = openedGrid->getNumberMaps();
+          shared_ptr<XdmfMap> openedMap;
+          for (i = 0; i < n; i++) {
+            openedMap = openedGrid->getMap(i);
+            mMaps.push_back(openedMap);
+            mPreviousMaps.push_back(openedMap);
+          }
+        }
+        if (openInformation) {
+          n = openedGrid->getNumberInformations();
+          shared_ptr<XdmfInformation> openedInformation;
+          for (i = 0; i < n; i++) {
+            openedInformation = openedGrid->getInformation(i);
+            mInformations.push_back(openedInformation);
+            mPreviousInformations.push_back(openedInformation);
+          }
+        }
+        if (openSets) {
+          n = openedGrid->getNumberSets();
+          shared_ptr<XdmfSet> openedSet;
+          for (i = 0; i < n; i++) {
+            openedSet = openedGrid->getSet(i);
+            mSets.push_back(openedSet);
+          }
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        shared_ptr<XdmfUnstructuredGrid> openedGrid =
+          mGridCollections.top()->getUnstructuredGrid(index);
+        mTopology = openedGrid->getTopology();
+        mGeometry = openedGrid->getGeometry();
+        mTime = openedGrid->getTime();
+        int i;
+        int n;
+        if (openAttributes) {
+          n = openedGrid->getNumberAttributes();
+          shared_ptr<XdmfAttribute> openedAttribute;
+          for (i = 0; i < n; i++) {
+            openedAttribute = openedGrid->getAttribute(i);
+            mAttributes.push_back(openedAttribute);
+            mPreviousAttributes.push_back(openedAttribute);
+          }
+        }
+        if (openMaps) {
+          n = openedGrid->getNumberMaps();
+          shared_ptr<XdmfMap> openedMap;
+          for (i = 0; i < n; i++) {
+            openedMap = openedGrid->getMap(i);
+            mMaps.push_back(openedMap);
+            mPreviousMaps.push_back(openedMap);
+          }
+        }
+        if (openInformation) {
+          n = openedGrid->getNumberInformations();
+          shared_ptr<XdmfInformation> openedInformation;
+          for (i = 0; i < n; i++) {
+            openedInformation = openedGrid->getInformation(i);
+            mInformations.push_back(openedInformation);
+            mPreviousInformations.push_back(openedInformation);
+          }
+        }
+        if (openSets) {
+          n = openedGrid->getNumberSets();
+          shared_ptr<XdmfSet> openedSet;
+          for (i = 0; i < n; i++) {
+            openedSet = openedGrid->getSet(i);
+            mSets.push_back(openedSet);
+          }
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeGridCollectionGrid(const int gridType, const int index)
+{
+  if (!mGridCollections.empty()) {
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        mGridCollections.top()->removeCurvilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        mGridCollections.top()->removeRectilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        mGridCollections.top()->removeRegularGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        mGridCollections.top()->removeUnstructuredGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::replaceGridCollectionGrid(const int gridType, const int index, char * name)
+{
+  if (!mGridCollections.empty()) {
+    int i;
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        if(mDimensions == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL,
+                               "Must set dimensions before replacing grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+        if(mGeometry == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set geometry before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+
+        shared_ptr<XdmfCurvilinearGrid> grid =
+          mGridCollections.top()->getCurvilinearGrid(index);
+        grid->setName(name);
+
+        grid->setGeometry(mGeometry);
+        grid->setDimensions(mDimensions);
+
+        for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+          grid->removeAttribute(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+            mAttributes.begin(); 
+            iter != mAttributes.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mAttributes.clear();
+
+        for( i=grid->getNumberInformations()-1;i>=0;i--) {
+          grid->removeInformation(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+            mInformations.begin(); 
+            iter != mInformations.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mInformations.clear();
+
+        for (i=grid->getNumberSets()-1;i>=0;i--) {
+          grid->removeSet(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+            mSets.begin(); 
+            iter != mSets.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mSets.clear();
+
+        for (i=grid->getNumberMaps()-1;i>=0;i--) {
+          grid->removeMap(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+            mMaps.begin(); 
+            iter != mMaps.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mMaps.clear();
+    
+        if(mTime) {
+          grid->setTime(mTime);
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range."); 
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        if(mCoordinates.empty()) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set Coordinates before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+
+        shared_ptr<XdmfRectilinearGrid> grid =
+          mGridCollections.top()->getRectilinearGrid(index);
+        grid->setCoordinates(mCoordinates);
+        mCoordinates.clear();
+        for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+          grid->removeAttribute(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+            mAttributes.begin(); 
+            iter != mAttributes.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mAttributes.clear();
+
+        for (i=grid->getNumberInformations()-1;i>=0;i--) {
+          grid->removeInformation(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+            mInformations.begin(); 
+            iter != mInformations.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mInformations.clear();
+
+        for (i=grid->getNumberSets()-1;i>=0;i--) {
+          grid->removeSet(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+            mSets.begin(); 
+            iter != mSets.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mSets.clear();
+
+        for (i=grid->getNumberMaps()-1;i>=0;i--) {
+          grid->removeMap(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+            mMaps.begin(); 
+            iter != mMaps.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mMaps.clear();
+    
+        if(mTime) {
+          grid->setTime(mTime);
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        if(mBrick == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set brick size before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+
+        if(mDimensions == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set dimensions before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+
+        if(mOrigin == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set origin before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+  
+        shared_ptr<XdmfRegularGrid> grid = mGridCollections.top()->getRegularGrid(index);
+        grid->setOrigin(mOrigin);
+        grid->setDimensions(mDimensions);
+        grid->setBrickSize(mBrick);
+
+        for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+          grid->removeAttribute(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+            mAttributes.begin(); 
+            iter != mAttributes.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mAttributes.clear();
+
+        for (i=grid->getNumberInformations()-1;i>=0;i--) {
+          grid->removeInformation(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+            mInformations.begin(); 
+            iter != mInformations.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mInformations.clear();
+
+        for (i=grid->getNumberSets()-1;i>=0;i--) {
+          grid->removeSet(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+            mSets.begin(); 
+            iter != mSets.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mSets.clear();
+
+        for (i=grid->getNumberMaps()-1;i>=0;i--) {
+          grid->removeMap(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+            mMaps.begin(); 
+            iter != mMaps.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mMaps.clear();
+    
+        if(mTime) {
+          grid->setTime(mTime);
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        if(mGeometry == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set geometry before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+        if(mTopology == NULL) {
+          try {
+            XdmfError::message(XdmfError::FATAL, 
+                               "Must set topology before adding grid.");
+          }
+          catch (XdmfError & e) {
+            throw e;
+          }
+        }
+        shared_ptr<XdmfUnstructuredGrid> grid =
+          mGridCollections.top()->getUnstructuredGrid(index);
+        grid->setName(name);
+        grid->setGeometry(mGeometry);
+        grid->setTopology(mTopology);
+
+        for (i=grid->getNumberAttributes()-1;i>=0;i--) {
+          grid->removeAttribute(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+            mAttributes.begin(); 
+            iter != mAttributes.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mAttributes.clear();
+
+        for (i=grid->getNumberInformations()-1;i>=0;i--) {
+          grid->removeInformation(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+            mInformations.begin(); 
+            iter != mInformations.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mInformations.clear();
+
+        for (i=grid->getNumberSets()-1;i>=0;i--) {
+          grid->removeSet(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfSet> >::const_iterator iter =
+            mSets.begin(); 
+            iter != mSets.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mSets.clear();
+
+        for (i=grid->getNumberMaps()-1;i>=0;i--) {
+          grid->removeMap(0);
+        }
+
+        for(std::vector<shared_ptr<XdmfMap> >::const_iterator iter =
+            mMaps.begin(); 
+            iter != mMaps.end();
+            ++iter) {
+          grid->insert(*iter);
+        }
+
+        mMaps.clear();
+    
+        if(mTime) {
+          grid->setTime(mTime);
+        }
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionGridName(const int gridType,
+                                            const int index,
+                                            char * returnName,
+                                            const int nameLength)
+{
+  if (!mGridCollections.empty()) {
+    shared_ptr<XdmfGrid> openedGrid;
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        openedGrid = mGridCollections.top()->getCurvilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        openedGrid = mGridCollections.top()->getRectilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        openedGrid = mGridCollections.top()->getRegularGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        openedGrid = mGridCollections.top()->getUnstructuredGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    char * tempName = strdup(openedGrid->getName().c_str());
+    memset(returnName, 0, nameLength);
+    memcpy(returnName, tempName, strlen(tempName)+1);
+    delete [] tempName;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionGridTag(const int gridType,
+                                           const int index,
+                                           char * returnTag,
+                                           const int tagLength)
+{
+  if (!mGridCollections.empty()) {
+    shared_ptr<XdmfGrid> openedGrid;
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        openedGrid = mGridCollections.top()->getCurvilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        openedGrid = mGridCollections.top()->getRectilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        openedGrid = mGridCollections.top()->getRegularGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        openedGrid = mGridCollections.top()->getUnstructuredGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    char * tempTag = strdup(openedGrid->getItemTag().c_str());
+    memset(returnTag, 0, tagLength);
+    memcpy(returnTag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveGridCollectionGridNumProperties(const int gridType, const int index)
+{
+  if (!mGridCollections.empty()) {
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        return mGridCollections.top()->getCurvilinearGrid(index)->getItemProperties().size();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        return -1;
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        return mGridCollections.top()->getRectilinearGrid(index)->getItemProperties().size();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        return -1;
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        return mGridCollections.top()->getRegularGrid(index)->getItemProperties().size();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        return -1;
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        return mGridCollections.top()->getUnstructuredGrid(index)->getItemProperties().size();
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        return -1;
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionGridProperty(const int gridType,
+                                                const int gridIndex,
+                                                const int index,
+                                                char * key,
+                                                const int keyLength,
+                                                char * value,
+                                                const int valueLength)
+{
+  if (!mGridCollections.empty()) {
+    shared_ptr<XdmfGrid> openedGrid;
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        openedGrid = mGridCollections.top()->getCurvilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        openedGrid = mGridCollections.top()->getRectilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        openedGrid = mGridCollections.top()->getRegularGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        openedGrid = mGridCollections.top()->getUnstructuredGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    if (index < (int)openedGrid->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        openedGrid->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGridCollectionGridPropertyByKey(const int gridType,
+                                                     const int index,
+                                                     char * key,
+                                                     char * value,
+                                                     const int valueLength)
+{
+  if (!mGridCollections.empty()) {
+    shared_ptr<XdmfGrid> openedGrid;
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberCurvilinearGrids()) {
+        openedGrid = mGridCollections.top()->getCurvilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      if (index < (int)mGridCollections.top()->getNumberRectilinearGrids()) {
+        openedGrid = mGridCollections.top()->getRectilinearGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      if (index < (int)mGridCollections.top()->getNumberRegularGrids()) {
+        openedGrid = mGridCollections.top()->getRegularGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      if (index < (int)mGridCollections.top()->getNumberUnstructuredGrids()) {
+        openedGrid = mGridCollections.top()->getUnstructuredGrid(index);
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Error: Index out of range.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((openedGrid->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(openedGrid->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::numDomainGrids(const int gridType)
+{
+  if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+    return mDomain->getNumberCurvilinearGrids();
+  }
+  else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+    return mDomain->getNumberRectilinearGrids();
+  }
+  else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+    return mDomain->getNumberRegularGrids();
+  }
+  else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+    return mDomain->getNumberUnstructuredGrids();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Invalid Grid Type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+int
+XdmfFortran::numGridCollectionGrids(const int gridType)
+{
+  if (!mGridCollections.empty()) {
+    if (gridType == XDMF_GRID_TYPE_CURVILINEAR) {
+      return mGridCollections.top()->getNumberCurvilinearGrids();
+    }
+    else if (gridType == XDMF_GRID_TYPE_RECTILINEAR) {
+      return mGridCollections.top()->getNumberRectilinearGrids();
+    }
+    else if (gridType == XDMF_GRID_TYPE_REGULAR) {
+      return mGridCollections.top()->getNumberRegularGrids();
+    }
+    else if (gridType == XDMF_GRID_TYPE_UNSTRUCTURED) {
+      return mGridCollections.top()->getNumberUnstructuredGrids();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Grid Type."); 
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: No Grid Collections have been loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+int
+XdmfFortran::retrieveGridCollectionType()
+{
+  if (!mGridCollections.empty()) {
+    shared_ptr<const XdmfGridCollectionType> returnType = mGridCollections.top()->getType();
+    if (returnType == XdmfGridCollectionType::Spatial()) {
+      return XDMF_GRID_COLLECTION_TYPE_SPATIAL;
+    }
+    else if (returnType == XdmfGridCollectionType::Temporal()) {
+      return XDMF_GRID_COLLECTION_TYPE_TEMPORAL;
+    }
+    else if (returnType == XdmfGridCollectionType::NoCollectionType()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Error: No Grid Collection Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Grid Collection Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "There is no grid collection currently loaded.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+float
+XdmfFortran::retrieveTime()
+{
+  return static_cast<float>(mTime->getValue());
+}
+
+void
+XdmfFortran::retrieveGeometryTag(char * tag, const int tagLength)
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before its tag can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    char * tempTag = strdup(mGeometry->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+}
+
+int
+XdmfFortran::retrieveGeometryType()
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before its type can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    shared_ptr<const XdmfGeometryType> returnType = mGeometry->getType();
+    if (returnType == XdmfGeometryType::XY()) {
+      return XDMF_GEOMETRY_TYPE_XY;
+    }
+    else if (returnType == XdmfGeometryType::XYZ()) {
+      return XDMF_GEOMETRY_TYPE_XYZ;
+    }
+    else if (returnType == XdmfGeometryType::Polar()) {
+      return XDMF_GEOMETRY_TYPE_POLAR;
+    }
+    else if (returnType == XdmfGeometryType::Spherical()) {
+      return XDMF_GEOMETRY_TYPE_SPHERICAL;
+    }
+    else if (returnType == XdmfGeometryType::NoGeometryType()) {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Uninitialized geometry type");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Invalid geometry type");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveGeometryValueType()
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before its value type can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    shared_ptr<const XdmfArrayType> dataType = mGeometry->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Geometry Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Geometry Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGeometryValues(void * values,
+                                    const int dataType,
+                                    const int numberRead,
+                                    const int startIndex,
+                                    const int arrayStride,
+                                    const int valueStride)
+{
+  if(mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before its values can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mGeometry->isInitialized()) {
+      mGeometry->read();
+    }
+    readFromArray(mGeometry,
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveGeometryNumPoints()
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before the number of points"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mGeometry->getNumberPoints();
+  }
+}
+
+int
+XdmfFortran::retrieveGeometrySize()
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before its size can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mGeometry->getSize();
+  }
+}
+
+void
+XdmfFortran::clearPreviousGeometries()
+{
+  mPreviousGeometries.clear();
+}
+
+void
+XdmfFortran::modifyGeometryValues(void * values,
+                                  const int arrayType,
+                                  const int numValues,
+                                  const int startIndex,
+                                  const int arrayStride,
+                                  const int valueStride)
+{
+  if(mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set geometry before its values can be modified.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mGeometry->isInitialized()) {
+      mGeometry->read();
+    }
+    writeToArray(mGeometry,
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveGeometryNumProperties()
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before the number of properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mGeometry->getItemProperties().size();
+  } 
+}
+
+void
+XdmfFortran::retrieveGeometryProperty(const int index,
+                                      char * key,
+                                      const int keyLength,
+                                      char * value,
+                                      const int valueLength)
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (index < (int)mGeometry->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mGeometry->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveGeometryPropertyByKey(char * key,
+                                           char * value,
+                                           const int valueLength)
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set geometry before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mGeometry->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mGeometry->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+}
+
+void
+XdmfFortran::setGeometryAsVariable(char * varname)
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set geometry before it "
+                         "can be set as a variable.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string newVar = varname;
+    mVariableSet[newVar] = mGeometry;
+  }
+}
+
+void
+XdmfFortran::setGeometryAsSubsetReference()
+{
+  if (mGeometry == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set geometry before it "
+                         "can be set as a variable.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    mSubsetReference = mGeometry;
+  }
+}
+
+void
+XdmfFortran::retrieveTopologyTag(char * tag, const int tagLength)
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before its tag can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    char * tempTag = strdup(mTopology->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+}
+
+int
+XdmfFortran::retrieveTopologyType()
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before its type can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    shared_ptr<const XdmfTopologyType> returnType =  mTopology->getType();
+    if (returnType ==  XdmfTopologyType::Polyvertex()) {
+      return XDMF_TOPOLOGY_TYPE_POLYVERTEX;
+    }
+    else if (returnType == XdmfTopologyType::Polyline(0)) {
+      return XDMF_TOPOLOGY_TYPE_POLYLINE;
+    }
+    else if (returnType == XdmfTopologyType::Polygon(0)) {
+      return XDMF_TOPOLOGY_TYPE_POLYGON;
+    }
+    else if (returnType == XdmfTopologyType::Triangle()) {
+      return XDMF_TOPOLOGY_TYPE_TRIANGLE;
+    }
+    else if (returnType == XdmfTopologyType::Quadrilateral()) {
+      return XDMF_TOPOLOGY_TYPE_QUADRILATERAL;
+    }
+    else if (returnType == XdmfTopologyType::Tetrahedron()) {
+      return XDMF_TOPOLOGY_TYPE_TETRAHEDRON;
+    }
+    else if (returnType == XdmfTopologyType::Pyramid()) {
+      return XDMF_TOPOLOGY_TYPE_PYRAMID;
+    }
+    else if (returnType == XdmfTopologyType::Wedge()) {
+      return XDMF_TOPOLOGY_TYPE_WEDGE;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON;
+    }
+    else if (returnType == XdmfTopologyType::Edge_3()) {
+      return XDMF_TOPOLOGY_TYPE_EDGE_3;
+    }
+    else if (returnType == XdmfTopologyType::Triangle_6()) {
+      return XDMF_TOPOLOGY_TYPE_TRIANGLE_6;
+    }
+    else if (returnType == XdmfTopologyType::Quadrilateral_8()) {
+      return XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8;
+    }
+    else if (returnType == XdmfTopologyType::Quadrilateral_9()) {
+      return XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9;
+    }
+    else if (returnType == XdmfTopologyType::Tetrahedron_10()) {
+      return XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10;
+    }
+    else if (returnType == XdmfTopologyType::Pyramid_13()) {
+      return XDMF_TOPOLOGY_TYPE_PYRAMID_13;
+    }
+    else if (returnType == XdmfTopologyType::Wedge_15()) {
+      return XDMF_TOPOLOGY_TYPE_WEDGE_15;
+    }
+    else if (returnType == XdmfTopologyType::Wedge_18()) {
+      return XDMF_TOPOLOGY_TYPE_WEDGE_18;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_20()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_24()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_27()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_64()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_125()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_216()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_343()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_512()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_729()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_1000()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000;
+    }
+    else if (returnType == XdmfTopologyType::Hexahedron_1331()) {
+      return XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331;
+    }
+    else if (returnType == XdmfTopologyType::Mixed()) {
+      return XDMF_TOPOLOGY_TYPE_MIXED;
+    }
+    else if (returnType == XdmfTopologyType::NoTopologyType()) {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Uninitialized topology type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Invalid topology type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveTopologyValueType()
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before its value type can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {   
+    shared_ptr<const XdmfArrayType> dataType = mTopology->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Topology Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Topology Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveTopologyValues(void * values,
+                                    const int dataType,
+                                    const int numberRead,
+                                    const int startIndex,
+                                    const int arrayStride,
+                                    const int valueStride)
+{
+  if(mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set topology before its values can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mTopology->isInitialized()) {
+      mTopology->read();
+    }
+    readFromArray(mTopology,
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveTopologyNumElements()
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before the number of Elements"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mTopology->getNumberElements();
+  }
+}
+
+int
+XdmfFortran::retrieveTopologySize()
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before its size can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mTopology->getSize();
+  }
+}
+
+void
+XdmfFortran::clearPreviousTopologies()
+{
+  mPreviousTopologies.clear();
+}
+
+void
+XdmfFortran::modifyTopologyValues(void * values,
+                                  const int arrayType,
+                                  const int numValues,
+                                  const int startIndex,
+                                  const int arrayStride,
+                                  const int valueStride)
+{
+  if(mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set topology before its values can be modified.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mTopology->isInitialized()) {
+      mTopology->read();
+    }
+    writeToArray(mTopology,
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveTopologyNumProperties()
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before the number of properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mTopology->getItemProperties().size();
+  } 
+}
+
+void
+XdmfFortran::retrieveTopologyProperty(const int index,
+                                      char * key,
+                                      const int keyLength,
+                                      char * value,
+                                      const int valueLength)
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before the properties it contains"
+                         " can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (index < (int)mTopology->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker = mTopology->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveTopologyPropertyByKey(char * key, char * value, const int valueLength)
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Topology before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mTopology->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mTopology->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+}
+
+void
+XdmfFortran::setTopologyAsVariable(char * varname)
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set Topology before it"
+                         " can be set as a variable.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string newVar = varname;
+    mVariableSet[newVar] = mTopology;
+  }
+}
+
+void
+XdmfFortran::setTopologyAsSubsetReference()
+{
+  if (mTopology == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set Topology before it"
+                         " can be set as a variable.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    mSubsetReference = mTopology;
+  }
+}
+
+int
+XdmfFortran::setDimensions(const int numValues, const int arrayType, void * pointValues)
+{
+  mDimensions = XdmfArray::New();
+
+  // insert dimension values into array
+  writeToArray(mDimensions, numValues, arrayType, pointValues);
+
+  int id = mPreviousDimensions.size();
+  mPreviousDimensions.push_back(mDimensions);
+  return id;
+}
+
+void
+XdmfFortran::clearDimensionsHeavyData()
+{
+  if (mDimensions) {
+    while (mDimensions->getNumberHeavyDataControllers() > 0)
+    {
+      mDimensions->removeHeavyDataController(0);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set dimensions before hdf5 linkage"
+                         " can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setDimensionsHDF5(const char * hdf5File,
+                               const char * hdf5Dataset,
+                               const unsigned int start,
+                               const unsigned int stride,
+                               const unsigned int numValues,
+                               const unsigned int dataspace)
+{
+  if (mDimensions) {
+    shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                         std::string(hdf5Dataset),
+                                                                         mDimensions->getArrayType(),
+                                                                         std::vector<unsigned int>(1, start),
+                                                                         std::vector<unsigned int>(1, stride),
+                                                                         std::vector<unsigned int>(1, numValues),
+                                                                         std::vector<unsigned int>(1, dataspace));
+
+    while (mDimensions->getNumberHeavyDataControllers() > 0)
+    {
+      mDimensions->removeHeavyDataController(0);
+    }
+
+    mDimensions->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set dimensions before hdf5 linkage"
+                         " can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setDimensionsBinary(const char * binFile,
+                                const int endian,
+                                const unsigned int seek,
+                                const unsigned int start,
+                                const unsigned int stride,
+                                const unsigned int numValues,
+                                const unsigned int dataspace)
+{
+  if (mDimensions) {
+    XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+    switch (endian) {
+      case XDMF_BINARY_ENDIAN_NATIVE:
+        newEndian = XdmfBinaryController::NATIVE;
+        break;
+      case XDMF_BINARY_ENDIAN_LITTLE:
+        newEndian = XdmfBinaryController::LITTLE;
+        break;
+      case XDMF_BINARY_ENDIAN_BIG:
+        newEndian = XdmfBinaryController::BIG;
+        break;
+      default:
+        break;
+    }
+    shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                               mDimensions->getArrayType(),
+                                                                               newEndian,
+                                                                               seek,
+                                                                               std::vector<unsigned int>(1, start),
+                                                                               std::vector<unsigned int>(1, stride),
+                                                                               std::vector<unsigned int>(1, numValues),
+                                                                               std::vector<unsigned int>(1, dataspace));
+
+    while (mDimensions->getNumberHeavyDataControllers() > 0)
+    {
+      mDimensions->removeHeavyDataController(0);
+    }
+
+    mDimensions->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set dimensions before hdf5 linkage"
+                         " can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::openPreviousDimensions(const int index)
+{
+  if ((int)mPreviousDimensions.size()>index) {
+    mDimensions = mPreviousDimensions[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousDimensions()
+{
+  mPreviousDimensions.clear();
+}
+
+void
+XdmfFortran::modifyDimensionsValues(void * values,
+                                    const int arrayType,
+                                    const int numValues,
+                                    const int startIndex,
+                                    const int arrayStride,
+                                    const int valueStride)
+{
+  if(mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set dimensions before its values"
+                         " can be modified.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mDimensions->isInitialized()) {
+      mDimensions->read();
+    }
+    writeToArray(mDimensions,
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+}
+
+void
+XdmfFortran::retrieveDimensionsTag(char * tag, const int tagLength)
+{
+  if (mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set dimensions before its tag can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    char * tempTag = strdup(mDimensions->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+}
+
+int
+XdmfFortran::retrieveDimensionsValueType()
+{
+  if (mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set dimensions before its value type"
+                         " can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    shared_ptr<const XdmfArrayType> dataType = mDimensions->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Dimension Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Dimension Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveDimensionsValues(void * values,
+                                      const int dataType,
+                                      const int numberRead,
+                                      const int startIndex,
+                                      const int arrayStride,
+                                      const int valueStride)
+{
+  if(mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set dimensions before its values"
+                         " can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mDimensions->isInitialized()) {
+      mDimensions->read();
+    }
+    readFromArray(mDimensions,
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveDimensionsSize()
+{
+  if (mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Dimensions before its size can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mDimensions->getSize();
+  }
+}
+
+int
+XdmfFortran::retrieveDimensionsNumProperties()
+{
+  if (mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set dimensions before the number of properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mDimensions->getItemProperties().size();
+  } 
+}
+
+void
+XdmfFortran::retrieveDimensionsProperty(const int index,
+                                        char * key,
+                                        const int keyLength,
+                                        char * value,
+                                        const int valueLength)
+{
+  if (mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set dimensions before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (index < (int)mDimensions->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mDimensions->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveDimensionsPropertyByKey(char * key,
+                                             char * value,
+                                             const int valueLength)
+{
+  if (mDimensions == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set dimensions before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mDimensions->getItemProperties().count(tempString))>0) {
+      char * tempValue =
+        strdup(mDimensions->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+}
+
+int
+XdmfFortran::setOrigin(const int numValues, const int arrayType, void * pointValues)
+{
+  mOrigin = XdmfArray::New();
+
+  // insert origin values into array
+  writeToArray(mOrigin, numValues, arrayType, pointValues);
+
+  int id = mPreviousOrigins.size();
+  mPreviousOrigins.push_back(mOrigin);
+  return id;
+}
+
+void
+XdmfFortran::clearOriginHeavyData()
+{
+  if (mOrigin) {
+    while (mOrigin->getNumberHeavyDataControllers() > 0)
+    {
+      mOrigin->removeHeavyDataController(0);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set Origin before hdf5 linkage can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setOriginHDF5(const char * hdf5File,
+                           const char * hdf5Dataset,
+                           const unsigned int start,
+                           const unsigned int stride,
+                           const unsigned int numValues,
+                           const unsigned int dataspace)
+{
+  if (mOrigin) {
+    shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                         std::string(hdf5Dataset),
+                                                                         mOrigin->getArrayType(),
+                                                                         std::vector<unsigned int>(1, start),
+                                                                         std::vector<unsigned int>(1, stride),
+                                                                         std::vector<unsigned int>(1, numValues),
+                                                                         std::vector<unsigned int>(1, dataspace));
+
+    while (mOrigin->getNumberHeavyDataControllers() > 0)
+    {
+      mOrigin->removeHeavyDataController(0);
+    }
+
+    mOrigin->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set Origin before hdf5 linkage can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setOriginBinary(const char * binFile,
+                             const int endian,
+                             const unsigned int seek,
+                             const unsigned int start,
+                             const unsigned int stride,
+                             const unsigned int numValues,
+                             const unsigned int dataspace)
+{
+  if (mOrigin) {
+    XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+    switch (endian) {
+      case XDMF_BINARY_ENDIAN_NATIVE:
+        newEndian = XdmfBinaryController::NATIVE;
+        break;
+      case XDMF_BINARY_ENDIAN_LITTLE:
+        newEndian = XdmfBinaryController::LITTLE;
+        break;
+      case XDMF_BINARY_ENDIAN_BIG:
+        newEndian = XdmfBinaryController::BIG;
+        break;
+      default:
+        break;
+    }
+    shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                               mOrigin->getArrayType(),
+                                                                               newEndian,
+                                                                               seek,
+                                                                               std::vector<unsigned int>(1, start),
+                                                                               std::vector<unsigned int>(1, stride),
+                                                                               std::vector<unsigned int>(1, numValues),
+                                                                               std::vector<unsigned int>(1, dataspace));
+
+    while (mOrigin->getNumberHeavyDataControllers() > 0)
+    {
+      mOrigin->removeHeavyDataController(0);
+    }
+
+    mOrigin->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Must set Origin before hdf5 linkage can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setPreviousOrigin(const int index)
+{
+  if (index < (int)mPreviousOrigins.size()) {
+    mOrigin = mPreviousOrigins[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of bounds.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousOrigins()
+{
+  mPreviousOrigins.clear();
+}
+
+void
+XdmfFortran::modifyOriginValues(void * values,
+                                const int arrayType,
+                                const int numValues,
+                                const int startIndex,
+                                const int arrayStride,
+                                const int valueStride)
+{
+  if(mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set origin before its values can be modified.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mOrigin->isInitialized()) {
+      mOrigin->read();
+    }
+    writeToArray(mOrigin,
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+}
+
+void
+XdmfFortran::retrieveOriginTag(char * tag, const int tagLength)
+{
+  if (mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set origin before its tag can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    char * tempTag = strdup(mOrigin->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+}
+
+int
+XdmfFortran::retrieveOriginValueType()
+{
+  if (mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set origin before its value type"
+                         " can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    shared_ptr<const XdmfArrayType> dataType = mOrigin->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Origin Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Origin Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveOriginValues(void * values,
+                                  const int dataType,
+                                  const int numberRead,
+                                  const int startIndex,
+                                  const int arrayStride,
+                                  const int valueStride)
+{
+  if(mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set origin before its values can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mOrigin->isInitialized()) {
+      mOrigin->read();
+    }
+    readFromArray(mOrigin,
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveOriginSize()
+{
+  if (mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set origin before its size can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mOrigin->getSize();
+  }
+}
+
+int
+XdmfFortran::retrieveOriginNumProperties()
+{
+  if (mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set origin before the number of properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mOrigin->getItemProperties().size();
+  } 
+}
+
+void
+XdmfFortran::retrieveOriginProperty(const int index,
+                                    char * key,
+                                    const int keyLength,
+                                    char * value,
+                                    const int valueLength)
+{
+  if (mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Origin before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (index < (int)mOrigin->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mOrigin->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveOriginPropertyByKey(char * key, char * value, const int valueLength)
+{
+  if (mOrigin == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set origin before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mOrigin->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mOrigin->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+}
+
+int
+XdmfFortran::setBrick(const int numValues, const int arrayType, void * pointValues)
+{
+  mBrick = XdmfArray::New();
+
+  // insert brick values into array
+  writeToArray(mBrick, numValues, arrayType, pointValues);
+
+  int id = mPreviousBricks.size();
+  mPreviousBricks.push_back(mBrick);
+  return id;
+}
+
+void
+XdmfFortran::clearBrickHeavyData()
+{
+  if (!mBrick) {
+    while (mBrick->getNumberHeavyDataControllers() > 0)
+    {
+      mBrick->removeHeavyDataController(0);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set Brick before hdf5 linkage"
+                         " can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setBrickHDF5(const char * hdf5File,
+                          const char * hdf5Dataset,
+                          const unsigned int start,
+                          const unsigned int stride,
+                          const unsigned int numValues,
+                          const unsigned int dataspace)
+{
+  if (mBrick) {
+    shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                           std::string(hdf5Dataset),
+                                                                           mBrick->getArrayType(),
+                                                                           std::vector<unsigned int>(1, start),
+                                                                           std::vector<unsigned int>(1, stride),
+                                                                           std::vector<unsigned int>(1, numValues),
+                                                                           std::vector<unsigned int>(1, dataspace));
+
+    while (mBrick->getNumberHeavyDataControllers() > 0)
+    {
+      mBrick->removeHeavyDataController(0);
+    }
+
+    mBrick->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set Brick before hdf5 linkage"
+                         " can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setBrickBinary(const char * binFile,
+                                const int endian,
+                                const unsigned int seek,
+                                const unsigned int start,
+                                const unsigned int stride,
+                                const unsigned int numValues,
+                                const unsigned int dataspace)
+{
+  if (!mBrick) {
+    XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+    switch (endian) {
+      case XDMF_BINARY_ENDIAN_NATIVE:
+        newEndian = XdmfBinaryController::NATIVE;
+        break;
+      case XDMF_BINARY_ENDIAN_LITTLE:
+        newEndian = XdmfBinaryController::LITTLE;
+        break;
+      case XDMF_BINARY_ENDIAN_BIG:
+        newEndian = XdmfBinaryController::BIG;
+        break;
+      default:
+        break;
+    }
+    shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                               mBrick->getArrayType(),
+                                                                               newEndian,
+                                                                               seek,
+                                                                               std::vector<unsigned int>(1, start),
+                                                                               std::vector<unsigned int>(1, stride),
+                                                                               std::vector<unsigned int>(1, numValues),
+                                                                               std::vector<unsigned int>(1, dataspace));
+
+    while (mBrick->getNumberHeavyDataControllers() > 0)
+    {
+      mBrick->removeHeavyDataController(0);
+    }
+
+    mBrick->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set Brick before hdf5 linkage"
+                         " can be established.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setPreviousBrick(const int index)
+{
+  if (index < (int)mPreviousBricks.size()) {
+    mBrick = mPreviousBricks[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of bounds.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousBricks()
+{
+  mPreviousBricks.clear();
+}
+
+void
+XdmfFortran::modifyBrickValues(void * values,
+                               const int arrayType,
+                               const int numValues,
+                               const int startIndex,
+                               const int arrayStride,
+                               const int valueStride)
+{
+  if(mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Must set brick before its values can be modified.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mBrick->isInitialized()) {
+      mBrick->read();
+    }
+    writeToArray(mBrick,
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+}
+
+void
+XdmfFortran::retrieveBrickTag(char * tag, const int tagLength)
+{
+  if (mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set Brick before its tag can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    char * tempTag = strdup(mBrick->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+}
+
+int
+XdmfFortran::retrieveBrickValueType()
+{
+  if (mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set brick before its value type can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    shared_ptr<const XdmfArrayType> dataType = mBrick->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Brick Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Brick Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveBrickValues(void * values,
+                                 const int dataType,
+                                 const int numberRead,
+                                 const int startIndex,
+                                 const int arrayStride,
+                                 const int valueStride)
+{
+  if(mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set brick before its values can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (!mBrick->isInitialized()) {
+      mBrick->read();
+    }
+    readFromArray(mBrick,
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+}
+
+int
+XdmfFortran::retrieveBrickSize()
+{
+  if (mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set brick before its size can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mBrick->getSize();
+  }
+}
+
+int
+XdmfFortran::retrieveBrickNumProperties()
+{
+  if (mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set brick before the number of properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+  else {
+    return mBrick->getItemProperties().size();
+  } 
+}
+
+void
+XdmfFortran::retrieveBrickProperty(const int index,
+                                   char * key,
+                                   const int keyLength,
+                                   char * value,
+                                   const int valueLength)
+{
+  if (mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set brick before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    if (index < (int)mBrick->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mBrick->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveBrickPropertyByKey(char * key, char * value, const int valueLength)
+{
+  if (mBrick == NULL) {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Must set brick before the properties"
+                         " it contains can be retrieved.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  else {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mBrick->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mBrick->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+}
+
+void
+XdmfFortran::addMap(char * name)
+{
+  shared_ptr<XdmfMap> addedMap = XdmfMap::New();
+  addedMap->setName(name);
+  mMaps.push_back(addedMap);
+}
+
+int
+XdmfFortran::retrieveNumMaps()
+{
+  return mMaps.size();
+}
+
+void
+XdmfFortran::clearMaps()
+{
+  mMaps.clear();
+}
+
+void
+XdmfFortran::retrieveMapTag(const int index, char * tag, const int tagLength)
+{
+  if (index < (int)mMaps.size()) {
+    char * tempTag = strdup(mMaps[index]->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::addRemoteNodeID(const int index, int localNodeID, int remoteTaskID, int remoteLocalNodeID)
+{
+  mMaps[index]->insert(remoteTaskID, localNodeID, remoteLocalNodeID);
+}
+
+void
+XdmfFortran::retrieveRemoteNodeIDs(const int index, const int localNodeID, const int remoteTaskID, int * remoteNodeIDs)
+{
+  if ((int)mMaps.size()>index) {
+    if (!mMaps[index]->isInitialized()) {
+      mMaps[index]->read();
+    }
+    if (mMaps[index]->getRemoteNodeIds(remoteTaskID).count(localNodeID)>0) {
+      std::set<int> returnSet = mMaps[index]->getRemoteNodeIds(remoteTaskID)[localNodeID];
+      std::set<int>::iterator walker;
+      int i = 0;
+      for (walker = returnSet.begin(); walker != returnSet.end();walker++) {
+        remoteNodeIDs[i] =  *walker;
+        i++;
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "The map does not contain a remote ID for the"
+                           " requested node.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of Range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveNumRemoteNodeIDs(const int index, const int localNodeID, const int remoteTaskID)
+{
+  if ((int)mMaps.size()<index) {
+    if (!mMaps[index]->isInitialized()) {
+      mMaps[index]->read();
+    }
+    if (mMaps[index]->getRemoteNodeIds(remoteTaskID).count(localNodeID)>0) {
+      return mMaps[index]->getRemoteNodeIds(remoteTaskID)[localNodeID].size();
+    }
+    else {
+      return 0;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of Range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+int
+XdmfFortran::storeMap(const int index)
+{
+  if (index < (int)mMaps.size()) {
+    int id = mPreviousMaps.size();
+    mPreviousMaps.push_back(mMaps[index]);
+    return id;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of Range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::addPreviousMap(const int index)
+{
+  if (index < (int)mPreviousMaps.size()) {
+    mMaps.push_back(mPreviousMaps[index]);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousMaps()
+{
+  mPreviousMaps.clear();
+}
+
+void
+XdmfFortran::removeMap(const int index)
+{ 
+  if (index < (int)mMaps.size()) {
+    mMaps.erase(mMaps.begin()+index);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveMapNumProperties(const int index)
+{
+  if (index < (int)mMaps.size()) {
+    return mMaps[index]->getItemProperties().size();
+  } 
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveMapProperty(const int mapIndex,
+                                 const int index,
+                                 char * key,
+                                 const int keyLength,
+                                 char * value,
+                                 const int valueLength)
+{
+  if (mapIndex < (int)mMaps.size()) {
+    if (index < (int)mMaps[index]->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mMaps[index]->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveMapPropertyByKey(const int index,
+                                      char * key,
+                                      char * value,
+                                      const int valueLength)
+{
+  if (index < (int)mMaps.size()) {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mMaps[index]->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mMaps[index]->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL, 
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveNumAttributes()
+{
+  return mAttributes.size();
+}
+
+void
+XdmfFortran::clearAttributes()
+{
+  mAttributes.clear();
+}
+
+void
+XdmfFortran::retrieveAttributeTag(const int index, char * tag, const int tagLength)
+{
+  if (index < (int)mAttributes.size()) {
+    char * tempTag = strdup(mAttributes[index]->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveAttributeName(const int index, char * name, const int nameLength)
+{
+  if (index < (int)mAttributes.size()) {
+    char * tempName = strdup(mAttributes[index]->getName().c_str());
+    memset(name, 0, nameLength);
+    memcpy(name, tempName, strlen(tempName)+1);
+    delete [] tempName;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveAttributeValueType(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    shared_ptr<const XdmfArrayType> dataType = mAttributes[index]->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Attribute Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Attribute Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveAttributeValues(const int index,
+                                     void * values,
+                                     const int dataType,
+                                     const int numberRead,
+                                     const int startIndex,
+                                     const int arrayStride,
+                                     const int valueStride)
+{
+  if (index < (int)mAttributes.size()) {
+    if (!mAttributes[index]->isInitialized()) {
+      mAttributes[index]->read();
+    }
+    readFromArray(mAttributes[index],
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeAttribute(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    mAttributes.erase(mAttributes.begin()+index);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  } 
+}
+
+void
+XdmfFortran::replaceAttribute(const int index,
+                              char * name,
+                              int attributeCenter,
+                              int attributeType,
+                              const int numValues,
+                              const int arrayType,
+                              void * values)
+{
+  if (index < (int)mAttributes.size()) {
+    shared_ptr<XdmfAttribute> currAttribute = XdmfAttribute::New();
+    currAttribute->setName(name);
+    switch(attributeCenter) {
+      case XDMF_ATTRIBUTE_CENTER_GRID:
+        currAttribute->setCenter(XdmfAttributeCenter::Grid());
+        break;
+      case XDMF_ATTRIBUTE_CENTER_CELL:
+        currAttribute->setCenter(XdmfAttributeCenter::Cell());
+        break;
+      case XDMF_ATTRIBUTE_CENTER_FACE:
+        currAttribute->setCenter(XdmfAttributeCenter::Face());
+        break;
+      case XDMF_ATTRIBUTE_CENTER_EDGE:
+        currAttribute->setCenter(XdmfAttributeCenter::Edge());
+        break;
+      case XDMF_ATTRIBUTE_CENTER_NODE:
+        currAttribute->setCenter(XdmfAttributeCenter::Node());
+        break;
+      default:
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Invalid attribute center");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+    }
+
+    switch(attributeType) {
+      case XDMF_ATTRIBUTE_TYPE_SCALAR:
+        currAttribute->setType(XdmfAttributeType::Scalar());
+        break;
+      case XDMF_ATTRIBUTE_TYPE_VECTOR:
+        currAttribute->setType(XdmfAttributeType::Vector());
+        break;
+      case XDMF_ATTRIBUTE_TYPE_TENSOR:
+        currAttribute->setType(XdmfAttributeType::Tensor());
+        break;
+      case XDMF_ATTRIBUTE_TYPE_MATRIX:
+        currAttribute->setType(XdmfAttributeType::Matrix());
+        break;
+      case XDMF_ATTRIBUTE_TYPE_TENSOR6:
+        currAttribute->setType(XdmfAttributeType::Tensor6());
+        break;
+      case XDMF_ATTRIBUTE_TYPE_GLOBALID:
+        currAttribute->setType(XdmfAttributeType::GlobalId());
+        break;
+      default:
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Invalid attribute type");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+    }
+
+    writeToArray(currAttribute, numValues, arrayType, values);
+    mAttributes[index] = currAttribute;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  } 
+}
+
+void
+XdmfFortran::openAttribute(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    int i;
+    shared_ptr<XdmfAttribute> openedAttribute = mAttributes[index];
+    int n = openedAttribute->getNumberInformations();
+    shared_ptr<XdmfInformation> openedInformation;
+    for (i = 0; i < n; i++) {
+      openedInformation = openedAttribute->getInformation(i);
+      mInformations.push_back(openedInformation);
+      mPreviousInformations.push_back(openedInformation);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveAttributeSize(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    return mAttributes[index]->getSize();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+int
+XdmfFortran::retrieveAttributeType(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    shared_ptr<const XdmfAttributeType> returnType =
+      mAttributes[index]->getType();
+    if (returnType == XdmfAttributeType::Scalar()) {
+      return XDMF_ATTRIBUTE_TYPE_SCALAR;
+    }
+    else if (returnType == XdmfAttributeType::Vector()) {
+      return XDMF_ATTRIBUTE_TYPE_VECTOR;
+    }
+    else if (returnType == XdmfAttributeType::Tensor()) {
+      return XDMF_ATTRIBUTE_TYPE_TENSOR;
+    }
+    else if (returnType == XdmfAttributeType::Matrix()) {
+      return XDMF_ATTRIBUTE_TYPE_MATRIX;
+    }
+    else if (returnType == XdmfAttributeType::Tensor6()) {
+      return XDMF_ATTRIBUTE_TYPE_TENSOR6;
+    }
+    else if (returnType == XdmfAttributeType::GlobalId()) {
+      return XDMF_ATTRIBUTE_TYPE_GLOBALID;
+    }
+    else {
+      return XDMF_ATTRIBUTE_TYPE_NOTYPE;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+int
+XdmfFortran::retrieveAttributeCenter(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    shared_ptr<const XdmfAttributeCenter> returnCenter =
+      mAttributes[index]->getCenter();
+    if (returnCenter == XdmfAttributeCenter::Grid()) {
+      return XDMF_ATTRIBUTE_CENTER_GRID;
+    }
+    else if (returnCenter == XdmfAttributeCenter::Cell()) {
+      return XDMF_ATTRIBUTE_CENTER_CELL;
+    }
+    else if (returnCenter == XdmfAttributeCenter::Face()) {
+      return XDMF_ATTRIBUTE_CENTER_FACE;
+    }
+    else if (returnCenter == XdmfAttributeCenter::Edge()) {
+      return XDMF_ATTRIBUTE_CENTER_EDGE;
+    }
+    else if (returnCenter == XdmfAttributeCenter::Node()) {
+      return XDMF_ATTRIBUTE_CENTER_NODE;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid Attribute Center.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::clearPreviousAttributes()
+{
+  mPreviousAttributes.clear();
+}
+
+void
+XdmfFortran::modifyAttributeValues(const int index,
+                                   void * values,
+                                   const int arrayType,
+                                   const int numValues,
+                                   const int startIndex,
+                                   const int arrayStride,
+                                   const int valueStride)
+{
+  if (index < (int)mAttributes.size()) {
+    if (!mAttributes[index]->isInitialized()) {
+      mAttributes[index]->read();
+    }
+    writeToArray(mAttributes[index],
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveAttributeNumProperties(const int index)
+{
+  if (index < (int)mAttributes.size()) {
+    return mAttributes[index]->getItemProperties().size();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  } 
+}
+
+void
+XdmfFortran::retrieveAttributeProperty(const int attributeIndex,
+                                       const int index,
+                                       char * key,
+                                       const int keyLength,
+                                       char * value,
+                                       const int valueLength)
+{
+  if (attributeIndex < (int)mAttributes.size()) {
+    if (index < (int)mAttributes[attributeIndex]->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mAttributes[attributeIndex]->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Property index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveAttributePropertyByKey(const int index,
+                                            char * key,
+                                            char * value,
+                                            const int valueLength)
+{
+  if (index < (int)mAttributes.size()) {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mAttributes[index]->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mAttributes[index]->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setAttributeAsVariable(char * varname, int index)
+{
+  if (index < (int)mAttributes.size()) {
+    std::string newVar = varname;
+    mVariableSet[newVar] = mAttributes[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setAttributeAsSubsetReference(int index)
+{
+  if (index < (int)mAttributes.size()) {
+    mSubsetReference = mAttributes[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::addCoordinate(char * name, const int numValues, const int arrayType, void * values)
+{
+  shared_ptr<XdmfArray> currArray = XdmfArray::New();
+  currArray->setName(name);
+
+  writeToArray(currArray, numValues, arrayType, values);
+
+  mCoordinates.push_back(currArray);
+
+  const int id = mPreviousCoordinates.size();
+  mPreviousCoordinates.push_back(currArray);
+  return id;
+}
+
+void
+XdmfFortran::addPreviousCoordinate(const int index)
+{
+  if (index < (int)mPreviousCoordinates.size()) {
+    mCoordinates.push_back(mPreviousCoordinates[index]);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearCoordinateHeavyData(const int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    while (mCoordinates[index]->getNumberHeavyDataControllers() > 0)
+    {
+      mCoordinates[index]->removeHeavyDataController(0);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setCoordinateHDF5(const int index,
+                               const char * hdf5File,
+                               const char * hdf5Dataset,
+                               const unsigned int start,
+                               const unsigned int stride,
+                               const unsigned int numValues,
+                               const unsigned int dataspace)
+{
+  if (index < (int)mCoordinates.size()) {
+    shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                         std::string(hdf5Dataset),
+                                                                         mCoordinates[index]->getArrayType(),
+                                                                         std::vector<unsigned int>(1, start),
+                                                                         std::vector<unsigned int>(1, stride),
+                                                                         std::vector<unsigned int>(1, numValues),
+                                                                         std::vector<unsigned int>(1, dataspace));
+
+    while (mCoordinates[index]->getNumberHeavyDataControllers() > 0)
+    {
+      mCoordinates[index]->removeHeavyDataController(0);
+    }
+
+    mCoordinates[index]->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setCoordinateBinary(const int index,
+                               const char * binFile,
+                                const int endian,
+                                const unsigned int seek,
+                                const unsigned int start,
+                                const unsigned int stride,
+                                const unsigned int numValues,
+                                const unsigned int dataspace)
+{
+  if (index < (int)mCoordinates.size()) {
+    XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+    switch (endian) {
+      case XDMF_BINARY_ENDIAN_NATIVE:
+        newEndian = XdmfBinaryController::NATIVE;
+        break;
+      case XDMF_BINARY_ENDIAN_LITTLE:
+        newEndian = XdmfBinaryController::LITTLE;
+        break;
+      case XDMF_BINARY_ENDIAN_BIG:
+        newEndian = XdmfBinaryController::BIG;
+        break;
+      default:
+        break;
+    }
+    shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                               mCoordinates[index]->getArrayType(),
+                                                                               newEndian,
+                                                                               seek,
+                                                                               std::vector<unsigned int>(1, start),
+                                                                               std::vector<unsigned int>(1, stride),
+                                                                               std::vector<unsigned int>(1, numValues),
+                                                                               std::vector<unsigned int>(1, dataspace));
+
+    while (mCoordinates[index]->getNumberHeavyDataControllers() > 0)
+    {
+      mCoordinates[index]->removeHeavyDataController(0);
+    }
+
+    mCoordinates[index]->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousCoordinates()
+{
+  mPreviousCoordinates.clear();
+}
+
+void
+XdmfFortran::modifyCoordinateValues(const int index,
+                                    void * values,
+                                    const int arrayType,
+                                    const int numValues,
+                                    const int startIndex,
+                                    const int arrayStride,
+                                    const int valueStride)
+{
+  if (index < (int)mCoordinates.size()) {
+    if (!mCoordinates[index]->isInitialized()) {
+      mCoordinates[index]->read();
+    }
+    writeToArray(mCoordinates[index],
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveNumCoordinates()
+{
+  return mCoordinates.size();
+}
+
+void
+XdmfFortran::retrieveCoordinateTag(const int index, char * tag, const int tagLength)
+{
+  if (index < (int)mCoordinates.size()) {
+    char * tempTag = strdup(mCoordinates[index]->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveCoordinateName(const int index, char * name, const int nameLength)
+{
+  if (index < (int)mCoordinates.size()) {
+    char * tempName = strdup(mCoordinates[index]->getName().c_str());
+    memset(name, 0, nameLength);
+    memcpy(name, tempName, strlen(tempName)+1);
+    delete [] tempName;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveCoordinateValueType(const int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    shared_ptr<const XdmfArrayType> dataType = mCoordinates[index]->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Coordinate Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Coordinate Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveCoordinateValues(const int index,
+                                      void * values,
+                                      const int dataType,
+                                      const int numberRead,
+                                      const int startIndex,
+                                      const int arrayStride,
+                                      const int valueStride)
+{
+  if (index < (int)mCoordinates.size()) {
+    if (!mCoordinates[index]->isInitialized()) {
+      mCoordinates[index]->read();
+    }
+    readFromArray(mCoordinates[index],
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeCoordinate(const int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    mCoordinates.erase(mCoordinates.begin()+index);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  } 
+}
+
+void
+XdmfFortran::replaceCoordinate(const int index,
+                               char * name,
+                               const int numValues,
+                               const int arrayType,
+                               void * values)
+{
+  if (index < (int)mCoordinates.size()) {
+    shared_ptr<XdmfArray> currArray = XdmfArray::New();
+    currArray->setName(name);
+    writeToArray(currArray, numValues, arrayType, values);
+    mCoordinates[index] = currArray;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveCoordinateSize(const int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    return mCoordinates[index]->getSize();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::clearCoordinates()
+{
+  mCoordinates.clear();
+}
+
+int
+XdmfFortran::retrieveCoordinateNumProperties(const int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    return mCoordinates[index]->getItemProperties().size();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  } 
+}
+
+void
+XdmfFortran::retrieveCoordinateProperty(const int coordinateIndex,
+                                        const int index,
+                                        char * key,
+                                        const int keyLength,
+                                        char * value,
+                                        const int valueLength)
+{
+  if (coordinateIndex < (int)mCoordinates.size()) {
+    if (index < (int)mCoordinates[coordinateIndex]->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mCoordinates[coordinateIndex]->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Property index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveCoordinatePropertyByKey(const int index,
+                                             char * key,
+                                             char * value,
+                                             const int valueLength)
+{
+  if (index < (int)mCoordinates.size()) {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mCoordinates[index]->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mCoordinates[index]->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setCoordinateAsVariable(char * varname, int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    std::string newVar = varname;
+    mVariableSet[newVar] = mCoordinates[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setCoordinateAsSubsetReference(int index)
+{
+  if (index < (int)mCoordinates.size()) {
+    mSubsetReference = mCoordinates[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int 
+XdmfFortran::addSet(char * name,
+                    const int newSetType,
+                    void * values,
+                    const int numValues,
+                    const int arrayType)
+{
+  const shared_ptr<XdmfSet> newSet = XdmfSet::New();
+  newSet->setName(name);
+
+  switch (newSetType) {
+    case XDMF_SET_TYPE_NODE:
+      newSet->setType(XdmfSetType::Node());
+      break;
+    case XDMF_SET_TYPE_CELL:
+      newSet->setType(XdmfSetType::Cell());
+      break;
+    case XDMF_SET_TYPE_FACE:
+      newSet->setType(XdmfSetType::Face());
+      break;
+    case XDMF_SET_TYPE_EDGE:
+      newSet->setType(XdmfSetType::Edge());
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid set type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+  }
+
+  for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+      mAttributes.begin(); 
+      iter != mAttributes.end();
+      ++iter) {
+    newSet->insert(*iter);
+  }
+  mAttributes.clear();
+
+  if (!mInformations.empty()) {
+    for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin(); 
+        iter != mInformations.end();
+        ++iter) {
+      newSet->insert(*iter);
+    }
+    mInformations.clear();
+  }
+
+  writeToArray(newSet, numValues, arrayType, values);
+
+  mSets.push_back(newSet);
+  int id = mPreviousSets.size();
+  mPreviousSets.push_back(newSet);
+  return id;
+}
+
+void
+XdmfFortran::clearSetHeavyData(const int index)
+{
+  if (index < (int)mSets.size()) {
+    while (mSets[index]->getNumberHeavyDataControllers() > 0)
+    {
+      mSets[index]->removeHeavyDataController(0);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setSetHDF5(const int index,
+                        const char * hdf5File,
+                        const char * hdf5Dataset,
+                        const unsigned int start,
+                        const unsigned int stride,
+                        const unsigned int numValues,
+                        const unsigned int dataspace)
+{
+  if (index < (int)mSets.size()) {
+    shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                         std::string(hdf5Dataset),
+                                                                         mSets[index]->getArrayType(),
+                                                                         std::vector<unsigned int>(1, start),
+                                                                         std::vector<unsigned int>(1, stride),
+                                                                         std::vector<unsigned int>(1, numValues),
+                                                                         std::vector<unsigned int>(1, dataspace));
+
+    while (mSets[index]->getNumberHeavyDataControllers() > 0)
+    {
+      mSets[index]->removeHeavyDataController(0);
+    }
+
+    mSets[index]->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setSetBinary(const int index,
+                          const char * binFile,
+                          const int endian,
+                          const unsigned int seek,
+                          const unsigned int start,
+                          const unsigned int stride,
+                          const unsigned int numValues,
+                          const unsigned int dataspace)
+{
+  if (index < (int)mSets.size()) {
+    XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+    switch (endian) {
+      case XDMF_BINARY_ENDIAN_NATIVE:
+        newEndian = XdmfBinaryController::NATIVE;
+        break;
+      case XDMF_BINARY_ENDIAN_LITTLE:
+        newEndian = XdmfBinaryController::LITTLE;
+        break;
+      case XDMF_BINARY_ENDIAN_BIG:
+        newEndian = XdmfBinaryController::BIG;
+        break;
+      default:
+        break;
+    }
+    shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                               mSets[index]->getArrayType(),
+                                                                               newEndian,
+                                                                               seek,
+                                                                               std::vector<unsigned int>(1, start),
+                                                                               std::vector<unsigned int>(1, stride),
+                                                                               std::vector<unsigned int>(1, numValues),
+                                                                               std::vector<unsigned int>(1, dataspace));
+
+    while (mSets[index]->getNumberHeavyDataControllers() > 0)
+    {
+      mSets[index]->removeHeavyDataController(0);
+    }
+
+    mSets[index]->insert(newController);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearSets()
+{
+  mSets.clear();
+}
+
+void
+XdmfFortran::addPreviousSet(const int index)
+{
+  if (index < (int)mPreviousSets.size()) {
+    mSets.push_back(mPreviousSets[index]);
+  }
+  else
+  {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousSets()
+{
+  mPreviousSets.clear();
+}
+
+void
+XdmfFortran::modifySetValues(const int index,
+                             void * values,
+                             const int arrayType,
+                             const int numValues,
+                             const int startIndex,
+                             const int arrayStride,
+                             const int valueStride)
+{
+  if (index < (int)mSets.size()) {
+    if (!mSets[index]->isInitialized()) {
+      mSets[index]->read();
+    }
+    writeToArray(mSets[index],
+                 numValues,
+                 arrayType,
+                 values,
+                 startIndex,
+                 arrayStride,
+                 valueStride);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveSetTag(const int index, char * tag, const int tagLength)
+{
+  if (index < (int)mSets.size()) {
+    char * tempTag = strdup(mSets[index]->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveSetName(const int index, char * name, const int nameLength)
+{
+  if (index < (int)mSets.size()) {
+    char * tempName = strdup(mSets[index]->getName().c_str());
+    memset(name, 0, nameLength);
+    memcpy(name, tempName, strlen(tempName)+1);
+    delete [] tempName;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveNumSets()
+{
+  return mSets.size();
+}
+
+int
+XdmfFortran::retrieveSetSize(const int index)
+{
+  if (index < (int)mSets.size()) {
+    return mSets[index]->getSize();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+int
+XdmfFortran::retrieveSetValueType(const int index)
+{
+  if (index < (int)mSets.size()) {
+    shared_ptr<const XdmfArrayType> dataType = mSets[index]->getArrayType();
+    if (dataType == XdmfArrayType::Int8()) {
+      return XDMF_ARRAY_TYPE_INT8;
+    }
+    else if (dataType == XdmfArrayType::Int16()) {
+      return XDMF_ARRAY_TYPE_INT16;
+    }
+    else if (dataType == XdmfArrayType::Int32()) {
+      return XDMF_ARRAY_TYPE_INT32;
+    }
+    else if (dataType == XdmfArrayType::Int64()) {
+      return XDMF_ARRAY_TYPE_INT64;
+    }
+    else if (dataType == XdmfArrayType::UInt8()) {
+      return XDMF_ARRAY_TYPE_UINT8;
+    }
+    else if (dataType == XdmfArrayType::UInt16()) {
+      return XDMF_ARRAY_TYPE_UINT16;
+    }
+    else if (dataType == XdmfArrayType::UInt32()) {
+      return XDMF_ARRAY_TYPE_UINT32;
+    }
+    else if (dataType == XdmfArrayType::Float32()) {
+      return XDMF_ARRAY_TYPE_FLOAT32;
+    }
+    else if (dataType == XdmfArrayType::Float64()) {
+      return XDMF_ARRAY_TYPE_FLOAT64;
+    }
+    else if (dataType == XdmfArrayType::Uninitialized()) {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Uninitialized Set Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid Set Data Type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveSetValues(const int index,
+                               void * values,
+                               const int dataType,
+                               const int numberRead,
+                               const int startIndex,
+                               const int arrayStride,
+                               const int valueStride)
+{
+  if (index < (int)mSets.size()) {
+    if (!mSets[index]->isInitialized()) {
+      mSets[index]->read();
+    }
+    readFromArray(mSets[index],
+                  dataType,
+                  values,
+                  numberRead,
+                  startIndex,
+                  arrayStride,
+                  valueStride);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveSetType(const int index)
+{
+  if (index < (int)mSets.size()) {
+    shared_ptr<const XdmfSetType> returnType = mSets[index]->getType();
+    if (returnType == XdmfSetType::Node()) {
+      return XDMF_SET_TYPE_NODE;
+    }
+    else if (returnType == XdmfSetType::Cell()) {
+      return XDMF_SET_TYPE_CELL;
+    }
+    else if (returnType == XdmfSetType::Face()) {
+      return XDMF_SET_TYPE_FACE;
+    }
+    else if (returnType == XdmfSetType::Edge()) {
+      return XDMF_SET_TYPE_EDGE;
+    }
+    else if (returnType == XdmfSetType::NoSetType()) {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Uninitialized set type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Invalid set type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::openSet(const int index, const int openAttribute, const int openInformation)
+{
+  if (index < (int)mSets.size()) {
+    shared_ptr<XdmfSet> openedSet = mSets[index];
+    int i;
+    int n;
+    n = openedSet->getNumberAttributes();
+    if (openAttribute) {
+      shared_ptr<XdmfAttribute> openedAttribute;
+      for (i = 0; i < n; i++) {
+        openedAttribute = openedSet->getAttribute(i);
+        mAttributes.push_back(openedAttribute);
+        mPreviousAttributes.push_back(openedAttribute);
+      }
+    }
+    if (openInformation) {
+      n = openedSet->getNumberInformations();
+      shared_ptr<XdmfInformation> openedInformation;
+      for (i = 0; i < n; i++) {
+        openedInformation = openedSet->getInformation(i);
+        mInformations.push_back(openedInformation);
+        mPreviousInformations.push_back(openedInformation);
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeSet(const int index)
+{
+  if (index < (int)mSets.size()) {
+    mSets.erase(mSets.begin()+index);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void 
+XdmfFortran::replaceSet(const int index,
+                        char * name,
+                        const int newSetType,
+                        void * values,
+                        const int numValues,
+                        const int arrayType)
+{
+  const shared_ptr<XdmfSet> newSet = XdmfSet::New();
+  newSet->setName(name);
+
+  switch (newSetType) {
+    case XDMF_SET_TYPE_NODE:
+      newSet->setType(XdmfSetType::Node());
+      break;
+    case XDMF_SET_TYPE_CELL:
+      newSet->setType(XdmfSetType::Cell());
+      break;
+    case XDMF_SET_TYPE_FACE:
+      newSet->setType(XdmfSetType::Face());
+      break;
+    case XDMF_SET_TYPE_EDGE:
+      newSet->setType(XdmfSetType::Edge());
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL, 
+                           "Invalid set type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+  }
+
+  for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+      mAttributes.begin(); 
+      iter != mAttributes.end();
+      ++iter) {
+    newSet->insert(*iter);
+  }
+  mAttributes.clear();
+
+  if (!mInformations.empty()) {
+    for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin(); 
+        iter != mInformations.end();
+        ++iter) {
+      newSet->insert(*iter);
+    }
+    mInformations.clear();
+  }
+
+  writeToArray(newSet, numValues, arrayType, values);
+
+  mSets[index] = newSet;
+}
+
+int
+XdmfFortran::retrieveSetNumProperties(const int index)
+{
+  if (index < (int)mSets.size()) {
+    return mSets[index]->getItemProperties().size();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveSetProperty(const int setIndex,
+                                 const int index,
+                                 char * key,
+                                 const int keyLength,
+                                 char * value,
+                                 const int valueLength)
+{
+  if (setIndex < (int)mSets.size()) {
+    if (index < (int)mSets[setIndex]->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker = mSets[setIndex]->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Property index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveSetPropertyByKey(const int index,
+                                      char * key,
+                                      char * value,
+                                      const int valueLength)
+{
+  if (index < (int)mSets.size()) {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mSets[index]->getItemProperties().count(tempString))>0) {
+      char * tempValue = strdup(mSets[index]->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setSetAsVariable(char * varname, int index)
+{
+  if (index < (int)mSets.size()) {
+    std::string newVar = varname;
+    mVariableSet[newVar] = mSets[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setSetAsSubsetReference(int index)
+{
+  if (index < (int)mSets.size()) {
+    mSubsetReference = mSets[index];
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveNumInformation()
+{
+  return mInformations.size();
+}
+
+void
+XdmfFortran::clearInformations()
+{
+  mInformations.clear();
+}
+
+void
+XdmfFortran::retrieveInformationTag(const int index, char * tag, const int tagLength)
+{
+  if (index < (int)mInformations.size()) {
+    char * tempTag = strdup(mInformations[index]->getItemTag().c_str());
+    memset(tag, 0, tagLength);
+    memcpy(tag, tempTag, strlen(tempTag)+1);
+    delete [] tempTag;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveInformation(const int index,
+                                 char * key,
+                                 const int keyLength,
+                                 char * value,
+                                 const int valueLength)
+{
+  if (index < (int)mInformations.size()) {
+    char * tempKey = strdup(mInformations[index]->getKey().c_str());
+    char * tempValue = strdup(mInformations[index]->getValue().c_str());
+    memset(key, 0, keyLength);
+    memset(value, 0, valueLength);
+    memcpy(key, tempKey, strlen(tempKey)+1);
+    memcpy(value, tempValue, strlen(tempValue)+1);
+    delete [] tempKey;
+    delete [] tempValue;
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::replaceInformation(const int index, char * key, char * value)
+{
+  if (index < (int)mInformations.size()) {
+    mInformations[index]->setKey(key);
+    mInformations[index]->setValue(value);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeInformation(const int index)
+{
+  if (index < (int)mInformations.size()) {
+    mInformations.erase(mInformations.begin()+index);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::openInformation(const int index)
+{
+  if (index < (int)mInformations.size()) {
+    shared_ptr<XdmfInformation> sourceInformation = mInformations[index];
+    int i;
+    int n = sourceInformation->getNumberInformations();
+    shared_ptr<XdmfInformation> openedInformation;
+    for (i = 0; i < n; i++) {
+      openedInformation = sourceInformation->getInformation(i);
+      mInformations.push_back(openedInformation);
+      mPreviousInformations.push_back(openedInformation);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveInformationByKey(char * key, char * value, const int valueLength)
+{
+  unsigned int i;
+  int found = 0;
+  std::string searchString(key);
+  char * tempValue;
+  for (i=0;i<mInformations.size();i++) {
+    if (searchString == mInformations[i]->getKey()) {
+      found = 1;
+      tempValue = strdup(mInformations[i]->getValue().c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      i = mInformations.size();
+      delete [] tempValue;
+    }
+  }
+  if (found == 0) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Item with specifed key does not exist.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::replaceInformationByKey(char * key, char * value)
+{
+  unsigned int i;
+  int found = 0;
+  std::string searchString(key);
+  for (i=0;i<mInformations.size();i++) {
+    if (searchString == mInformations[i]->getKey()) {
+      mInformations[i]->setValue(value);
+      i = mInformations.size();
+      found = 1;
+    }
+  }
+  if (found == 0) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Item with specifed key does not exist.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeInformationByKey(char * key)
+{
+  unsigned int i;
+  int found = 0;
+  std::string searchString(key);
+  for (i=0;i<mInformations.size();i++) {
+    if (searchString == mInformations[i]->getKey()) {
+      mInformations.erase(mInformations.begin()+i);
+      i = mInformations.size();
+      found = 1;
+    }
+  }
+  if (found == 0) {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Item with specifed key does not exist.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearPreviousInformation()
+{
+  mPreviousInformations.clear();
+}
+
+int
+XdmfFortran::retrieveInformationNumProperties(int const index)
+{
+  if (index < (int)mInformations.size()) {
+    return mInformations[index]->getItemProperties().size();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+    return -1;
+  }
+}
+
+void
+XdmfFortran::retrieveInformationProperty(const int informationIndex,
+                                         const int index,
+                                         char * key,
+                                         const int keyLength,
+                                         char * value,
+                                         const int valueLength)
+{
+  if (informationIndex < (int)mInformations.size()) {
+    if (index < (int)mInformations[informationIndex]->getItemProperties().size()) {
+      std::map<std::string, std::string>::iterator walker =
+        mInformations[informationIndex]->getItemProperties().begin();
+      for (int i = 0; i<index; i++) {
+        walker++;
+      }
+      char * tempKey = strdup((*walker).first.c_str());
+      memset(key, 0, keyLength);
+      memcpy(key, tempKey, strlen(tempKey)+1);
+      delete [] tempKey;
+      char * tempValue = strdup((*walker).second.c_str());
+      memset(value, 0, valueLength);
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Property index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::retrieveInformationPropertyByKey(const int index,
+                                              char * key,
+                                              char * value,
+                                              const int valueLength)
+{
+  if (index < (int)mInformations.size()) {
+    std::string tempString = key;
+    memset(value, 0, valueLength);
+    if ((mInformations[index]->getItemProperties().count(tempString))>0) {
+      char * tempValue =
+        strdup(mInformations[index]->getItemProperties()[tempString].c_str());
+      memcpy(value, tempValue, strlen(tempValue)+1);
+      delete [] tempValue;
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::addInformationArray(const int index,
+                                 char * name,
+                                 void * values,
+                                 const int numValues,
+                                 const int arrayType)
+{
+  if (index < (int)mInformations.size()) {
+    shared_ptr<XdmfArray> newArray = XdmfArray::New();
+    newArray->setName(name);
+    writeToArray(newArray, numValues, arrayType, values);
+    mInformations[index]->insert(newArray);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::clearInformationArrayHeavyData(const int index,
+                                            const int arrayIndex)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      shared_ptr<XdmfArray> modifiedArray =
+        mInformations[index]->getArray(arrayIndex);
+      while (modifiedArray->getNumberHeavyDataControllers() > 0)
+      {
+        modifiedArray->removeHeavyDataController(0);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setInformationArrayHDF5(const int index,
+                                     const int arrayIndex,
+                                     const char * hdf5File,
+                                     const char * hdf5Dataset,
+                                     const unsigned int start,
+                                     const unsigned int stride,
+                                     const unsigned int numValues,
+                                     const unsigned int dataspace)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      shared_ptr<XdmfArray> modifiedArray =
+        mInformations[index]->getArray(arrayIndex);
+      shared_ptr<XdmfHDF5Controller> newController = XdmfHDF5Controller::New(std::string(hdf5File),
+                                                                             std::string(hdf5Dataset),
+                                                                             modifiedArray->getArrayType(),
+                                                                             std::vector<unsigned int>(1, start),
+                                                                             std::vector<unsigned int>(1, stride),
+                                                                             std::vector<unsigned int>(1, numValues),
+                                                                             std::vector<unsigned int>(1, dataspace));
+      while (modifiedArray->getNumberHeavyDataControllers() > 0)
+      {
+        modifiedArray->removeHeavyDataController(0);
+      }
+
+      modifiedArray->insert(newController);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setInformationArrayBinary(const int index,
+                                       const int arrayIndex,
+                                       const char * binFile,
+                                       const int endian,
+                                       const unsigned int seek,
+                                       const unsigned int start,
+                                       const unsigned int stride,
+                                       const unsigned int numValues,
+                                       const unsigned int dataspace)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      shared_ptr<XdmfArray> modifiedArray =
+        mInformations[index]->getArray(arrayIndex);
+      XdmfBinaryController::Endian newEndian = XdmfBinaryController::NATIVE;
+      switch (endian) {
+        case XDMF_BINARY_ENDIAN_NATIVE:
+          newEndian = XdmfBinaryController::NATIVE;
+          break;
+        case XDMF_BINARY_ENDIAN_LITTLE:
+          newEndian = XdmfBinaryController::LITTLE;
+          break;
+        case XDMF_BINARY_ENDIAN_BIG:
+          newEndian = XdmfBinaryController::BIG;
+          break;
+        default:
+          break;
+      }
+      shared_ptr<XdmfBinaryController> newController = XdmfBinaryController::New(std::string(binFile),
+                                                                                 mDimensions->getArrayType(),
+                                                                                 newEndian,
+                                                                                 seek,
+                                                                                 std::vector<unsigned int>(1, start),
+                                                                                 std::vector<unsigned int>(1, stride),
+                                                                                 std::vector<unsigned int>(1, numValues),
+                                                                                 std::vector<unsigned int>(1, dataspace));
+      while (modifiedArray->getNumberHeavyDataControllers() > 0)
+      {
+        modifiedArray->removeHeavyDataController(0);
+      }
+
+      modifiedArray->insert(newController);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::insertInformationIntoInformation(const int toIndex,
+                                              const int fromIndex,
+                                              const bool removeFromArray)
+{
+  if (toIndex < (int)mInformations.size() && fromIndex < (int)mInformations.size()) {
+    if (toIndex != fromIndex) {
+      mInformations[toIndex]->insert(mInformations[fromIndex]);
+      if (removeFromArray) {
+        mInformations.erase(mInformations.begin()+fromIndex);
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Information may not be inserted into itself."
+                           " Doing so would cause an infinte loop when writing.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::modifyInformationArray(const int index,
+                                    const int arrayIndex,
+                                    void * values,
+                                    const int arrayType,
+                                    const int numValues,
+                                    const int insertStart,
+                                    const int arrayStride,
+                                    const int valueStride)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      shared_ptr<XdmfArray> modifiedArray =
+        mInformations[index]->getArray(arrayIndex);
+      if (!modifiedArray->isInitialized()) {
+        modifiedArray->read();
+      }
+      writeToArray(modifiedArray,
+                   numValues,
+                   arrayType,
+                   values,
+                   insertStart,
+                   arrayStride,
+                   valueStride);
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::removeInformationArray(const int index,
+                                    const int arrayIndex)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      mInformations[index]->removeArray(arrayIndex);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Array index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::retrieveInformationArraySize(const int index,
+                                          const int arrayIndex)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      return mInformations[index]->getArray(arrayIndex)->getSize();
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Array index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  return -1;
+}
+
+int
+XdmfFortran::retrieveInformationArrayValueType(const int index,
+                                               const int arrayIndex)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      shared_ptr<const XdmfArrayType> dataType = mInformations[index]->getArray(arrayIndex)->getArrayType();
+      if (dataType == XdmfArrayType::Int8()) {
+        return XDMF_ARRAY_TYPE_INT8;
+      }
+      else if (dataType == XdmfArrayType::Int16()) {
+        return XDMF_ARRAY_TYPE_INT16;
+      }
+      else if (dataType == XdmfArrayType::Int32()) {
+        return XDMF_ARRAY_TYPE_INT32;
+      }
+      else if (dataType == XdmfArrayType::Int64()) {
+        return XDMF_ARRAY_TYPE_INT64;
+      }
+      else if (dataType == XdmfArrayType::UInt8()) {
+        return XDMF_ARRAY_TYPE_UINT8;
+      }
+      else if (dataType == XdmfArrayType::UInt16()) {
+        return XDMF_ARRAY_TYPE_UINT16;
+      }
+      else if (dataType == XdmfArrayType::UInt32()) {
+        return XDMF_ARRAY_TYPE_UINT32;
+      }
+      else if (dataType == XdmfArrayType::Float32()) {
+        return XDMF_ARRAY_TYPE_FLOAT32;
+      }
+      else if (dataType == XdmfArrayType::Float64()) {
+        return XDMF_ARRAY_TYPE_FLOAT64;
+      }
+      else if (dataType == XdmfArrayType::Uninitialized()) {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Uninitialized Set Data Type.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        return -1;
+      }
+      else {
+        try {
+          XdmfError::message(XdmfError::FATAL,
+                             "Invalid Set Data Type.");
+        }
+        catch (XdmfError & e) {
+          throw e;
+        }
+        return -1;
+      }
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Array index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  return -1;
+}
+
+void
+XdmfFortran::retrieveInformationArrayValues(const int index,
+                                            const int arrayIndex,
+                                            void * values,
+                                            const int dataType,
+                                            const int numberRead,
+                                            const int startIndex,
+                                            const int arrayStride,
+                                            const int valueStride)
+{
+  if (index < (int)mInformations.size()) {
+    if (arrayIndex < (int)mInformations[index]->getNumberArrays()) {
+      if (!mInformations[index]->getArray(arrayIndex)->isInitialized()) {
+        mInformations[index]->getArray(arrayIndex)->read();
+      }
+      readFromArray(mInformations[index]->getArray(arrayIndex),
+                    dataType,
+                    values,
+                    numberRead,
+                    startIndex,
+                    arrayStride,
+                    valueStride);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Array index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setInformationArrayAsVariable(char * varname, int infoindex, int index)
+{
+  if (infoindex < (int)mInformations.size()) {
+    if (index < mInformations[infoindex]->getNumberArrays()) {
+      std::string newVar = varname;
+      mVariableSet[newVar] = mInformations[infoindex]->getArray(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::setInformationArrayAsSubsetReference(int infoindex, int index)
+{
+  if (infoindex < (int)mInformations.size()) {
+    if (index < mInformations[infoindex]->getNumberArrays()) {
+      mSubsetReference = mInformations[infoindex]->getArray(index);
+    }
+    else {
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Error: Index out of range.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::addFunctionAsAttribute(char * expression,
+                                    const char * const name,
+                                    const int attributeCenter,
+                                    const int attributeType)
+{
+  shared_ptr<XdmfAttribute> currAttribute = XdmfAttribute::New();
+  currAttribute->setName(name);
+
+  switch(attributeCenter) {
+  case XDMF_ATTRIBUTE_CENTER_GRID:
+    currAttribute->setCenter(XdmfAttributeCenter::Grid());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_CELL:
+    currAttribute->setCenter(XdmfAttributeCenter::Cell());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_FACE:
+    currAttribute->setCenter(XdmfAttributeCenter::Face());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_EDGE:
+    currAttribute->setCenter(XdmfAttributeCenter::Edge());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_NODE:
+    currAttribute->setCenter(XdmfAttributeCenter::Node());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid attribute center");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  switch(attributeType) {
+  case XDMF_ATTRIBUTE_TYPE_SCALAR:
+    currAttribute->setType(XdmfAttributeType::Scalar());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_VECTOR:
+    currAttribute->setType(XdmfAttributeType::Vector());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_TENSOR:
+    currAttribute->setType(XdmfAttributeType::Tensor());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_MATRIX:
+    currAttribute->setType(XdmfAttributeType::Matrix());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_TENSOR6:
+    currAttribute->setType(XdmfAttributeType::Tensor6());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_GLOBALID:
+    currAttribute->setType(XdmfAttributeType::GlobalId());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid attribute type");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin();
+      iter != mInformations.end();
+      ++iter) {
+    currAttribute->insert(*iter);
+  }
+  mInformations.clear();
+
+  // Set Function instead of setting values
+  std::string expressionstring = std::string(expression);
+
+  std::map<std::string, shared_ptr<XdmfArray> > functionVariables = std::map<std::string, shared_ptr<XdmfArray> >(mVariableSet);
+
+  // Copy variables into new map
+
+  shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, functionVariables);
+
+  currAttribute->setReference(function);
+  currAttribute->setReadMode(XdmfArray::Reference);
+
+  mAttributes.push_back(currAttribute);
+
+  const int id = mPreviousAttributes.size();
+  mPreviousAttributes.push_back(currAttribute);
+  return id;
+}
+
+int
+XdmfFortran::addFunctionAsCoordinate(char * expression,
+                                     char * name)
+{
+  shared_ptr<XdmfArray> currArray = XdmfArray::New();
+  currArray->setName(name);
+
+  // Set Function instead of setting values
+  std::string expressionstring = std::string(expression);
+
+  std::map<std::string, shared_ptr<XdmfArray> > functionVariables = std::map<std::string, shared_ptr<XdmfArray> >(mVariableSet);
+
+  // Copy variables into new map
+
+  shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, functionVariables);
+
+  currArray->setReference(function);
+  currArray->setReadMode(XdmfArray::Reference);
+
+  mCoordinates.push_back(currArray);
+
+  const int id = mPreviousCoordinates.size();
+  mPreviousCoordinates.push_back(currArray);
+  return id;
+}
+
+int
+XdmfFortran::addFunctionAsSet(char * expression,
+                              char * name,
+                              const int newSetType)
+{
+  const shared_ptr<XdmfSet> newSet = XdmfSet::New();
+  newSet->setName(name);
+
+  switch (newSetType) {
+    case XDMF_SET_TYPE_NODE:
+      newSet->setType(XdmfSetType::Node());
+      break;
+    case XDMF_SET_TYPE_CELL:
+      newSet->setType(XdmfSetType::Cell());
+      break;
+    case XDMF_SET_TYPE_FACE:
+      newSet->setType(XdmfSetType::Face());
+      break;
+    case XDMF_SET_TYPE_EDGE:
+      newSet->setType(XdmfSetType::Edge());
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Invalid set type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+  }
+
+  for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+      mAttributes.begin();
+      iter != mAttributes.end();
+      ++iter) {
+    newSet->insert(*iter);
+  }
+  mAttributes.clear();
+
+  if (!mInformations.empty()) {
+    for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin();
+        iter != mInformations.end();
+        ++iter) {
+      newSet->insert(*iter);
+    }
+    mInformations.clear();
+  }
+
+  // Set Function instead of setting values
+  std::string expressionstring = std::string(expression);
+
+  std::map<std::string, shared_ptr<XdmfArray> > functionVariables = std::map<std::string, shared_ptr<XdmfArray> >(mVariableSet);
+
+  // Copy variables into new map
+
+  shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, functionVariables);
+
+  newSet->setReference(function);
+  newSet->setReadMode(XdmfArray::Reference);
+
+  mSets.push_back(newSet);
+  int id = mPreviousSets.size();
+  mPreviousSets.push_back(newSet);
+  return id;
+}
+
+void
+XdmfFortran::addFunctionAsInformationArray(char * expression,
+                                           const int index,
+                                           char * name)
+{
+  if (index < (int)mInformations.size()) {
+    shared_ptr<XdmfArray> newArray = XdmfArray::New();
+    newArray->setName(name);
+    // Set Function instead of setting values
+    std::string expressionstring = std::string(expression);
+    std::map<std::string, shared_ptr<XdmfArray> > functionVariables = std::map<std::string, shared_ptr<XdmfArray> >(mVariableSet);
+    // Copy variables into new map
+    shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, functionVariables);
+    newArray->setReference(function);
+    newArray->setReadMode(XdmfArray::Reference);
+    mInformations[index]->insert(newArray);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::setFunctionAsTopology(char * expression,
+                                   const int topologyType,
+                                   const int numNodes)
+{
+  mTopology = XdmfTopology::New();
+
+  switch(topologyType) {
+  case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+    mTopology->setType(XdmfTopologyType::Polyvertex());
+    break;
+  case XDMF_TOPOLOGY_TYPE_POLYLINE:
+    mTopology->setType(XdmfTopologyType::Polyline(numNodes));
+    break;
+  case XDMF_TOPOLOGY_TYPE_POLYGON:
+    mTopology->setType(XdmfTopologyType::Polygon(numNodes));
+    break;
+  case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+    mTopology->setType(XdmfTopologyType::Triangle());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+    mTopology->setType(XdmfTopologyType::Quadrilateral());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+    mTopology->setType(XdmfTopologyType::Tetrahedron());
+    break;
+  case XDMF_TOPOLOGY_TYPE_PYRAMID:
+    mTopology->setType(XdmfTopologyType::Pyramid());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE:
+    mTopology->setType(XdmfTopologyType::Wedge());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+    mTopology->setType(XdmfTopologyType::Hexahedron());
+    break;
+  case XDMF_TOPOLOGY_TYPE_EDGE_3:
+    mTopology->setType(XdmfTopologyType::Edge_3());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+    mTopology->setType(XdmfTopologyType::Triangle_6());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+    mTopology->setType(XdmfTopologyType::Quadrilateral_8());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+    mTopology->setType(XdmfTopologyType::Quadrilateral_9());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+    mTopology->setType(XdmfTopologyType::Tetrahedron_10());
+    break;
+  case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+    mTopology->setType(XdmfTopologyType::Pyramid_13());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+    mTopology->setType(XdmfTopologyType::Wedge_15());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+    mTopology->setType(XdmfTopologyType::Wedge_18());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+    mTopology->setType(XdmfTopologyType::Hexahedron_20());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+    mTopology->setType(XdmfTopologyType::Hexahedron_24());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+    mTopology->setType(XdmfTopologyType::Hexahedron_27());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+    mTopology->setType(XdmfTopologyType::Hexahedron_64());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+    mTopology->setType(XdmfTopologyType::Hexahedron_125());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+    mTopology->setType(XdmfTopologyType::Hexahedron_216());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+    mTopology->setType(XdmfTopologyType::Hexahedron_343());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+    mTopology->setType(XdmfTopologyType::Hexahedron_512());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+    mTopology->setType(XdmfTopologyType::Hexahedron_729());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+    mTopology->setType(XdmfTopologyType::Hexahedron_1000());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+    mTopology->setType(XdmfTopologyType::Hexahedron_1331());
+    break;
+  case XDMF_TOPOLOGY_TYPE_MIXED:
+    mTopology->setType(XdmfTopologyType::Mixed());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid topology type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  // Set Function instead of setting values
+  std::string expressionstring = std::string(expression);
+
+  std::map<std::string, shared_ptr<XdmfArray> > functionVariables = std::map<std::string, shared_ptr<XdmfArray> >(mVariableSet);
+
+  // Copy variables into new map
+
+  shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, functionVariables);
+
+  mTopology->setReference(function);
+  mTopology->setReadMode(XdmfArray::Reference);
+
+  const int id = mPreviousTopologies.size();
+  mPreviousTopologies.push_back(mTopology);
+  return id;
+}
+
+int
+XdmfFortran::setFunctionAsGeometry(char * expression,
+                                   const int geometryType)
+{
+  mGeometry = XdmfGeometry::New();
+
+  switch(geometryType) {
+  case XDMF_GEOMETRY_TYPE_XYZ:
+    mGeometry->setType(XdmfGeometryType::XYZ());
+    break;
+  case XDMF_GEOMETRY_TYPE_XY:
+    mGeometry->setType(XdmfGeometryType::XY());
+    break;
+  case XDMF_GEOMETRY_TYPE_POLAR:
+    mGeometry->setType(XdmfGeometryType::Polar());
+    break;
+  case XDMF_GEOMETRY_TYPE_SPHERICAL:
+    mGeometry->setType(XdmfGeometryType::Spherical());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid geometry type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  // Set Function instead of setting values
+  std::string expressionstring = std::string(expression);
+
+  std::map<std::string, shared_ptr<XdmfArray> > functionVariables = std::map<std::string, shared_ptr<XdmfArray> >(mVariableSet);
+
+  // Copy variables into new map
+
+  shared_ptr<XdmfFunction> function = XdmfFunction::New(expression, functionVariables);
+
+  mGeometry->setReference(function);
+  mGeometry->setReadMode(XdmfArray::Reference);
+
+  const int id = mPreviousGeometries.size();
+  mPreviousGeometries.push_back(mGeometry);
+  return id;
+}
+
+int
+XdmfFortran::addSubsetAsAttribute(int start,
+                                  int stride,
+                                  int dimensions,
+                                  const char * const name,
+                                  const int attributeCenter,
+                                  const int attributeType)
+{
+  shared_ptr<XdmfAttribute> currAttribute = XdmfAttribute::New();
+  currAttribute->setName(name);
+
+  switch(attributeCenter) {
+  case XDMF_ATTRIBUTE_CENTER_GRID:
+    currAttribute->setCenter(XdmfAttributeCenter::Grid());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_CELL:
+    currAttribute->setCenter(XdmfAttributeCenter::Cell());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_FACE:
+    currAttribute->setCenter(XdmfAttributeCenter::Face());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_EDGE:
+    currAttribute->setCenter(XdmfAttributeCenter::Edge());
+    break;
+  case XDMF_ATTRIBUTE_CENTER_NODE:
+    currAttribute->setCenter(XdmfAttributeCenter::Node());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid attribute center");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  switch(attributeType) {
+  case XDMF_ATTRIBUTE_TYPE_SCALAR:
+    currAttribute->setType(XdmfAttributeType::Scalar());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_VECTOR:
+    currAttribute->setType(XdmfAttributeType::Vector());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_TENSOR:
+    currAttribute->setType(XdmfAttributeType::Tensor());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_MATRIX:
+    currAttribute->setType(XdmfAttributeType::Matrix());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_TENSOR6:
+    currAttribute->setType(XdmfAttributeType::Tensor6());
+    break;
+  case XDMF_ATTRIBUTE_TYPE_GLOBALID:
+    currAttribute->setType(XdmfAttributeType::GlobalId());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL, "Invalid attribute type");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin();
+      iter != mInformations.end();
+      ++iter) {
+    currAttribute->insert(*iter);
+  }
+  mInformations.clear();
+
+  // Generate Subset instead of filling values
+
+  std::vector<unsigned int> newStart;
+  newStart.push_back(start);
+  std::vector<unsigned int> newStride;
+  newStride.push_back(stride);
+  std::vector<unsigned int> newDimension;
+  newDimension.push_back(dimensions);
+
+  shared_ptr<XdmfSubset> subset = XdmfSubset::New(mSubsetReference,
+                                                  newStart,
+                                                  newStride,
+                                                  newDimension);
+
+  currAttribute->setReference(subset);
+  currAttribute->setReadMode(XdmfArray::Reference);
+
+  mAttributes.push_back(currAttribute);
+
+  const int id = mPreviousAttributes.size();
+  mPreviousAttributes.push_back(currAttribute);
+  return id;
+}
+
+int
+XdmfFortran::addSubsetAsCoordinate(int start,
+                                   int stride,
+                                   int dimensions,
+                                   char * name)
+{
+  shared_ptr<XdmfArray> currArray = XdmfArray::New();
+  currArray->setName(name);
+
+  // Generate Subset instead of filling values
+
+  std::vector<unsigned int> newStart;
+  newStart.push_back(start);
+  std::vector<unsigned int> newStride;
+  newStride.push_back(stride);
+  std::vector<unsigned int> newDimension;
+  newDimension.push_back(dimensions);
+
+  shared_ptr<XdmfSubset> subset = XdmfSubset::New(mSubsetReference,
+                                                  newStart,
+                                                  newStride,
+                                                  newDimension);
+
+  currArray->setReference(subset);
+  currArray->setReadMode(XdmfArray::Reference);
+
+  mCoordinates.push_back(currArray);
+
+  const int id = mPreviousCoordinates.size();
+  mPreviousCoordinates.push_back(currArray);
+  return id;
+
+}
+
+int
+XdmfFortran::addSubsetAsSet(int start,
+                            int stride,
+                            int dimensions,
+                            char * name,
+                            const int newSetType)
+{
+  const shared_ptr<XdmfSet> newSet = XdmfSet::New();
+  newSet->setName(name);
+
+  switch (newSetType) {
+    case XDMF_SET_TYPE_NODE:
+      newSet->setType(XdmfSetType::Node());
+      break;
+    case XDMF_SET_TYPE_CELL:
+      newSet->setType(XdmfSetType::Cell());
+      break;
+    case XDMF_SET_TYPE_FACE:
+      newSet->setType(XdmfSetType::Face());
+      break;
+    case XDMF_SET_TYPE_EDGE:
+      newSet->setType(XdmfSetType::Edge());
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Invalid set type.");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+      return -1;
+  }
+
+  for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+      mAttributes.begin();
+      iter != mAttributes.end();
+      ++iter) {
+    newSet->insert(*iter);
+  }
+  mAttributes.clear();
+
+  if (!mInformations.empty()) {
+    for(std::vector<shared_ptr<XdmfInformation> >::const_iterator iter =
+        mInformations.begin();
+        iter != mInformations.end();
+        ++iter) {
+      newSet->insert(*iter);
+    }
+    mInformations.clear();
+  }
+
+  // Generate Subset instead of filling values
+
+  std::vector<unsigned int> newStart;
+  newStart.push_back(start);
+  std::vector<unsigned int> newStride;
+  newStride.push_back(stride);
+  std::vector<unsigned int> newDimension;
+  newDimension.push_back(dimensions);
+
+  shared_ptr<XdmfSubset> subset = XdmfSubset::New(mSubsetReference,
+                                                  newStart,
+                                                  newStride,
+                                                  newDimension);
+
+  newSet->setReference(subset);
+  newSet->setReadMode(XdmfArray::Reference);
+
+  mSets.push_back(newSet);
+  int id = mPreviousSets.size();
+  mPreviousSets.push_back(newSet);
+  return id;
+}
+
+void
+XdmfFortran::addSubsetAsInformationArray(int start,
+                                         int stride,
+                                         int dimensions,
+                                         const int index,
+                                         char * name)
+{
+  if (index < (int)mInformations.size()) {
+    shared_ptr<XdmfArray> newArray = XdmfArray::New();
+    newArray->setName(name);
+    // Generate Subset instead of filling values
+    std::vector<unsigned int> newStart;
+    newStart.push_back(start);
+    std::vector<unsigned int> newStride;
+    newStride.push_back(stride);
+    std::vector<unsigned int> newDimension;
+    newDimension.push_back(dimensions);
+    shared_ptr<XdmfSubset> subset = XdmfSubset::New(mSubsetReference,
+                                                    newStart,
+                                                    newStride,
+                                                    newDimension);
+    newArray->setReference(subset);
+    newArray->setReadMode(XdmfArray::Reference);
+    mInformations[index]->insert(newArray);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Index out of range.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+int
+XdmfFortran::setSubsetAsTopology(int start,
+                                 int stride,
+                                 int dimensions,
+                                 const int topologyType,
+                                 const int numNodes)
+{
+  mTopology = XdmfTopology::New();
+
+  switch(topologyType) {
+  case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+    mTopology->setType(XdmfTopologyType::Polyvertex());
+    break;
+  case XDMF_TOPOLOGY_TYPE_POLYLINE:
+    mTopology->setType(XdmfTopologyType::Polyline(numNodes));
+    break;
+  case XDMF_TOPOLOGY_TYPE_POLYGON:
+    mTopology->setType(XdmfTopologyType::Polygon(numNodes));
+    break;
+  case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+    mTopology->setType(XdmfTopologyType::Triangle());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+    mTopology->setType(XdmfTopologyType::Quadrilateral());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+    mTopology->setType(XdmfTopologyType::Tetrahedron());
+    break;
+  case XDMF_TOPOLOGY_TYPE_PYRAMID:
+    mTopology->setType(XdmfTopologyType::Pyramid());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE:
+    mTopology->setType(XdmfTopologyType::Wedge());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+    mTopology->setType(XdmfTopologyType::Hexahedron());
+    break;
+  case XDMF_TOPOLOGY_TYPE_EDGE_3:
+    mTopology->setType(XdmfTopologyType::Edge_3());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+    mTopology->setType(XdmfTopologyType::Triangle_6());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+    mTopology->setType(XdmfTopologyType::Quadrilateral_8());
+    break;
+  case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+    mTopology->setType(XdmfTopologyType::Quadrilateral_9());
+    break;
+  case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+    mTopology->setType(XdmfTopologyType::Tetrahedron_10());
+    break;
+  case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+    mTopology->setType(XdmfTopologyType::Pyramid_13());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+    mTopology->setType(XdmfTopologyType::Wedge_15());
+    break;
+  case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+    mTopology->setType(XdmfTopologyType::Wedge_18());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+    mTopology->setType(XdmfTopologyType::Hexahedron_20());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+    mTopology->setType(XdmfTopologyType::Hexahedron_24());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+    mTopology->setType(XdmfTopologyType::Hexahedron_27());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+    mTopology->setType(XdmfTopologyType::Hexahedron_64());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+    mTopology->setType(XdmfTopologyType::Hexahedron_125());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+    mTopology->setType(XdmfTopologyType::Hexahedron_216());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+    mTopology->setType(XdmfTopologyType::Hexahedron_343());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+    mTopology->setType(XdmfTopologyType::Hexahedron_512());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+    mTopology->setType(XdmfTopologyType::Hexahedron_729());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+    mTopology->setType(XdmfTopologyType::Hexahedron_1000());
+    break;
+  case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+    mTopology->setType(XdmfTopologyType::Hexahedron_1331());
+    break;
+  case XDMF_TOPOLOGY_TYPE_MIXED:
+    mTopology->setType(XdmfTopologyType::Mixed());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid topology type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  // Generate Subset instead of filling values
+
+  std::vector<unsigned int> newStart;
+  newStart.push_back(start);
+  std::vector<unsigned int> newStride;
+  newStride.push_back(stride);
+  std::vector<unsigned int> newDimension;
+  newDimension.push_back(dimensions);
+
+  shared_ptr<XdmfSubset> subset = XdmfSubset::New(mSubsetReference,
+                                                  newStart,
+                                                  newStride,
+                                                  newDimension);
+
+  mTopology->setReference(subset);
+  mTopology->setReadMode(XdmfArray::Reference);
+
+  const int id = mPreviousTopologies.size();
+  mPreviousTopologies.push_back(mTopology);
+  return id;
+}
+
+int
+XdmfFortran::setSubsetAsGeometry(int start,
+                                 int stride,
+                                 int dimensions,
+                                 const int geometryType)
+{
+  mGeometry = XdmfGeometry::New();
+
+  switch(geometryType) {
+  case XDMF_GEOMETRY_TYPE_XYZ:
+    mGeometry->setType(XdmfGeometryType::XYZ());
+    break;
+  case XDMF_GEOMETRY_TYPE_XY:
+    mGeometry->setType(XdmfGeometryType::XY());
+    break;
+  case XDMF_GEOMETRY_TYPE_POLAR:
+    mGeometry->setType(XdmfGeometryType::Polar());
+    break;
+  case XDMF_GEOMETRY_TYPE_SPHERICAL:
+    mGeometry->setType(XdmfGeometryType::Spherical());
+    break;
+  default:
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Invalid geometry type.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+
+  // Generate Subset instead of filling values
+
+  std::vector<unsigned int> newStart;
+  newStart.push_back(start);
+  std::vector<unsigned int> newStride;
+  newStride.push_back(stride);
+  std::vector<unsigned int> newDimension;
+  newDimension.push_back(dimensions);
+
+  shared_ptr<XdmfSubset> subset = XdmfSubset::New(mSubsetReference,
+                                                  newStart,
+                                                  newStride,
+                                                  newDimension);
+
+  mGeometry->setReference(subset);
+  mGeometry->setReadMode(XdmfArray::Reference);
+
+  const int id = mPreviousGeometries.size();
+  mPreviousGeometries.push_back(mGeometry);
+  return id;
+}
+
+void
+XdmfFortran::clearFunctionVariables()
+{
+  mVariableSet.clear();
+}
+
+void
+XdmfFortran::removeFunctionVariable(char * varname)
+{
+  std::string tempstring = varname;
+  mVariableSet.erase(tempstring);
+}
+
+void
+XdmfFortran::clearPrevious()
+{
+  mPreviousTopologies.clear();
+  mPreviousGeometries.clear();
+  mPreviousAttributes.clear();
+  mPreviousMaps.clear();
+  mPreviousSets.clear();
+  mPreviousDimensions.clear();
+  mPreviousOrigins.clear();
+  mPreviousBricks.clear();
+  mPreviousCoordinates.clear();
+}
+
+void
+XdmfFortran::setAllowSetSplitting(bool newAllow)
+{
+  mAllowSetSplitting = newAllow;
+}
+
+void
+XdmfFortran::setMaxFileSize(int newSize)
+{
+  mMaxFileSize = newSize;
+}
+
+void 
+XdmfFortran::write(const char * const xmlFilePath,
+                   const int datalimit,
+                   const bool release)
+{
+  shared_ptr<XdmfWriter> writer;
+  if (mHeavyDataWriter == NULL) {
+    writer = XdmfWriter::New(xmlFilePath);
+    mHeavyDataWriter = writer->getHeavyDataWriter();
+  }
+  else {
+    writer = XdmfWriter::New(xmlFilePath, mHeavyDataWriter);
+  }
+  writer->setLightDataLimit(datalimit);
+  writer->getHeavyDataWriter()->setReleaseData(release);
+  shared_dynamic_cast<XdmfHDF5Writer>(writer->getHeavyDataWriter())->setFileSizeLimit(mMaxFileSize);
+  shared_dynamic_cast<XdmfHDF5Writer>(writer->getHeavyDataWriter())->setAllowSetSplitting(mAllowSetSplitting);
+  mDomain->accept(writer);
+}
+
+void 
+XdmfFortran::writeHDF5(const char * const xmlFilePath,
+                       const bool release)
+{
+  if (mHeavyDataWriter == NULL || mHeavyDataWriter->getFilePath() != xmlFilePath) {
+    shared_ptr<XdmfHDF5Writer> writer = XdmfHDF5Writer::New(xmlFilePath);
+    writer->setFileSizeLimit(mMaxFileSize);
+    writer->setAllowSetSplitting(mAllowSetSplitting);
+    writer->setReleaseData( release );
+    mHeavyDataWriter = writer;
+  }
+  if (mHeavyDataWriter->getReleaseData() != release) {
+    mHeavyDataWriter->setReleaseData(release);
+  }
+  mHeavyDataWriter->openFile();
+  mDomain->accept(mHeavyDataWriter);
+  mHeavyDataWriter->closeFile();
+}
+
+void
+XdmfFortran::initHDF5(const char * const xmlFilePath,
+                      const bool release)
+{
+  shared_ptr<XdmfHDF5Writer> writer = XdmfHDF5Writer::New(xmlFilePath);
+  writer->setFileSizeLimit(mMaxFileSize);
+  writer->setAllowSetSplitting(mAllowSetSplitting);
+  writer->setReleaseData(release);
+  mHeavyDataWriter = writer;
+}
+
+#ifdef XDMF_BUILD_DSM
+
+void
+XdmfFortran::initDSMServer(const char * const filePath,
+                           MPI_Comm comm,
+                           int bufferSize,
+                           int startCoreIndex,
+                           int endCoreIndex)
+{
+  // Non-Threaded version
+  std::string writtenFile(filePath);
+  if (bufferSize > 0) {
+    mDSMWriter = XdmfHDF5WriterDSM::New(writtenFile, comm, (unsigned int) bufferSize, startCoreIndex, endCoreIndex);
+    mDSMWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Non-positive DSM buffer size.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::acceptDSM(int numConnections)
+{
+  if (mDSMWriter) {
+    mDSMWriter->getServerBuffer()->GetComm()->OpenPort();
+    mDSMWriter->getServerBuffer()->SendAccept(numConnections);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Attempting to accept connection when DSM is not set up.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::closeDSMPort()
+{
+  if (mDSMWriter) {
+    mDSMWriter->getServerBuffer()->GetComm()->ClosePort();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Attempting to close a port when DSM is not set up.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::connectDSM(const char * const filePath,
+                        MPI_Comm comm)
+{
+  std::string writtenFile(filePath);
+  XdmfDSMCommMPI * dsmComm = new XdmfDSMCommMPI();
+  dsmComm->DupComm(comm);
+  dsmComm->Init();
+  XdmfDSMBuffer * dsmBuffer = new XdmfDSMBuffer();
+  dsmBuffer->SetIsServer(false);
+  dsmBuffer->SetComm(dsmComm);
+  dsmBuffer->SetIsConnected(true);
+
+  mDSMWriter = XdmfHDF5WriterDSM::New(writtenFile, dsmBuffer);
+
+  mDSMWriter->setMode(XdmfHeavyDataWriter::Hyperslab);
+
+  // Currently uses default config file name
+  mDSMWriter->getServerBuffer()->GetComm()->ReadDsmPortName();
+
+  mDSMWriter->getServerBuffer()->Connect();
+  // To check if the DSM writer is using server mode
+  // bool test = mDSMWriter->getServerMode();
+}
+
+MPI_Comm
+XdmfFortran::getDSMInterComm()
+{
+  // Sanity check
+  if (mDSMWriter) {
+    return mDSMWriter->getServerBuffer()->GetComm()->GetInterComm();
+  }
+  else {
+    return MPI_COMM_NULL;
+  }
+}
+
+MPI_Comm
+XdmfFortran::getDSMIntraComm()
+{
+  // Sanity check
+  if (mDSMWriter) {
+    return mDSMWriter->getServerBuffer()->GetComm()->GetIntraComm();
+  }
+  else {
+    return MPI_COMM_NULL;
+  }
+}
+
+// Call only on one core
+void
+XdmfFortran::stopDSM()
+{
+  if (mDSMWriter) {
+    mDSMWriter->stopDSM();
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Stop called when DSM not initialized.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+  mDSMWriter =  shared_ptr<XdmfHDF5WriterDSM>();
+}
+
+void
+XdmfFortran::readFromDSM(const char * const dsmDataSetPath,
+                         const int arrayType,
+                         void * values,
+                         const int start,
+                         const int stride,
+                         const int dimensions,
+                         const int dataspace)
+{
+  if (mDSMWriter) {
+    shared_ptr<const XdmfArrayType> writtenArrayType = shared_ptr<const XdmfArrayType>();
+    switch(arrayType) {
+    case XDMF_ARRAY_TYPE_INT8:
+      writtenArrayType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      writtenArrayType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      writtenArrayType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      writtenArrayType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_UINT8:
+      writtenArrayType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      writtenArrayType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      writtenArrayType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      writtenArrayType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      writtenArrayType = XdmfArrayType::Float64();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Invalid array number type");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    std::vector<unsigned int> startVector;
+    startVector.push_back(start);
+    std::vector<unsigned int> strideVector;
+    strideVector.push_back(stride);
+    std::vector<unsigned int> dimVector;
+    dimVector.push_back(dimensions);
+    std::vector<unsigned int> dataVector;
+    dataVector.push_back(dataspace);
+    std::string writtenPath(dsmDataSetPath);
+    shared_ptr<XdmfHDF5ControllerDSM> writerController =
+      XdmfHDF5ControllerDSM::New(mDSMWriter->getFilePath(),
+                                 writtenPath,
+                                 writtenArrayType,
+                                 startVector,
+                                 strideVector,
+                                 dimVector,
+                                 dataVector,
+                                 mDSMWriter->getServerBuffer());
+
+    shared_ptr<XdmfArray> readArray = XdmfArray::New();
+
+    readArray->insert(writerController);
+    readArray->read();
+
+    readFromArray(readArray,
+                  arrayType,
+                  values,
+                  dimensions,
+                  0,
+                  1,
+                  1);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Attempting to read from DSM when DSM is not set up.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+void
+XdmfFortran::writeToDSM(const char * const dsmDataSetPath,
+                        const int arrayType,
+                        void * values,
+                        const int start,
+                        const int stride,
+                        const int dimensions,
+                        const int dataspace)
+{
+  if (mDSMWriter) {
+    shared_ptr<const XdmfArrayType> writtenArrayType = shared_ptr<const XdmfArrayType>();
+    switch(arrayType) {
+    case XDMF_ARRAY_TYPE_INT8:
+      writtenArrayType = XdmfArrayType::Int8();
+      break;
+    case XDMF_ARRAY_TYPE_INT16:
+      writtenArrayType = XdmfArrayType::Int16();
+      break;
+    case XDMF_ARRAY_TYPE_INT32:
+      writtenArrayType = XdmfArrayType::Int32();
+      break;
+    case XDMF_ARRAY_TYPE_INT64:
+      writtenArrayType = XdmfArrayType::Int64();
+      break;
+    case XDMF_ARRAY_TYPE_UINT8:
+      writtenArrayType = XdmfArrayType::UInt8();
+      break;
+    case XDMF_ARRAY_TYPE_UINT16:
+      writtenArrayType = XdmfArrayType::UInt16();
+      break;
+    case XDMF_ARRAY_TYPE_UINT32:
+      writtenArrayType = XdmfArrayType::UInt32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT32:
+      writtenArrayType = XdmfArrayType::Float32();
+      break;
+    case XDMF_ARRAY_TYPE_FLOAT64:
+      writtenArrayType = XdmfArrayType::Float64();
+      break;
+    default:
+      try {
+        XdmfError::message(XdmfError::FATAL,
+                           "Invalid array number type");
+      }
+      catch (XdmfError & e) {
+        throw e;
+      }
+    }
+    std::vector<unsigned int> startVector;
+    startVector.push_back(start);
+    std::vector<unsigned int> strideVector;
+    strideVector.push_back(stride);
+    std::vector<unsigned int> dimVector;
+    dimVector.push_back(dimensions);
+    std::vector<unsigned int> dataVector;
+    dataVector.push_back(dataspace);
+    std::string writtenPath(dsmDataSetPath);
+    shared_ptr<XdmfHDF5ControllerDSM> writerController =
+      XdmfHDF5ControllerDSM::New(mDSMWriter->getFilePath(),
+                                 writtenPath,
+                                 writtenArrayType,
+                                 startVector,
+                                 strideVector,
+                                 dimVector,
+                                 dataVector,
+                                 mDSMWriter->getServerBuffer());
+
+    shared_ptr<XdmfArray> writtenArray = XdmfArray::New();
+    writeToArray(writtenArray,
+                 dimensions,
+                 arrayType,
+                 values);
+    writtenArray->insert(writerController);
+    mDSMWriter->setNotifyOnWrite(false);
+    writtenArray->accept(mDSMWriter);
+  }
+  else {
+    try {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Attempting to write to DSM when DSM is not set up.");
+    }
+    catch (XdmfError & e) {
+      throw e;
+    }
+  }
+}
+
+#endif
+
+void
+XdmfFortran::read(const char * const xmlFilePath)
+{
+  shared_ptr<XdmfReader> reader = XdmfReader::New();
+  mDomain = shared_dynamic_cast<XdmfDomain>(reader->read( xmlFilePath )); 
+}
+
+//temporary fix, hopefully
+int
+XdmfFortran::setTopologyPolyline(const unsigned int nodesPerElement,
+                                 const unsigned int numValues,
+                                 const int arrayType,
+                                 const void * const connectivityValues)
+{
+  mTopology = XdmfTopology::New();
+  mTopology->setType(XdmfTopologyType::Polyline(nodesPerElement));
+  // insert connectivity values into array
+  writeToArray(mTopology,
+               numValues,
+               arrayType,
+               connectivityValues);
+  const int id = mPreviousTopologies.size();
+  mPreviousTopologies.push_back(mTopology);
+  return id;
+}
+
+int
+XdmfFortran::setTopologyPolygon(const unsigned int nodesPerElement,
+                                const unsigned int numValues,
+                                const int arrayType,
+                                const void * const connectivityValues)
+{
+  mTopology = XdmfTopology::New();
+  mTopology->setType(XdmfTopologyType::Polygon(nodesPerElement));
+  // insert connectivity values into array
+  writeToArray(mTopology,
+               numValues,
+               arrayType,
+               connectivityValues);
+  const int id = mPreviousTopologies.size();
+  mPreviousTopologies.push_back(mTopology);
+  return id;
+}
+
+//
+// C++ will mangle the name based on the argument list. This tells the
+// compiler not to mangle the name so we can call it from 'C' (but
+// really Fortran in this case)
+//
+extern "C"
+{
+  // C Wrapper Functions
+
+  // Main Xdmf Functions
+
+  void
+  XdmfInit(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = new XdmfFortran();
+    *pointer = reinterpret_cast<long>(xdmfFortran);
+  }
+
+  void
+  XdmfClose(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    delete xdmfFortran;
+  }
+
+  int
+  XdmfAddAttribute(long * pointer, 
+                   char * const name,
+                   int  * attributeCenter,
+                   int  * attributeType,
+                   int  * numValues,
+                   int  * arrayType,
+                   void * values)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addAttribute(name,
+                                     *attributeCenter,
+                                     *attributeType,
+                                     *numValues,
+                                     *arrayType, 
+                                     values);
+  }
+
+  void
+  XdmfClearAttributeHeavyData(long * pointer,
+                              int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearAttributeHeavyData(*index);
+  }
+
+  void XdmfSetAttributeHDF5(long * pointer,
+                            int * index,
+                            char * const hdf5File,
+                            char * const hdf5Dataset,
+                            unsigned int * start,
+                            unsigned int * stride,
+                            unsigned int * numValues,
+                            unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setAttributeHDF5(*index,
+                                  hdf5File,
+                                  hdf5Dataset,
+                                  *start,
+                                  *stride,
+                                  *numValues,
+                                  *dataspace);
+  }
+
+  void XdmfSetAttributeBinary(long * pointer,
+                              int * index,
+                              char * binFile,
+                              int * endian,
+                              unsigned int * seek,
+                              unsigned int * start,
+                              unsigned int * stride,
+                              unsigned int * numValues,
+                              unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setAttributeBinary(*index,
+                                  binFile,
+                                  *endian,
+                                  *seek,
+                                  *start,
+                                  *stride,
+                                  *numValues,
+                                  *dataspace);
+  }
+
+  void
+  XdmfAddGrid(long * pointer, 
+              char * gridName,
+              bool * writeToHDF5)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGrid(gridName, *writeToHDF5);
+  }
+
+  void
+  XdmfAddGridCurvilinear(long * pointer,
+                         char * gridName,
+                         bool * writeToHDF5)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGridCurvilinear(gridName, *writeToHDF5);
+  }
+
+  void
+  XdmfAddGridRectilinear(long * pointer,
+                         char * gridName,
+                         bool * writeToHDF5)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGridRectilinear(gridName, *writeToHDF5);
+  }
+
+  void
+  XdmfAddGridRegular(long * pointer,
+                     char * gridName,
+                     bool * writeToHDF5)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGridRegular(gridName, *writeToHDF5);
+  }
+
+  void
+  XdmfAddGridCollection(long * pointer, 
+                        char * name,
+                        int  * gridCollectionType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGridCollection(name,
+                                   *gridCollectionType);
+  }
+
+  void XdmfAddGridReference(long * pointer,
+                            int * gridType,
+                            char * filePath,
+                            const char * xmlPath)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGridReference(*gridType,
+                                  filePath,
+                                  xmlPath);
+  }
+
+  void XdmfAddGridCollectionReference(long * pointer,
+                                      char * filePath,
+                                      char * xmlPath)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addGridCollectionReference(filePath,
+                                            xmlPath);
+  }
+
+  int
+  XdmfAddInformation(long * pointer, 
+                     char * key, 
+                     char * value)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addInformation(key, value);
+  }
+
+  void
+  XdmfAddPreviousAttribute(long * pointer, 
+                           int  * attributeId)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addPreviousAttribute(*attributeId);
+  }
+
+  void
+  XdmfAddPreviousInformation(long * pointer, 
+                             int  * informationId)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addPreviousInformation(*informationId);
+  }
+
+  void
+  XdmfCloseGridCollection(long * pointer, bool * writeToHDF5)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->closeGridCollection(*writeToHDF5);
+  }
+
+  int
+  XdmfSetGeometry(long * pointer, 
+                  int  * geometryType, 
+                  int  * numValues,
+                  int  * arrayType, 
+                  void * pointValues)
+  {
+
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setGeometry(*geometryType, 
+                                    *numValues,
+                                    *arrayType, 
+                                    pointValues);
+  }
+
+  void
+  XdmfClearGeometryHeavyData(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearGeometryHeavyData();
+  }
+
+  void XdmfSetGeometryHDF5(long * pointer,
+                           char * hdf5File,
+                           char * hdf5Dataset,
+                           unsigned int * start,
+                           unsigned int * stride,
+                           unsigned int * numValues,
+                           unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setGeometryHDF5(hdf5File,
+                                 hdf5Dataset,
+                                 *start,
+                                 *stride,
+                                 *numValues,
+                                 *dataspace);
+  }
+
+  void XdmfSetGeometryBinary(long * pointer,
+                             char * binFile,
+                             int * endian,
+                             unsigned int * seek,
+                             unsigned int * start,
+                             unsigned int * stride,
+                             unsigned int * numValues,
+                             unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setGeometryBinary(binFile,
+                                   *endian,
+                                   *seek,
+                                   *start,
+                                   *stride,
+                                   *numValues,
+                                   *dataspace);
+  }
+
+  void
+  XdmfSetPreviousGeometry(long * pointer, 
+                          int  * geometryId)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setPreviousGeometry(*geometryId);
+  }
+
+  void
+  XdmfSetPreviousTopology(long * pointer, 
+                          int  * topologyId)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setPreviousTopology(*topologyId);
+  }
+
+  void
+  XdmfSetTime(long   * pointer, 
+              double * time)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setTime(*time);
+  }
+
+  int
+  XdmfSetTopology(long * pointer, 
+                  int  * topologyType, 
+                  int  * numValues,
+                  int  * arrayType,
+                  void * connectivityValues)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setTopology(*topologyType, 
+                                    *numValues, 
+                                    *arrayType,
+                                    connectivityValues,
+                                    0);
+  }
+
+  void
+  XdmfClearTopologyHeavyData(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearTopologyHeavyData();
+  }
+
+  void XdmfSetTopologyHDF5(long * pointer,
+                           char * hdf5File,
+                           char * hdf5Dataset,
+                           unsigned int * start,
+                           unsigned int * stride,
+                           unsigned int * numValues,
+                           unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setTopologyHDF5(hdf5File,
+                                 hdf5Dataset,
+                                 *start,
+                                 *stride,
+                                 *numValues,
+                                 *dataspace);
+  }
+
+  void XdmfsetTopologyBinary(long * pointer,
+                             char * binFile,
+                             int * endian,
+                             unsigned int * seek,
+                             unsigned int * start,
+                             unsigned int * stride,
+                             unsigned int * numValues,
+                             unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setTopologyBinary(binFile,
+                                   *endian,
+                                   *seek,
+                                   *start,
+                                   *stride,
+                                   *numValues,
+                                   *dataspace);
+  }
+
+  void
+  XdmfRetrieveNumDomainGridCollections(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total =  xdmfFortran->retrieveNumDomainGridCollections();
+  }
+
+  void
+  XdmfRetrieveNumGridCollectionGridCollections(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total =  xdmfFortran->numGridCollectionGridCollections();
+  }
+
+  void
+  XdmfRetrieveDomainTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveDomainNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveDomainNumProperties();
+  }
+
+  void
+  XdmfRetrieveDomainProperty(long * pointer,
+                             int * index,
+                             char * key,
+                             int * keyLength,
+                             char * value,
+                             int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainProperty(*index,
+                                        key,
+                                        *keyLength,
+                                        value,
+                                        *valueLength);
+  }
+
+  void
+  XdmfRetrieveDomainPropertyByKey(long * pointer,
+                                  char * key,
+                                  char * value,
+                                  int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainPropertyByKey(key, value, *valueLength);
+  }
+
+  void
+  XdmfOpenDomainGridCollection(long * pointer,
+                               int * index,
+                               int * openMaps,
+                               int * openAttributes,
+                               int * openInformation,
+                               int * openSets)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openDomainGridCollection(*index,
+                                          *openMaps,
+                                          *openAttributes,
+                                          *openInformation,
+                                          *openSets);
+  }
+
+  void XdmfReadDomainGridCollection(long * pointer,
+                                     int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->readDomainGridCollection(*index);
+  }
+
+  void
+  XdmfRemoveDomainGridCollection(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeDomainGridCollection(*index);
+  }
+
+  void
+  XdmfOpenGridCollectionGridCollection(long * pointer,
+                                       int * index,
+                                       int * openMaps,
+                                       int * openAttributes,
+                                       int * openInformation,
+                                       int * openSets)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openGridCollectionGridCollection(*index,
+                                                  *openMaps,
+                                                  *openAttributes,
+                                                  *openInformation,
+                                                  *openSets);
+  }
+
+  void XdmfReadGridCollectionGridCollection(long * pointer,
+                                            int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->readGridCollectionGridCollection(*index);
+  }
+
+  void
+  XdmfRemoveGridCollectionGridCollection(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeGridCollectionGridCollection(*index);
+  }
+
+  void
+  XdmfRetrieveGridCollectionTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveGridCollectionNumProperties();
+  }
+
+  void
+  XdmfRetrieveGridCollectionProperty(long * pointer,
+                                     int * index,
+                                     char * key,
+                                     int * keyLength,
+                                     char * value,
+                                     int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionProperty(*index,
+                                                key,
+                                                *keyLength,
+                                                value,
+                                                *valueLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionPropertyByKey(long * pointer,
+                                          char * key,
+                                          char * value,
+                                          int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionPropertyByKey(key, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionNumGrids(long * pointer, int * gridType, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->numGridCollectionGrids(*gridType);
+  }
+
+  void
+  XdmfRetrieveDomainNumGrids(long * pointer, int * gridType, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->numDomainGrids(*gridType);
+  }
+  
+  void
+  XdmfOpenDomainGrid(long * pointer,
+                     int * gridType,
+                     int * index,
+                     int * openMaps,
+                     int * openAttributes,
+                     int * openInformation,
+                     int * openSets)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openDomainGrid(*gridType,
+                                *index,
+                                *openMaps,
+                                *openAttributes,
+                                *openInformation,
+                                *openSets);
+  }
+
+  void XdmfReadDomainGrid(long * pointer,
+                          int * gridType,
+                          int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->readDomainGrid(*gridType,
+                                *index);
+  }
+
+  void
+  XdmfRemoveDomainGrid(long * pointer, int * gridType, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeDomainGrid(*gridType, *index);
+  }
+
+  void
+  XdmfReplaceDomainGrid(long * pointer, int * gridType, int * index, char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceDomainGrid(*gridType, *index, name);
+  }
+
+  void
+  XdmfRetrieveDomainGridTag(long * pointer,
+                            int * gridType,
+                            int * index,
+                            char * tag,
+                            int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainGridTag(*gridType, *index, tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveDomainGridName(long * pointer,
+                             int * gridType,
+                             int * index,
+                             char * name,
+                             int * nameLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainGridName(*gridType, *index, name, *nameLength);
+  }
+
+  void
+  XdmfRetrieveDomainGridNumProperties(long * pointer,
+                                      int * gridType,
+                                      int * index,
+                                      int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveDomainGridNumProperties(*gridType, *index);
+  }
+
+  void
+  XdmfRetrieveDomainGridProperty(long * pointer,
+                                 int * gridType,
+                                 int * gridIndex,
+                                 int * index,
+                                 char * key,
+                                 int * keyLength,
+                                 char * value,
+                                 int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainGridProperty(*gridType,
+                                            *gridIndex,
+                                            *index,
+                                            key,
+                                            *keyLength,
+                                            value,
+                                            *valueLength);
+  }
+
+  void
+  XdmfRetrieveDomainGridPropertyByKey(long * pointer,
+                                      int * gridType,
+                                      int * index,
+                                      char * key,
+                                      char * value,
+                                      int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDomainGridPropertyByKey(*gridType, *index, key, value, *valueLength);
+  }
+
+  void
+  XdmfOpenGridCollectionGrid(long * pointer,
+                             int * gridType,
+                             int * index,
+                             int * openMaps,
+                             int * openAttributes,
+                             int * openInformation,
+                             int * openSets)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openGridCollectionGrid(*gridType,
+                                        *index,
+                                        *openMaps,
+                                        *openAttributes,
+                                        *openInformation,
+                                        *openSets);
+  }
+
+  void XdmfReadGridCollectionGrid(long * pointer,
+                                  int * gridType,
+                                  int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->readGridCollectionGrid(*gridType,
+                                        *index);
+  }
+
+  void
+  XdmfRemoveGridCollectionGrid(long * pointer, int * gridType, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeGridCollectionGrid(*gridType, *index);
+  }
+
+  void
+  XdmfReplaceGridCollectionGrid(long * pointer, int * gridType, int * index, char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceGridCollectionGrid(*gridType, *index, name);
+  }
+
+  void
+  XdmfRetrieveGridCollectionGridTag(long * pointer,
+                                    int * gridType,
+                                    int * index,
+                                    char * tag,
+                                    int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionGridTag(*gridType, *index, tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionGridName(long * pointer,
+                                     int * gridType,
+                                     int * index,
+                                     char * name,
+                                     int * nameLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionGridName(*gridType, *index, name, *nameLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionGridNumProperties(long * pointer,
+                                              int * gridType,
+                                              int * index,
+                                              int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveGridCollectionGridNumProperties(*gridType, *index);
+  }
+
+  void
+  XdmfRetrieveGridCollectionGridProperty(long * pointer,
+                                         int * gridType,
+                                         int * gridIndex,
+                                         int * index,
+                                         char * key,
+                                         int * keyLength,
+                                         char * value,
+                                         int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionGridProperty(*gridType,
+                                                    *gridIndex,
+                                                    *index,
+                                                    key,
+                                                    *keyLength,
+                                                    value,
+                                                    *valueLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionGridPropertyByKey(long * pointer,
+                                              int * gridType,
+                                              int *index,
+                                              char * key,
+                                              char * value,
+                                              int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGridCollectionGridPropertyByKey(*gridType,
+                                                         *index,
+                                                         key,
+                                                         value,
+                                                         *valueLength);
+  }
+
+  void
+  XdmfRetrieveGridCollectionType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveGridCollectionType();
+  }
+
+  void
+  XdmfRetrieveTime(long * pointer, double * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total =  xdmfFortran->retrieveTime();
+  }
+
+  void
+  XdmfRetrieveTopologyTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveTopologyTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveTopologyValues(long * pointer,
+                             void * values,
+                             int * dataType,
+                             int * numberRead,
+                             int * startIndex,
+                             int * arrayStride,
+                             int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveTopologyValues(values,
+                                        *dataType,
+                                        *numberRead,
+                                        *startIndex,
+                                        *arrayStride,
+                                        *valueStride);
+  }
+
+  void
+  XdmfRetrieveTopologyType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType =  xdmfFortran->retrieveTopologyType();
+  }
+
+  void
+  XdmfRetrieveTopologyValueType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType =  xdmfFortran->retrieveTopologyValueType();
+  }
+
+  void
+  XdmfRetrieveTopologyNumElements(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveTopologyNumElements();
+  }
+
+  void
+  XdmfRetrieveTopologySize(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveTopologySize();
+  }
+
+  void
+  XdmfClearPreviousTopologies(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousTopologies();
+  }
+
+  void
+  XdmfModifyTopologyValues(long * pointer,
+                           void * values,
+                           int * arrayType,
+                           int * numValues,
+                           int * startIndex,
+                           int * arrayStride,
+                           int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyTopologyValues(values,
+                                      *arrayType,
+                                      *numValues,
+                                      *startIndex,
+                                      *arrayStride,
+                                      *valueStride);
+  }
+
+  void  
+  XdmfRetrieveTopologyNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveTopologyNumProperties();
+  }
+
+  void
+  XdmfRetrieveTopologyProperty(long * pointer,
+                               int * index,
+                               char * key,
+                               int * keyLength,
+                               char * value,
+                               int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveTopologyProperty(*index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveTopologyPropertyByKey(long * pointer,
+                                    char * key,
+                                    char * value,
+                                    int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveTopologyPropertyByKey(key, value, *valueLength);
+  }
+
+  void
+  XdmfSetTopologyAsVariable(long * pointer, char * varname)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setTopologyAsVariable(varname);
+  }
+
+  void
+  XdmfSetTopologyAsSubsetReference(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setTopologyAsSubsetReference();
+  }
+
+  void
+  XdmfRetrieveGeometryTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGeometryTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveGeometryValues(long * pointer,
+                             void * values,
+                             int * dataType,
+                             int * numberRead,
+                             int * startIndex,
+                             int * arrayStride,
+                             int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGeometryValues(values,
+                                        *dataType,
+                                        *numberRead,
+                                        *startIndex,
+                                        *arrayStride,
+                                        *valueStride);
+  }
+
+  void
+  XdmfRetrieveGeometryType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveGeometryType();
+  }
+
+  void
+  XdmfRetrieveGeometryValueType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveGeometryValueType();
+  }
+
+  void
+  XdmfRetrieveGeometryNumPoints(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveGeometryNumPoints();
+  }
+
+  void
+  XdmfRetrieveGeometrySize(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveGeometrySize();
+  }
+
+  void
+  XdmfClearPreviousGeometries(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousGeometries();
+  }
+
+  void
+  XdmfModifyGeometryValues(long * pointer,
+                           void * values,
+                           int * arrayType,
+                           int * numValues,
+                           int * startIndex,
+                           int * arrayStride,
+                           int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyGeometryValues(values,
+                                      *arrayType,
+                                      *numValues,
+                                      *startIndex,
+                                      *arrayStride,
+                                      *valueStride);
+  }
+
+  void  
+  XdmfRetrieveGeometryNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveGeometryNumProperties();
+  }
+
+  void
+  XdmfRetrieveGeometryProperty(long * pointer,
+                               int * index,
+                               char * key,
+                               int * keyLength,
+                               char * value,
+                               int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGeometryProperty(*index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveGeometryPropertyByKey(long * pointer,
+                                    char * key,
+                                    char * value,
+                                    int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveGeometryPropertyByKey(key, value, *valueLength);
+  }
+
+  void
+  XdmfSetGeometryAsVariable(long * pointer, char * varname)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setGeometryAsVariable(varname);
+  }
+
+  void
+  XdmfSetGeometryAsSubsetReference(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setGeometryAsSubsetReference();
+  }
+
+  int
+  XdmfSetDimensions(long * pointer, int  * numValues, int  * arrayType, void * pointValues)
+  {
+
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setDimensions(*numValues, *arrayType, pointValues);
+  }
+
+  void
+  XdmfClearDimensionsHeavyData(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearDimensionsHeavyData();
+  }
+
+  void XdmfSetDimensionsHDF5(long * pointer,
+                             char * hdf5File,
+                             char * hdf5Dataset,
+                             unsigned int * start,
+                             unsigned int * stride,
+                             unsigned int * numValues,
+                             unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setDimensionsHDF5(hdf5File,
+                                   hdf5Dataset,
+                                   *start,
+                                   *stride,
+                                   *numValues,
+                                   *dataspace);
+  }
+
+  void XdmfSetDimensionsBinary(long * pointer,
+                               char * binFile,
+                               int * endian,
+                               unsigned int * seek,
+                               unsigned int * start,
+                               unsigned int * stride,
+                               unsigned int * numValues,
+                               unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setDimensionsBinary(binFile,
+                                     *endian,
+                                     *seek,
+                                     *start,
+                                     *stride,
+                                     *numValues,
+                                     *dataspace);
+  }
+
+  void
+  XdmfOpenPreviousDimensions(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openPreviousDimensions(*index);  
+  }
+
+  void
+  XdmfClearPreviousDimensions(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousDimensions();
+  }
+
+  void
+  XdmfModifyDimensionsValues(long * pointer,
+                             void * values,
+                             int * arrayType,
+                             int * numValues,
+                             int * startIndex,
+                             int * arrayStride,
+                             int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyDimensionsValues(values,
+                                        *arrayType,
+                                        *numValues,
+                                        *startIndex,
+                                        *arrayStride,
+                                        *valueStride);
+  }
+
+  void
+  XdmfRetrieveDimensionsTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDimensionsTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveDimensionsValues(long * pointer,
+                               void * values,
+                               int * dataType,
+                               int * numberRead,
+                               int * startIndex,
+                               int * arrayStride,
+                               int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDimensionsValues(values,
+                                          *dataType,
+                                          *numberRead,
+                                          *startIndex,
+                                          *arrayStride,
+                                          *valueStride);
+  }
+
+  void
+  XdmfRetrieveDimensionsValueType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType =  xdmfFortran->retrieveDimensionsValueType();
+  }
+
+  void
+  XdmfRetrieveDimensionsSize(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveDimensionsSize();
+  }
+
+  void  
+  XdmfRetrieveDimensionsNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveDimensionsNumProperties();
+  }
+
+  void
+  XdmfRetrieveDimensionsProperty(long * pointer,
+                                 int * index,
+                                 char * key,
+                                 int * keyLength,
+                                 char * value,
+                                 int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDimensionsProperty(*index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveDimensionsPropertyByKey(long * pointer, char * key, char * value, int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveDimensionsPropertyByKey(key, value, *valueLength);
+  }
+
+  int
+  XdmfSetOrigin(long * pointer, int  * numValues, int  * arrayType, void * pointValues)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setOrigin(*numValues, *arrayType, pointValues);
+  }
+
+  void
+  XdmfClearOriginHeavyData(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearOriginHeavyData();
+  }
+
+  void XdmfSetOriginHDF5(long * pointer,
+                         char * hdf5File,
+                         char * hdf5Dataset,
+                         unsigned int * start,
+                         unsigned int * stride,
+                         unsigned int * numValues,
+                         unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setOriginHDF5(hdf5File,
+                               hdf5Dataset,
+                               *start,
+                               *stride,
+                               *numValues,
+                               *dataspace);
+  }
+
+  void XdmfSetOriginBinary(long * pointer,
+                           char * binFile,
+                           int * endian,
+                           unsigned int * seek,
+                           unsigned int * start,
+                           unsigned int * stride,
+                           unsigned int * numValues,
+                           unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setOriginBinary(binFile,
+                                 *endian,
+                                 *seek,
+                                 *start,
+                                 *stride,
+                                 *numValues,
+                                 *dataspace);
+  }
+
+  void
+  XdmfSetPreviousOrigin(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setPreviousOrigin(*index);
+  }
+
+  void
+  XdmfClearPreviousOrigins(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousOrigins();
+  }
+
+  void
+  XdmfModifyOriginValues(long * pointer,
+                         void * values,
+                         int * arrayType,
+                         int * numValues,
+                         int * startIndex,
+                         int * arrayStride,
+                         int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyOriginValues(values,
+                                    *arrayType,
+                                    *numValues,
+                                    *startIndex,
+                                    *arrayStride,
+                                    *valueStride);
+  }
+
+  void
+  XdmfRetrieveOriginTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveOriginTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveOriginValues(long * pointer,
+                           void * values,
+                           int * dataType,
+                           int * numberRead,
+                           int * startIndex,
+                           int * arrayStride,
+                           int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveOriginValues(values,
+                                      *dataType,
+                                      *numberRead,
+                                      *startIndex,
+                                      *arrayStride,
+                                      *valueStride);
+  }
+
+  void
+  XdmfRetrieveOriginValueType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType =  xdmfFortran->retrieveOriginValueType();
+  }
+
+  void
+  XdmfRetrieveOriginSize(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveOriginSize();
+  }
+
+  void  
+  XdmfRetrieveOriginNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveOriginNumProperties();
+  }
+
+  void
+  XdmfRetrieveOriginProperty(long * pointer,
+                             int * index,
+                             char * key,
+                             int * keyLength,
+                             char * value,
+                             int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveOriginProperty(*index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveOriginPropertyByKey(long * pointer,
+                                  char * key,
+                                  char * value,
+                                  int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveOriginPropertyByKey(key, value, *valueLength);
+  }
+
+  int
+  XdmfSetBrick(long * pointer, int  * numValues, int  * arrayType, void * pointValues)
+  {
+
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setBrick(*numValues, *arrayType, pointValues);
+  }
+
+  void
+  XdmfClearBrickHeavyData(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearBrickHeavyData();
+  }
+
+  void XdmfSetBrickHDF5(long * pointer,
+                        char * hdf5File,
+                        char * hdf5Dataset,
+                        unsigned int * start,
+                        unsigned int * stride,
+                        unsigned int * numValues,
+                        unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setBrickHDF5(hdf5File,
+                              hdf5Dataset,
+                              *start,
+                              *stride,
+                              *numValues,
+                              *dataspace);
+  }
+
+  void XdmfSetBrickBinary(long * pointer,
+                          char * binFile,
+                          int * endian,
+                          unsigned int * seek,
+                          unsigned int * start,
+                          unsigned int * stride,
+                          unsigned int * numValues,
+                          unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setBrickBinary(binFile,
+                                *endian,
+                                *seek,
+                                *start,
+                                *stride,
+                                *numValues,
+                                *dataspace);
+  }
+
+  void
+  XdmfSetPreviousBrick(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setPreviousBrick(*index);
+  }
+
+  void
+  XdmfClearPreviousBricks(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousBricks();
+  }
+
+  void
+  XdmfModifyBrickValues(long * pointer,
+                        void * values,
+                        int * arrayType,
+                        int * numValues,
+                        int * startIndex,
+                        int * arrayStride,
+                        int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyBrickValues(values,
+                                   *arrayType,
+                                   *numValues,
+                                   *startIndex,
+                                   *arrayStride,
+                                   *valueStride);
+  }
+
+  void
+  XdmfRetrieveBrickTag(long * pointer, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveBrickTag(tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveBrickValues(long * pointer,
+                          void * values,
+                          int * dataType,
+                          int * numberRead,
+                          int * startIndex,
+                          int * arrayStride,
+                          int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveBrickValues(values,
+                                     *dataType,
+                                     *numberRead,
+                                     *startIndex,
+                                     *arrayStride,
+                                     *valueStride);
+  }
+
+  void
+  XdmfRetrieveBrickValueType(long * pointer, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType =  xdmfFortran->retrieveBrickValueType();
+  }
+
+  void
+  XdmfRetrieveBrickSize(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveBrickSize();
+  }
+
+  void  
+  XdmfRetrieveBrickNumProperties(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveBrickNumProperties();
+  }
+
+  void
+  XdmfRetrieveBrickProperty(long * pointer,
+                            int * index,
+                            char * key,
+                            int * keyLength,
+                            char * value,
+                            int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveBrickProperty(*index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveBrickPropertyByKey(long * pointer, char * key, char * value, int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveBrickPropertyByKey(key, value, *valueLength);
+  }
+
+  void
+  XdmfAddMap(long * pointer, char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addMap(name);
+  }
+
+  void
+  XdmfRetrieveNumMaps(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveNumMaps();
+  }
+
+  void
+  XdmfRetrieveMapTag(long * pointer, int * index, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveMapTag(*index, tag, *tagLength);
+  }
+
+  void
+  XdmfAddRemoteNodeID(long * pointer,
+                      int * index,
+                      int * localNodeID,
+                      int * remoteTaskID,
+                      int * remoteLocalNodeID)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addRemoteNodeID(*index,
+                                 *localNodeID,
+                                 *remoteTaskID,
+                                 *remoteLocalNodeID);
+  }
+
+  void
+  XdmfRetrieveRemoteNodeIDs(long * pointer,
+                            int * index,
+                            int * localNodeID,
+                            int * remoteTaskID,
+                            int * remoteLocalNodeIDs)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveRemoteNodeIDs(*index,
+                                       *localNodeID,
+                                       *remoteTaskID,
+                                       remoteLocalNodeIDs);
+  }
+
+  void
+  XdmfRetrieveNumRemoteNodeIDs(long * pointer,
+                               int * index,
+                               int * localNodeID,
+                               int * remoteTaskID,
+                               int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveNumRemoteNodeIDs(*index, *localNodeID, *remoteTaskID);
+  }
+
+  void
+  XdmfClearMaps(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearMaps();
+  }
+
+  void
+  XdmfRemoveMap(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeMap(*index);
+  }
+
+  int
+  XdmfStoreMap(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->storeMap(*index);
+  }
+
+  void
+  XdmfAddPreviousMap(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addPreviousMap(*index);
+  }
+
+  void
+  XdmfClearPreviousMaps(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousMaps();
+  }
+
+  void  
+  XdmfRetrieveMapNumProperties(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveMapNumProperties(*index);
+  }
+
+  void
+  XdmfRetrieveMapProperty(long * pointer,
+                          int * mapIndex,
+                          int * index,
+                          char * key,
+                          int * keyLength,
+                          char * value,
+                          int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveMapProperty(*mapIndex,
+                                     *index,
+                                     key,
+                                     *keyLength,
+                                     value,
+                                     *valueLength);
+  }
+
+  void
+  XdmfRetrieveMapPropertyByKey(long * pointer,
+                               int * index,
+                               char * key,
+                               char * value,
+                               int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveMapPropertyByKey(*index, key, value, *valueLength);
+  }
+
+  void
+  XdmfClearAttributes(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearAttributes();
+  }
+
+  void
+  XdmfModifyAttributeValues(long * pointer,
+                            int * index,
+                            void * values,
+                            int * arrayType,
+                            int * numValues,
+                            int * startIndex,
+                            int * arrayStride,
+                            int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyAttributeValues(*index,
+                                       values,
+                                       *arrayType,
+                                       *numValues,
+                                       *startIndex,
+                                       *arrayStride,
+                                       *valueStride);
+  }
+
+  void
+  XdmfRetrieveNumAttributes(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveNumAttributes();
+  }
+
+  void
+  XdmfReplaceAttribute(long * pointer,
+                       int * index,
+                       char * name,
+                       int * attributeCenter,
+                       int * attributeType,
+                       int * numValues,
+                       int * arrayType,
+                       void * values)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceAttribute(*index,
+                                  name,
+                                  *attributeCenter,
+                                  *attributeType,
+                                  *numValues,
+                                  *arrayType,
+                                  values);
+  }
+
+  void
+  XdmfRemoveAttribute(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeAttribute(*index);
+  }
+
+  void
+  XdmfOpenAttribute(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openAttribute(*index);
+  }
+
+  void
+  XdmfRetrieveAttributeTag(long * pointer, int * index, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveAttributeTag(*index, tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveAttributeName(long * pointer, int * index, char * name, int * nameLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveAttributeName(*index, name, *nameLength);
+  }
+
+  void
+  XdmfRetrieveAttributeValues(long * pointer,
+                              int * index,
+                              void * values,
+                              int * dataType,
+                              int * numberRead,
+                              int * startIndex,
+                              int * arrayStride,
+                              int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveAttributeValues(*index,
+                                         values,
+                                         *dataType,
+                                         *numberRead,
+                                         *startIndex,
+                                         *arrayStride,
+                                         *valueStride);
+  }
+
+  void
+  XdmfRetrieveAttributeType(long * pointer, int * index, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveAttributeType(*index);
+  }
+
+  void
+  XdmfRetrieveAttributeCenter(long * pointer, int * index, int * returnCenter)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnCenter = xdmfFortran->retrieveAttributeCenter(*index);
+  }
+
+  void
+  XdmfRetrieveAttributeValueType(long * pointer, int * index, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveAttributeValueType(*index);
+  }
+
+  void
+  XdmfRetrieveAttributeSize(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveAttributeSize(*index);
+  }
+
+  void
+  XdmfClearPreviousAttributes(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousAttributes();
+  }
+
+  void
+  XdmfRetrieveAttributeNumProperties(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveAttributeNumProperties(*index);
+  }
+
+  void
+  XdmfRetrieveAttributeProperty(long * pointer,
+                                int * attributeIndex,
+                                int * index,
+                                char * key,
+                                int * keyLength,
+                                char * value,
+                                int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveAttributeProperty(*attributeIndex,
+                                           *index,
+                                           key,
+                                           *keyLength,
+                                           value,
+                                           *valueLength);
+  }
+
+  void
+  XdmfRetrieveAttributePropertyByKey(long * pointer,
+                                     int * index,
+                                     char * key,
+                                     char * value,
+                                     int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveAttributePropertyByKey(*index, key, value, *valueLength);
+  }
+
+  void
+  XdmfSetAttributeAsVariable(long * pointer, char * varname, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setAttributeAsVariable(varname, *index);
+  }
+
+  void
+  XdmfSetAttributeAsSubsetReference(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setAttributeAsSubsetReference(*index);
+  }
+
+  void
+  XdmfRetrieveNumCoordinates(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveNumCoordinates();
+  }
+
+  int
+  XdmfAddCoordinate(long * pointer, char * name, int  * numValues, int  * arrayType, void * values)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addCoordinate(name, *numValues, *arrayType, values);
+  }
+
+  void
+  XdmfClearCoordinateHeavyData(long * pointer,
+                               int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearCoordinateHeavyData(*index);
+  }
+
+  void XdmfSetCoordinateHDF5(long * pointer,
+                             int * index,
+                             char * hdf5File,
+                             char * hdf5Dataset,
+                             unsigned int * start,
+                             unsigned int * stride,
+                             unsigned int * numValues,
+                             unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setCoordinateHDF5(*index,
+                                   hdf5File,
+                                   hdf5Dataset,
+                                   *start,
+                                   *stride,
+                                   *numValues,
+                                   *dataspace);
+  }
+
+  void XdmfSetCoordinateBinary(long * pointer,
+                               int * index,
+                               char * binFile,
+                               int * endian,
+                               unsigned int * seek,
+                               unsigned int * start,
+                               unsigned int * stride,
+                               unsigned int * numValues,
+                               unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setCoordinateBinary(*index,
+                                     binFile,
+                                     *endian,
+                                     *seek,
+                                     *start,
+                                     *stride,
+                                     *numValues,
+                                     *dataspace);
+  }
+
+  void
+  XdmfAddPreviousCoordinate(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addPreviousCoordinate(*index);
+  }
+
+  void
+  XdmfClearPreviousCoordinates(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousCoordinates();
+  }
+
+  void
+  XdmfReplaceCoordinate(long * pointer,
+                        int * index,
+                        char * name,
+                        int * numValues,
+                        int * arrayType,
+                        void * values)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceCoordinate(*index, name, *numValues, *arrayType, values);
+  }
+
+  void
+  XdmfRemoveCoordinate(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeCoordinate(*index);
+  }
+
+  void
+  XdmfRetrieveCoordinateTag(long * pointer, int * index, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveCoordinateTag(*index, tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveCooridnateName(long * pointer, int * index, char * name, int * nameLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveCoordinateName(*index, name, *nameLength);
+  }
+
+  void
+  XdmfRetrieveCoordinateValues(long * pointer,
+                               int * index,
+                               void * values,
+                               int * dataType,
+                               int * numberRead,
+                               int * startIndex,
+                               int * arrayStride,
+                               int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveCoordinateValues(*index,
+                                          values,
+                                          *dataType,
+                                          *numberRead,
+                                          *startIndex,
+                                          *arrayStride,
+                                          *valueStride);
+  }
+
+  void
+  XdmfRetrieveCoordinateValueType(long * pointer, int * index, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveCoordinateValueType(*index);
+  }
+
+  void
+  XdmfRetrieveCoordinateSize(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveCoordinateSize(*index);
+  }
+
+  void
+  XdmfClearCoordinates(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearCoordinates();
+  }
+
+  void
+  XdmfModifyCoordinateValues(long * pointer,
+                             int * index,
+                             void * values,
+                             int * arrayType,
+                             int * numValues,
+                             int * startIndex,
+                             int * arrayStride,
+                             int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyCoordinateValues(*index,
+                                        values,
+                                        *arrayType,
+                                        *numValues,
+                                        *startIndex,
+                                        *arrayStride,
+                                        *valueStride);
+  }
+
+  void
+  XdmfRetrieveCoordinateNumProperties(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveCoordinateNumProperties(*index);
+  }
+
+  void
+  XdmfRetrieveCoordinateProperty(long * pointer,
+                                 int * coordinateIndex,
+                                 int * index,
+                                 char * key,
+                                 int * keyLength,
+                                 char * value,
+                                 int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveCoordinateProperty(*coordinateIndex,
+                                            *index,
+                                            key,
+                                            *keyLength,
+                                            value,
+                                            *valueLength);
+  }
+
+  void
+  XdmfRetrieveCoordinatePropertyByKey(long * pointer,
+                                      int * index,
+                                      char * key,
+                                      char * value,
+                                      int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveCoordinatePropertyByKey(*index, key, value, *valueLength);
+  }
+
+  void
+  XdmfSetCoordinateAsVariable(long * pointer, char * varname, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setCoordinateAsVariable(varname, *index);
+  }
+
+  void
+  XdmfSetCoordinateAsSubsetReference(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setCoordinateAsSubsetReference(*index);
+  }
+
+  void
+  XdmfRetrieveSetTag(long * pointer, int * index, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveSetTag(*index, tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveSetName(long * pointer, int * index, char * name, int * nameLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveSetTag(*index, name, *nameLength);
+  }
+
+  void
+  XdmfRetrieveSetType(long * pointer, int * index, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveSetType(*index);
+  }
+
+  int
+  XdmfAddSet(long * pointer,
+             char * name,
+             int * newSetType,
+             char * values,
+             int * numValues,
+             int * arrayType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addSet(name, *newSetType, values, *numValues, *arrayType);
+  }
+
+  void
+  XdmfClearSetHeavyData(long * pointer,
+                        int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearSetHeavyData(*index);
+  }
+
+  void XdmfSetSetHDF5(long * pointer,
+                      int * index,
+                      char * hdf5File,
+                      char * hdf5Dataset,
+                      unsigned int * start,
+                      unsigned int * stride,
+                      unsigned int * numValues,
+                      unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setSetHDF5(*index,
+                            hdf5File,
+                            hdf5Dataset,
+                            *start,
+                            *stride,
+                            *numValues,
+                            *dataspace);
+  }
+
+  void XdmfSetSetBinary(long * pointer,
+                        int * index,
+                        char * binFile,
+                        int * endian,
+                        unsigned int * seek,
+                        unsigned int * start,
+                        unsigned int * stride,
+                        unsigned int * numValues,
+                        unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setSetBinary(*index,
+                              binFile,
+                              *endian,
+                              *seek,
+                              *start,
+                              *stride,
+                              *numValues,
+                              *dataspace);
+  }
+
+  void
+  XdmfAddPreviousSet(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addPreviousSet(*index);
+  }
+
+  void
+  XdmfClearPreviousSets(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousSets();
+  }
+
+  void
+  XdmfClearSets(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearSets();
+  }
+
+  void
+  XdmfModifySetValues(long * pointer,
+                      int * index,
+                      void * values,
+                      int * arrayType,
+                      int * numValues,
+                      int * startIndex,
+                      int * arrayStride,
+                      int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifySetValues(*index,
+                                 values,
+                                 *arrayType,
+                                 *numValues,
+                                 *startIndex,
+                                 *arrayStride,
+                                 *valueStride);
+  }
+
+  void
+  XdmfRetrieveNumSets(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveNumSets();
+  }
+
+  void
+  XdmfRetrieveSetSize(long * pointer, int * total, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveSetSize(*index);
+  }
+
+  void
+  XdmfRetrieveSetValueType(long * pointer, int * index, int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveSetValueType(*index);
+  }
+
+  void
+  XdmfRetrieveSetValues(long * pointer,
+                        int * index,
+                        void * values,
+                        int * dataType,
+                        int * numberRead,
+                        int * startIndex,
+                        int * arrayStride,
+                        int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveSetValues(*index,
+                                   values,
+                                   *dataType,
+                                   *numberRead,
+                                   *startIndex,
+                                   *arrayStride,
+                                   *valueStride);
+  }
+
+  void
+  XdmfOpenSet(long * pointer, int * index, int * openAttributes, int * openInformation)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openSet(*index, *openAttributes, *openInformation);
+  }
+
+  void
+  XdmfRemoveSet(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeSet(*index);
+  }
+
+  void
+  XdmfReplaceSet(long * pointer,
+                 int * index,
+                 char * name,
+                 int * newSetType,
+                 char * values,
+                 int * numValues,
+                 int * arrayType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceSet(*index, name, *newSetType, values, *numValues, *arrayType);
+  }
+
+  void
+  XdmfRetrieveSetNumProperties(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveSetNumProperties(*index);
+  }
+
+  void
+  XdmfRetrieveSetProperty(long * pointer,
+                          int * setIndex,
+                          int * index,
+                          char * key,
+                          int * keyLength,
+                          char * value,
+                          int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveSetProperty(*setIndex, *index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRetrieveSetPropertyByKey(long * pointer,
+                               int * index,
+                               char * key,
+                               char * value,
+                               int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveSetPropertyByKey(*index, key, value, *valueLength);
+  }
+
+  void
+  XdmfSetSetAsVariable(long * pointer, char * varname, int * index)
+  {
+   XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+   xdmfFortran->setSetAsVariable(varname, *index);
+  }
+
+  void
+  XdmfSetSetAsSubsetReference(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setSetAsSubsetReference(*index);
+  }
+
+  void
+  XdmfRetrieveNumInformation(long * pointer, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveNumInformation();
+  }
+
+  void
+  XdmfRetrieveInformationTag(long * pointer, int * index, char * tag, int * tagLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveInformationTag(*index, tag, *tagLength);
+  }
+
+  void
+  XdmfRetrieveInformation(long * pointer,
+                          int * index, 
+                          char * key,
+                          int * keyLength,
+                          char * value,
+                          int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveInformation(*index, key, *keyLength, value, *valueLength);
+  }
+
+  void
+  XdmfRemoveInformation(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeInformation(*index);
+  }
+
+  void
+  XdmfReplaceInformation(long * pointer, int * index, char * key, char * value)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceInformation(*index, key, value);
+  }
+
+  void
+  XdmfOpenInformation(long * pointer, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->openInformation(*index);
+  }
+
+  void
+  XdmfRetrieveInformationByKey(long * pointer, char * key, char * value, int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveInformationByKey(key, value, *valueLength);
+  }
+
+  void
+  XdmfRemoveInformationByKey(long * pointer, char * key)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeInformationByKey(key);
+  }
+
+  void
+  XdmfReplaceInformationByKey(long * pointer, char * key, char * value)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->replaceInformationByKey(key, value);
+  }
+
+  void
+  XdmfClearPreviousInformation(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPreviousInformation();
+  }
+
+  void
+  XdmfClearInformations(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearInformations();
+  }
+
+  void
+  XdmfRetrieveInformationNumProperties(long * pointer, int * index, int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveInformationNumProperties(*index);
+  }
+
+  void
+  XdmfRetrieveInformationProperty(long * pointer,
+                                  int * informationIndex,
+                                  int * index,
+                                  char * key,
+                                  int * keyLength,
+                                  char * value,
+                                  int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveInformationProperty(*informationIndex,
+                                             *index,
+                                             key,
+                                             *keyLength,
+                                             value,
+                                             *valueLength);
+  }
+
+  void
+  XdmfRetrieveInformationPropertyByKey(long * pointer, int * index, char * key, char * value, int * valueLength)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveInformationPropertyByKey(*index, key, value, *valueLength);
+  }
+
+  void
+  XdmfAddInformationArray(long * pointer, int * index, char * name, void * values, int * numValues, int * arrayType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addInformationArray(*index, name, values, *numValues, *arrayType);
+  }
+
+  void
+  XdmfClearInformationArrayHeavyData(long * pointer,
+                                     int * index,
+                                     int * arrayIndex)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->clearInformationArrayHeavyData(*index, *arrayIndex);
+  }
+
+  void XdmfSetInformationArrayHDF5(long * pointer,
+                                   int * index,
+                                   int * arrayIndex,
+                                   char * hdf5File,
+                                   char * hdf5Dataset,
+                                   unsigned int * start,
+                                   unsigned int * stride,
+                                   unsigned int * numValues,
+                                   unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setInformationArrayHDF5(*index,
+                                         *arrayIndex,
+                                         hdf5File,
+                                         hdf5Dataset,
+                                         *start,
+                                         *stride,
+                                         *numValues,
+                                         *dataspace);
+  }
+
+  void XdmfSetInformationArrayBinary(long * pointer,
+                                     int * index,
+                                     int * arrayIndex,
+                                     char * binFile,
+                                     int * endian,
+                                     unsigned int * seek,
+                                     unsigned int * start,
+                                     unsigned int * stride,
+                                     unsigned int * numValues,
+                                     unsigned int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setInformationArrayBinary(*index,
+                                           *arrayIndex,
+                                           binFile,
+                                           *endian,
+                                           *seek,
+                                           *start,
+                                           *stride,
+                                           *numValues,
+                                           *dataspace);
+  }
+
+  void
+  XdmfInsertInformationIntoInformation(long * pointer,
+                                       int * toIndex,
+                                       int * fromIndex,
+                                       bool * removeFromArray)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->insertInformationIntoInformation(*toIndex, *fromIndex, *removeFromArray);
+  }
+
+  void
+  XdmfModifyInformationArray(long * pointer,
+                             int * index,
+                             int * arrayIndex,
+                             void * values,
+                             int * arrayType,
+                             int * numValues,
+                             int * insertStart,
+                             int * arrayStride,
+                             int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->modifyInformationArray(*index,
+                                        *arrayIndex,
+                                        values,
+                                        *arrayType,
+                                        *numValues,
+                                        *insertStart,
+                                        *arrayStride,
+                                        *valueStride);
+  }
+
+  void
+  XdmfRemoveInformationArray(long * pointer, int * index, int * arrayIndex)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeInformationArray(*index, *arrayIndex);
+  }
+
+  void
+  XdmfRetrieveInformationArraySize(long * pointer,
+                                   int * index,
+                                   int * arrayIndex,
+                                   int * total)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *total = xdmfFortran->retrieveInformationArraySize(*index, *arrayIndex);
+  }
+
+  void
+  XdmfRetrieveInformationArrayValueType(long * pointer,
+                                        int * index,
+                                        int * arrayIndex,
+                                        int * returnType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    *returnType = xdmfFortran->retrieveInformationArrayValueType(*index, *arrayIndex);
+  }
+
+  void
+  XdmfRetrieveInformationArrayValues(long * pointer,
+                                     int * index,
+                                     int * arrayIndex,
+                                     void * values,
+                                     int * dataType,
+                                     int * numberRead,
+                                     int * startIndex,
+                                     int * arrayStride, 
+                                     int * valueStride)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->retrieveInformationArrayValues(*index,
+                                                *arrayIndex,
+                                                values,
+                                                *dataType,
+                                                *numberRead,
+                                                *startIndex,
+                                                *arrayStride,
+                                                *valueStride);
+  }
+
+  void
+  XdmfSetInformationArrayAsVariable(long * pointer, char * varname, int * infoindex, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setInformationArrayAsVariable(varname, *infoindex, *index);
+  }
+
+  void
+  XdmfSetInformationArrayAsSubsetReference(long * pointer, int * infoindex, int * index)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setInformationArrayAsSubsetReference(*infoindex, *index);
+  }
+
+  int
+  XdmfAddFunctionAsAttribute(long * pointer,
+                             char * expression,
+                             char * name,
+                             int * attributeCenter,
+                             int * attributeType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addFunctionAsAttribute(expression, name, *attributeCenter, *attributeType);
+  }
+
+  int
+  XdmfAddFunctionAsCoordinate(long * pointer,
+                              char * expression,
+                              char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addFunctionAsCoordinate(expression, name);
+  }
+
+  int
+  XdmfAddFunctionAsSet(long * pointer,
+                       char * expression,
+                       char * name,
+                       int * newSetType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addFunctionAsSet(expression, name, *newSetType);
+  }
+
+  void
+  XdmfAddFunctionAsInformationArray(long * pointer,
+                                    char * expression,
+                                    int * index,
+                                    char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addFunctionAsInformationArray(expression, *index, name);
+  }
+
+  int
+  XdmfSetFunctionAsTopology(long * pointer,
+                            char * expression,
+                            int * topologyType,
+                            int * numNodes)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setFunctionAsTopology(expression, *topologyType, *numNodes);
+  }
+
+  int
+  XdmfSetFunctionAsGeometry(long * pointer,
+                            char * expression,
+                            int * geometryType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setFunctionAsGeometry(expression, *geometryType);
+  }
+
+  int
+  XdmfAddSubsetAsAttribute(long * pointer,
+                           int * start,
+                           int * stride,
+                           int * dimensions,
+                           char * name,
+                           int * attributeCenter,
+                           int * attributeType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addSubsetAsAttribute(*start,
+                                             *stride,
+                                             *dimensions,
+                                             name,
+                                             *attributeCenter,
+                                             *attributeType);
+  }
+
+  int
+  XdmfAddSubsetAsCoordinate(long * pointer,
+                            int * start,
+                            int * stride,
+                            int * dimensions,
+                            char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addSubsetAsCoordinate(*start,
+                                              *stride,
+                                              *dimensions,
+                                              name);
+  }
+
+  int
+  XdmfAddSubsetAsSet(long * pointer,
+                     int * start,
+                     int * stride,
+                     int * dimensions,
+                     char * name,
+                     int * newSetType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->addSubsetAsSet(*start,
+                                       *stride,
+                                       *dimensions,
+                                       name,
+                                       *newSetType);
+  }
+
+  void
+  XdmfAddSubsetAsInformationArray(long * pointer,
+                                  int * start,
+                                  int * stride,
+                                  int * dimensions,
+                                  int * index,
+                                  char * name)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->addSubsetAsInformationArray(*start,
+                                             *stride,
+                                             *dimensions,
+                                             *index,
+                                             name);
+  }
+
+  int
+  XdmfSetSubsetAsTopology(long * pointer,
+                          int * start,
+                          int * stride,
+                          int * dimensions,
+                          int * topologyType,
+                          int * numNodes)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);\
+    return xdmfFortran->setSubsetAsTopology(*start,
+                                            *stride,
+                                            *dimensions,
+                                            *topologyType,
+                                            *numNodes);
+  }
+
+  int
+  XdmfSetSubsetAsGeometry(long * pointer,
+                          int * start,
+                          int * stride,
+                          int * dimensions,
+                          int * geometryType)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setSubsetAsGeometry(*start,
+                                            *stride,
+                                            *dimensions,
+                                            *geometryType);
+  }
+
+  void
+  XdmfClearFunctionVariables(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearFunctionVariables();
+  }
+
+  void
+  XdmfRemoveFunctionVariable(long * pointer, char * varname)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->removeFunctionVariable(varname);
+  }
+
+  void
+  XdmfClearPrevious(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->clearPrevious();
+  }
+
+  void
+  XdmfSetAllowSetSplitting(long * pointer, bool * newAllow)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setAllowSetSplitting(*newAllow);
+  }
+
+  void
+  XdmfSetMaxFileSize(long * pointer, int * newSize)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->setMaxFileSize(*newSize);
+  }
+
+  void
+  XdmfWrite(long * pointer,
+            char * xmlFilePath,
+            int * datalimit,
+            bool * release)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->write(xmlFilePath, *datalimit, *release);
+  }
+
+#ifdef XDMF_BUILD_DSM
+
+  void
+  XdmfInitDSMServer(long * pointer,
+                    char * filePath,
+                    MPI_Fint * comm,
+                    int * bufferSize,
+                    int * startCoreIndex,
+                    int * endCoreIndex)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    MPI_Comm tempComm = MPI_Comm_f2c(*comm);
+    xdmfFortran->initDSMServer(filePath,
+                               tempComm,
+                               *bufferSize,
+                               *startCoreIndex,
+                               *endCoreIndex);
+  }
+
+  void
+  XdmfAcceptDSM(long * pointer, int * numConnections)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->acceptDSM(*numConnections);
+  }
+
+  void
+  XdmfCloseDSMPort(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->closeDSMPort();
+  }
+
+  void
+  XdmfConnectDSM(long * pointer,
+                 char * filePath,
+                 MPI_Fint * comm)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    MPI_Comm tempComm = MPI_Comm_f2c(*comm);
+    xdmfFortran->connectDSM(filePath, tempComm);
+  }
+
+  void
+  XdmfGetDSMInterComm(long * pointer, MPI_Fint * returnComm)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    MPI_Comm tempComm = xdmfFortran->getDSMInterComm();
+    *returnComm = MPI_Comm_c2f(tempComm);
+  }
+
+  void
+  XdmfGetDSMIntraComm(long * pointer, MPI_Fint * returnComm)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    MPI_Comm tempComm = xdmfFortran->getDSMIntraComm();
+    *returnComm = MPI_Comm_c2f(tempComm);
+  }
+
+  void
+  XdmfStopDSM(long * pointer)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->stopDSM();
+  }
+
+  void
+  XdmfReadFromDSM(long * pointer,
+                  char * dsmDataSetPath,
+                  int * arrayType,
+                  void * values,
+                  int * start,
+                  int * stride,
+                  int * dimensions,
+                  int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->readFromDSM(dsmDataSetPath,
+                             *arrayType,
+                             values,
+                             *start,
+                             *stride,
+                             *dimensions,
+                             *dataspace);
+  }
+
+  void
+  XdmfWriteToDSM(long * pointer,
+                 char * dsmDataSetPath,
+                 int * arrayType,
+                 void * values,
+                 int * start,
+                 int * stride,
+                 int * dimensions,
+                 int * dataspace)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->writeToDSM(dsmDataSetPath,
+                            *arrayType,
+                            values,
+                            *start,
+                            *stride,
+                            *dimensions,
+                            *dataspace);
+  }
+
+#endif
+
+  void
+  XdmfWriteHDF5(long * pointer,
+                char * xmlFilePath,
+                bool * release)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->writeHDF5(xmlFilePath, release);
+  }
+
+  void
+  XdmfInitHDF5(long * pointer,
+                char * xmlFilePath,
+                bool * release)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    xdmfFortran->initHDF5(xmlFilePath, release);
+  }
+
+  void
+  XdmfRead(long * pointer,
+           char * xmlFilePath)
+  {
+    struct stat buffer;
+    if ( stat(xmlFilePath, &buffer) == 0 ) { 
+       XdmfFortran * xdmfFortran = (XdmfFortran *) *pointer;
+       xdmfFortran->read( xmlFilePath );
+    }   
+  }
+
+  int
+  XdmfSetTopologyPolyline(long * pointer,
+                          int * nodesPerElement,
+                          int * numValues,
+                          int * arrayType,
+                          void * connectivityValues)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setTopologyPolyline(*nodesPerElement,
+                                            *numValues,
+                                            *arrayType,
+                                            connectivityValues);
+  }
+
+  int
+  XdmfSetTopologyPolygon(long * pointer,
+                         int * nodesPerElement,
+                         int * numValues,
+                         int * arrayType,
+                         void * connectivityValues)
+  {
+    XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
+    return xdmfFortran->setTopologyPolygon(*nodesPerElement,
+                                           *numValues,
+                                           *arrayType,
+                                           connectivityValues);
+  }
+}
diff --git a/utils/XdmfFortran.hpp b/utils/XdmfFortran.hpp
new file mode 100644
index 0000000..d2b439a
--- /dev/null
+++ b/utils/XdmfFortran.hpp
@@ -0,0 +1,3934 @@
+/*******************************************************************/
+/*                               XDMF                              */
+/*                   eXtensible Data Model and Format              */
+/*                                                                 */
+/*  Id : Id  */
+/*  Date : $Date$ */
+/*  Version : $Revision$ */
+/*                                                                 */
+/*  Author:                                                        */
+/*     John Vines                                                  */
+/*     john.m.vines at us.army.mil                                    */
+/*     US Army Research Laboratory                                 */
+/*     Aberdeen Proving Ground, MD                                 */
+/*                                                                 */
+/*     Copyright @ 2012 US Army Research Laboratory                */
+/*     All Rights Reserved                                         */
+/*     See Copyright.txt or http://www.arl.hpc.mil/ice for details */
+/*                                                                 */
+/*     This software is distributed WITHOUT ANY WARRANTY; without  */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS     */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice   */
+/*     for more information.                                       */
+/*                                                                 */
+/*******************************************************************/
+#ifndef XDMFFORTRAN_HPP_
+#define XDMFFORTRAN_HPP_
+
+// Forward Declarations
+class XdmfAttribute;
+class XdmfDomain;
+class XdmfGeometry;
+class XdmfGridCollection;
+class XdmfFunction;
+class XdmfInformation;
+class XdmfTime;
+class XdmfTopology;
+class XdmfSubset;
+class XdmfArray;
+class XdmfMap;
+class XdmfSet;
+class XdmfCurvilinearGrid;
+class XdmfRectilinearGrid;
+class XdmfRegularGrid;
+class XdmfUnstructuredGrid;
+class XdmfHeavyDataWriter;
+class XdmfHDF5WriterDSM;
+
+//Includes
+#include <stack>
+#include <vector>
+#include <map>
+#include "XdmfUtils.hpp"
+#include "XdmfSharedPtr.hpp"
+
+#ifdef XDMF_BUILD_DSM 
+  #include "mpi.h"
+#endif
+
+/**
+ * Array Type
+ */
+#define XDMF_ARRAY_TYPE_INT8                             0
+#define XDMF_ARRAY_TYPE_INT16                            1
+#define XDMF_ARRAY_TYPE_INT32                            2
+#define XDMF_ARRAY_TYPE_INT64                            3
+#define XDMF_ARRAY_TYPE_UINT8                            4
+#define XDMF_ARRAY_TYPE_UINT16                           5
+#define XDMF_ARRAY_TYPE_UINT32                           6
+#define XDMF_ARRAY_TYPE_FLOAT32                          7
+#define XDMF_ARRAY_TYPE_FLOAT64                          8
+
+/**
+ * Attribute Center
+ */
+#define XDMF_ATTRIBUTE_CENTER_GRID                       100
+#define XDMF_ATTRIBUTE_CENTER_CELL                       101
+#define XDMF_ATTRIBUTE_CENTER_FACE                       102
+#define XDMF_ATTRIBUTE_CENTER_EDGE                       103
+#define XDMF_ATTRIBUTE_CENTER_NODE                       104
+
+/**
+ * Attribute Type
+ */
+#define XDMF_ATTRIBUTE_TYPE_SCALAR                       200
+#define XDMF_ATTRIBUTE_TYPE_VECTOR                       201
+#define XDMF_ATTRIBUTE_TYPE_TENSOR                       202
+#define XDMF_ATTRIBUTE_TYPE_MATRIX                       203
+#define XDMF_ATTRIBUTE_TYPE_TENSOR6                      204
+#define XDMF_ATTRIBUTE_TYPE_GLOBALID                     205
+#define XDMF_ATTRIBUTE_TYPE_NOTYPE                       206
+
+/**
+ * Geometry Type
+ */
+#ifndef XDMF_GEOMETRY_TYPE_XYZ
+  #define XDMF_GEOMETRY_TYPE_XYZ                         301
+#endif
+#ifndef XDMF_GEOMETRY_TYPE_XY
+  #define XDMF_GEOMETRY_TYPE_XY                          302
+#endif
+#ifndef XDMF_GEOMETRY_TYPE_POLAR
+  #define XDMF_GEOMETRY_TYPE_POLAR                       303
+#endif
+#ifndef XDMF_GEOMETRY_TYPE_SPHERICAL
+  #define XDMF_GEOMETRY_TYPE_SPHERICAL                   304
+#endif
+
+
+/**
+ * Grid Collection Type
+ */
+#define XDMF_GRID_COLLECTION_TYPE_SPATIAL                400
+#define XDMF_GRID_COLLECTION_TYPE_TEMPORAL               401
+
+/**
+ * Topology Type
+ */
+#ifndef XDMF_C_TOPOLOGY_TYPES
+#define XDMF_C_TOPOLOGY_TYPES
+#define XDMF_TOPOLOGY_TYPE_POLYVERTEX                    500
+#define XDMF_TOPOLOGY_TYPE_POLYLINE                      501
+#define XDMF_TOPOLOGY_TYPE_POLYGON                       502
+#define XDMF_TOPOLOGY_TYPE_POLYHEDRON                    503
+#define XDMF_TOPOLOGY_TYPE_TRIANGLE                      504
+#define XDMF_TOPOLOGY_TYPE_QUADRILATERAL                 505
+#define XDMF_TOPOLOGY_TYPE_TETRAHEDRON                   506
+#define XDMF_TOPOLOGY_TYPE_PYRAMID                       507
+#define XDMF_TOPOLOGY_TYPE_WEDGE                         508
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON                    509
+#define XDMF_TOPOLOGY_TYPE_EDGE_3                        510
+#define XDMF_TOPOLOGY_TYPE_TRIANGLE_6                    511
+#define XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8               512
+#define XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9               513
+#define XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10                514
+#define XDMF_TOPOLOGY_TYPE_PYRAMID_13                    515
+#define XDMF_TOPOLOGY_TYPE_WEDGE_15                      516
+#define XDMF_TOPOLOGY_TYPE_WEDGE_18                      517
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20                 518
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24                 519
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27                 520
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64                 521
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125                522
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216                523
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343                524
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512                525
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729                526
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000               527
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331               528
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64        529
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125       530
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216       531
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343       532
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512       533
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729       534
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000      535
+#define XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331      536
+#define XDMF_TOPOLOGY_TYPE_MIXED                         537
+#endif
+
+/**
+ * Set Type
+ */
+#define XDMF_SET_TYPE_NODE                               601
+#define XDMF_SET_TYPE_CELL                               602
+#define XDMF_SET_TYPE_FACE                               603
+#define XDMF_SET_TYPE_EDGE                               604
+
+/**
+ * Grid Type
+ */
+#define XDMF_GRID_TYPE_CURVILINEAR                       701
+#define XDMF_GRID_TYPE_RECTILINEAR                       702
+#define XDMF_GRID_TYPE_REGULAR                           703
+#define XDMF_GRID_TYPE_UNSTRUCTURED                      704
+
+/**
+ * Binary Endian
+ */
+#define XDMF_BINARY_ENDIAN_NATIVE                        801
+#define XDMF_BINARY_ENDIAN_LITTLE                        802
+#define XDMF_BINARY_ENDIAN_BIG                           803
+
+
+// This works with g77 and gfortran. Different compilers require different
+// name mangling.
+#if !defined(WIN32)
+#define XdmfInit xdmfinit_
+#define XdmfClose xdmfclose_
+#define XdmfAddAttribute xdmfaddattribute_
+#define XdmfClearAttributeHeavyData xdmfclearattributeheavydata_
+#define XdmfSetAttributeHDF5 xdmfsetattributehdf5_
+#define XdmfSetAttributeBinary xdmfsetattributebinary_
+#define XdmfAddGrid xdmfaddgrid_
+#define XdmfAddGridCurvilinear xdmfaddgridcurvilinear_
+#define XdmfAddGridRectilinear xdmfaddgridrectilinear_
+#define XdmfAddGridRegular xdmfaddgridregular_
+#define XdmfAddGridCollection xdmfaddgridcollection_
+#define XdmfAddGridReference xdmfaddgridreference__
+#define XdmfAddGridCollectionReference xdmfaddgridcollectionreference_
+#define XdmfAddInformation xdmfaddinformation_
+#define XdmfAddPreviousAttribute xdmfaddpreviousattribute_
+#define XdmfAddPreviousInformation xdmfaddpreviousinformation_
+#define XdmfCloseGridCollection xdmfclosegridcollection_
+#define XdmfSetGeometry xdmfsetgeometry_
+#define XdmfClearGeometryHeavyData xdmfcleargeometryheavydata_
+#define XdmfSetGeometryHDF5 xdmfsetgeometryhdf5_
+#define XdmfSetGeometryBinary xdmfsetgeometrybinary_
+#define XdmfSetPreviousGeometry xdmfsetpreviousgeometry_
+#define XdmfSetPreviousTopology xdmfsetprevioustopology_
+#define XdmfSetTime xdmfsettime_
+#define XdmfSetTopology xdmfsettopology_
+#define XdmfClearTopologyHeavyData xdmfcleartopologyheavydata_
+#define XdmfSetTopologyHDF5 xdmfsettopologyhdf5_
+#define XdmfSetTopologyBinary xdmfsettopologybinary_
+#define XdmfSetAllowSetSplitting xdmfsetallowsetsplitting_
+#define XdmfSetMaxFileSize xdmfsetmaxfilesize_
+#define XdmfWrite xdmfwrite_
+#define XdmfRead xdmfread_
+#define XdmfInitDSMServer xdmfinitdsmserver_
+#define XdmfAcceptDSM xdmfacceptdsm_
+#define XdmfCloseDSMPort xdmfclosedsmport_
+#define XdmfConnectDSM xdmfconnectdsm_
+#define XdmfGetDSMInterComm xdmfgetdsmintercomm_
+#define XdmfGetDSMIntraComm xdmfgetdsmintracomm_
+#define XdmfStopDSM xdmfstopdsm_
+#define XdmfReadFromDSM xdmfreadfromdsm_
+#define XdmfWriteToDSM xdmfwritetodsm_
+#define XdmfWriteHDF5 xdmfwritehdf5_
+#define XdmfInitHDF5 xdmfinithdf5_
+#define XdmfSetTopologyPolyline xdmfsettopologypolyline_
+#define XdmfSetTopologyPolygon xdmfsettopologypolygon_
+#define XdmfRetrieveNumDomainGridCollections xdmfretrievenumdomaingridcollections_
+#define XdmfRetrieveNumGridCollectionGridCollections xdmfretrievenumgridcollectiongridcollections_
+#define XdmfRetrieveDomainTag xdmfretrievedomaintag_
+#define XdmfRetrieveDomainNumProperties xdmfretrievedomainnumproperties_
+#define XdmfRetrieveDomainProperty xdmfretrievedomainproperty_
+#define XdmfRetrieveDomainPropertyByKey xdmfretrievedomainpropertybykey_
+#define XdmfOpenDomainGridCollection xdmfopendomaingridcollection_
+#define XdmfReadDomainnGridCollection xdmfreaddomaingridcollection_
+#define XdmfRemoveDomainGridCollection xdmfremovedomaingridcollection_
+#define XdmfOpenGridCollectionGridCollection xdmfopengridcollectiongridcollection_
+#define XdmfReadGridCollectionGridCollection xdmfreadgridcollectiongridcollection_
+#define XdmfRemoveGridCollectionGridCollection xdmfremovegricollectiongridcollection_
+#define XdmfRetrieveGridCollectionTag xdmfretrievegridcollectiontag_
+#define XdmfRetrieveGridCollectionNumProperties xdmfretrievegridcollectionnumproperties_
+#define XdmfRetrieveGridCollectionProperty xdmfretrievegridcollectionproperty_
+#define XdmfRetrieveGridCollectionPropertyByKey xdmfretrievegridcollectionpropertybykey_
+#define XdmfRetrieveGridCollectionNumGrids xdmfretrievegridcollectionnumgrids_
+#define XdmfRetrieveDomainNumGrids xdmfretrievedomainnumgrids_
+#define XdmfOpenDomainGrid xdmfopendomaingrid_
+#define XdmfReadDomainGrid xdmfreaddomaingrid_
+#define XdmfRemoveDomainGrid xdmfremovedomaingrid_
+#define XdmfReplaceDomainGrid xdmfreplacedomaingrid_
+#define XdmfRetrieveDomainGridTag xdmfretrievedomaingridtag_
+#define XdmfRetrieveDomainGridName xdmfretrievedomaingridname_
+#define XdmfRetrieveDomainGridNumProperties xdmfretrievedomaingridnumproperties_
+#define XdmfRetrieveDomainGridProperty xdmfretrievedomaingridproperty_
+#define XdmfRetrieveDomainGridPropertyByKey xdmfretrievedomaingridpropertybykey_
+#define XdmfOpenGridCollectionGrid xdmfopengridcollectiongrid_
+#define XdmfReadGridCollectionGrid xdmfreadgridcollectiongrid_
+#define XdmfRemoveGridCollectionGrid xdmfremovegridcollectiongrid_
+#define XdmfReplaceGridCollectionGrid xdmfreplacegridcollectiongrid_
+#define XdmfRetrieveGridCollectionGridTag xdmfretrievegridcollectiongridtag_
+#define XdmfRetrieveGridCollectionGridName xdmfretrievegridcollectiongridname_
+#define XdmfRetrieveGridCollectionGridNumProperties xdmfretrievegridcollectiongridnumproperties_
+#define XdmfRetrieveGridCollectionGridProperty xdmfretrievegridcollectiongridproperty_
+#define XdmfRetrieveGridCollectionGridPropertyByKey xdmfretrievegridcollectiongridpropertybykey_
+#define XdmfRetrieveGridCollectionType xdmfretrievegridcollectiontype_
+#define XdmfRetrieveTime xdmfretrievetime_
+#define XdmfRetrieveTopologyTag xdmfretrievetopologytag_
+#define XdmfRetrieveTopologyType xdmfretrievetopologytype_
+#define XdmfRetrieveTopologyValueType xdmfretrievetopologyvaluetype_
+#define XdmfRetrieveTopologyValues xdmfretrievetopologyvalues_
+#define XdmfRetrieveTopologyNumElements xdmfretrievetopologynumelements_
+#define XdmfRetrieveTopologySize xdmfretrievetopologysize_
+#define XdmfClearPreviousTopologies xdmfclearprevioustopologies_
+#define XdmfModifyTopologyValues xdmfmodifytopologyvalues_
+#define XdmfRetrieveTopologyNumProperties xdmfretrievetopologynumproperties_
+#define XdmfRetrieveTopologyProperty xdmfretrievetopologyproperty_
+#define XdmfRetrieveTopologyPropertyByKey xdmfretrievetopologypropertybykey_
+#define XdmfSetTopologyAsVariable xdmfsettopologyasvariable_
+#define XdmfSetTopologyAsSubsetReference xdmfsettopologyassubsetreference_
+#define XdmfRetrieveGeometryTag xdmfretrievegeometrytag_
+#define XdmfRetrieveGeometryType xdmfretrievegeometrytype_
+#define XdmfRetrieveGeometryValues xdmfretrievegeometryvalues_
+#define XdmfRetrieveGeometryValueType xdmfretrievegeometryvaluetype_
+#define XdmfRetrieveGeometryNumPoints xdmfretrievegeometrynumpoints_
+#define XdmfRetrieveGeometrySize xdmfretrievegeometrysize_
+#define XdmfClearPreviousGeometries xdmfclearpreviousgeometries_
+#define XdmfModifyGeometryValues xdmfmodifygeometryvalues_
+#define XdmfRetrieveGeometryNumProperties xdmfretrievegeometrynumproperties_
+#define XdmfRetrieveGeometryProperty xdmfretrievegeometryproperty_
+#define XdmfRetrieveGeometryPropertyByKey xdmfretrievegeometrypropertybykey_
+#define XdmfSetGeometryAsVariable xdmfsetgeometryasvariable_
+#define XdmfSetGeometryAsSubsetReference xdmfsetgeometryassubsetreference_
+#define XdmfSetDimensions xdmfsetdimensions_
+#define XdmfClearDimensionsHeavyData xdmfcleardimensionsheavydata_
+#define XdmfSetDimensionsHDF5 xdmfsetdimensionshdf5_
+#define XdmfSetDimensionsBinary xdmfsetdimensionsbinary_
+#define XdmfOpenPreviousDimensions xdmfopenpreviousdimensions_
+#define XdmfClearPreviousDimensions xdmfclearpreviousdimensions_
+#define XdmfModifyDimensionsValues xdmfmodifydimensionsvalues_
+#define XdmfRetrieveDimensionsTag xdmfretrievedimensionstag_
+#define XdmfRetrieveDimensionsType xdmfretrievedimensionstype_
+#define XdmfRetrieveDimensionsValueType xdmfretrievedimensionsvaluetype_
+#define XdmfRetrieveDimensionsValues xdmfretrievedimensionsvalues_
+#define XdmfRetrieveDimensionsNumElements xdmfretrievedimensionsnumelements_
+#define XdmfRetrieveDimensionsSize xdmfretrievedimensionssize_
+#define XdmfRetrieveDimensionsNumProperties xdmfretrievedimensionsnumproperties_
+#define XdmfRetrieveDimensionsProperty xdmfretrievedimensionsproperty_
+#define XdmfRetrieveDimensionsPropertyByKey xdmfretrievedimensionspropertybykey_
+#define XdmfSetOrigin xdmfsetorigin_
+#define XdmfClearOriginHeavyData xdmfclearoriginheavydata_
+#define XdmfSetOriginHDF5 xdmfsetoriginhdf5_
+#define XdmfSetOriginBinary xdmfsetoriginbinary_
+#define XdmfSetPreviousOrigin xdmfsetpreviousorigin_
+#define XdmfClearPreviousOrigins xdmfclearpreviousorigins_
+#define XdmfModifyOriginValues xdmfmodifyoriginvalues_
+#define XdmfRetrieveOriginTag xdmfretrieveorigintag_
+#define XdmfRetrieveOriginType xdmfretrieveorigintype_
+#define XdmfRetrieveOriginValueType xdmfretrieveoriginvaluetype_
+#define XdmfRetrieveOriginValues xdmfretrieveoriginvalues_
+#define XdmfRetrieveOriginNumElements xdmfretrieveoriginnumelements_
+#define XdmfRetrieveOriginSize xdmfretrieveoriginsize_
+#define XdmfRetrieveOriginNumProperties xdmfretrieveoriginnumproperties_
+#define XdmfRetrieveOriginProperty xdmfretrieveoriginproperty_
+#define XdmfRetrieveOriginPropertyByKey xdmfretrieveoriginpropertybykey_
+#define XdmfSetBrick xdmfsetbrick_
+#define XdmfClearBrickHeavyData xdmfclearbrickheavydata_
+#define XdmfSetBrickHDF5 xdmfsetbrickhdf5_
+#define XdmfSetBrickBinary xdmfsetbrickbinary_
+#define XdmfSetPreviousBrick xdmfsetpreviousbrick_
+#define XdmfClearPreviousBricks xdmfclearpreviousbricks_
+#define XdmfModifyBrickValues xdmfmodifybrickvalues_
+#define XdmfRetrieveBrickTag xdmfretrievebricktag_
+#define XdmfRetrieveBrickType xdmfretrievebricktype_
+#define XdmfRetrieveBrickValueType xdmfretrievebrickvaluetype_
+#define XdmfRetrieveBrickValues xdmfretrievebrickvalues_
+#define XdmfRetrieveBrickNumElements xdmfretrievebricknumelements_
+#define XdmfRetrieveBrickSize xdmfretrievebricksize_
+#define XdmfRetrieveBrickNumProperties xdmfretrievebricknumproperties_
+#define XdmfRetrieveBrickProperty xdmfretrievebrickproperty_
+#define XdmfRetrieveBrickPropertyByKey xdmfretrievebrickpropertybykey_
+#define XdmfAddMap xdmfaddmap_
+#define XdmfRetrieveNumMaps xdmfretrievenummaps_
+#define XdmfAddRemoteNodeID xdmfaddremotenodeid_
+#define XdmfRetrieveRemoteNodeIDs xdmfretrieveremotenodeids_
+#define XdmfRetrieveNumRemoteNodeIDs xdmfretrievenumremotenodeids_
+#define XdmfRemoveMap xdmfremovemap_
+#define XdmfClearMaps xdmfclearmaps_
+#define XdmfStoreMap xdmfstoremap_
+#define XdmfAddPreviousMap xdmfaddpreviousmap_
+#define XdmfClearPreviousMaps xdmfclearpreviousmaps_
+#define XdmfRetrieveMapNumProperties xdmfretrievemapnumproperties_
+#define XdmfRetrieveMapProperty xdmfretrievemapproperty_
+#define XdmfRetrieveMapPropertyByKey xdmfretrievemappropertybykey_
+#define XdmfRetrieveNumAttributes xdmfretrievenumattributes_
+#define XdmfClearAttributes xdmfclearattributes_
+#define XdmfModifyAttributeValues xdmfmodifyattributevalues_
+#define XdmfRemoveAttribute xdmfremoveattribute_
+#define XdmfReplaceAttribute xdmfreplaceattribute_
+#define XdmfOpenAttribute xdmfopenattribute_
+#define XdmfRetrieveAttributeTag xdmfretrieveattributetag_
+#define XdmfRetrieveAttributeName xdmfretrieveattributename_
+#define XdmfRetrieveAttributeType xdmfretrieveattributetype_
+#define XdmfRetrieveAttributeCenter xdmfretrieveattributecenter_
+#define XdmfRetrieveAttributeValues xdmfretrieveattributevalues_
+#define XdmfRetrieveAttributeValueType xdmfretrieveattributevaluetype_
+#define XdmfRetrieveAttributeSize xdmfretrieveattributesize_
+#define XdmfClearPreviousAttributes xdmfclearpreviousattributes_
+#define XdmfRetrieveAttributeNumProperties xdmfretrieveattributenumproperties_
+#define XdmfRetrieveAttributeProperty xdmfretrieveattributeproperty_
+#define XdmfRetrieveAttributePropertyByKey xdmfretrieveattributepropertybykey_
+#define XdmfSetAttributeAsVariable xdmfsetattributeasvariable_
+#define XdmfSetAttributeAsSubsetReference xdmfsetattributeassubsetreference_
+#define XdmfAddCoordinate xdmfaddcoordinate_
+#define XdmfClearCoordinateHeavyData xdmfclearcoordinateheavydata_
+#define XdmfSetCoordinateHDF5 xdmfsetcoordinatehdf5_
+#define XdmfSetCoordinateBinary xdmfsetcoordinatebinary_
+#define XdmfAddPreviousCoordinate xdmfaddpreviouscoordinate_
+#define XdmfClearPreviousCoordinates xdmfclearpreviouscoordinates_
+#define XdmfModifyCoordinateValues xdmfmodifycoordinatevalues_
+#define XdmfRetrieveNumCoordinates xdmfretrievenumcoordinates_
+#define XdmfRemoveCoordinate xdmfremovecoordinate_
+#define XdmfReplaceCoordinate xdmfreplacecoordinate_
+#define XdmfRetrieveCoordinateTag xdmfretrievecoordinatetag_
+#define XdmfRetrieveCoordinateName xdmfretrievecoordinatename_
+#define XdmfRetrieveCoordinateValues xdmfretrievecoordinatevalues_
+#define XdmfRetrieveCoordinateValueType xdmfretrievecoordinatevaluetype_
+#define XdmfRetrieveCoordinateSize xdmfretrievecoordinatesize_
+#define XdmfClearCoordinates xdmfclearcoordinates_
+#define XdmfRetrieveCoordinateNumProperties xdmfretrievecoordinatenumproperties_
+#define XdmfRetrieveCoordinateProperty xdmfretrievecoordinateproperty_
+#define XdmfRetrieveCoordinatePropertyByKey xdmfretrievecoordinatepropertybykey_
+#define XdmfSetCoordinateAsVariable xdmfsetcoordinateasvariable_
+#define XdmfSetCoordinateAsSubsetReference xdmfsetcoordinateassubsetreference_
+#define XdmfRetrieveSetTag xdmfretrievesettag_
+#define XdmfRetrieveSetName xdmfretrievesetname_
+#define XdmfRetrieveSetType xdmfretrievesettype_
+#define XdmfAddSet xdmfaddset_
+#define XdmfAddPreviousSet xdmfaddpreviousset_
+#define XdmfClearSetHeavyData xdmfclearsetheavydata_
+#define XdmfSetSetHDF5 xdmfsetsethdf5_
+#define XdmfSetSetBinary xdmfsetsetbinary_
+#define XdmfClearPreviousSets xdmfclearprevioussets_
+#define XdmfClearSets xdmfclearsets_
+#define XdmfModifySetValues xdmfmodifysetvalues_
+#define XdmfRetrieveNumSets xdmfretrievenumsets_
+#define XdmfRetrieveSetSize xdmfretrievesetsize_
+#define XdmfRetrieveSetValues xdmfretrievesetvalues_
+#define XdmfRetrieveSetValueType xdmfretrievesetvaluetype_
+#define XdmfOpenSet xdmfopenset_
+#define XdmfRemoveSet xdmfremoveset_
+#define XdmfReplaceSet xdmfreplaceset_
+#define XdmfRetrieveSetNumProperties xdmfretrievesetnumproperties_
+#define XdmfRetrieveSetProperty xdmfretrievesetproperty_
+#define XdmfRetrieveSetPropertyByKey xdmfretrievesetpropertybykey_
+#define XdmfSetSetAsVariable xdmfsetsetasvariable_
+#define XdmfSetSetAsSubsetReference xdmfsetsetassubsetreference_
+#define XdmfRetrieveNumInformation xdmfretrievenuminformation_
+#define XdmfRetrieveInformationTag xdmfretrieveinformationtag_
+#define XdmfClearInformations xdmfclearinformations_
+#define XdmfRetrieveInformation xdmfretrieveinformation_
+#define XdmfRemoveInformation xdmfremoveinformation_
+#define XdmfReplaceInformation xdmfreplaceinformation_
+#define XdmfOpenInformation xdmfopeninformation_
+#define XdmfRetrieveInformationByKey xdmfretrieveinformationbykey_
+#define XdmfRemoveInformationByKey xdmfremoveinformationbykey_
+#define XdmfReplaceInformationByKey xdmfreplaceinformationbykey_
+#define XdmfClearPreviousInformation xdmfclearpreviousinformation_
+#define XdmfRetrieveInformationNumProperties xdmfretrieveinformationnumproperties_
+#define XdmfRetrieveInformationProperty xdmfretrieveinformationproperty_
+#define XdmfRetrieveInformationPropertyByKey xdmfretrieveinformationpropertybykey_
+#define XdmfAddInformationArray xdmfaddinformationarray_
+#define XdmfClearInformationArrayHeavyData xdmfclearinformationarrayheavydata_
+#define XdmfSetInformationArrayHDF5 xdmfsetinformationarrayhdf5_
+#define XdmfSetInformationArrayBinary xdmfsetinformationarraybinary_
+#define XdmfInsertInformationIntoInformation xdmfinsertinformationintoinformation_
+#define XdmfModifyInformationArray xdmfmodifyinformationarray_
+#define XdmfRemoveInformationArray xdmfremoveinformationarray_
+#define XdmfRetrieveInformationArraySize xdmfretrieveinformationarraysize_
+#define XdmfRetrieveInformationArrayValueType xdmfretrieveinformationarrayvaluetype_
+#define XdmfRetrieveInformationArrayValues xdmfretrieveinformationarrayvalues_
+#define XdmfSetInformationArrayAsVariable xdmfsetinformationarrayasvariable_
+#define XdmfSetInformationArrayAsSubsetReference xdmfsetinformationarrayassubsetreference_
+#define XdmfAddFunctionAsAttribute xdmfaddfunctionasattribute_
+#define XdmfAddFunctionAsCoordinate xdmfaddfunctionascoordinate_
+#define XdmfAddFunctionAsSet xdmfaddfunctionasset_
+#define XdmfAddFunctionAsInformationArray xdmfaddfunctionasinformationarray_
+#define XdmfSetFunctionAsTopology xdmfsetfunctionastopology_
+#define XdmfSetFunctionAsGeometry xdmfsetfunctionasgeometry_
+#define XdmfAddSubsetAsAttribute xdmfaddsubsetasattribute_
+#define XdmfAddSubsetAsCoordinate xdmfaddsubsetascoordinate_
+#define XdmfAddSubsetAsSet xdmfaddsubsetasset_
+#define XdmfAddSubsetAsInformationArray xdmfaddsubsetasinformationarray_
+#define XdmfSetSubsetAsTopology xdmfsetsubsetastopology_
+#define XdmfSetSubsetAsGeometry xdmfsetsubsetasgeometry_
+#define XdmfClearFunctionVariables xdmfclearfunctionvariables_
+#define XdmfRemoveFunctionVariable xdmfremovefunctionvariable_
+#define XdmfClearPrevious xdmfclearprevious_
+#endif
+
+/**
+ * @brief XdmfFortran provides an interface to outputting xdmf files
+ * from Fortran.
+ *
+ * Fortran programs will include Xdmf.f and link against libXdmfUtils.
+ */
+class XDMFUTILS_EXPORT XdmfFortran {
+  
+public:
+
+  /**
+   * Create a new xdmf file from fortran.
+   *
+   * @return    Constructed XdmfFortran.
+   */
+  XdmfFortran();
+
+  virtual ~XdmfFortran();
+
+  /**
+   * Add an attribute that will be inserted into the next grid or grid
+   * collection.
+   *
+   * @param     name                    Name of the attribute.
+   * @param     attributeCenter         The attribute center.
+   * @param     attributeType           The attribute type.
+   * @param     numValues               Number of attribute values to copy.
+   * @param     arrayType               Type of attribute values.
+   * @param     values                  Array of attribute values.
+   *
+   * @return                            int providing id to fortran if reusing.
+   */
+  int addAttribute(const char * const name,
+                   const int attributeCenter,
+                   const int attributeType,
+                   const unsigned int numValues,
+                   const int arrayType,
+                   const void * const values);
+
+  /**
+   * Remove heavy data linkage from the specified attribute.
+   *
+   * @param     index           Index of the Attribute which will have its heavydata linkage removed.
+   */
+  void clearAttributeHeavyData(const int index);
+
+  /**
+   * Set HDF5 linkage for the specified attribute.
+   *
+   * @param     index           Index of the Attribute which will have its hdf5 linkage set.
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setAttributeHDF5(const int index,
+                        const char * hdf5File,
+                        const char * hdf5Dataset,
+                        const unsigned int start,
+                        const unsigned int stride,
+                        const unsigned int numValues,
+                        const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the specified attribute.
+   *
+   * @param     index           Index of the Attribute which will have its binary linkage set.
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setAttributeBinary(const int index,
+                          const char * binFile,
+                          const int endian,
+                          const unsigned int seek,
+                          const unsigned int start,
+                          const unsigned int stride,
+                          const unsigned int numValues,
+                          const unsigned int dataspace);
+
+  /**
+   * Add unstructured grid to domain or collection. Inserts geometry, topology,
+   * attributes, and informations into grid. If no geometry or
+   * topology is set, an error is generated.
+   * The top of parentAttributes, parentInformations, and parentSets
+   * are placed in mAttributes, mInformations, and mSets
+   *
+   * @param     name            Name of the grid.
+   * @param     writeToHDF5     Whether to write the grid to hdf5 after adding it
+   */
+  void addGrid(const char * const name, const bool writeToHDF5);
+
+  /**
+   * Add curvilinear grid to domain or collection. Inserts geometry, dimensions,
+   * attributes, and informations into grid. If no geometry or
+   * dimensions are set, an error is generated.
+   * The top of parentAttributes, parentInformations, and parentSets
+   * are placed in mAttributes, mInformations, and mSets
+   *
+   * @param     name            Name of the grid.
+   * @param     writeToHDF5     Whether to write the grid to hdf5 after adding it
+   */
+  void addGridCurvilinear(const char * const name, const bool writeToHDF5);
+
+  /**
+   * Add rectilinear grid to domain or collection. Inserts coordinate,
+   * attributes, and informations into grid. If no geometry or
+   * topology is set, an error is generated.
+   * The top of parentAttributes, parentInformations, and parentSets
+   * are placed in mAttributes, mInformations, and mSets
+   *
+   * @param     name            Name of the grid.
+   * @param     writeToHDF5     Whether to write the grid to hdf5 after adding it
+   */
+  void addGridRectilinear(const char * const name, const bool writeToHDF5);
+
+  /**
+   * Add rectilinear grid to domain or collection. Inserts origin, brick, dimensions,
+   * attributes, and informations into grid. If no geometry or
+   * topology is set, an error is generated.
+   * The top of parentAttributes, parentInformations, and parentSets
+   * are placed in mAttributes, mInformations, and mSets
+   *
+   * @param     name            Name of the grid.
+   * @param     writeToHDF5     Whether to write the grid to hdf5 after adding it
+   */
+  void addGridRegular(const char * const name, const bool writeToHDF5);
+
+  /**
+   * Add grid collection to domain or collection. Inserts attributes
+   * and informations into collection.
+   * The top of parentAttributes, parentInformations, and parentSets
+   * are placed in mAttributes, mInformations, and mSets
+   *
+   * @param     name                    Name of the collection.
+   * @param     gridCollectionType      The grid collection type.
+   */
+  void addGridCollection(const char * const name,
+                         const int gridCollectionType);
+
+  /**
+   * Adds a grid that is a reference to a file.
+   *
+   * @param     filePath        Path to the file where the grid is located.
+   * @param     xmlPath         Xml path to the grid being referenced.
+   */
+  void addGridCollectionReference(const char * filePath,
+                                  const char * xmlPath);
+
+  /**
+   * Adds a grid that is a reference to a file.
+   *
+   * @param     gridType        The type of grid being referenced.
+   * @param     filePath        Path to the file where the grid is located.
+   * @param     xmlPath         Xml path to the grid being referenced.
+   */
+  void addGridReference(const int gridType,
+                        const char * filePath,
+                        const char * xmlPath);
+
+  /**
+   * Add an information that will be inserted into the next added
+   * grid or grid collection.
+   *
+   * @param     key     String containing the key of the information to
+   *                    create.
+   * @param     value   String containing the value of the information to
+   *                    create.
+   *
+   * @return            int providing id to fortran if reusing.
+   */
+  int addInformation(const char * const key,
+                     const char * const value);
+
+
+  /**
+   * Add an attribute that will be inserted into the next grid or grid
+   * collection. This will reuse a previously added attribute so that
+   * xpointers can be used when writing to file (reducing file size).
+   *
+   * @param     attributeId     Returned from a previous addAttribute().
+   */
+  void addPreviousAttribute(const int attributeId);
+
+  /**
+   * Add an information that will be inserted into the next grid or grid
+   * collection. This will reuse a previously added information so that
+   * xpointers can be used when writing to file (reducing file size).
+   *
+   * @param     informationId   Returned from a previous addInformation().
+   */
+  void addPreviousInformation(const int informationId);
+
+  /**
+   * Closes grid collection. No additional grids or collections can be
+   * added to the current collection.
+   *
+   * @param     writeToHDF5     Whether to write the grid to hdf5 after adding it
+   */
+  void closeGridCollection(const bool writeToHDF5);
+
+  /**
+   * Set the geometry (point data) that will be added to the next grid.
+   *
+   * @param     geometryType    The geometry type.
+   * @param     numValues       Number of point values to copy.
+   * @param     arrayType       Type of point values.
+   * @param     pointValues     Array of point values.
+   *
+   * @return                    int providing id to fortran if reusing.
+   */
+  int setGeometry(const int geometryType, 
+                  const unsigned int numValues,
+                  const int arrayType, 
+                  const void * const pointValues);
+
+  /**
+   * Remove heavy data linkage from the geometry.
+   */
+  void clearGeometryHeavyData();
+
+  /**
+   * Set HDF5 linkage for the geometry.
+   *
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setGeometryHDF5(const char * hdf5File,
+                       const char * hdf5Dataset,
+                       const unsigned int start,
+                       const unsigned int stride,
+                       const unsigned int numValues,
+                       const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the geometry.
+   *
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setGeometryBinary(const char * binFile,
+                         const int endian,
+                         const unsigned int seek,
+                         const unsigned int start,
+                         const unsigned int stride,
+                         const unsigned int numValues,
+                         const unsigned int dataspace);
+
+  /**
+   * Set the geometry (point data) that will be added to the next grid.
+   * This will reuse a previously set geometry so that xpointers can be
+   * used when writing to file (reducing file size);
+   *
+   * @param     geometryId      Returned from previous setGeometry()
+   */
+  void setPreviousGeometry(const int geometryId);
+
+  /**
+   * Set the topology (connectivity data) that will be added to the
+   * next grid.  This will reuse a previously set topology so that
+   * xpointers can be used when writing to file (reducing file size);
+   *
+   * @param     topologyId      Returned from previous setTopology()
+   */
+  void setPreviousTopology(const int topologyId);
+
+  /**
+   * Set the time that will be added to the next grid or grid
+   * collection.
+   *
+   * @param     time    Time value to insert.
+   */
+  void setTime(const double time);
+  
+  /**
+   * Set the topology (connectivity data) that will be added to the
+   * next grid.
+   *
+   * @param     topologyType            The topology type.
+   * @param     numValues               Number of connectivity values to copy.
+   * @param     arrayType               Type of connectivity values.
+   * @param     connectivityValues      Array of connectivity values.
+   *
+   * @return                            int providing id to fortran if reusing.
+   */
+  int setTopology(const int topologyType, 
+                  const unsigned int numValues,
+                  const int arrayType,
+                  const void * const connectivityValues,
+                  const int numNodes);
+
+  /**
+   * Remove heavy data linkage from the topology.
+   */
+  void clearTopologyHeavyData();
+
+  /**
+   * Set HDF5 linkage for the topology.
+   *
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setTopologyHDF5(const char * hdf5File,
+                       const char * hdf5Dataset,
+                       const unsigned int start,
+                       const unsigned int stride,
+                       const unsigned int numValues,
+                       const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the topology.
+   *
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setTopologyBinary(const char * binFile,
+                         const int endian,
+                         const unsigned int seek,
+                         const unsigned int start,
+                         const unsigned int stride,
+                         const unsigned int numValues,
+                         const unsigned int dataspace);
+
+  /**
+   * Returns the number of grid collections currently
+   * contained in the domain
+   *
+   * @return    The number of grid collections
+   */
+  int retrieveNumDomainGridCollections();
+
+  /**
+   * Returns the number of grid collections currently
+   * contained in the grid collection on top of mGridCollections
+   *
+   * @return    The number of grid collections
+   */
+  int numGridCollectionGridCollections();
+
+  /**
+   * Fills the provided character pointer with the value of the Domain's tag
+   *
+   * @param     tag             The pointer to the point where the string will be written
+   * @param     tagLength       The size of the array assigned at the tag pointer
+   */
+  void retrieveDomainTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the number of properties contained within the domain.
+   *
+   * @return    The number of properties that the domain has.
+   */
+  int retrieveDomainNumProperties();
+
+  /**
+   * Fills the key and length from the property at the index specified.
+   * Since this refers to a map it is not completely reliable that the values will 
+   * stay at the same indexes when new values are added.
+   * Using retrieve by key is more reliable.
+   *
+   * Throws an error if the index is out of bounds
+   *
+   * @param     index           The index of the property to fill from
+   * @param     key             The pointer to the location where the key will be written
+   * @param     keyLength       The size of the array assigned to the key pointer
+   * @param     value           The pointer to the location where the value will be written
+   * @param     valueLength     The size of the array assigned to the value pointer
+   */
+  void retrieveDomainProperty(const int index,
+                              char * key,
+                              const int keyLength,
+                              char * value,
+                              const int valueLength);
+
+  /**
+   * Searches the properties of the domain for one with the specified key.
+   * Stores the value found at a provided pointer.
+   * 
+   * Throws an error if the key does not match any values
+   * 
+   * @param     key             A pointer to the key being searched for
+   * @param     value           A pointer to the location where the value will be written
+   * @param     valueLength     The size of the Array assigned to the value pointer
+   */
+  void retrieveDomainPropertyByKey(char * key, char * value, const int valueLength);
+
+  /**
+   * Makes the specified grid collection owned by the domain accessable
+   * by adding it to mGridCollections.
+   * Pushes the previous contents of mAttributes, mInformations, and mSets
+   * onto parentAttributes, parentInformations, and parentSets
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index                   The index of the grid collection in the domain
+   *                                    that is to be opened
+   * @param     openMaps                Set to 1 to open maps
+   * @param     openAttributes          Set to 1 to open attributes
+   * @param     openInformation         Set to 1 to open information
+   * @param     openSets                Set to 1 to open sets
+   */
+  void openDomainGridCollection(const int index,
+                                const int openMaps,
+                                const int openAttributes,
+                                const int openInformation,
+                                const int openSets);
+
+  /**
+   * Reads the the grid reference of the grid collection at the specified index in
+   * the Domain.
+   *
+   * @param     index   The index of the grid collection to be read
+   */
+  void readDomainGridCollection(const int index);
+
+  /**
+   * Removes the specifed grid collection from mDomain's grid collections
+   *
+   * Throws an error if the index is out of bounds
+   *
+   * @param     index   The index of the grid collection to be removed
+   */
+  void removeDomainGridCollection(const int index);
+
+  /**
+   * Makes the specified grid collection owned by the grid collection on top of
+   * mGridCollections accessable by adding it to mGridCollections.
+   * Pushes the previous contents of mAttributes, mInformations, and mSets
+   * onto parentAttributes, parentInformations, and parentSets
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index                   The index of the grid collection in the domain
+   *                                    that is to be opened
+   * @param     openMaps                Set to 1 to open maps
+   * @param     openAttributes          Set to 1 to open attributes
+   * @param     openInformation         Set to 1 to open information
+   * @param     openSets                Set to 1 to open sets
+   */
+  void openGridCollectionGridCollection(const int index,
+                                        const int openMaps,
+                                        const int openAttributes,
+                                        const int openInformation,
+                                        const int openSets);
+
+  /**
+   * Reads the the grid reference of the grid collection at the specified index in
+   * the grid collection on the top of the stack.
+   *
+   * @param     index   The index of the grid collection to be read
+   */
+  void readGridCollectionGridCollection(const int index);
+
+  /**
+   * Removes the specifed grid collection from the
+   * grid collections owned by the grid collection on top of mGridCollections
+   *
+   * Throws an error if the index is out of bounds
+   *
+   * @param     index   The index of the grid collection to be removed
+   */
+  void removeGridCollectionGridCollection(const int index);
+
+  /**
+   * Fills the provided character pointer with the value of the name of the
+   * grid collection on top of mGridCollections
+   *
+   * @param     name            The pointer to the point where the string
+   *                            will be written
+   * @param     nameLength      The size of the array assigned at the name pointer
+   */
+  void retrieveGridCollectionName(char * name, const int nameLength);
+
+  /**
+   * Fills the provided character pointer with the value of the tag of the
+   * grid collection on top of mGridCollections
+   *
+   * @param     tag             The pointer to the point where the string
+   *                            will be written
+   * @param     tagLength       The size of the array assigned at the tag pointer
+   */
+  void retrieveGridCollectionTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the number of properties contained within the grid collection on
+   * top of mGridCollections.
+   *
+   * @return    The number of properties that the grid collection has.
+   */
+  int retrieveGridCollectionNumProperties();
+
+  /**
+   * Fills the key and length from the property at the index specified.
+   * Since this refers to a map it is not completely reliable that the values will 
+   * stay at the same indexes when new values are added.
+   * Using retrieve by key is more reliable.
+   *
+   * Throws an error if the index is out of bounds
+   *
+   * @param     index           The index of the property to fill from
+   * @param     key             The pointer to the location where the key
+   *                            will be written
+   * @param     keyLength       The size of the array assigned to the key pointer
+   * @param     value           The pointer to the location where the value
+   *                            will be written
+   * @param     valueLength     The size of the array assigned to the value pointer
+   */
+  void retrieveGridCollectionProperty(const int index,
+                                      char * key,
+                                      const int keyLength,
+                                      char * value,
+                                      const int valueLength);
+
+  /**
+   * Searches the properties of the Grid Collection on top of mGridCollections
+   * for one with the specified key.
+   * Stores the value found at a provided pointer.
+   * 
+   * Throws an error if the key does not match any values
+   * 
+   * @param     key             A pointer to the key being searched for
+   * @param     value           A pointer to the location where the value
+   *                            will be written
+   * @param     valueLength     The size of the Array assigned to the value pointer
+   */
+  void retrieveGridCollectionPropertyByKey(char * key, char * value, int const valueLength);
+
+  /**
+   * Opens a grid of the specified type from the domain by
+   * placing its topography, geometry, time, etc..
+   * into the appropriate containers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType                The type of the grid expressed as an integer,
+   *                                    Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index                   The index of the grid to be opened
+   * @param     openMaps                Set to 1 to open maps
+   * @param     openAttributes          Set to 1 to open attributes
+   * @param     openInformation         Set to 1 to open information
+   * @param     openSets                Set to 1 to open sets
+   */
+  void openDomainGrid(const int gridType,
+                      const int index,
+                      const int openMaps,
+                      const int openAttributes,
+                      const int openInformation,
+                      const int openSets);
+
+  /**
+   * Read the grid reference of a grid of the specified type at the specified
+   * index contained within the domain.
+   */
+  void readDomainGrid(const int gridType,
+                      const int index);
+
+  /**
+   * Removes a grid of the specified type from the domain
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the grid to be opened
+   */
+  void removeDomainGrid(const int gridType, const int index);
+
+  /**
+   * Replaces a grid of the specified type from the domain by
+   * placing the appropriate data into the specified grid
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the grid to be opened
+   * @param     name            A pointer to the name of the grid replacing
+   *                            the indicated grid
+   */
+  void replaceDomainGrid(const int gridType, const int index, char * name);
+
+  /**
+   * Retrieves the name of the specified grid and places it at the locaiton provided.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The of the specified grid represented as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   * @param     name            The pointer to where the string will be written
+   * @param     nameLength      The size of the array assigned to the name pointer
+   */
+  void retrieveDomainGridName(const int gridType,
+                              const int index,
+                              char * name,
+                              const int nameLength);
+
+  /**
+   * Retrieves the tag of the specified grid and places it at the location provided.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The of the specified grid represented as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   * @param     tag             The pointer to the point where the string will be written
+   * @param     tagLength       The size of the array assigned at the tag pointer
+   */
+  void retrieveDomainGridTag(const int gridType,
+                             const int index,
+                             char * tag,
+                             const int tagLength);
+
+  /**
+   * Retrieves the number of properties that the specified grid has.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The of the specified grid represented as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   *
+   * @return                    The number of properties that thte grid has.
+   */
+  int retrieveDomainGridNumProperties(const int gridType, const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specified index
+   * in the properties of the grid at the specified index.
+   *
+   * Since the properties are stored in a map the location of individual pairs are mutable.
+   * Use retrieve by key for more oonsistent results.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The of the specified grid represented as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     gridIndex       The index of the specified grid
+   * @param     index           The index of the property to fill from
+   * @param     key             The pointer to the location where the key will be written
+   * @param     keyLength       The size of the array assigned to the key pointer
+   * @param     value           The pointer to the location where the value will be written
+   * @param     valueLength     The size of the array assigned to the value pointer
+   */
+  void retrieveDomainGridProperty(const int gridType,
+                                  const int gridIndex,
+                                  const int index,
+                                  char * key,
+                                  const int keyLength,
+                                  char * value,
+                                  const int valueLength);
+
+  /**
+   * Searches for the property that corresponds with the supplied key
+   * in the properties of the grid at the specified index.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the key has no matching value
+   *
+   * @param     gridType        The of the specified grid represented as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   * @param     key             A pointer to the key being searched for
+   * @param     value           A pointer to the location where the value will be written
+   * @param     valueLength     The size of the Array assigned to the value pointer
+   */
+  void retrieveDomainGridPropertyByKey(const int gridType,
+                                       const int index,
+                                       char * key,
+                                       char * value,
+                                       const int valueLength);
+
+  /**
+   * Opens a grid of the specified type from the grid collection
+   * on top of mGridCollections by placing its
+   * topography, geometry, time, etc.. into the appropriate 
+   * containers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType                The type of the grid expressed as an integer,
+   *                                    Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index                   The index of the grid to be opened
+   * @param     openMaps                Set to 1 to open maps
+   * @param     openAttributes          Set to 1 to open attributes
+   * @param     openInformation         Set to 1 to open information
+   * @param     openSets                Set to 1 to open sets
+   */
+  void openGridCollectionGrid(const int gridType,
+                              const int index,
+                              const int openMaps,
+                              const int openAttributes,
+                              const int openInformation,
+                              const int openSets);
+
+  /**
+   * Reads the grid reference for a grid of the specified type
+   * at the specified index of the grid collection on the top of the stack.
+   */
+  void readGridCollectionGrid(const int gridType,
+                              const int index);
+
+  /**
+   * Removes a grid of the specified type from the grid collection
+   * on top of mGridCollections
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the grid to be opened
+   */
+  void removeGridCollectionGrid(const int gridType, const int index);
+
+  /**
+   * Replaces a grid of the specified type from the grid collection
+   * on top of mGridCollections by placing the appropriate data into it
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the grid to be opened
+   * @param     name            A pointer to the name of the grid to be
+   *                            replacing the specified one
+   */
+  void replaceGridCollectionGrid(const int gridType, const int index, char * name);
+
+  /**
+   * Retrieves the name of the specified grid and places it at the locaiton provided.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   * @param     name            The pointer to where the string will be written
+   * @param     nameLength      The size of the array assigned to the name pointer
+   */
+  void retrieveGridCollectionGridName(const int gridType,
+                                      const int index,
+                                      char * name,
+                                      const int nameLength);
+
+  /**
+   * Retrieves the tag of the specified grid and places it at the location provided.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   * @param     tag             The pointer to the point where the string will be written
+   * @param     tagLength       The size of the array assigned at the tag pointer
+   */
+  void retrieveGridCollectionGridTag(const int gridType,
+                                     const int index,
+                                     char * tag,
+                                     const int tagLength);
+
+  /**
+   * Retrieves the number of properties that the specified grid has.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   *
+   * @return                    The number of properties that thte grid has.
+   */
+  int retrieveGridCollectionGridNumProperties(const int gridType, const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specified index
+   * in the properties of the grid at the specified index.
+   *
+   * Since the properties are stored in a map the location of individual pairs are mutable.
+   * Use retrieve by key for more oonsistent results.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     GridIndex       The index of the specified grid
+   * @param     index           The index of the property to fill from
+   * @param     key             The pointer to the location where the key will be written
+   * @param     keyLength       The size of the array assigned to the key pointer
+   * @param     value           The pointer to the location where the value will be written
+   * @param     valueLength     The size of the array assigned to the value pointer
+   */
+  void retrieveGridCollectionGridProperty(const int gridType,
+                                          const int gridIndex,
+                                          const int index,
+                                          char * key,
+                                          const int keyLength,
+                                          char * value,
+                                          const int valueLength);
+
+  /**
+   * Searches for the property that corresponds with the supplied key
+   * in the properties of the grid at the specified index.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the key has no matching value
+   *
+   * @param     gridType        The type of the grid expressed as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   * @param     index           The index of the specified grid
+   * @param     key             A pointer to the key being searched for
+   * @param     value           A pointer to the location where the value will be written
+   * @param     valueLength     The size of the Array assigned to the value pointer
+   */
+  void retrieveGridCollectionGridPropertyByKey(const int gridType,
+                                               const int index,
+                                               char * key,
+                                               char * value,
+                                               const int valueLength);
+
+  /**
+   * Returns the number of grids of a specified type that the domain contains
+   *
+   * @param     gridType        The specified type of grid as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   *
+   * @return                    The number of grids
+   */
+  int numDomainGrids(const int gridType);
+
+  /**
+   * Returns the number of grids of a specified type that
+   * the top grid collection in mGridCollections contains
+   *
+   * Returns an error if there are no grid collections in mGridCollections
+   *
+   * @param     gridType        The specified type of grid as an integer,
+   *                            Ex: XDMF_GRID_TYPE_UNSTRUCTURED
+   *
+   * @return                    The number of grids
+   */
+  int numGridCollectionGrids(const int gridType);
+
+  /**
+   * Returns the type of the grid collection on top of the mGridCollections stack
+   *
+   * @return    The grid collection's type, Ex: XDMF_GRID_COLLECTION_TYPE_TEMPORAL
+   */
+  int retrieveGridCollectionType();
+
+  /**
+   * Returns the time stored in mTime
+   *
+   * @return    The value of mTime as a float
+   */
+  float retrieveTime();
+
+  /**
+   * Retrieves the Geometry's tag and stores it into the provided pointer
+   *
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveGeometryTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the geometry's type as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the geometry isn't set
+   *
+   * @return    The geometry's type, EX: XDMF_GEOMETRY_TYPE_XY
+   */
+  int retrieveGeometryType();
+
+  /**
+   * Returns the geometry's datatype as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the geometry isn't set
+   *
+   * @return    The geometry's type, EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveGeometryValueType();
+
+  /**
+   * Returns a pointer to the array of values contained in the geometry
+   *
+   * Returns an error if the geometry is not set
+   *
+   * @param     values          A void pointer to the array to recieve the
+   *                            geometry's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the attribute's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the
+   *                            read values are placed in the supplied array
+   */
+  void retrieveGeometryValues(void * values,
+                              const int dataType,
+                              const int numberRead,
+                              const int startIndex,
+                              const int arrayStride,
+                              const int valueStride);
+
+  /**
+   * returns the number of points contained within the geometry
+   *
+   * @return    The number of points
+   */
+  int retrieveGeometryNumPoints();
+
+  /**
+   * returns the size of the geometry
+   *
+   * @return    The size
+   */
+  int retrieveGeometrySize();
+
+  /**
+   * Clears mPreviousGeometries. Use to reduce memory load.
+   */
+  void clearPreviousGeometries();
+
+  /**
+   * Overwrites a section of the geometry using the provided values.
+   *
+   * Returns an error if the geometry is not set
+   *
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the geometry.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifyGeometryValues(void * values,
+                            const int arrayType,
+                            const int numValues,
+                            const int startIndex,
+                            const int arrayStride,
+                            const int valueStride);
+
+  /**
+   * Returns the number of properties currently stored in the geometry.
+   *
+   * @return    The number of properties associated with the geometry
+   */
+  int retrieveGeometryNumProperties();
+
+  /**
+   * Retrieves the key and value of the property at the specifed index
+   * of the Geometry
+   * and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the property that is
+   *                            being retrieved
+   * @param     key             A pointer to the location where the
+   *                            key value will be stored
+   * @param     keyLength       the size of the key variable
+   * @param     value           A pointer to the location where the value
+   *                            of the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveGeometryProperty(const int index,
+                                char * key,
+                                const int keyLength,
+                                char * value,
+                                const int valueLength);
+
+  /**
+   * Retrieves the value of a property of the geometry when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value of the
+   *                            property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveGeometryPropertyByKey(char * key, char * value, const int valueLength);
+
+  /**
+   * Sets the current geometry as a function variable.
+   *
+   * @param     varname         The name that the geometry will be associated with.
+   */
+  void setGeometryAsVariable(char * varname);
+
+  /**
+   * Sets the current geometry as the current subset reference.
+   */
+  void setGeometryAsSubsetReference();
+
+  /**
+   * Retrieves the topology's tag and stores it into the provided pointer
+   *
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveTopologyTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the topology's type as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the topology isn't set
+   *
+   * @return    The topology's type, EX: XDMF_TOPOLOGY_TYPE_POLYVERTEX
+   */
+  int retrieveTopologyType();
+
+  /**
+   * Returns the topology's datatype as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the topology isn't set
+   *
+   * @return    The topology's data type, EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveTopologyValueType();
+
+  /**
+   * Returns a pointer to the array of values contained in the topology
+   *
+   * Returns an error if the topology is not set
+   *
+   * @param     values          A void pointer to the array to recieve the
+   *                            topology's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the attribute's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the read values
+   *                            are placed in the supplied array
+   */
+  void retrieveTopologyValues(void * values,
+                              const int dataType,
+                              const int numberRead,
+                              const int startIndex,
+                              const int arrayStride,
+                              const int valueStride);
+
+  /**
+   * returns the number of elements contained within the topology
+   *
+   * @return    The number of elements
+   */
+  int retrieveTopologyNumElements();
+
+  /**
+   * returns the size of the topology
+   *
+   * @return    The size
+   */
+  int retrieveTopologySize();
+
+  /**
+   * Clears mPreviousTopologies. Use to reduce memory load.
+   */
+  void clearPreviousTopologies();
+
+  /**
+   * Overwrites a section of the topology using the provided values.
+   *
+   * Returns an error if the topology is not set
+   *
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the topology.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifyTopologyValues(void * values,
+                            const int arrayType,
+                            const int numValues,
+                            const int startIndex,
+                            const int arrayStride,
+                            const int valueStride);
+
+  /**
+   * Returns the number of properties currently stored in the topology.
+   *
+   * @return    The number of properties associated with the topology
+   */
+  int retrieveTopologyNumProperties();
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of the Topology
+   * and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the property that is being retrieved
+   * @param     key             A pointer to the location where the key value will be stored
+   * @param     keyLength       the size of the key variable
+   * @param     value           A pointer to the location where the value of the
+   *                            property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveTopologyProperty(const int index,
+                                char * key,
+                                const int keyLength,
+                                char * value,
+                                const int valueLength);
+
+  /**
+   * Retrieves the value of a property of the topology when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveTopologyPropertyByKey(char * key, char * value, const int valueLength);
+
+  /**
+   * Sets the topology as an array variable associated with a specific name.
+   * Used in conjuction with Functions.
+   *
+   * @param     varname The variable to accociate with the current topology.
+   */
+  void setTopologyAsVariable(char * varname);
+
+  /**
+   * Sets the topology as the current subset reference.
+   */
+  void setTopologyAsSubsetReference();
+
+  /**
+   * Set the dimensions that will be added to the next grid.
+   *
+   * @param     numValues       Number of point values to copy.
+   * @param     arrayType       Type of point values.
+   * @param     pointValues     Array of point values.
+   *
+   * @return    int providing id to fortran if reusing.
+   */
+  int setDimensions(const int numValues, const int arrayType, void * pointValues);
+
+  /**
+   * Remove heavy data linkage from the dimensions.
+   */
+  void clearDimensionsHeavyData();
+
+  /**
+   * Set HDF5 linkage for the dimensions.
+   *
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setDimensionsHDF5(const char * hdf5File,
+                         const char * hdf5Dataset,
+                         const unsigned int start,
+                         const unsigned int stride,
+                         const unsigned int numValues,
+                         const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the dimensions.
+   *
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setDimensionsBinary(const char * binFile,
+                           const int endian,
+                           const unsigned int seek,
+                           const unsigned int start,
+                           const unsigned int stride,
+                           const unsigned int numValues,
+                           const unsigned int dataspace);
+
+  /**
+   * Replaces mDimensions with the specified dimensions from mPreviousDimensions
+   *
+   * Returns an error if the index is out of range
+   *
+   * @param     index   The index of the specified dimension
+   */
+  void openPreviousDimensions(const int index);
+
+  /**
+   * Clears mPreviousDimensions. Use to reduce memory load.
+   */
+  void clearPreviousDimensions();
+
+  /**
+   * Overwrites a section of the dimensions using the provided values.
+   *
+   * Returns an error if the dimensions are not set
+   *
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on
+   *                            the dimensions.
+   * @param     valueStride     The increment between value pulls from
+   *                            the pointer written from.
+   */
+  void modifyDimensionsValues(void * values,
+                              const int arrayType,
+                              const int numValues,
+                              const int startIndex,
+                              const int arrayStride,
+                              const int valueStride);
+
+  /**
+   * Retrieves the dimensions' tag and stores it into the provided pointer
+   *
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveDimensionsTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the dimensions' datatype as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the dimension isn't set
+   *
+   * @return    The dimensions' type, EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveDimensionsValueType();
+
+  /**
+   * Returns a pointer to the array of values contained in the dimensions
+   *
+   * Returns an error if the dimensions are not set
+   *
+   * @param     values          A void pointer to the array to recieve the
+   *                            geometry's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            The data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the attribute's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that
+   *                            the read values are placed in the supplied array
+   */
+  void retrieveDimensionsValues(void * values,
+                                const int dataType,
+                                const int numberRead,
+                                const int startIndex,
+                                const int arrayStride,
+                                const int valueStride);
+
+  /**
+   * returns the size of the dimensions
+   *
+   * @return    The size
+   */
+  int retrieveDimensionsSize();
+
+  /**
+   * Returns the number of properties currently stored in the dimensions.
+   *
+   * @return    The number of properties associated with the dimensions
+   */
+  int retrieveDimensionsNumProperties();
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of the dimensions
+   * and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the property that is being retrieved
+   * @param     key             A pointer to the location where the
+   *                            key value will be stored
+   * @param     keyLength       The size of the key variable
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveDimensionsProperty(const int index,
+                                  char * key,
+                                  const int keyLength,
+                                  char * value,
+                                  const int valueLength);
+
+  /**
+   * Retrieves the value of a property of the dimensions when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveDimensionsPropertyByKey(char * key, char * value, const int valueLength);
+
+  /**
+   * Set the origin that will be added to the next grid.
+   *
+   * @param     numValues       Number of point values to copy.
+   * @param     arrayType       Type of point values.
+   * @param     pointValues     Array of point values.
+   *
+   * @return    int providing id to fortran if reusing.
+   */
+  int setOrigin(const int numValues, const int arrayType, void * pointValues);
+
+  /**
+   * Remove heavy data linkage from the origin.
+   */
+  void clearOriginHeavyData();
+
+  /**
+   * Set HDF5 linkage for the origin.
+   *
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setOriginHDF5(const char * hdf5File,
+                     const char * hdf5Dataset,
+                     const unsigned int start,
+                     const unsigned int stride,
+                     const unsigned int numValues,
+                     const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the origin.
+   *
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setOriginBinary(const char * binFile,
+                       const int endian,
+                       const unsigned int seek,
+                       const unsigned int start,
+                       const unsigned int stride,
+                       const unsigned int numValues,
+                       const unsigned int dataspace);
+
+  /**
+   * Sets mOrigin to a specified origin in mPreviousOrigins
+   *
+   * @param     index   The index of the specified origin
+   */
+  void setPreviousOrigin(const int index);
+  
+  /**
+   * Clears mPreviousOrigins. Use to reduce memory load.
+   */
+  void clearPreviousOrigins();
+
+  /**
+   * Overwrites a section of the origin using the provided values.
+   *
+   * Returns an error if the origin is not set
+   *
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from
+   *                            the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the origin.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifyOriginValues(void * values,
+                          const int arrayType,
+                          const int numValues,
+                          const int startIndex,
+                          const int arrayStride,
+                          const int valueStride);
+
+  /**
+   * Retrieves the origin's tag and stores it into the provided pointer
+   *
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveOriginTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the origin's datatype as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the origin isn't set
+   *
+   * @return    The origin's type, EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveOriginValueType();
+
+  /**
+   * Returns a pointer to the array of values contained in the origin
+   *
+   * Returns an error if the origin is not set
+   *
+   * @param     values          A void pointer to the array to recieve the
+   *                            geometry's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the attribute's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the
+   *                            read values are placed in the supplied array
+   */
+  void retrieveOriginValues(void * values,
+                            const int dataType,
+                            const int numberRead,
+                            const int startIndex,
+                            const int arrayStride,
+                            const int valueStride);
+
+  /**
+   * returns the size of the origin
+   *
+   * @return    The size
+   */
+  int retrieveOriginSize();
+
+  /**
+   * Returns the number of properties currently stored in the origin.
+   *
+   * @return    The number of properties associated with the origin
+   */
+  int retrieveOriginNumProperties();
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of the origin
+   * and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the property that is being retrieved
+   * @param     key             A pointer to the location where the
+   *                            key value will be stored
+   * @param     keyLength       The size of the key variable
+   * @param     value           A pointer to the location where the
+   *                            value of the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveOriginProperty(const int index,
+                              char * key,
+                              const int keyLength,
+                              char * value,
+                              const int valueLength);
+
+  /**
+   * Retrieves the value of a property of the origin when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the
+   *                            value of the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveOriginPropertyByKey(char * key,
+                                   char * value,
+                                   const int valueLength);
+
+  /**
+   * Set the brick size that will be added to the next grid.
+   *
+   * @param     numValues       Number of point values to copy.
+   * @param     arrayType       Type of point values.
+   * @param     pointValues     Array of point values.
+   *
+   * @return    int providing id to fortran if reusing.
+   */
+  int setBrick(const int numValues, const int arrayType, void * pointValues);
+
+  /**
+   * Remove heavy data linkage from the Brick size.
+   */
+  void clearBrickHeavyData();
+
+  /**
+   * Set HDF5 linkage for the brick size.
+   *
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setBrickHDF5(const char * hdf5File,
+                    const char * hdf5Dataset,
+                    const unsigned int start,
+                    const unsigned int stride,
+                    const unsigned int numValues,
+                    const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the brick size.
+   *
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setBrickBinary(const char * binFile,
+                      const int endian,
+                      const unsigned int seek,
+                      const unsigned int start,
+                      const unsigned int stride,
+                      const unsigned int numValues,
+                      const unsigned int dataspace);
+
+  /**
+   * Sets the brick size to a specified brick size stored in mPreviousBricks
+   *
+   * @param     index   The index of the specifed brick size
+   */
+  void setPreviousBrick(const int index);
+
+  /**
+   * Clears mPreviousBricks. Use to reduce memory load.
+   */
+  void clearPreviousBricks();
+
+  /**
+   * Overwrites a section of the brick using the provided values.
+   *
+   * Returns an error if the brick is not set
+   *
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the brick.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifyBrickValues(void * values,
+                         const int arrayType,
+                         const int numValues,
+                         const int startIndex,
+                         const int arrayStride,
+                         const int valueStride);
+
+  /**
+   * Retrieves the Geometry's tag and stores it into the provided pointer
+   *
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveBrickTag(char * tag, const int tagLength);
+
+  /**
+   * Returns the brick's datatype as an integer.
+   *
+   * Returns an error if it doesn't recognize the type or if the brick isn't set
+   *
+   * @return    The brick's type, EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveBrickValueType();
+
+  /**
+   * Returns a pointer to the array of values contained in the brick
+   *
+   * Returns an error if the brick is not set
+   *
+   * @param     values          A void pointer to the array to recieve
+   *                            the brick's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the attribute's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the read values
+   *                            are placed in the supplied array
+   */
+  void retrieveBrickValues(void * values,
+                           const int dataType,
+                           const int numberRead,
+                           const int startIndex,
+                           const int arrayStride,
+                           const int valueStride);
+
+  /**
+   * returns the size of the brick size
+   *
+   * @return    The size
+   */
+  int retrieveBrickSize();
+
+  /**
+   * Returns the number of properties currently stored in the brick size.
+   *
+   * @return    The number of properties associated with the brick
+   */
+  int retrieveBrickNumProperties();
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of the brick size
+   * and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the property that is being retrieved
+   * @param     key             A pointer to the location where the key value will be stored
+   * @param     keyLength       The size of the key variable
+   * @param     value           A pointer to the location where the value of the property
+   *                            will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveBrickProperty(const int index,
+                             char * key,
+                             const int keyLength,
+                             char * value,
+                             const int valueLength);
+
+  /**
+   * Retrieves the value of a property of the brick size when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveBrickPropertyByKey(char * key, char * value, const int valueLength);
+
+  /**
+   * Pushes a blank map onto mMaps.
+   *
+   * @param     name    A pointer to the name of the map to be added
+   */
+  void addMap(char * name);
+
+  /**
+   * Returns the number of maps stored in mMaps
+   *
+   * @return    The number of maps
+   */
+  int retrieveNumMaps();
+
+  /**
+   * Retrieves the specified map's tag and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the map whose tag is being retrieved
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveMapTag(const int index, char * tag, const int tagLength);
+
+  /**
+   * Adds id dependancies to the specified map in mMaps
+   *
+   * @param     index                   The index of the map for the data to
+   *                                    be added to
+   * @param     localNodeID             The ID of the local node
+   * @param     remoteTaskID            The task ID to be associated with
+   *                                    the local node
+   * @param     remoteLocalNodeID       The remote local node to be associated
+   *                                    with the local node and task id
+   */
+  void addRemoteNodeID(const int index, int localNodeID, int remoteTaskID, int remoteLocalNodeID);
+
+  /**
+   * Gets the remote local ids associated with the provided local node and
+   * task from a specified map in mMaps
+   *
+   * @param     index           The index of the map which the data is to be
+   *                            retrieved from
+   * @param     localNodeID     The ID of the local node whose remote local
+   *                            node is to be found
+   * @param     remoteTaskID    The ID of the task whose remote local node
+   *                            is to be found
+   * @param     remoteNodeID    A pointer to the location where the remote local IDs
+   *                            will be returned to
+   */
+  void retrieveRemoteNodeIDs(const int index,
+                             const int localNodeID,
+                             const int remoteTaskID,
+                             int * remoteNodeIDs);
+
+  /**
+   * Gets the number of remote local ids associated with the provided local node
+   * and task from a specified map in mMaps
+   *
+   * @param     index           The index of the map which the data is to be
+   *                            retrieved from
+   * @param     localNodeID     The ID of the local node whose number of
+   *                            associated remote local nodes is to be found
+   * @param     remoteTaskID    The ID of the task whose number of associated
+   *                            remote local nodes is to be found
+   *
+   * @return                    The number of remote node ids associated with
+   *                            the supplied IDs
+   */
+  int retrieveNumRemoteNodeIDs(const int index,
+                               const int localNodeID,
+                               const int remoteTaskID);
+
+  /**
+   * Clears mMaps of all added maps.
+   */
+  void clearMaps();
+
+  /**
+   * Removes the specified map from mMaps.
+   *
+   * @param     index   The index of the map to be removed.
+   */
+  void removeMap(const int index);
+
+  /**
+   * Stores specified mMap in mPreviousMaps.
+   *
+   * Gives an error if the index is out of bounds
+   *
+   * @param     index   The index of the specified map in mMaps
+   *
+   * @return            The id of the corresponding map in mPreviousMaps
+   */
+  int storeMap(const int index);
+
+  /**
+   * Replaces the current mMap with one specified from mPreviousMaps.
+   *
+   * Gives an error if the index is out of range.
+   *
+   * @param     index   The index of the specified map
+   */
+  void addPreviousMap(const int index);
+
+  /**
+   * Clears mPreviousMaps. Use to reduce memory load.
+   */
+  void clearPreviousMaps();
+
+  /**
+   * Returns the number of properties currently stored in the specified map in mMaps.
+   *
+   * @param     index   The index of the specified map
+   *
+   * @return            The number of properties associated with the map
+   */
+  int retrieveMapNumProperties(const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of the
+   * specified map in mMaps and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     mapIndex        The index of the specified map
+   * @param     index           The index of the property that is being retrieved
+   * @param     key             A pointer to the location where the key value
+   *                            will be stored
+   * @param     keyLength       The size of the key variable
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveMapProperty(const int mapIndex,
+                           const int index,
+                           char * key,
+                           const int keyLength,
+                           char * value,
+                           const int valueLength);
+
+  /**
+   * Retrieves the value of a property of the specified map when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     index           The index of the specified map
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveMapPropertyByKey(const int index,
+                                char * key,
+                                char * value,
+                                const int valueLength);
+
+  /**
+   * Returns the number of attributes currently loaded.
+   *
+   * @return    The number of attributes in mAttributes
+   */
+  int retrieveNumAttributes();
+
+  /**
+   * Removes the attribute at the supplied index from mAttributes
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the Attribute to be removed
+   */
+  void removeAttribute(const int index);
+
+  /**
+   * Replaces the specified attribute in mAttributes with one made using the
+   * supplied components
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index                   The index of the Attribute to be replaced
+   * @param     name                    A pointer to the name of the new attribute
+   * @param     attributeCenter         An integer representation of the center of
+   *                                    the new attribute Ex:XDMF_ATTRIBUTE_CENTER_NODE
+   * @param     attributeType           An integer representation of the type of
+   *                                    the new attribute Ex:XDMF_ATTRIBUTE_TYPE_SCALAR
+   * @param     numValues               The number of values contained at the array
+   *                                    located at the supplied void pointer
+   * @param     arrayType               An integer representation of the type of
+   *                                    data contained within the array
+   *                                    Ex:XDMF_ARRAY_TYPE_INT32
+   * @param     values                  A pointer to the location of the values
+   *                                    that will be used to fill the new attribute
+   */
+  void replaceAttribute(const int index,
+                        char * name,
+                        const int attributeCenter,
+                        const int attributeType,
+                        const int numValues,
+                        const int arrayType,
+                        void * values);
+
+  /**
+   * Opens the specified attribute by placing the information it contains in mInformations
+   *
+   * @param     index   The index of the specified information
+   */
+  void openAttribute(const int index);
+
+  /**
+   * Retrieves the specified Attribute's tag and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the attribute whose tag is being retrieved
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveAttributeTag(const int index, char * tag, const int tagLength);
+
+  /**
+   * Retrieves the specified Attribute's name and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the attribute whose name is being retrieved
+   * @param     name            The location where the name will be stored
+   * @param     nameLength      The size fo the array at the provided pointer
+   */
+  void retrieveAttributeName(const int index, char * name, const int nameLength);
+
+  /**
+   * Clears mAttributes of all added attributes
+   */
+  void clearAttributes();
+
+  /**
+   * Returns a pointer the values of a specified attribute
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index that the specified Attribute exists at
+   * @param     values          A void pointer to the array to recieve the
+   *                            attribute's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the attribute's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the
+   *                            read values are placed in the supplied array
+   */
+  void retrieveAttributeValues(const int index,
+                               void * values,
+                               const int dataType,
+                               const int numberRead,
+                               const int startIndex,
+                               const int arrayStride,
+                               const int valueStride);
+
+  /**
+   * Returns the datatype of the specified attribute as an integer.
+   * 
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the attribute
+   *
+   * @return            The type of the specified attribute as an integer,
+   *                    EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveAttributeValueType(const int index);
+
+  /**
+   * Returns the number of values in the specified Attribute
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the attribute
+   *
+   * @return            The number of values contained in the specified attribute
+   */
+  int retrieveAttributeSize(const int index);
+
+  /**
+   * Returns the type of the specified attribute as an integer.
+   * 
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the attribute
+   *
+   * @return            The type of the specified attribute as an integer,
+   *                    EX: XDMF_ATTRIBUTE_TYPE_SCALAR
+   */
+  int retrieveAttributeType(const int index);
+
+  /**
+   * Returns the center of the specified attribute as an integer.
+   * 
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the attribute
+   *
+   * @return            The center of the specified attribute as an integer,
+   *                    EX: XDMF_ATTRIBUTE_CENTER_NODE
+   */
+  int retrieveAttributeCenter(const int index);
+
+  /**
+   * Clears mPreviousAttributes. Use to reduce memory load.
+   */
+  void clearPreviousAttributes();
+
+  /**
+   * Overwrites a section of the specified attribute using the provided values.
+   *
+   * Returns an error if the index is out of range
+   *
+   * @param     index           The index of the attribute to be modified
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the attribute.
+   * @param     valueStride     The increment between value pulls from the pointer written from.
+   */
+  void modifyAttributeValues(const int index,
+                             void * values,
+                             const int arrayType,
+                             const int numValues,
+                             const int startIndex,
+                             const int arrayStride,
+                             const int valueStride);
+
+  /**
+   * Returns the number of properties currently stored in the specified attribute.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the attribute whose number of properties is being retrieved
+   *
+   * @return            The number of properties associated with the specified attribute
+   */
+  int retrieveAttributeNumProperties(const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specifed index
+   * of the specified attribute and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     attributeIndex          The index of the attribute that is being retrieved
+   * @param     index                   The index of the property that is being retrieved
+   * @param     key                     A pointer to the location where the key value
+   *                                    will be stored
+   * @param     keyLength               The size of the key variable
+   * @param     value                   A pointer to the location where the value
+   *                                    of the property will be stored
+   * @param     valueLength             The size of the value variable
+   */
+  void retrieveAttributeProperty(const int attributeIndex,
+                                 const int index,
+                                 char * key,
+                                 const int keyLength,
+                                 char * value,
+                                 const int valueLength);
+
+  /**
+   * Retrieves the value of a property of a specified attribute when given its key.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the key has no matching value
+   *
+   * @param     index           The index of the attribute whose property
+   *                            is being retrieved
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value
+   *                            of the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveAttributePropertyByKey(const int index,
+                                      char * key,
+                                      char * value,
+                                      const int valueLength);
+
+  /**
+   * Sets the specified attribute as an array variable associated with a specific name.
+   * Used in conjuction with Functions.
+   *
+   * @param     varname The variable to accociate with the attribute.
+   * @param     index   The index of the attribute to be associated.
+   */
+  void setAttributeAsVariable(char * varname, int index);
+
+  /**
+   * Sets the specified attribute as the current subset reference.
+   *
+   * @param     index   The index of the attribute to be used.
+   */
+  void setAttributeAsSubsetReference(int index);
+
+  /**
+   * Returns the number of coordinates currently loaded.
+   *
+   * @return    The number of coordinates in mCoordinates
+   */
+  int retrieveNumCoordinates();
+
+  /**
+   * Removes the coordinate at the supplied index from mCoordinates
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the Coordinate to be removed
+   */
+  void removeCoordinate(const int index);
+
+  /**
+   * Add an coordinate that will be inserted into the next grid or grid
+   * collection.
+   *
+   * @param     name            Name of the coordinate.
+   * @param     numValues       Number of coordinate values to copy.
+   * @param     arrayType       Type of coordinate values.
+   * @param     values          Array of coordinate values.
+   *
+   * @return                    int providing id to fortran if reusing.
+   */
+  int addCoordinate(char * name, const int numValues, const int arrayType, void * values);
+
+  /**
+   * Adds a specified coordinate from mPreviousCoordinates to mCoordinates
+   *
+   * @param     index   The index of the specified coordinate
+   */
+  void addPreviousCoordinate(const int index);
+
+  /**
+   * Clears mPreviousCoordinates. Use to reduce memory load.
+   */
+  void clearPreviousCoordinates();
+
+  /**
+   * Remove heavy data linkage from the specified coordinate.
+   *
+   * @param     index           Index of the Coordinate which will have its heavydata linkage removed.
+   */
+  void clearCoordinateHeavyData(const int index);
+
+  /**
+   * Set HDF5 linkage for the specified coordinate.
+   *
+   * @param     index           Index of the Coordinate which will have its hdf5 linkage set.
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setCoordinateHDF5(const int index,
+                         const char * hdf5File,
+                         const char * hdf5Dataset,
+                         const unsigned int start,
+                         const unsigned int stride,
+                         const unsigned int numValues,
+                         const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the specified coordinate.
+   *
+   * @param     index           Index of the Coordinate which will have its binary linkage set.
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setCoordinateBinary(const int index,
+                           const char * binFile,
+                           const int endian,
+                           const unsigned int seek,
+                           const unsigned int start,
+                           const unsigned int stride,
+                           const unsigned int numValues,
+                           const unsigned int dataspace);
+
+  /**
+   * Replaces the specified coordinate in mCoordinates with one made using
+   * the supplied components
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the coordinate to be replaced
+   * @param     name            A pointer to the name of the new coordinate
+   * @param     numValues       The number of values contained at the array
+   *                            located at the supplied void pointer
+   * @param     arrayType       An integer representation of the type of data
+   *                            contained within the array Ex:XDMF_ARRAY_TYPE_INT32
+   * @param     values          A pointer to the location of the values that
+   *                            will be used to fill the new coordinate
+   */
+  void replaceCoordinate(const int index,
+                         char * name,
+                         const int numValues,
+                         const int arrayType,
+                         void * values);
+
+  /**
+   * Retrieves the specified Coordinate's tag and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the coordinate whose tag is being retrieved
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveCoordinateTag(const int index, char * tag, const int tagLength);
+
+  /**
+   * Retrieves the specified Coordinate's name and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the coordinate whose name is being retrieved
+   * @param     name            The location where the name will be stored
+   * @param     nameLength      The size fo the array at the provided pointer
+   */
+  void retrieveCoordinateName(const int index, char * name, const int nameLength);
+
+  /**
+   * Returns a pointer the values of a specified coordinate
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index that the specified coordinate exists at
+   * @param     values          A void pointer to the array to recieve the
+   *                            coordinate's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the coordinate's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the
+   *                            read values are placed in the supplied array
+   */
+  void retrieveCoordinateValues(const int index,
+                                void * values,
+                                const int dataType,
+                                const int numberRead,
+                                const int startIndex,
+                                const int arrayStride,
+                                const int valueStride);
+
+  /**
+   * Returns the datatype of the specified coordinate as an integer.
+   * 
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the coordinate
+   *
+   * @return            The type of the specified coordinate as an integer,
+   *                    EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveCoordinateValueType(const int index);
+
+  /**
+   * Returns the number of values in the specified coordinate
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the coordinate
+   *
+   * @return            The number of values contained in the specified coordinate
+   */
+  int retrieveCoordinateSize(const int index);
+
+  /**
+   * Clears mCoordinates of all added coordiantes.
+   */
+  void clearCoordinates();
+
+  /**
+   * Overwrites a section of the specified coordinate using the provided values.
+   *
+   * Returns an error if the index is out of range
+   *
+   * @param     index           The index of the coordinate to be modified
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the coordinate.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifyCoordinateValues(const int index,
+                              void * values,
+                              const int arrayType,
+                              const int numValues,
+                              const int startIndex,
+                              const int arrayStride,
+                              const int valueStride);
+
+  /**
+   * Returns the number of properties currently stored in the specified coordinate.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the coordinate whose number of properties
+   *                    is being retrieved
+   *
+   * @return            The number of properties associated with the specified
+   *                    coordinate
+   */
+  int retrieveCoordinateNumProperties(const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of
+   * the specified coordinate and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     coordinateIndex         The index of the coordinate that is
+   *                                    being retrieved
+   * @param     index                   The index of the property that is
+   *                                    being retrieved
+   * @param     key                     A pointer to the location where the
+   *                                    key value will be stored
+   * @param     keyLength               The size of the key variable
+   * @param     value                   A pointer to the location where the
+   *                                    value of the property will be stored
+   * @param     valueLength             The size of the value variable
+   */
+  void retrieveCoordinateProperty(const int coordinateIndex,
+                                  const int index,
+                                  char * key,
+                                  const int keyLength,
+                                  char * value,
+                                  const int valueLength);
+
+  /**
+   * Retrieves the value of a property of a specified coordinate when given its key.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the key has no matching value
+   *
+   * @param     index           The index of the coordinate whose property is
+   *                            being retrieved
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveCoordinatePropertyByKey(const int index,
+                                       char * key,
+                                       char * value,
+                                       const int valueLength);
+
+  /**
+   * Sets the specified coordinate as an array variable associated with a specific name.
+   * Used in conjuction with Functions.
+   *
+   * @param     varname The variable to accociate with the coordinate.
+   * @param     index   The index of the coordinate to be associated.
+   */
+  void setCoordinateAsVariable(char * varname, int index);
+
+  /**
+   * Sets the specified coordinate as the current subset reference.
+   *
+   * @param     index   The index of the coordinate to be associated.
+   */
+  void setCoordinateAsSubsetReference(int index);
+
+  /**
+   * Retrieves the specified set's tag and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the set whose tag is being retrieved
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveSetTag(const int index, char * tag, const int tagLength);
+
+  /**
+   * Retrieves the specified set's name and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the set whose name is being retrieved
+   * @param     name            The location where the name will be stored
+   * @param     nameLength      The size fo the array at the provided pointer
+   */
+  void retrieveSetName(const int index, char * name, const int nameLength);
+
+  /**
+   * Retrievest the type of the specified set
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the specified set
+   *
+   * @return            The set's type as an integer Ex. XDMF_SET_TYPE_NODE
+   */
+  int retrieveSetType(const int index);
+
+  /**
+   * Adds a set to mSets that contains the current contents to mInformations
+   * and mAttributes.
+   * Then the top of parentAttributes and parentInformations
+   * are placed in mAttributes and mInformations
+   *
+   * @param     name            A pointer to the location of the name for the set
+   * @param     newSetType      The integer equivalent to the set type of the
+   *                            added set Ex: XDMF_SET_TYPE_NODE
+   * @param     values          A pointer to the location where the values to be
+   *                            placed in the set will are stored
+   * @param     numValues       The amount of values in the array at the provided pointer
+   * @param     arrayType       The integer representation of the datatype of the values
+   *                            Ex: XDMF_ARRAY_TYPE_INT32
+   *
+   * @return                    An ID that can be used to recall the set from mPreviousSets
+   */
+  int addSet(char * name,
+             const int newSetType,
+             void * values,
+             const int numValues,
+             const int arrayType);
+
+  /**
+   * Remove heavy data linkage from the specified set.
+   */
+  void clearSetHeavyData(const int index);
+
+  /**
+   * Set HDF5 linkage for the specified set.
+   *
+   * @param     index           Index of the Set which will have its hdf5 linkage set.
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setSetHDF5(const int index,
+                  const char * hdf5File,
+                  const char * hdf5Dataset,
+                  const unsigned int start,
+                  const unsigned int stride,
+                  const unsigned int numValues,
+                  const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the specified set.
+   *
+   * @param     index           Index of the Set which will have its binary linkage set.
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setSetBinary(const int index,
+                    const char * binFile,
+                    const int endian,
+                    const unsigned int seek,
+                    const unsigned int start,
+                    const unsigned int stride,
+                    const unsigned int numValues,
+                    const unsigned int dataspace);
+
+  /**
+   * Adds the specifed set from mPreviousSets into mSets.
+   *
+   * @param     index   The index of the set in mPreviousSets to be added
+   */
+  void addPreviousSet(const int index);
+
+  /**
+   * Clears mPreviousSets. Use to reduce memory load.
+   */
+  void clearPreviousSets();
+
+  /**
+   * Clears mSets of all added Sets
+   */
+  void clearSets();
+
+  /**
+   * Overwrites a section of the specified set using the provided values.
+   *
+   * Returns an error if the index is out of range
+   *
+   * @param     index           The index of the set to be modified
+   * @param     values          A pointer to the values to be written.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     startIndex      The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the set.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifySetValues(const int index,
+                       void * values,
+                       const int arrayType,
+                       const int numValues,
+                       const int startIndex,
+                       const int arrayStride,
+                       const int valueStride);
+
+  /**
+   * Returns the number of sets in mSets
+   *
+   * @return    The number of sets
+   */
+  int retrieveNumSets();
+
+  /**
+   * Returns the number of values in the specified set
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index to the set
+   *
+   * @return            The number of values contained in the specified set
+   */
+  int retrieveSetSize(const int index);
+
+  /**
+   * Returns a pointer the values of a specified set
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index that the specified set exists at
+   * @param     values          A void pointer to the array to recieve the
+   *                            set's values
+   * @param     dataType        An integer corresponding to the datatype that
+   *                            the data will be stored in
+   * @param     numberRead      The number of values read into the values array
+   * @param     startIndex      The place to start reading from the set's array
+   * @param     arrayStride     The distance between values read
+   *                            (1 reads all values, 2 reads every other, ect..)
+   * @param     valueStride     The distance between the places that the
+   *                            read values are placed in the supplied array
+   */
+  void retrieveSetValues(const int index,
+                         void * values,
+                         const int dataType,
+                         const int numberRead,
+                         const int startIndex,
+                         const int arrayStride,
+                         const int valueStride);
+
+  /**
+   * Returns the datatype of the specified set as an integer.
+   * 
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   the index of the Set
+   *
+   * @return            The type of the specified Set's values as an integer,
+   *                    EX: XDMF_ARRAY_TYPE_INT8
+   */
+  int retrieveSetValueType(const int index);
+
+  /**
+   * Opens the set at the specified index by placing its attributes and
+   * information in mAttributes and mInformations. Pushes the previous
+   * contents of those two containers into parentAttributes and parentInformations.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index                   The index of the specified set
+   * @param     openAttributes          Set to 1 to open attributes
+   * @param     openInformation         Set to 1 to open information
+   */
+  void openSet(const int index, const int openAttributes, const int openInformation);
+
+  /**
+   * Removes the specified set from mSets.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the set to be removed
+   */
+  void removeSet(const int index);
+
+  /**
+   * Replaces a specified set in mSets with a set that contains
+   * the current contents to mInformations and mAttributes.
+   * Then the top of parentAttributes and parentInformations
+   * are placed in mAttributes and mInformations
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the set to be replaced
+   * @param     name            A pointer to the location of the name for the set
+   * @param     newSetType      The integer equivalent to the set type of the
+   *                            added set Ex: XDMF_SET_TYPE_NODE
+   * @param     values          A pointer to the location where the values to be
+   *                            placed in the set will are stored
+   * @param     numValues       The amount of values in the array at the provided pointer
+   * @param     arrayType       The integer representation of the datatype
+   *                            of the values Ex: XDMF_ARRAY_TYPE_INT32
+   */
+  void replaceSet(const int index,
+                  char * name,
+                  const int newSetType,
+                  void * values,
+                  const int numValues,
+                  const int arrayType);
+
+  /**
+   * Returns the number of properties currently stored in the specified set.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the set whose number of properties is being retrieved
+   *
+   * @return            The number of properties associated with the specified set
+   */
+  int retrieveSetNumProperties(const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of
+   * the specified set and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     setIndex        The index of the set that is being retrieved
+   * @param     index           The index of the property that is being retrieved
+   * @param     key             A pointer to the location where the key value
+   *                            will be stored
+   * @param     keyLength       The size of the key variable
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveSetProperty(const int setIndex,
+                           const int index,
+                           char * key,
+                           const int keyLength,
+                           char * value,
+                           const int valueLength);
+
+  /**
+   * Retrieves the value of a property of a specified set when given its key.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the key has no matching value
+   *
+   * @param     index           The index of the set whose property is being
+   *                            retrieved
+   * @param     key             A pointer to the value of the key that is being
+   *                            searched for
+   * @param     value           A pointer to the location where the value of
+   *                            the property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveSetPropertyByKey(const int index,
+                                char * key,
+                                char * value,
+                                const int valueLength);
+
+  /**
+   * Sets the specified set as an array variable associated with a specific name.
+   * Used in conjuction with Functions.
+   *
+   * @param     varname The variable to accociate with the set.
+   * @param     index   The index of the set.
+   */
+  void setSetAsVariable(char * varname, int index);
+
+  /**
+   * Sets the specified set as the current subset reference.
+   *
+   * @param     index   The index of the set.
+   */
+  void setSetAsSubsetReference(int index);
+
+  /**
+   * Returns the number of information currently stored in mInformations.
+   *
+   * @return    the number of information contained within mInformations
+   */
+  int retrieveNumInformation();
+
+  /**
+   * Retrieves the specified information's tag and stores it into the provided pointer
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the information whose tag is being retrieved
+   * @param     tag             The location where the tag will be stored
+   * @param     tagLength       The size fo the array at the provided pointer
+   */
+  void retrieveInformationTag(const int index, char * tag, const int tagLength);
+
+  /**
+   * Retrieves the key and value of the Information at the specifed index
+   * and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the property that is being
+   *                            retrieved
+   * @param     key             A pointer to the location where the
+   *                            key value will be stored
+   * @param     keyLength       The size of the key variable
+   * @param     value           A pointer to the location where the
+   *                            value of the information will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveInformation(const int index,
+                           char * key,
+                           const int keyLength,
+                           char * value,
+                           const int valueLength);
+
+  /**
+   * Removes the information at the specified index.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the information to be removed
+   */
+  void removeInformation(const int index);
+
+  /**
+   * Replaces the key and value of the information at the specified index
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the information to be changed
+   * @param     key     A pointer to the new key
+   * @param     value   A pointer to the new value
+   */
+  void replaceInformation(const int index, char * key, char * value);
+
+  /**
+   * Opens the specified information by placing the information it contains
+   * in mInformations
+   *
+   * @param     index   The index of the information to be opened
+   */
+  void openInformation(const int index);
+
+  /**
+   * Retrieves the value of a specified information when given its key.
+   *
+   * Returns an error if the key has no matching value
+   *
+   * @param     key             A pointer to the value of the key that is
+   *                            being searched for
+   * @param     value           A pointer to the location where the value
+   *                            of the information will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveInformationByKey(char * key, char * value, const int valueLength);
+
+  /**
+   * Removes the information with the specified key
+   *
+   * Returns an error if the key does not match an information
+   *
+   * @param     key     A pointer to the value of the key being searched for
+   */
+  void removeInformationByKey(char * key);
+
+  /**
+   * Replaces the value of the information with the specified key
+   *
+   * Returns an error if the key does not match a value
+   *
+   * @param     key     A pointer to the value of the key being searched for
+   * @param     value   A pointer to the value that will be placed into the information
+   */
+  void replaceInformationByKey(char * key, char * value);
+
+  /**
+   * Clears mPreviousInformations. Use to reduce memory load.
+   */
+  void clearPreviousInformation();
+
+  /**
+   * Clears mInformations of all added information.
+   */
+  void clearInformations();
+
+  /**
+   * Returns the number of properties currently stored in the specified information.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index   The index of the information whose number of properties
+   *                    is being retrieved
+   *
+   * @return            The number of properties associated with the specified
+   *                    information
+   */
+  int retrieveInformationNumProperties(const int index);
+
+  /**
+   * Retrieves the key and value of the property at the specifed index of the
+   * specified information and modifies the values at the provided pointers
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     informationIndex        The index of the information that is
+   *                                    being retrieved
+   * @param     index                   The index of the property that is being
+   *                                    retrieved
+   * @param     key                     A pointer to the location where the
+   *                                    key value will be stored
+   * @param     keyLength               The size of the key variable
+   * @param     value                   A pointer to the location where the
+   *                                    value of the property will be stored
+   * @param     valueLength             The size of the value variable
+   */
+  void retrieveInformationProperty(const int informationIndex,
+                                   const int index,
+                                   char * key,
+                                   const int keyLength,
+                                   char * value,
+                                   const int valueLength);
+
+  /**
+   * Retrieves the value of a property of a specified information when given its key.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the key has no matching value
+   *
+   * @param     index           The index of the information whose property is
+   *                            being retrieved
+   * @param     key             A pointer to the value of the key that is being
+   *                            searched for
+   * @param     value           A pointer to the location where the value of the
+   *                            property will be stored
+   * @param     valueLength     The size of the value variable
+   */
+  void retrieveInformationPropertyByKey(const int index,
+                                        char * key,
+                                        char * value,
+                                        const int valueLength);
+
+  /**
+   * Adds an array containing the provided values into the specified information.
+   *
+   * Returns an error if the index is out of bounds
+   *
+   * @param     index           The index of the information that the array
+   *                            will be added into.
+   * @param     values          A pointer to the values to be contained in
+   *                            the added array.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     arrayType       The data type that the array will consist of.
+   */
+  void addInformationArray(const int index,
+                           char * name,
+                           void * values,
+                           const int numValues,
+                           const int arrayType);
+
+  /**
+   * Remove heavy data linkage from the specified Information Array.
+   *
+   * @param     index           Index of the Information holding the array which
+   *                            will have its heavydata linkage removed.
+   * @param     arrayIndex      Index of the array in the specified information
+   */
+  void clearInformationArrayHeavyData(const int index,
+                                      const int arrayIndex);
+
+  /**
+   * Set HDF5 linkage for the specified Information Array.
+   *
+   * @param     index           Index of the Information holding the array
+                                which will have its hdf5 linkage set.
+   * @param     arrayIndex      Index of the array in the specified information
+   * @param     hdf5File        Filename for the hdf5 linkage
+   * @param     hdf5Dataset     Dataset name for the hdf5 linkage
+   * @param     start           Starting index in the hdf5 dataset
+   * @param     stride          Distance between values in the hdf5 dataset
+   * @param     numValues       Number of values in the hdf5 dataset
+   * @param     dataspace       Total size of the hdf5 dataset.
+   */
+  void setInformationArrayHDF5(const int index,
+                               const int arrayIndex,
+                               const char * hdf5File,
+                               const char * hdf5Dataset,
+                               const unsigned int start,
+                               const unsigned int stride,
+                               const unsigned int numValues,
+                               const unsigned int dataspace);
+
+  /**
+   * Set Binary linkage for the specified Information Array.
+   *
+   * @param     index           Index of the Information holding the array
+                                which will have its binary linkage set.
+   * @param     arrayIndex      Index of the array in the specified information
+   * @param     binFile         Filename for the binary linkage
+   * @param     endian          Endianness of the dataset
+   * @param     seek            Offset of the dataset in the binary file
+   * @param     start           Starting index in the binary dataset
+   * @param     stride          Distance between values in the binary dataset
+   * @param     numValues       Number of values in the binary dataset
+   * @param     dataspace       Total size of the binary dataset.
+   */
+  void setInformationArrayBinary(const int index,
+                                 const int arrayIndex,
+                                 const char * binFile,
+                                 const int endian,
+                                 const unsigned int seek,
+                                 const unsigned int start,
+                                 const unsigned int stride,
+                                 const unsigned int numValues,
+                                 const unsigned int dataspace);
+
+  /**
+   * Makes an information a child of another information.
+   * Has an option to remove the Information from mInformation.
+   *
+   * Returns an error if either index is out of range
+   * Returns an error if the index are the same
+   *
+   * @param     toIndex         The index of the parent information.
+   * @param     fromIndex       The index of the child information.
+   * @param     removeFromArray Whether to remove the information at
+   *                            fromIndex from mInformation
+   */
+  void insertInformationIntoInformation(const int toIndex,
+                                        const int fromIndex,
+                                        const bool removeFromArray);
+
+  /**
+   * Overwrites a section of the specified array using the provided values.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the array index is out of bounds
+   *
+   * @param     index           The index of the information that controls
+   *                            the array to be modified.
+   * @param     arrayIndex      The index of the array in the information.
+   * @param     values          A pointer to the values to be written.
+   * @param     arrayType       The data type of the values to be inserted.
+   * @param     numValues       The number of values to be pulled from the pointer.
+   * @param     insertStart     The point in the array for editing to start.
+   * @param     arrayStride     The increment between value placements on the
+   *                            array being written to.
+   * @param     valueStride     The increment between value pulls from the
+   *                            pointer written from.
+   */
+  void modifyInformationArray(const int index,
+                              const int arrayIndex,
+                              void * values,
+                              const int arrayType,
+                              const int numValues,
+                              const int insertStart,
+                              const int arrayStride,
+                              const int valueStride);
+
+  /**
+   * Removes an array from an information.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the array index is out of bounds
+   *
+   * @param     index           The index of the information that controls the
+   *                            array to be removed.
+   * @param     arrayIndex      The index of the array in the information.
+   */
+  void removeInformationArray(const int index,
+                              const int arrayIndex);
+
+  /**
+   * Gets the amount of values stored in the specified array.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the array index is out of bounds
+   *
+   * @param     index           The index of the information that controls the
+   *                            array to be removed.
+   * @param     arrayIndex      The index of the array in the information.
+   */
+  int retrieveInformationArraySize(const int index,
+                                   const int arrayIndex);
+
+  /**
+   * Gets the array type of the specified array.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the array index is out of bounds
+   *
+   * @param     index           The index of the information that controls the
+   *                            array whose type is being retrieved.
+   * @param     arrayIndex      The index of the array in the information.
+   */
+  int retrieveInformationArrayValueType(const int index,
+                                        const int arrayIndex);
+
+  /**
+   * Retrieves the values contained in the specified array.
+   *
+   * Returns an error if the index is out of bounds
+   * Returns an error if the array index is out of bounds
+   *
+   * @param     index           The index of the information that controls the
+   *                            array whose data is being retrieved.
+   * @param     arrayIndex      The index of the array in the information.
+   * @param     values          A pointer that the read values will be placed in.
+   * @param     dataType        The type that the read data will be read in as.
+   * @param     numberRead      The number of data items read from the array.
+   * @param     startIndex      The index of the first value to be read.
+   * @param     arrayStride     The increment beteween read values in the array.
+   * @param     valueStride     The increment betweeen written values in the pointer.
+   */
+  void retrieveInformationArrayValues(const int index,
+                                      const int arrayIndex,
+                                      void * values,
+                                      const int dataType,
+                                      const int numberRead,
+                                      const int startIndex,
+                                      const int arrayStride,
+                                      const int valueStride);
+
+  /**
+   * Sets the specified information array as an array variable associated with a specific name.
+   * Used in conjuction with Functions.
+   *
+   * @param     varname         The variable to accociate with the array.
+   * @param     infoindex       The index of the information holding the array
+   * @param     index           The index of the array.
+   */
+  void setInformationArrayAsVariable(char * varname, int infoindex, int index);
+
+  /**
+   * Sets the specified information array as the current subset reference.
+   *
+   * @param     infoindex       The index of the information holding the array
+   * @param     index           The index of the array.
+   */
+  void setInformationArrayAsSubsetReference(int infoindex, int index);
+
+  /**
+   * Creates an attribute that is a function of other arrays.
+   * Interacts with setXXXXAsVariable
+   *
+   * @param     expression      The function that will be processed when creating the array.
+   * @param     name            The name of the array.
+   * @param     attributeCenter The center of the attribute being created.
+   * @param     attributeType   The attribute type of the attribute being created.
+   */
+  int addFunctionAsAttribute(char * expression,
+                             const char * const name,
+                             const int attributeCenter,
+                             const int attributeType);
+
+  /**
+   * Creates a coordinate that is a function of other arrays.
+   * Interacts with setXXXXAsVariable
+   *
+   * @param     expression      The function that will be processed when creating the array.
+   * @param     name            The name of the array.
+   */
+  int addFunctionAsCoordinate(char * expression,
+                              char * name);
+
+  /**
+   * Creates a set that is a function of other arrays.
+   * Interacts with setXXXXAsVariable
+   *
+   * @param     expression      The function that will be processed when creating the array.
+   * @param     name            The name of the array.
+   * @param     newSetType      The set type of the set being created.
+   */
+  int addFunctionAsSet(char * expression,
+                       char * name,
+                       const int newSetType);
+
+  /**
+   * Creates a information array that is a function of other arrays.
+   * Interacts with setXXXXAsVariable
+   *
+   * @param     expression      The function that will be processed when creating the array.
+   * @param     index           The index of the information that the array will be added to.
+   * @param     name            The name of the array.
+   */
+  void addFunctionAsInformationArray(char * expression,
+                                     const int index,
+                                     char * name);
+
+  /**
+   * Creates a topology that is a function of other arrays.
+   * Interacts with setXXXXAsVariable
+   *
+   * @param     expression      The function that will be processed when creating the array.
+   * @param     topologyType    The set type of the set being created.
+   * @param     numNodes        The number of nodes in the new topology.
+   */
+  int setFunctionAsTopology(char * expression,
+                            const int topologyType,
+                            const int numNodes);
+
+  /**
+   * Creates a geometry that is a function of other arrays.
+   * Interacts with setXXXXAsVariable
+   *
+   * @param     expression      The function that will be processed when creating the array.
+   * @param     geometryType    The set type of the set being created.
+   */
+  int setFunctionAsGeometry(char * expression,
+                            const int geometryType);
+
+  /**
+   * Creates an attribute that is a subset of another array.
+   * Interacts with setXXXXAsSubsetReference
+   *
+   * @param     start           The starting index of the subset within the reference.
+   * @param     stride          The distance between values taken from the reference
+   * @param     dimensions      The total number of values taken from the reference.
+   * @param     name            The name of the array.
+   * @param     attributeCenter The center of the attribute being created.
+   * @param     attributeType   The attribute type of the attribute being created.
+   */
+  int addSubsetAsAttribute(int start,
+                           int stride,
+                           int dimensions,
+                           const char * const name,
+                           const int attributeCenter,
+                           const int attributeType);
+
+  /**
+   * Creates a coordinate that is a subset of another array.
+   * Interacts with setXXXXAsSubsetReference
+   *
+   * @param     start           The starting index of the subset within the reference.
+   * @param     stride          The distance between values taken from the reference
+   * @param     dimensions      The total number of values taken from the reference.
+   * @param     name            The name of the array.
+   */
+  int addSubsetAsCoordinate(int start,
+                            int stride,
+                            int dimensions,
+                            char * name);
+  /**
+   * Creates a set that is a subset of another array.
+   * Interacts with setXXXXAsSubsetReference
+   *
+   * @param     start           The starting index of the subset within the reference.
+   * @param     stride          The distance between values taken from the reference
+   * @param     dimensions      The total number of values taken from the reference.
+   * @param     name            The name of the array.
+   * @param     newSetType      The set type of the set being created.
+   */
+  int addSubsetAsSet(int start,
+                     int stride,
+                     int dimensions,
+                     char * name,
+                     const int newSetType);
+
+  /**
+   * Creates a information array that is a subset of another array.
+   * Interacts with setXXXXAsSubsetReference
+   *
+   * @param     start           The starting index of the subset within the reference.
+   * @param     stride          The distance between values taken from the reference
+   * @param     dimensions      The total number of values taken from the reference.
+   * @param     index           The index of the information that the array will be added to.
+   * @param     name            The name of the array.
+   */
+  void addSubsetAsInformationArray(int start,
+                                   int stride,
+                                   int dimensions,
+                                   const int index,
+                                   char * name);
+
+  /**
+   * Creates a topology that is a subset of another array.
+   * Interacts with setXXXXAsSubsetReference
+   *
+   * @param     start           The starting index of the subset within the reference.
+   * @param     stride          The distance between values taken from the reference
+   * @param     dimensions      The total number of values taken from the reference.
+   * @param     topologyType    The set type of the set being created.
+   * @param     numNodes        The number of nodes in the new topology.
+   */
+  int setSubsetAsTopology(int start,
+                          int stride,
+                          int dimensions,
+                          const int topologyType,
+                          const int numNodes);
+
+  /**
+   * Creates a geometry that is a subset of another array.
+   * Interacts with setXXXXAsSubsetReference
+   *
+   * @param     start           The starting index of the subset within the reference.
+   * @param     stride          The distance between values taken from the reference
+   * @param     dimensions      The total number of values taken from the reference.
+   * @param     geometryType    The set type of the set being created.
+   */
+  int setSubsetAsGeometry(int start,
+                          int stride,
+                          int dimensions,
+                          const int geometryType);
+
+  /**
+   * Clears all variables from the variable list.
+   */
+  void clearFunctionVariables();
+
+  /**
+   * Removes the variable with the specified name from the variable list.
+   *
+   */
+  void removeFunctionVariable(char * varname);
+
+  /**
+   * clears all of the mPrevious vectors. Used to reduce memory load.
+   */
+  void clearPrevious();
+
+  /**
+   * Sets whether to allow the hdf5 writer to split large data sets across multiple files.
+   * Setting to true removes compatibiliity with previous versions.
+   * When off it will write sets that will not fit into a file to the current file
+   * before moving to the next should file splitting be enabled.
+   * Default is off (false).
+   *
+   * @param     newAllow        Whether to allow splitting or not
+   */
+  void setAllowSetSplitting(bool newAllow);
+
+  /**
+   * Sets the file size at which the hdf5 writer will move to a new file.
+   * Default is no splitting (value=0)
+   * 
+   * @param     newSize         New maximum file size before moving
+   */
+  void setMaxFileSize(int newSize);
+
+  /**
+   * Write constructed file to disk.
+   *
+   * @param     xmlFilePath     The path to the xml file to write to.
+   * @param     release         Whether the HDF5 writer will release data after finishing
+   */
+  void write(const char * const xmlFilePath, const int dataLimit, const bool release);
+
+  /** 
+   * Write HDF5 heavy data to disk and release
+   *
+   * @param     xmlFilePath     The path to the xml file to write to.
+   * @param     release         Whether or not to release data after a write
+   */
+  void writeHDF5(const char * const xmlFilePath, const bool release);
+
+#ifdef XDMF_BUILD_DSM
+
+  /**
+   * Starts up a dsm server on cores from the start index to the end index.
+   * The server cores are blocked and will not proceed past this point
+   * until the dsm is stopped.
+   *
+   * @param     filePath        A string denoting the file path to the virtual file.
+   * @param     comm            The Communicator between all cores,
+   *                            worker and server.
+   * @param     bufferSize      The size of the memory buffer allocated per core.
+   * @param     startCoreIndex  The core index on which the dsm section begins.
+   * @param     endCoreIndex    The core index on which the dsm section ends.
+   */
+  void initDSMServer(const char * const filePath,
+                     MPI_Comm comm, 
+                     int bufferSize,
+                     int startCoreIndex,
+                     int endCoreIndex);
+
+  /**
+   * Accepts new connections into an initialized dsm server.
+   *
+   * @param     numConnections  The number of incoming connections to accept.
+   */
+  void acceptDSM(int numConnections);
+
+  /**
+   * Closes the currently open port to the comm.
+   */
+  void closeDSMPort();
+
+  /**
+   * Connects to an initialized dsm server.
+   *
+   * @param     filePath        The file path that the DSMWriter will be writing to,
+   *                            should be the same as on the server side.
+   * @param     comm            The local communicator to be connected to the
+   *                            server communicator.
+   */
+  void connectDSM(const char * const filePath, MPI_Comm comm);
+
+  /**
+   * Gets the communicator across the entire dsm and all connected to it.
+   *
+   * @return    The overarching communicator.
+   */
+  MPI_Comm getDSMInterComm();
+
+  /**
+   * Gets the local communicator that the worker cores share.
+   *
+   * @return    The communicator for the local worker group
+   */
+  MPI_Comm getDSMIntraComm();
+
+  /**
+   * Stops the currently running dsm server.
+   */
+  void stopDSM();
+
+  /**
+   * Writes the provided values to the DSM using at the location generated by
+   * the provided start, stride, dimensions, and dataspace.
+   *
+   * @param     dsmDataSetPath  The path to the dataset being written to.
+   *                            Will overwrite current dsm if different.
+   * @param     arrayType       The data type of the data to be written to the set.
+   * @param     values          A pointer to the values to be written.
+   * @param     start           The starting index to write to.
+   * @param     stride          The increment between writing data.
+   * @param     dimensions      The number of data items written.
+   * @param     dataspace       The total number of data items in the dataset.
+   */
+  void writeToDSM(const char * const dsmDataSetPath,
+                  const int arrayType,
+                  void * values,
+                  const int start,
+                  const int stride,
+                  const int dimensions,
+                  const int dataspace);
+
+  /**
+   * Reads the data in the dsm at the location generated from the
+   * start, stride, dimensions, and dataspace and places it into the
+   * provided pointer.
+   *
+   * @param     dsmDataSetPath  The path to the dataset being read.
+   * @param     arrayType       The data type of the data being read.
+   * @param     values          A pointer to the location that the data
+   *                            will be stored at.
+   * @param     start           The starting index of the read.
+   * @param     stride          The increment between read values.
+   * @param     dimensions      The amount of value to be read.
+   * @param     dataspace       The total number of data items in the dataset.
+   */
+  void readFromDSM(const char * const dsmDataSetPath,
+                   const int arrayType,
+                   void * values,
+                   const int start,
+                   const int stride,
+                   const int dimensions,
+                   const int dataspace);
+
+#endif
+
+  /**
+   * Generate the persistant hdf5 writer so it doesn't need to be generated later
+   *
+   * @param     xmlFilePath     The path to the xml file to write to.
+   * @param     release         Whether or not to release data after a write
+   */
+  void initHDF5(const char * const xmlFilePath, const bool release);
+
+  /** 
+   * Read xml file and make it the domain. Replaces current domain.
+   *
+   * @param     xmlFilePath     The path to the xml file to read.
+   */
+  void read(const char * const xmlFilePath);
+
+
+  /** 
+   * Set the topology (connectivity data) for a polyline that will be
+   * added to the next grid.
+   *
+   * @param     nodesPerElement         Number of nodes in the polyline.
+   * @param     numValues               Number of connectivity values to copy.
+   * @param     arrayType               Type of connectivity values.
+   * @param     connectivityValues      Array of connectivity values.
+   *
+   * @return                            int providing id to fortran if reusing.
+   */
+  int setTopologyPolyline(const unsigned int nodesPerElement, 
+                          const unsigned int numValues,
+                          const int arrayType,
+                          const void * const connectivityValues);
+
+  /**
+   * Set the topology (connectivity data) for a polygon that will be
+   * added to the next grid.
+   *
+   * @param     nodesPerElement         Number of nodes in the polygon.
+   * @param     numValues               Number of connectivity values to copy.
+   * @param     arrayType               Type of connectivity values.
+   * @param     connectivityValues      Array of connectivity values.
+   *
+   * @return                            int providing id to fortran if reusing.
+   */
+  int setTopologyPolygon(const unsigned int nodesPerElement,
+                         const unsigned int numValues,
+                         const int arrayType,
+                         const void * const connectivityValues);
+
+private:
+
+  template <typename T>
+  void
+  insertElements(const T grid,
+                 std::vector<shared_ptr<XdmfAttribute> > & mAttributes,
+                 std::vector<shared_ptr<XdmfInformation> > & mInformations,
+                 std::vector<shared_ptr<XdmfSet> > & mSets,
+                 std::vector<shared_ptr<XdmfMap> > & mMaps,
+                 shared_ptr<XdmfTime> mTime,
+                 shared_ptr<XdmfDomain> mDomain,
+                 std::stack<shared_ptr<XdmfGridCollection> > & mGridCollections);
+
+  void
+  readFromArray(shared_ptr<XdmfArray> array,
+                const int arrayType,
+                void * const values,
+                const unsigned int numValues,
+                const unsigned int startIndex,
+                const unsigned int arrayStride,
+                const unsigned int valuesStride);
+
+  void
+  writeToArray(shared_ptr<XdmfArray> array,
+               const unsigned int numValues,
+               const int arrayType,
+               const void * const values,
+               const unsigned int offset = 0,
+               const unsigned int arrayStride = 1,
+               const unsigned int valueStride = 1);
+  
+  shared_ptr<XdmfDomain>                        mDomain;
+  shared_ptr<XdmfGeometry>                      mGeometry;
+  shared_ptr<XdmfTime>                          mTime;
+  shared_ptr<XdmfTopology>                      mTopology;
+  shared_ptr<XdmfArray>                         mBrick;
+  shared_ptr<XdmfArray>                         mOrigin;
+  shared_ptr<XdmfArray>                         mDimensions;
+  shared_ptr<XdmfHeavyDataWriter>               mHeavyDataWriter;
+  shared_ptr<XdmfHDF5WriterDSM>                 mDSMWriter;
+
+  std::vector<shared_ptr<XdmfAttribute> >       mAttributes;
+  std::vector<shared_ptr<XdmfArray> >           mCoordinates;
+  std::stack<shared_ptr<XdmfGridCollection> >   mGridCollections;
+  std::vector<shared_ptr<XdmfInformation> >     mInformations;
+  std::vector<shared_ptr<XdmfSet> >             mSets;
+  std::vector<shared_ptr<XdmfMap> >             mMaps;
+  std::map<std::string, shared_ptr<XdmfArray> > mVariableSet;
+  shared_ptr<XdmfArray>                         mSubsetReference;
+
+  std::vector<shared_ptr<XdmfAttribute> >       mPreviousAttributes;
+  std::vector<shared_ptr<XdmfGeometry> >        mPreviousGeometries;
+  std::vector<shared_ptr<XdmfInformation> >     mPreviousInformations;
+  std::vector<shared_ptr<XdmfSet> >             mPreviousSets;
+  std::vector<shared_ptr<XdmfTopology> >        mPreviousTopologies;
+  std::vector<shared_ptr<XdmfArray> >           mPreviousDimensions;
+  std::vector<shared_ptr<XdmfArray> >           mPreviousOrigins;
+  std::vector<shared_ptr<XdmfArray> >           mPreviousBricks;
+  std::vector<shared_ptr<XdmfArray> >           mPreviousCoordinates;
+  std::vector<shared_ptr<XdmfMap> >             mPreviousMaps;
+  std::vector<shared_ptr<XdmfFunction> >        mPreviousFunctions;
+  std::vector<shared_ptr<XdmfSubset> >          mPreviousSubsets;
+
+  unsigned int mMaxFileSize;
+  bool mAllowSetSplitting;
+
+};
+
+#endif /* XDMFFORTRAN_HPP_ */
diff --git a/utils/XdmfGeometryConverter.cpp b/utils/XdmfGeometryConverter.cpp
new file mode 100644
index 0000000..9a224c7
--- /dev/null
+++ b/utils/XdmfGeometryConverter.cpp
@@ -0,0 +1,357 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopologyConverter.cpp                                           */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2013 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cmath>
+#include <map>
+#include <iostream>
+#include <vector>
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryConverter.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfError.hpp"
+
+shared_ptr<XdmfGeometryConverter>
+XdmfGeometryConverter::New()
+{
+  shared_ptr<XdmfGeometryConverter> p(new XdmfGeometryConverter());
+  return p;
+}
+
+XdmfGeometryConverter::XdmfGeometryConverter()
+{
+}
+
+XdmfGeometryConverter::XdmfGeometryConverter(const XdmfGeometryConverter &)
+{
+}
+
+XdmfGeometryConverter::~XdmfGeometryConverter()
+{
+}
+
+shared_ptr<XdmfGeometry>
+XdmfGeometryConverter::convertToCartesian(const shared_ptr<XdmfGeometry> & geometryToConvert) const
+{
+  if (geometryToConvert->getType() == XdmfGeometryType::NoGeometryType())
+  {
+    XdmfError::message(XdmfError::FATAL,
+                         "Error: Converted Geometry size doesn't have a geometry type set");
+  }
+
+  if (geometryToConvert->getType() == XdmfGeometryType::XY() ||
+      geometryToConvert->getType() == XdmfGeometryType::XYZ())
+  {
+    // Already in Cartesian form
+    return geometryToConvert;
+  }
+  else
+  {
+    shared_ptr<XdmfGeometry> returnGeometry = XdmfGeometry::New();
+
+    if (!geometryToConvert->isInitialized()) {
+      geometryToConvert->read();
+    }
+
+    if (geometryToConvert->getSize()%geometryToConvert->getType()->getDimensions() != 0)
+    {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Converted Geometry size doesn't match number of dimensions");
+    }
+    else
+    {
+      if (geometryToConvert->getType()->getDimensions() == 2)
+      {
+        // Polar to XY
+        returnGeometry->setType(XdmfGeometryType::XY());
+        if (geometryToConvert->getSize() < 2)
+        {
+          return returnGeometry;
+        }
+        std::vector<double> origin = geometryToConvert->getOrigin();
+        returnGeometry->setOrigin(origin);
+        unsigned int i = 0;
+        while(i+1 < geometryToConvert->getSize())
+        {
+          double radius = geometryToConvert->getValue<double>(i);
+          double inclination = geometryToConvert->getValue<double>(i+1);
+
+          double x = (radius * std::sin(inclination));
+          double y = (radius * std::cos(inclination));
+          returnGeometry->pushBack(x);
+          returnGeometry->pushBack(y);
+          i = i + 2;
+        }
+      }
+      else if (geometryToConvert->getType()->getDimensions() == 3)
+      {
+        // Spherical to XYZ
+        returnGeometry->setType(XdmfGeometryType::XYZ());
+        if (geometryToConvert->getSize() < 3)
+        {
+          return returnGeometry;
+        }
+        std::vector<double> origin = geometryToConvert->getOrigin();
+        returnGeometry->setOrigin(origin);
+        unsigned int i = 0;
+        while(i+2 < geometryToConvert->getSize())
+        {
+          double radius = geometryToConvert->getValue<double>(i);
+          double inclination = geometryToConvert->getValue<double>(i+1);
+          double azimuth = geometryToConvert->getValue<double>(i+2);
+
+
+          double x = (radius * std::sin(inclination) * std::cos(azimuth));
+          double y = (radius * std::sin(inclination) * std::sin(azimuth));
+          double z = (radius * std::cos(inclination));
+
+          returnGeometry->pushBack(x);
+          returnGeometry->pushBack(y);
+          returnGeometry->pushBack(z);
+          i = i + 3;
+        }
+      }
+      else
+      {
+        XdmfError::message(XdmfError::FATAL,
+                         "Error: Converted Geometry has an invalid number of dimensions");
+      }
+    }
+    return returnGeometry;
+  }
+}
+
+shared_ptr<XdmfGeometry>
+XdmfGeometryConverter::convertToSpherical(const shared_ptr<XdmfGeometry> & geometryToConvert) const
+{
+  if (geometryToConvert->getType() == XdmfGeometryType::NoGeometryType())
+  {
+    XdmfError::message(XdmfError::FATAL,
+                       "Error: Converted Geometry size doesn't have a geometry type set");
+  }
+
+  if (geometryToConvert->getType() == XdmfGeometryType::Polar() ||
+      geometryToConvert->getType() == XdmfGeometryType::Spherical())
+  {
+    // Already in Spherical form
+    return geometryToConvert;
+  }
+  else
+  {
+    shared_ptr<XdmfGeometry> returnGeometry = XdmfGeometry::New();
+
+    if (!geometryToConvert->isInitialized()) {
+      geometryToConvert->read();
+    }
+
+    if (geometryToConvert->getSize()%geometryToConvert->getType()->getDimensions() != 0)
+    {
+      XdmfError::message(XdmfError::FATAL,
+                         "Error: Converted Geometry size doesn't match number of dimensions"); 
+    }
+    else
+    {
+      if (geometryToConvert->getType()->getDimensions() == 2)
+      {
+        // XY to Polar
+        returnGeometry->setType(XdmfGeometryType::Polar());
+        // insert origin
+        std::vector<double> origin = geometryToConvert->getOrigin();
+        returnGeometry->setOrigin(origin); 
+        unsigned int i = 0;
+        while(i+1 < geometryToConvert->getSize())
+        {
+          double x = geometryToConvert->getValue<double>(i);
+          double y = geometryToConvert->getValue<double>(i+1);
+
+          double radius = std::sqrt(std::pow(x, 2) + std::pow(y, 2));
+          double inclination = std::acos(x/radius);
+          returnGeometry->pushBack(radius);
+          returnGeometry->pushBack(inclination);
+          i = i + 2;
+        }
+      }
+      else if (geometryToConvert->getType()->getDimensions() == 3)
+      {
+        // XYZ to Spherical
+        returnGeometry->setType(XdmfGeometryType::Spherical());
+        // insert origin
+        std::vector<double> origin = geometryToConvert->getOrigin();
+        returnGeometry->setOrigin(origin);
+        unsigned int i = 0;
+        while(i+2 < geometryToConvert->getSize())
+        {
+          double x = geometryToConvert->getValue<double>(i);
+          double y = geometryToConvert->getValue<double>(i+1);
+          double z = geometryToConvert->getValue<double>(i+2);
+
+          double radius = std::sqrt(std::pow(x, 2) + std::pow(y, 2) + std::pow(z, 2));
+          double inclination = std::acos(z/radius);
+          double azimuth = std::atan(y/x);
+          returnGeometry->pushBack(radius);
+          returnGeometry->pushBack(inclination);
+          returnGeometry->pushBack(azimuth);
+          i = i + 3;
+        }
+      }
+      else
+      {
+        XdmfError::message(XdmfError::FATAL,
+                         "Error: Converted Geometry has an invalid number of dimensions");
+      }
+    }
+    return returnGeometry;
+  }
+}
+
+void
+XdmfGeometryConverter::convertToCartesianOverwrite(shared_ptr<XdmfGeometry> & geometryToConvert) const
+{
+  if (!(geometryToConvert->getType() == XdmfGeometryType::XY() ||
+        geometryToConvert->getType() == XdmfGeometryType::XYZ()))
+  {
+    shared_ptr<XdmfGeometry> tempGeometry = convertToCartesian(geometryToConvert);
+    // Change the type of the geometry provided
+    geometryToConvert->setType(tempGeometry->getType());
+    // Move values over to the original to complete the conversion
+    geometryToConvert->swap(tempGeometry);
+  }
+}
+
+void
+XdmfGeometryConverter::convertToSphericalOverwrite(shared_ptr<XdmfGeometry> & geometryToConvert) const
+{
+  if (!(geometryToConvert->getType() == XdmfGeometryType::Polar() ||
+        geometryToConvert->getType() == XdmfGeometryType::Spherical()))
+  {
+    shared_ptr<XdmfGeometry> tempGeometry = convertToSpherical(geometryToConvert);
+    // Change the type of the geometry provided
+    geometryToConvert->setType(tempGeometry->getType());
+    // Move values over to the original to complete the conversion
+    geometryToConvert->swap(tempGeometry);
+  }
+}
+
+shared_ptr<XdmfGeometry>
+XdmfGeometryConverter::zeroOrigin(const shared_ptr<XdmfGeometry> & geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> returnGeometry = shared_ptr<XdmfGeometry>();
+  std::vector<double> origin = geometryToConvert->getOrigin();
+  if (origin.size() < geometryToConvert->getType()->getDimensions())
+  {
+    while (origin.size() < geometryToConvert->getType()->getDimensions())
+    {
+      origin.push_back(0.0);
+    }
+  }
+  if (geometryToConvert->getType() == XdmfGeometryType::XY() ||
+      geometryToConvert->getType() == XdmfGeometryType::XYZ())
+  {
+    returnGeometry = XdmfGeometry::New();
+    returnGeometry->setType(geometryToConvert->getType());
+    returnGeometry->initialize(geometryToConvert->getArrayType(), geometryToConvert->getDimensions());
+    // Simply add the origin as an offset.
+    unsigned int originIndex = 0;
+    for (unsigned int i = 0; i < geometryToConvert->getSize(); ++i)
+    {
+      returnGeometry->insert(i, (geometryToConvert->getValue<double>(i) + origin[originIndex]));
+      originIndex = (originIndex + 1) % geometryToConvert->getType()->getDimensions();
+    }
+  }
+  else if (geometryToConvert->getType() == XdmfGeometryType::Polar() ||
+           geometryToConvert->getType() == XdmfGeometryType::Spherical())
+  {
+    // The spherical version needs to convert to cartesian and back.
+    returnGeometry = convertToSpherical(zeroOrigin(convertToCartesian(geometryToConvert)));
+  }
+  return returnGeometry;
+}
+
+void
+XdmfGeometryConverter::zeroOriginOverwrite(shared_ptr<XdmfGeometry> & geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeometry = zeroOrigin(geometryToConvert);
+  geometryToConvert->swap(tempGeometry);;
+}
+
+// C Wrappers
+
+XDMFGEOMETRYCONVERTER *
+XdmfGeometryConverterNew()
+{
+  shared_ptr<XdmfGeometryConverter> generatedConverter = XdmfGeometryConverter::New();
+  return (XDMFGEOMETRYCONVERTER *)((void *)(new XdmfGeometryConverter(*generatedConverter.get())));
+}
+
+XDMFGEOMETRY * XdmfGeometryConverterConvertToCartesian(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeo = shared_ptr<XdmfGeometry>((XdmfGeometry *) geometryToConvert, XdmfNullDeleter());
+  return (XDMFGEOMETRY *)((void *)(new XdmfGeometry(*((((XdmfGeometryConverter *)converter)->convertToCartesian(tempGeo)).get()))));
+}
+
+XDMFGEOMETRY * XdmfGeometryConverterConvertToSpherical(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeo = shared_ptr<XdmfGeometry>((XdmfGeometry *) geometryToConvert, XdmfNullDeleter());
+  return (XDMFGEOMETRY *)((void *)(new XdmfGeometry(*((((XdmfGeometryConverter *)converter)->convertToSpherical(tempGeo)).get()))));
+}
+
+void XdmfGeometryConverterConvertToCartesianOverwrite(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeo = shared_ptr<XdmfGeometry>((XdmfGeometry *) geometryToConvert, XdmfNullDeleter());
+  ((XdmfGeometryConverter *)converter)->convertToCartesianOverwrite(tempGeo);
+}
+
+void XdmfGeometryConverterConvertToSphericalOverwrite(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeo = shared_ptr<XdmfGeometry>((XdmfGeometry *) geometryToConvert, XdmfNullDeleter());
+  ((XdmfGeometryConverter *)converter)->convertToSphericalOverwrite(tempGeo);
+}
+
+XDMFGEOMETRY * XdmfGeometryConverterZeroOrigin(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeo = shared_ptr<XdmfGeometry>((XdmfGeometry *) geometryToConvert, XdmfNullDeleter());
+  return (XDMFGEOMETRY *)((void *)(new XdmfGeometry(*((((XdmfGeometryConverter *)converter)->zeroOrigin(tempGeo)).get()))));
+}
+
+void XdmfGeometryConverterZeroOriginOverwrite(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert)
+{
+  shared_ptr<XdmfGeometry> tempGeo = shared_ptr<XdmfGeometry>((XdmfGeometry *) geometryToConvert, XdmfNullDeleter());
+  ((XdmfGeometryConverter *)converter)->zeroOriginOverwrite(tempGeo);
+}
+
+void
+XdmfGeometryConverterFree(XDMFGEOMETRYCONVERTER * converter)
+{
+  if (converter != NULL) {
+    delete ((XdmfGeometryConverter *)converter);
+    converter = NULL;
+  }
+}
diff --git a/utils/XdmfGeometryConverter.hpp b/utils/XdmfGeometryConverter.hpp
new file mode 100644
index 0000000..6165e98
--- /dev/null
+++ b/utils/XdmfGeometryConverter.hpp
@@ -0,0 +1,155 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfGeometryConverter.hpp                                           */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Andrew Burns                                                          */
+/*     andrew.j.burns2 at us.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2014 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFGEOMETRYCONVERTER_HPP_
+#define XDMFGEOMETRYCONVERTER_HPP_
+
+// C Compatible Includes
+#include "XdmfUtils.hpp"
+#include "XdmfGeometry.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+//class XdmfGeometry;
+
+// Includes
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Converts an geometry to a different coordinate system.
+ *
+ * Converts between the Cartesian and Spherical coordinate systems.
+ * Maintains number of dimensions, datatype converted to double
+ * precision floating point (XdmfArrayType::Float64()).
+ *
+ * The cmath library is used for the conversions so angles
+ * are treated as radians.
+ */
+class XDMFUTILS_EXPORT XdmfGeometryConverter {
+
+public:
+
+  /**
+   * Create a new XdmfGeometryConverter.
+   *
+   * @return    constructed XdmfGeometryConverter.
+   */
+  static shared_ptr<XdmfGeometryConverter> New();
+
+  virtual ~XdmfGeometryConverter();
+
+  /**
+   * Converts the provided geometry to Cartesian coordinates.
+   *
+   * @param     geometryToConvert       The geometry to be converted
+   *                                    to Cartesian coordinates.
+   *
+   * @return                            The geometry equivalent for
+   *                                    the Cartesian Coordinate system.
+   */
+  shared_ptr<XdmfGeometry>
+  convertToCartesian(const shared_ptr<XdmfGeometry> & geometryToConvert) const;
+
+  /**
+   * Converts the provided geometry to spherical coordinates.
+   *
+   * @param     geometryToConvert       The geometry to be converted
+   *                                    to spherical coordinates.
+   *
+   * @return                            The geometry equivalent for
+   *                                    the Spherical Coordinate system.
+   */
+  shared_ptr<XdmfGeometry>
+  convertToSpherical(const shared_ptr<XdmfGeometry> & geometryToConvert) const;
+
+ /**
+   * Converts the provided geometry to Cartesian coordinates. This version
+   * overwrites the data in the geometry provided instead of returning a new one.
+   *
+   * @param     geometryToConvert       The geometry to be converted
+   *                                    to Cartesian coordinates.
+   */
+  void
+  convertToCartesianOverwrite(shared_ptr<XdmfGeometry> & geometryToConvert) const;
+
+  /**
+   * Converts the provided geometry to spherical coordinates.  This version
+   * overwrites the data in the geometry provided instead of returning a new one.
+   *
+   * @param     geometryToConvert       The geometry to be converted
+   *                                    to spherical coordinates.
+   */
+  void
+  convertToSphericalOverwrite(shared_ptr<XdmfGeometry> & geometryToConvert) const;
+
+  shared_ptr<XdmfGeometry>
+  zeroOrigin(const shared_ptr<XdmfGeometry> & geometryToConvert);
+
+  void
+  zeroOriginOverwrite(shared_ptr<XdmfGeometry> & geometryToConvert);
+
+  XdmfGeometryConverter(const XdmfGeometryConverter &);
+
+protected:
+
+  XdmfGeometryConverter();
+
+private:
+
+  void operator=(const XdmfGeometryConverter &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFGEOMETRYCONVERTER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFGEOMETRYCONVERTER XDMFGEOMETRYCONVERTER;
+
+XDMFUTILS_EXPORT XDMFGEOMETRYCONVERTER * XdmfGeometryConverterNew();
+
+XDMFUTILS_EXPORT XDMFGEOMETRY * XdmfGeometryConverterConvertToCartesian(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert);
+
+XDMFUTILS_EXPORT XDMFGEOMETRY * XdmfGeometryConverterConvertToSpherical(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert);
+
+XDMFUTILS_EXPORT void XdmfGeometryConverterConvertToCartesianOverwrite(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert);
+
+XDMFUTILS_EXPORT void XdmfGeometryConverterConvertToSphericalOverwrite(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert);
+
+XDMFUTILS_EXPORT XDMFGEOMETRY * XdmfGeometryConverterZeroOrigin(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert);
+
+XDMFUTILS_EXPORT void XdmfGeometryConverterZeroOriginOverwrite(XDMFGEOMETRYCONVERTER * converter, XDMFGEOMETRY * geometryToConvert);
+
+XDMFUTILS_EXPORT void XdmfGeometryConverterFree(XDMFGEOMETRYCONVERTER * converter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFTOPOLOGYCONVERTER_HPP_ */
diff --git a/utils/XdmfPartitioner.cpp b/utils/XdmfPartitioner.cpp
new file mode 100644
index 0000000..d0631cd
--- /dev/null
+++ b/utils/XdmfPartitioner.cpp
@@ -0,0 +1,1426 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfPartitioner.cpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef BUILD_EXE
+
+extern "C"
+{
+#include <metis.h>
+}
+
+#include <iostream>
+#include <sstream>
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfError.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfMap.hpp"
+#include "XdmfPartitioner.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+
+//
+// local methods
+//
+namespace {
+
+  shared_ptr<XdmfGraph>
+  addSymmetricEntries(const shared_ptr<XdmfGraph> graph)
+  {
+    const shared_ptr<XdmfArray> rowPointer = graph->getRowPointer();
+    const shared_ptr<XdmfArray> columnIndex = graph->getColumnIndex();
+    const unsigned int numberRows = graph->getNumberRows();
+
+    std::set<std::pair<unsigned int, unsigned int> > entrySet;
+    for(unsigned int i=0; i<numberRows; ++i) {
+      for(unsigned int j=rowPointer->getValue<unsigned int>(i);
+          j<rowPointer->getValue<unsigned int>(i+1);
+          ++j) {
+        const unsigned int k = columnIndex->getValue<unsigned int>(j);
+        entrySet.insert(std::make_pair(i, k));
+        entrySet.insert(std::make_pair(k, i));
+      }
+    }
+
+    shared_ptr<XdmfGraph> toReturn = XdmfGraph::New(numberRows);
+    shared_ptr<XdmfArray> toReturnRowPointer = toReturn->getRowPointer();
+    shared_ptr<XdmfArray> toReturnColumnIndex = toReturn->getColumnIndex();
+    shared_ptr<XdmfArray> toReturnValues = toReturn->getValues();
+
+    unsigned int currentRow = 1;
+    for(std::set<std::pair<unsigned int, unsigned int> >::const_iterator
+          iter = entrySet.begin();
+        iter != entrySet.end();
+        ++iter) {
+      const std::pair<unsigned int, unsigned int> & entry = *iter;
+      const unsigned int row = entry.first;
+      const unsigned int column = entry.second;
+      for(unsigned int j = currentRow; j<row; ++j) {
+        toReturnRowPointer->insert<unsigned int>(j,
+                                                 toReturnColumnIndex->getSize());
+      }
+
+      currentRow = row + 1;
+      toReturnColumnIndex->pushBack<unsigned int>(column);
+      toReturnValues->pushBack<double>(1.0);
+      toReturnRowPointer->insert(row+1,
+                                 toReturnColumnIndex->getSize());
+    }
+
+    return toReturn;
+
+  }
+
+}
+
+shared_ptr<XdmfPartitioner>
+XdmfPartitioner::New()
+{
+  shared_ptr<XdmfPartitioner> p(new XdmfPartitioner());
+  return p;
+}
+
+XdmfPartitioner::XdmfPartitioner()
+{
+}
+
+XdmfPartitioner::XdmfPartitioner(const XdmfPartitioner & partitioner) :
+  mIgnoredSets(partitioner.mIgnoredSets)
+{
+}
+
+XdmfPartitioner::~XdmfPartitioner()
+{
+}
+
+void
+XdmfPartitioner::ignore(const shared_ptr<const XdmfSet> set)
+{
+  mIgnoredSets.insert(set.get());
+}
+
+void
+XdmfPartitioner::ignore(const XdmfSet * set)
+{
+  mIgnoredSets.insert(set);
+}
+
+void
+XdmfPartitioner::partition(const shared_ptr<XdmfGraph> graphToPartition,
+                           const unsigned int numberOfPartitions) const
+{
+
+  // Make sure row pointer and column index are non null
+  if(!(graphToPartition->getRowPointer() &&
+       graphToPartition->getColumnIndex())) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Current graph's row pointer or column index is null "
+                       "in XdmfPartitioner::partition");
+  }
+ 
+  graphToPartition->removeAttribute("Partition");
+
+  shared_ptr<XdmfAttribute> attribute = XdmfAttribute::New();
+  attribute->setName("Partition");
+  attribute->setCenter(XdmfAttributeCenter::Node());
+  attribute->setType(XdmfAttributeType::Scalar());
+  graphToPartition->insert(attribute);
+
+  idx_t numberVertices = graphToPartition->getNumberNodes();
+  
+  // Handle case where we partition onto 1 processor. Metis for some reason
+  // handles this incorrectly (indices are 1 instead of zero even though 
+  // correct numbering option is supplied to metis)
+  if(numberOfPartitions == 1) {
+    attribute->resize<idx_t>(numberVertices, 0);
+    return;
+  }
+
+  shared_ptr<XdmfArray> rowPointer = graphToPartition->getRowPointer();
+  shared_ptr<XdmfArray> columnIndex = graphToPartition->getColumnIndex();
+
+  idx_t numberConstraints = 1;
+
+  bool releaseRowPointer = false;
+  if(!rowPointer->isInitialized()) {
+    rowPointer->read();
+    releaseRowPointer = true;
+  }
+  bool releaseColumnIndex = false;
+  if(!columnIndex->isInitialized()) {
+    columnIndex->read();
+    releaseColumnIndex = true;
+  }
+
+  shared_ptr<XdmfGraph> graph = graphToPartition;
+
+  // Check whether graph is directed, if so we need to make it undirected
+  // in order to partition with metis. From metis FAQ:
+  //
+  // The partitioning routines in METIS can only partition undirected graphs
+  // (i.e., graphs in which for each edge (v,u) there is also an edge (u,v)).
+  // For partitioning purposes, the directionality of an edge does not play
+  // any role because if edge (u,v) is cut so will the edge (v,u). For this
+  // reason, a directed graph can be easily partitioned by METIS by first
+  // converting it into the corresponding undirected graph. That is, create
+  // a graph for each directed edge (u,v) also contains the (v,u) edge as
+  // well.
+  const unsigned int numberRows = graphToPartition->getNumberRows();
+  for(unsigned int i=0; i<numberRows; ++i) {
+    for(unsigned int j=rowPointer->getValue<unsigned int>(i);
+        j<rowPointer->getValue<unsigned int>(i+1);
+        ++j) {
+      const unsigned int k = columnIndex->getValue<unsigned int>(j);
+      bool symmetric = false;
+      for(unsigned int l=rowPointer->getValue<unsigned int>(k);
+          l<rowPointer->getValue<unsigned int>(k+1);
+          ++l) {
+        const unsigned int m = columnIndex->getValue<unsigned int>(l);
+        if(i == m) {
+          symmetric = true;
+          break;
+        }
+      }
+      if(!symmetric) {
+        graph = addSymmetricEntries(graphToPartition);
+        if(releaseRowPointer) {
+          rowPointer->release();
+        }
+        if(releaseColumnIndex) {
+          columnIndex->release();
+        }
+        rowPointer = graph->getRowPointer();
+        columnIndex = graph->getColumnIndex();
+        break;
+      }
+    }
+  }
+
+  // copy into metis data structures
+  idx_t * xadj = new idx_t[rowPointer->getSize()];
+  rowPointer->getValues(0,
+                        xadj,
+                        rowPointer->getSize());
+  if(releaseRowPointer) {
+    rowPointer->release();
+  }
+  idx_t * adjncy = new idx_t[columnIndex->getSize()];
+  columnIndex->getValues(0,
+                         adjncy,
+                         columnIndex->getSize());
+  if(releaseColumnIndex) {
+    columnIndex->release();
+  }
+
+  idx_t * vwgt = NULL; // equal vertex weights
+  idx_t * vsize = NULL; // equal vertex sizes
+  idx_t * adjwgt = NULL; // equal edge weights
+  idx_t numParts = numberOfPartitions;
+  real_t * tpwgts = NULL; // equal constraints and partition weights
+  real_t * ubvec = NULL; // default load imbalance tolerance
+  idx_t * options = NULL; // default options
+  idx_t objval;
+  idx_t * part = new idx_t[numberVertices];
+
+  METIS_PartGraphRecursive(&numberVertices,
+                           &numberConstraints,
+                           xadj,
+                           adjncy,
+                           vwgt,
+                           vsize,
+                           adjwgt,
+                           &numParts,
+                           tpwgts,
+                           ubvec,
+                           options,
+                           &objval,
+                           part);
+
+  delete [] xadj;
+  delete [] adjncy;
+
+  attribute->insert(0,
+                    part,
+                    numberVertices);
+
+  delete [] part;
+
+  return;
+}
+
+
+shared_ptr<XdmfGridCollection>
+XdmfPartitioner::partition(const shared_ptr<XdmfUnstructuredGrid> gridToPartition,
+                           const unsigned int numberOfPartitions,
+                           const MetisScheme metisScheme,
+                           const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) const
+{
+
+  if(heavyDataWriter) {
+    heavyDataWriter->openFile();
+  }
+
+  // Make sure geometry and topology are non null
+  if(!(gridToPartition->getGeometry() && gridToPartition->getTopology())) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Current grid's geometry or topology is null in "
+                       "XdmfPartitioner::partition");
+  }
+
+  const shared_ptr<XdmfGeometry> geometry =
+    gridToPartition->getGeometry();
+  const shared_ptr<const XdmfGeometryType> geometryType =
+    geometry->getType();
+  const unsigned int geometryDimensions = geometryType->getDimensions();
+  const shared_ptr<XdmfTopology> topology =
+    gridToPartition->getTopology();
+  const shared_ptr<const XdmfTopologyType> topologyType =
+    topology->getType();
+
+  const unsigned int nodesPerElement = topologyType->getNodesPerElement();
+
+  bool releaseTopology = false;
+  if(!topology->isInitialized()) {
+    topology->read();
+    releaseTopology = true;
+  }
+
+  idx_t numElements = topology->getNumberElements();
+  idx_t numNodes = geometry->getNumberPoints();
+
+  // allocate metisConnectivity arrays
+  idx_t * metisConnectivityEptr = new idx_t[numElements + 1];
+  idx_t * metisConnectivityEind = new idx_t[nodesPerElement * numElements];
+
+  metisConnectivityEptr[0] = 0;
+
+  unsigned int metisConnectivityEptrValue = 0;
+  unsigned int connectivityOffset = 0;
+  idx_t * metisConnectivityPtr = metisConnectivityEind;
+  for(int i=0; i<numElements; ++i) {
+    metisConnectivityEptrValue += nodesPerElement;
+    metisConnectivityEptr[i + 1] = metisConnectivityEptrValue;
+    topology->getValues(connectivityOffset,
+                        metisConnectivityPtr,
+                        nodesPerElement);
+    connectivityOffset += topologyType->getNodesPerElement();
+    metisConnectivityPtr += nodesPerElement;
+  }
+
+  idx_t * vwgt = NULL; // equal weight
+  idx_t * vsize = NULL; // equal size
+  idx_t ncommon = 1; // FIXME
+  idx_t nparts = numberOfPartitions;
+  real_t * tpwgts = NULL;
+  idx_t * options = NULL;
+  idx_t objval;
+
+  idx_t * elementsPartition = new idx_t[numElements];
+  idx_t * nodesPartition = new idx_t[numNodes];
+
+  if(metisScheme == DUAL_GRAPH) {
+    METIS_PartMeshDual(&numElements,
+                       &numNodes,
+                       metisConnectivityEptr,
+                       metisConnectivityEind,
+                       vwgt,
+                       vsize,
+                       &ncommon,
+                       &nparts,
+                       tpwgts,
+                       options,
+                       &objval,
+                       elementsPartition,
+                       nodesPartition);
+  }
+  else if(metisScheme == NODAL_GRAPH) {
+    METIS_PartMeshNodal(&numElements,
+                        &numNodes,
+                        metisConnectivityEptr,
+                        metisConnectivityEind,
+                        vwgt,
+                        vsize,
+                        &nparts,
+                        tpwgts,
+                        options,
+                        &objval,
+                        elementsPartition,
+                        nodesPartition);
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Invalid metis partitioning scheme selected in "
+                       "XdmfPartitioner::partition");
+  }
+
+  delete [] metisConnectivityEptr;
+  delete [] metisConnectivityEind;
+  delete [] nodesPartition;
+
+  // map of global node ids to pair of partition id and local node id
+  std::vector<std::map<unsigned int, unsigned int> > 
+    nodeIdMap(numNodes);
+  // map of global element ids to pair of partition id and local element id
+  std::vector<std::pair<unsigned int, unsigned int> > 
+    elementIdMap(numElements);
+  
+  // keep count of number of nodes and element per partition, needed to
+  // generate local node and element ids
+  std::vector<unsigned int> localNodeCounts(numberOfPartitions, 0);
+  std::vector<unsigned int> localElementCounts(numberOfPartitions, 0);
+  
+  // fill maps
+  unsigned int totalIndex = 0;
+  for(int i=0; i<numElements; ++i) {
+    const unsigned int partitionId = elementsPartition[i];
+    for(unsigned int j=0; j<nodesPerElement; ++j) {
+      const unsigned int globalNodeId = 
+        topology->getValue<unsigned int>(totalIndex++);
+      std::map<unsigned int, unsigned int> & localNodeIds = 
+        nodeIdMap[globalNodeId];
+      std::map<unsigned int, unsigned int>::const_iterator iter = 
+        localNodeIds.find(partitionId);
+      if(iter == localNodeIds.end()) {
+        localNodeIds[partitionId] = localNodeCounts[partitionId];
+        localNodeCounts[partitionId]++;
+      }
+      else {
+        localNodeIds[partitionId] = iter->second;
+      }
+    }
+    elementIdMap[i] = std::make_pair(partitionId,
+                                     localElementCounts[partitionId]);
+    localElementCounts[partitionId]++;
+  }
+  delete [] elementsPartition;
+
+  // create returned partitioned grid
+  shared_ptr<XdmfGridCollection> partitionedGrid =
+    XdmfGridCollection::New();
+  partitionedGrid->setType(XdmfGridCollectionType::Spatial());
+
+  // add unstructured grids to partitionedGrid and initialize topology
+  // and geometry in each
+  for(unsigned int i=0; i<numberOfPartitions; ++i) {
+    const unsigned int localElementCount = localElementCounts[i];
+    const unsigned int localNodeCount = localNodeCounts[i];
+    std::stringstream name;
+    name << gridToPartition->getName() << "_" << i;
+    const shared_ptr<XdmfUnstructuredGrid> grid = 
+      XdmfUnstructuredGrid::New();
+    grid->setName(name.str());
+    partitionedGrid->insert(grid);
+    shared_ptr<XdmfGeometry> localGeometry = grid->getGeometry();
+    localGeometry->setType(geometryType);
+    localGeometry->initialize(geometry->getArrayType(),
+                              localNodeCount * geometryDimensions);
+    shared_ptr<XdmfTopology> localTopology = grid->getTopology();
+    localTopology->setType(topologyType);
+    localTopology->initialize(topology->getArrayType(),
+                              localElementCount * nodesPerElement);
+  }
+  
+  bool releaseGeometry = false;
+  if(!geometry->isInitialized()) {
+    geometry->read();
+    releaseGeometry = true;
+  }
+
+  // fill geometry for each partition
+  for(int i=0; i<numNodes; ++i) {
+    const std::map<unsigned int, unsigned int> & localNodeIds = nodeIdMap[i];
+    for(std::map<unsigned int, unsigned int>::const_iterator iter = 
+          localNodeIds.begin(); iter != localNodeIds.end(); ++iter) {
+      const unsigned int partitionId = iter->first;
+      const unsigned int localNodeId = iter->second;
+      const shared_ptr<XdmfUnstructuredGrid> grid = 
+        partitionedGrid->getUnstructuredGrid(partitionId);
+      const shared_ptr<XdmfGeometry> localGeometry = grid->getGeometry();
+      localGeometry->insert(localNodeId * geometryDimensions,
+                            geometry,
+                            i * geometryDimensions,
+                            geometryDimensions);
+    }
+  }
+
+  if(releaseGeometry) {
+    geometry->release();
+  }
+
+  // write geometries to disk if possible
+  if(heavyDataWriter) {
+    for(unsigned int i=0; i<numberOfPartitions; ++i) {
+      const shared_ptr<XdmfUnstructuredGrid> grid = 
+        partitionedGrid->getUnstructuredGrid(i);
+      const shared_ptr<XdmfGeometry> localGeometry = grid->getGeometry();
+      if(localGeometry->getSize() > 0) {
+        localGeometry->accept(heavyDataWriter);
+        localGeometry->release();
+      }
+    }
+  }
+
+  // fill topology for each partition
+  for(int i=0; i<numElements; ++i) {
+    const std::pair<unsigned int, unsigned int> & partitionElementPair = 
+      elementIdMap[i];
+    const unsigned int partitionId = partitionElementPair.first;
+    const unsigned int localElementId = partitionElementPair.second;
+    const shared_ptr<XdmfUnstructuredGrid> grid = 
+      partitionedGrid->getUnstructuredGrid(partitionId);
+    const shared_ptr<XdmfTopology> localTopology = grid->getTopology();
+    for(unsigned int j=0; j<nodesPerElement; ++j) {
+      const unsigned int globalNodeId =
+        topology->getValue<unsigned int>(i*nodesPerElement + j);
+      const unsigned int localNodeId = nodeIdMap[globalNodeId][partitionId];
+      localTopology->insert(localElementId*nodesPerElement + j, localNodeId);
+    }
+  }
+
+  if(releaseTopology) {
+    topology->release();
+  }
+
+  // write topology to disk if possible
+  if(heavyDataWriter) {
+    for(unsigned int i=0; i<numberOfPartitions; ++i) {
+      const shared_ptr<XdmfUnstructuredGrid> grid = 
+        partitionedGrid->getUnstructuredGrid(i);
+      const shared_ptr<XdmfTopology> localTopology = grid->getTopology();
+      if(localTopology->getSize() > 0) {
+        localTopology->accept(heavyDataWriter);
+        localTopology->release();
+      }
+    }
+  }
+
+  // split attributes
+  const unsigned int numberAttributes = gridToPartition->getNumberAttributes();
+  for(unsigned int i=0; i<numberAttributes; ++i) {
+    const shared_ptr<XdmfAttribute> attribute = 
+      gridToPartition->getAttribute(i);
+    bool releaseAttribute = false;
+    if(!attribute->isInitialized()) {
+      attribute->read();
+      releaseAttribute = true;
+    }
+    const shared_ptr<const XdmfAttributeCenter> attributeCenter = 
+      attribute->getCenter();
+    std::vector<shared_ptr<XdmfAttribute> > localAttributes;
+    localAttributes.reserve(numberOfPartitions);
+    if(attributeCenter == XdmfAttributeCenter::Grid()) {
+      // insert into each partition
+      for(unsigned int j=0; j<numberOfPartitions; ++j) {
+        partitionedGrid->getUnstructuredGrid(j)->insert(attribute);
+      }
+      localAttributes.push_back(attribute);
+    }
+    else if(attributeCenter == XdmfAttributeCenter::Cell()) {
+      const unsigned int numberComponents = attribute->getSize() / numElements;
+      for(unsigned int j=0; j<numberOfPartitions; ++j) {
+        const shared_ptr<XdmfAttribute> localAttribute = XdmfAttribute::New();
+        localAttribute->setName(attribute->getName());
+        localAttribute->setCenter(attribute->getCenter());
+        localAttribute->setType(attribute->getType());
+        localAttribute->initialize(attribute->getArrayType(),
+                                   localElementCounts[j] * numberComponents);
+        partitionedGrid->getUnstructuredGrid(j)->insert(localAttribute);
+        localAttributes.push_back(localAttribute);
+      }
+      for(int j=0; j<numElements; ++j) {
+        const std::pair<unsigned int, unsigned int> & partitionElementPair = 
+          elementIdMap[j];
+        const unsigned int partitionId = partitionElementPair.first;
+        const unsigned int localElementId = partitionElementPair.second;
+        const shared_ptr<XdmfAttribute> localAttribute = 
+          localAttributes[partitionId];
+        localAttribute->insert(localElementId * numberComponents,
+                               attribute,
+                               j * numberComponents,
+                               numberComponents);
+      }
+    }
+    else if(attributeCenter == XdmfAttributeCenter::Node()) {
+      const unsigned int numberComponents = attribute->getSize() / numNodes;
+      for(unsigned int j=0; j<numberOfPartitions; ++j) {
+        const shared_ptr<XdmfAttribute> localAttribute = XdmfAttribute::New();
+        localAttribute->setName(attribute->getName());
+        localAttribute->setCenter(attribute->getCenter());
+        localAttribute->setType(attribute->getType());
+        localAttribute->initialize(attribute->getArrayType(),
+                                   localNodeCounts[j] * numberComponents);
+        partitionedGrid->getUnstructuredGrid(j)->insert(localAttribute);
+        localAttributes.push_back(localAttribute);
+      }
+      for(int j=0; j<numNodes; ++j) {
+        const std::map<unsigned int, unsigned int> & localNodeIds = 
+          nodeIdMap[j];
+        for(std::map<unsigned int, unsigned int>::const_iterator iter = 
+              localNodeIds.begin(); iter != localNodeIds.end(); ++iter) {
+          const unsigned int partitionId = iter->first;
+          const unsigned int localNodeId = iter->second;        
+          const shared_ptr<XdmfAttribute> localAttribute = 
+            localAttributes[partitionId];
+          localAttribute->insert(localNodeId * numberComponents,
+                                 attribute,
+                                 j * numberComponents,
+                                 numberComponents);
+        }
+      }
+    }
+    
+    if(heavyDataWriter) {
+      for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+            localAttributes.begin(); iter != localAttributes.end(); ++iter) {
+        const shared_ptr<XdmfAttribute> localAttribute = *iter;
+        if(!localAttribute->isInitialized()) {
+          localAttribute->read();
+        }
+        if(localAttribute->getSize() > 0) {
+          localAttribute->accept(heavyDataWriter);
+          localAttribute->release();
+        }
+      }
+    }
+
+    if(releaseAttribute) {
+      attribute->release();
+    }    
+  }
+
+  // create globalnodeid if required
+  bool generateGlobalNodeIds = !gridToPartition->getAttribute("GlobalNodeId");
+  std::vector<shared_ptr<XdmfAttribute> > globalNodeIds;
+  globalNodeIds.reserve(numberOfPartitions);
+  if(generateGlobalNodeIds) {
+    for(unsigned int i=0; i<numberOfPartitions; ++i) {
+      const shared_ptr<XdmfAttribute> globalNodeId = XdmfAttribute::New();
+      globalNodeId->setName("GlobalNodeId");
+      globalNodeId->setCenter(XdmfAttributeCenter::Node());
+      globalNodeId->setType(XdmfAttributeType::GlobalId());
+      globalNodeId->initialize(XdmfArrayType::UInt32(),
+                               localNodeCounts[i]);
+      partitionedGrid->getUnstructuredGrid(i)->insert(globalNodeId);
+      globalNodeIds.push_back(globalNodeId);
+    }
+    for(int i=0; i<numNodes; ++i) {
+      const std::map<unsigned int, unsigned int> & localNodeIds = 
+        nodeIdMap[i];
+      for(std::map<unsigned int, unsigned int>::const_iterator iter = 
+            localNodeIds.begin(); iter != localNodeIds.end(); ++iter) {
+        const unsigned int partitionId = iter->first;
+        const unsigned int localNodeId = iter->second;        
+        const shared_ptr<XdmfAttribute> globalNodeId = 
+          globalNodeIds[partitionId];
+        globalNodeId->insert<unsigned int>(localNodeId,
+                                           i);
+      }
+    }
+    if(heavyDataWriter) {
+      for(std::vector<shared_ptr<XdmfAttribute> >::const_iterator iter =
+            globalNodeIds.begin(); iter != globalNodeIds.end(); ++iter) {
+        const shared_ptr<XdmfAttribute> globalNodeId = *iter;
+        if(globalNodeId->getSize() > 0) {
+          globalNodeId->accept(heavyDataWriter);
+          globalNodeId->release();
+        }
+      }
+    }
+  }
+  else {
+    for(unsigned int i=0; i<numberOfPartitions; ++i) {
+      const shared_ptr<XdmfUnstructuredGrid> grid = 
+        partitionedGrid->getUnstructuredGrid(i);
+        globalNodeIds.push_back(grid->getAttribute("GlobalNodeId"));
+    }
+  }
+ 
+  // split sets
+  const unsigned int numberSets = gridToPartition->getNumberSets();
+  for(unsigned int i=0; i<numberSets; ++i) {
+    const shared_ptr<XdmfSet> set = gridToPartition->getSet(i);
+    if(mIgnoredSets.find(set.get()) == mIgnoredSets.end()) {
+      bool releaseSet = false;
+      if(!set->isInitialized()) {
+        set->read();
+        releaseSet = true;
+      }
+      const shared_ptr<const XdmfSetType> setType = set->getType();
+      const unsigned int setSize = set->getSize();
+      std::vector<shared_ptr<XdmfSet> > localSets;
+      localSets.reserve(numberOfPartitions);
+      if(setType == XdmfSetType::Cell()) {
+        for(unsigned int j=0; j<numberOfPartitions; ++j) {
+          const shared_ptr<XdmfSet> localSet = XdmfSet::New();
+          localSets.push_back(localSet);
+        }
+        for(unsigned int j=0; j<setSize; ++j) {
+           const unsigned int globalElementId = set->getValue<unsigned int>(j);
+          const std::pair<unsigned int, unsigned int> & partitionElementPair = 
+            elementIdMap[globalElementId];
+          const unsigned int partitionId = partitionElementPair.first;
+          const unsigned int localElementId = partitionElementPair.second;
+          const shared_ptr<XdmfSet> localSet = localSets[partitionId];
+          localSet->pushBack<unsigned int>(localElementId);
+        }
+      }
+      else if(setType == XdmfSetType::Node()) {
+        for(unsigned int j=0; j<numberOfPartitions; ++j) {
+          const shared_ptr<XdmfSet> localSet = XdmfSet::New();
+          localSets.push_back(localSet);
+        }
+        for(unsigned int j=0; j<setSize; ++j) {
+          const unsigned int globalNodeId = set->getValue<unsigned int>(j);
+          const std::map<unsigned int, unsigned int> & localNodeIds = 
+            nodeIdMap[globalNodeId];
+          for(std::map<unsigned int, unsigned int>::const_iterator iter = 
+                localNodeIds.begin(); iter != localNodeIds.end(); ++iter) {
+            const unsigned int partitionId = iter->first;
+            const unsigned int localNodeId = iter->second;        
+            const shared_ptr<XdmfSet> localSet = localSets[partitionId];
+            localSet->pushBack<unsigned int>(localNodeId);
+          }
+        }
+      }
+
+      for(std::vector<shared_ptr<XdmfSet> >::size_type j=0; 
+          j<localSets.size(); ++j) {
+        const shared_ptr<XdmfSet> localSet = localSets[j];
+        if(localSet->getSize() > 0) {
+          partitionedGrid->getUnstructuredGrid(j)->insert(localSet);
+          localSet->setName(set->getName());
+          localSet->setType(set->getType());
+          if(heavyDataWriter) {
+            localSet->accept(heavyDataWriter);
+            localSet->release();
+          }
+        }
+      }
+
+      const unsigned int numberAttributes = set->getNumberAttributes();
+      for(unsigned int j=0; j<numberAttributes; ++j) {
+        const shared_ptr<XdmfAttribute> attribute = set->getAttribute(j);  
+        bool releaseAttribute = false;
+        if(!attribute->isInitialized()) {
+          attribute->read();
+          releaseAttribute = true;
+        }
+
+        const shared_ptr<const XdmfAttributeCenter> attributeCenter = 
+          attribute->getCenter();
+        const unsigned int attributeSize = attribute->getSize();
+        const unsigned int numberComponents = attributeSize / setSize;        
+        std::vector<shared_ptr<XdmfAttribute> > localAttributes;
+        localAttributes.reserve(numberOfPartitions);
+        if(attributeCenter == XdmfAttributeCenter::Cell()) {
+          for(unsigned int k=0; k<numberOfPartitions; ++k) {
+            const shared_ptr<XdmfSet> localSet = localSets[k];
+            const shared_ptr<XdmfAttribute> localAttribute = 
+              XdmfAttribute::New();
+            localAttribute->reserve(numberComponents * localSet->getSize());
+            localAttributes.push_back(localAttribute);
+          }
+          for(unsigned int k=0; k<setSize; ++k) {
+            const unsigned int globalElementId = 
+              set->getValue<unsigned int>(k);
+            const std::pair<unsigned int, unsigned int> & 
+              partitionElementPair = elementIdMap[globalElementId];
+            const unsigned int partitionId = partitionElementPair.first;
+            const shared_ptr<XdmfAttribute> localAttribute = 
+              localAttributes[partitionId];
+            localAttribute->insert(localAttribute->getSize(),
+                                   attribute,
+                                   k * numberComponents,
+                                   numberComponents);
+          }
+        }
+        else if(attributeCenter == XdmfAttributeCenter::Node()) {
+          for(unsigned int k=0; k<numberOfPartitions; ++k) {
+            const shared_ptr<XdmfSet> localSet = localSets[k];
+            const shared_ptr<XdmfAttribute> localAttribute = 
+              XdmfAttribute::New();
+            localAttribute->reserve(numberComponents * localSet->getSize());
+            localAttributes.push_back(localAttribute);
+          }
+          for(unsigned int k=0; k<setSize; ++k) {
+            const unsigned int globalNodeId = set->getValue<unsigned int>(k);
+            const std::map<unsigned int, unsigned int> & localNodeIds = 
+              nodeIdMap[globalNodeId];
+            for(std::map<unsigned int, unsigned int>::const_iterator iter = 
+                  localNodeIds.begin(); iter != localNodeIds.end(); ++iter) {
+              const unsigned int partitionId = iter->first;
+              const shared_ptr<XdmfAttribute> localAttribute = 
+                localAttributes[partitionId];
+              localAttribute->insert(localAttribute->getSize(),
+                                     attribute,
+                                     k * numberComponents,
+                                     numberComponents);
+            }
+          }
+        }
+
+        if(releaseAttribute) {
+          attribute->release();
+        }
+
+        for(std::vector<shared_ptr<XdmfAttribute> >::size_type k=0; 
+            k<localAttributes.size(); ++k) {
+          const shared_ptr<XdmfAttribute> localAttribute = localAttributes[k];
+          if(localAttribute->getSize() > 0) {
+            localSets[k]->insert(localAttribute);
+            localAttribute->setName(attribute->getName());
+            localAttribute->setCenter(attribute->getCenter());
+            localAttribute->setType(attribute->getType());
+            if(heavyDataWriter) {
+              localAttribute->accept(heavyDataWriter);
+              localAttribute->release();
+            }
+          }
+        }    
+      }
+      
+      if(releaseSet) {
+        set->release();
+      }
+    }
+  }
+    
+  // add XdmfMap to map boundary nodes between partitions
+  std::vector<shared_ptr<XdmfMap> > maps = XdmfMap::New(globalNodeIds);
+  for(unsigned int i=0; i<numberOfPartitions; ++i) {
+    shared_ptr<XdmfMap> map = maps[i];
+    map->setName("Subdomain Boundary");
+    partitionedGrid->getUnstructuredGrid(i)->insert(map);
+    if(heavyDataWriter) {
+      map->accept(heavyDataWriter);
+      map->release();
+    }
+  }
+
+  return partitionedGrid;
+}
+
+shared_ptr<XdmfUnstructuredGrid>
+XdmfPartitioner::unpartition(const shared_ptr<XdmfGridCollection> gridToUnPartition) const
+{
+  
+  const shared_ptr<XdmfUnstructuredGrid> returnValue =
+      XdmfUnstructuredGrid::New();
+    const shared_ptr<XdmfTopology> returnValueTopology =
+      returnValue->getTopology();
+    const shared_ptr<XdmfGeometry> returnValueGeometry =
+      returnValue->getGeometry();
+
+    const unsigned int numberUnstructuredGrids =
+      gridToUnPartition->getNumberUnstructuredGrids();
+
+    unsigned int elementOffset = 0;
+
+    for(unsigned int i=0; i<numberUnstructuredGrids; ++i) {
+
+      const shared_ptr<XdmfUnstructuredGrid> grid =
+        gridToUnPartition->getUnstructuredGrid(i);
+
+      const shared_ptr<XdmfAttribute> globalNodeIds =
+        grid->getAttribute("GlobalNodeId");
+
+      if(!globalNodeIds) {
+        XdmfError::message(XdmfError::FATAL,
+                           "Cannot find GlobalNodeId attribute in "
+                           "XdmfPartitioner::unpartition");
+      }
+
+      bool releaseGlobalNodeIds = false;
+      if(!globalNodeIds->isInitialized()) {
+        globalNodeIds->read();
+        releaseGlobalNodeIds = true;
+      }
+
+      // handle topology
+      const shared_ptr<XdmfTopology> topology = grid->getTopology();
+
+      if(i==0) {
+        returnValueTopology->setType(topology->getType());
+        returnValueTopology->initialize(topology->getArrayType());
+      }
+
+      returnValueTopology->reserve(returnValueTopology->getSize() +
+                                   topology->getSize());
+
+      bool releaseTopology = false;
+      if(!topology->isInitialized()) {
+        topology->read();
+        releaseTopology = true;
+      }
+
+      for(unsigned int j=0; j<topology->getSize(); ++j) {
+        const unsigned int localNodeId = topology->getValue<unsigned int>(j);
+        const unsigned int globalNodeId =
+          globalNodeIds->getValue<unsigned int>(localNodeId);
+        returnValueTopology->pushBack(globalNodeId);
+      }
+
+      if(releaseTopology) {
+        topology->release();
+      }
+
+      // handle geometry
+      const shared_ptr<XdmfGeometry> geometry = grid->getGeometry();
+      const shared_ptr<const XdmfGeometryType> geometryType =
+        geometry->getType();
+      const unsigned int geometryDimension = geometryType->getDimensions();
+
+      if(i==0) {
+        returnValueGeometry->setType(geometryType);
+        returnValueGeometry->initialize(geometry->getArrayType());
+      }
+
+      bool releaseGeometry = false;
+      if(!geometry->isInitialized()) {
+        geometry->read();
+        releaseGeometry = true;
+      }
+
+      for(unsigned int j=0; j<globalNodeIds->getSize(); ++j) {
+        const unsigned int globalNodeId =
+          globalNodeIds->getValue<unsigned int>(j);
+        returnValueGeometry->insert(globalNodeId * geometryDimension,
+                                    geometry,
+                                    j * geometryDimension,
+                                    geometryDimension);
+      }
+
+      if(releaseGeometry) {
+        geometry->release();
+      }
+
+      // handle attributes
+      for(unsigned int j=0; j<grid->getNumberAttributes(); ++j) {
+
+        const shared_ptr<XdmfAttribute> attribute = grid->getAttribute(j);
+        const shared_ptr<const XdmfAttributeCenter> attributeCenter =
+          attribute->getCenter();
+
+        bool releaseAttribute = false;
+        if(!attribute->isInitialized()) {
+          attribute->read();
+          releaseAttribute = true;
+        }
+
+        shared_ptr<XdmfAttribute> returnValueAttribute;
+
+        if(i==0) {
+          returnValueAttribute = XdmfAttribute::New();
+          returnValueAttribute->setName(attribute->getName());
+          returnValueAttribute->setCenter(attributeCenter);
+          returnValueAttribute->setType(attribute->getType());
+          returnValueAttribute->initialize(attribute->getArrayType());
+          returnValue->insert(returnValueAttribute);
+        }
+        else {
+          returnValueAttribute = returnValue->getAttribute(attribute->getName());
+        }
+
+
+        if(attributeCenter == XdmfAttributeCenter::Grid()) {
+          returnValueAttribute->insert(0,
+                                       attribute,
+                                       0,
+                                       attribute->getSize());
+        }
+        else if(attributeCenter == XdmfAttributeCenter::Cell()) {
+          returnValueAttribute->insert(returnValueAttribute->getSize(),
+                                       attribute,
+                                       0,
+                                       attribute->getSize());
+        }
+        else if(attributeCenter == XdmfAttributeCenter::Node()) {
+
+          const unsigned int numberComponents =
+            attribute->getSize() / geometry->getNumberPoints();
+
+          for(unsigned int k=0; k<globalNodeIds->getSize(); ++k) {
+            const unsigned int globalNodeId =
+              globalNodeIds->getValue<unsigned int>(k);
+            returnValueAttribute->insert(globalNodeId * numberComponents,
+                                         attribute,
+                                         k * numberComponents,
+                                         numberComponents);
+          }
+
+        }
+
+        if(releaseAttribute) {
+          attribute->release();
+        }
+
+      }
+
+      // handle sets
+      for(unsigned int j=0; j<grid->getNumberSets(); ++j) {
+
+        const shared_ptr<XdmfSet> set = grid->getSet(j);
+        const shared_ptr<const XdmfSetType> setType = set->getType();
+
+        bool releaseSet = false;
+        if(!set->isInitialized()) {
+          set->read();
+          releaseSet = true;
+        }
+
+        shared_ptr<XdmfSet> returnValueSet = returnValue->getSet(set->getName());
+        if(!returnValueSet) {
+          returnValueSet = XdmfSet::New();
+          returnValueSet->setName(set->getName());
+          returnValueSet->setType(setType);
+          returnValue->insert(returnValueSet);
+        }
+
+        if(setType == XdmfSetType::Cell()) {
+          for(unsigned int k=0; k<set->getSize(); ++k) {
+            const unsigned int localCellId = set->getValue<unsigned int>(k);
+            returnValueSet->pushBack(localCellId + elementOffset);
+          }
+        }
+        else if(setType == XdmfSetType::Node()) {
+          for(unsigned int k=0; k<set->getSize(); ++k){
+            const unsigned int localNodeId = set->getValue<unsigned int>(k);
+            const unsigned int globalNodeId =
+              globalNodeIds->getValue<unsigned int>(localNodeId);
+            returnValueSet->pushBack(globalNodeId);
+          }
+        }
+
+        for(unsigned int k=0; k<set->getNumberAttributes(); ++k) {
+          const shared_ptr<XdmfAttribute> attribute = set->getAttribute(k);
+
+          bool releaseAttribute = false;
+          if(!attribute->isInitialized()) {
+            attribute->read();
+            releaseAttribute = true;
+          }
+
+          const shared_ptr<const XdmfAttributeCenter> attributeCenter =
+            attribute->getCenter();
+          const shared_ptr<const XdmfAttributeType> attributeType =
+            attribute->getType();
+
+          shared_ptr<XdmfAttribute> returnValueAttribute =
+            returnValueSet->getAttribute(attribute->getName());
+          if(!returnValueAttribute) {
+            returnValueAttribute = XdmfAttribute::New();
+            returnValueAttribute->setName(attribute->getName());
+            returnValueAttribute->setCenter(attributeCenter);
+            returnValueAttribute->setType(attributeType);
+            returnValueSet->insert(returnValueAttribute);
+          }
+
+          if(attributeCenter == XdmfAttributeCenter::Cell() ||
+             attributeCenter == XdmfAttributeCenter::Node()) {
+            returnValueAttribute->insert(returnValueAttribute->getSize(),
+                                         attribute,
+                                         0,
+                                         attribute->getSize());
+          }
+
+          if(releaseAttribute) {
+            attribute->release();
+          }
+
+        }
+
+      }
+
+      elementOffset += topology->getNumberElements();
+
+      if(releaseGlobalNodeIds) {
+        globalNodeIds->release();
+      }
+
+    }
+
+    return returnValue;
+
+  }
+
+// C Wrappers
+
+XDMFPARTITIONER *
+XdmfPartitionerNew()
+{
+  shared_ptr<XdmfPartitioner> generatedPartitioner = XdmfPartitioner::New();
+  return (XDMFPARTITIONER *)((void *)(new XdmfPartitioner(*generatedPartitioner.get())));
+}
+
+void
+XdmfPartitionerIgnore(XDMFPARTITIONER * partitioner,
+                      XDMFSET * set)
+{
+  ((XdmfPartitioner *)partitioner)->ignore((XdmfSet *)set);
+}
+
+void
+XdmfPartitionerPartitionGraph(XDMFPARTITIONER * partitioner,
+                              XDMFGRAPH * graphToPartition,
+                              unsigned int numberOfPartitions)
+{
+  shared_ptr<XdmfGraph> tempGraph = shared_ptr<XdmfGraph>((XdmfGraph *) graphToPartition, XdmfNullDeleter());
+  ((XdmfPartitioner *)partitioner)->partition(tempGraph, numberOfPartitions);
+}
+
+XDMFGRIDCOLLECTION *
+XdmfPartitionerPartitionUnstructuredGrid(XDMFPARTITIONER * partitioner,
+                                         XDMFUNSTRUCTUREDGRID * gridToPartition,
+                                         unsigned int numberOfPartitions,
+                                         int metisScheme,
+                                         XDMFHEAVYDATAWRITER * heavyDataWriter)
+{
+  XdmfPartitioner::MetisScheme passedScheme = XdmfPartitioner::DUAL_GRAPH;
+  switch (metisScheme)
+  {
+    case XDMF_PARTITIONER_SCHEME_DUAL_GRAPH:
+      passedScheme = XdmfPartitioner::DUAL_GRAPH;
+      break;
+    case XDMF_PARTITIONER_SCHEME_NODAL_GRAPH:
+      passedScheme = XdmfPartitioner::NODAL_GRAPH;
+      break;
+    default:
+      break;
+  }
+  shared_ptr<XdmfUnstructuredGrid> tempGrid = shared_ptr<XdmfUnstructuredGrid>((XdmfUnstructuredGrid *) gridToPartition, XdmfNullDeleter());
+  if (heavyDataWriter)
+  {
+    shared_ptr<XdmfHeavyDataWriter> tempwriter = shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *) heavyDataWriter, XdmfNullDeleter());
+    return (XDMFGRIDCOLLECTION *)((void *)(new XdmfGridCollection(*((((XdmfPartitioner *)partitioner)->partition(tempGrid, numberOfPartitions, passedScheme, tempwriter)).get()))));
+  }
+  else
+  {
+    return (XDMFGRIDCOLLECTION *)((void *)(new XdmfGridCollection(*((((XdmfPartitioner *)partitioner)->partition(tempGrid, numberOfPartitions, passedScheme)).get()))));
+  }
+}
+
+XDMFUNSTRUCTUREDGRID *
+XdmfPartitionerUnpartition(XDMFPARTITIONER * partitioner,
+                           XDMFGRIDCOLLECTION * gridToUnPartition)
+{
+  shared_ptr<XdmfGridCollection> tempGrid = shared_ptr<XdmfGridCollection>((XdmfGridCollection *) gridToUnPartition, XdmfNullDeleter());
+  return (XDMFUNSTRUCTUREDGRID *)((void *)(new XdmfUnstructuredGrid(*((((XdmfPartitioner *)partitioner)->unpartition(tempGrid)).get()))));
+}
+
+void
+XdmfPartitionerFree(XDMFPARTITIONER * partitioner)
+{
+  if (partitioner != NULL) {
+    delete ((XdmfPartitioner *)partitioner);
+    partitioner = NULL;
+  }
+}
+
+#else
+
+#include <cstdio>
+#include <iostream>
+#include <sstream>
+#include "XdmfDomain.hpp"
+#include "XdmfGraph.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfGridCollectionType.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfPartitioner.hpp"
+#include "XdmfReader.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+  namespace {
+
+    //
+    // print usage
+    //
+    inline void
+    printUsage(const char * programName)
+    {
+
+      std::cerr << "usage: " << programName << " "
+                << "[-s metis_scheme] [-r] [-u]"
+                << "<input file> <number of partitions> [output file]"
+                << std::endl;
+      std::cerr << "\t-s metis_scheme: 1 - Dual Graph" << std::endl;
+      std::cerr << "\t-s metis_scheme: 2 - Node Graph" << std::endl;
+      std::cerr << "\t-u unpartition file" << std::endl;
+
+      //
+      //
+      //
+      return;
+
+    }
+
+    //
+    // process command line
+    //
+    void
+    processCommandLine(std::string                  & inputFileName,
+                       std::string                  & outputFileName,
+                       unsigned int                 & numberOfPartitions,
+                       XdmfPartitioner::MetisScheme & metisScheme,
+                       bool                         & unpartition,
+                       int                            ac,
+                       char                         * av[])
+    {
+
+      int c;
+      bool errorFlag = false;
+
+      while( (c=getopt(ac, av, "s:ur")) != -1 )
+        switch(c){
+
+        case 's': {
+          const int value = std::atoi(optarg);
+          if(value == 1) {
+            metisScheme = XdmfPartitioner::DUAL_GRAPH;
+          }
+          else if(value == 2) {
+            metisScheme = XdmfPartitioner::NODAL_GRAPH;
+          }
+          else {
+            errorFlag = true;
+          }
+          break;
+        }
+        case 'u':
+          unpartition = true;
+          break;
+        case '?':
+          errorFlag = true;
+          break;
+        }
+
+      if (optind >= ac)
+        errorFlag = true;
+      else {
+        inputFileName = av[optind];
+        ++optind;
+      }
+
+      if(!unpartition) {
+        if (optind >= ac)
+          errorFlag = true;
+        else {
+          numberOfPartitions = atoi(av[optind]);
+          ++optind;
+        }
+      }
+
+      if (optind < ac) {
+        outputFileName = av[optind];
+        ++optind;
+      }
+
+      //
+      // check errorFlag
+      //
+      if (errorFlag == true) {
+        printUsage(av[0]);
+        std::exit(EXIT_FAILURE);
+      }
+
+    }
+
+  }
+
+  /**
+   * XdmfPartitioner is a command line utility for partitioning Xdmf grids.
+   * The XdmfPartitioner uses the metis library to partition Triangular,
+   * Quadrilateral, Tetrahedral, and Hexahedral XdmfGridUnstructureds.
+   *
+   * Usage:
+   *     XdmfPartitioner <path-of-file-to-partition> <num-partitions>
+   *                     (Optional: <path-to-output-file>)
+   *
+   */
+  int main(int argc, char* argv[])
+  {
+
+    std::string inputFileName = "";
+    std::string outputFileName = "";
+    unsigned int numberOfPartitions = 0;
+    XdmfPartitioner::MetisScheme metisScheme = XdmfPartitioner::DUAL_GRAPH;
+    bool unpartition = false;
+
+    processCommandLine(inputFileName,
+                       outputFileName,
+                       numberOfPartitions,
+                       metisScheme,
+                       unpartition,
+                       argc,
+                       argv);
+
+    std::cout << inputFileName << std::endl;
+
+    FILE * refFile = fopen(inputFileName.c_str(), "r");
+    if (refFile) {
+      // Success
+      fclose(refFile);
+    }
+    else {
+      std::cout << "Cannot open file: " << argv[1] << std::endl;
+      return 1;
+    }
+
+    std::string meshName;
+    if(outputFileName.compare("") == 0) {
+      meshName = inputFileName;
+    }
+    else {
+      meshName = outputFileName;
+    }
+
+    if(meshName.find_last_of("/\\") != std::string::npos) {
+      meshName = meshName.substr(meshName.find_last_of("/\\") + 1,
+                                 meshName.length());
+    }
+
+    if (meshName.rfind(".") != std::string::npos) {
+      meshName = meshName.substr(0, meshName.rfind("."));
+    }
+
+    if(outputFileName.compare("") == 0) {
+      std::stringstream newMeshName;
+      if(unpartition) {
+        newMeshName << meshName << "_unpartitioned";
+      }
+      else {
+        newMeshName << meshName << "_p" << numberOfPartitions;
+      }
+      meshName = newMeshName.str();
+    }
+
+    shared_ptr<XdmfReader> reader = XdmfReader::New();
+    shared_ptr<XdmfDomain> domain =
+      shared_dynamic_cast<XdmfDomain>(reader->read(inputFileName));
+
+    if(unpartition) {
+      if(domain->getNumberGridCollections() == 0) {
+        std::cout << "No grid collections to unpartition" << std::endl;
+        return 1;
+      }
+    }
+    else {
+      if(domain->getNumberUnstructuredGrids() == 0 &&
+         domain->getNumberGridCollections() == 0 &&
+         domain->getNumberGraphs() == 0) {
+        std::cout << "No grids or graphs to partition" << std::endl;
+        return 1;
+      }
+    }
+
+    std::stringstream heavyFileName;
+    heavyFileName << meshName << ".h5";
+    shared_ptr<XdmfHDF5Writer> heavyDataWriter =
+      XdmfHDF5Writer::New(heavyFileName.str());
+    heavyDataWriter->setReleaseData(true);
+
+    shared_ptr<XdmfDomain> newDomain = XdmfDomain::New();
+
+    shared_ptr<XdmfPartitioner> partitioner = XdmfPartitioner::New();
+
+    if(unpartition) {
+      shared_ptr<XdmfGridCollection> gridCollection = 
+        domain->getGridCollection(0);
+      const shared_ptr<const XdmfGridCollectionType> collectionType = 
+        gridCollection->getType();
+      if(collectionType == XdmfGridCollectionType::Spatial()) {
+        shared_ptr<XdmfUnstructuredGrid> toWrite =
+          partitioner->unpartition(gridCollection);
+        newDomain->insert(toWrite);
+      }
+      else if(collectionType == XdmfGridCollectionType::Temporal()) {
+        const unsigned int numberTimesteps = 
+          gridCollection->getNumberGridCollections();
+        if(numberTimesteps == 0) {
+          std::cout << "No grid collections to unpartition" << std::endl;
+          return 1;
+        }
+        shared_ptr<XdmfGridCollection> newCollection = 
+          XdmfGridCollection::New();
+        newCollection->setType(XdmfGridCollectionType::Temporal());
+        for(unsigned int i=0; i<numberTimesteps; ++i) {
+          const shared_ptr<XdmfGridCollection> spatialCollection = 
+            gridCollection->getGridCollection(i);
+          const shared_ptr<XdmfTime> time = spatialCollection->getTime();
+          assert(spatialCollection->getType() == 
+                 XdmfGridCollectionType::Spatial());
+          const shared_ptr<XdmfUnstructuredGrid> toWrite = 
+            partitioner->unpartition(spatialCollection);
+          toWrite->accept(heavyDataWriter);
+          toWrite->setTime(time);
+          newCollection->insert(toWrite);
+        }
+        newDomain->insert(newCollection);
+      }
+    }
+    else {
+      if(domain->getNumberGraphs() == 0) {
+        shared_ptr<XdmfUnstructuredGrid> gridToPartition;
+        if(domain->getNumberUnstructuredGrids() == 0) {
+          // repartition
+          gridToPartition =
+            partitioner->unpartition(domain->getGridCollection(0));
+        }
+        else {
+          gridToPartition = domain->getUnstructuredGrid(0);
+        }
+        shared_ptr<XdmfGridCollection> toWrite =
+          partitioner->partition(gridToPartition,
+                                 numberOfPartitions,
+                                 metisScheme,
+                                 heavyDataWriter);
+        newDomain->insert(toWrite);
+      }
+      else {
+        shared_ptr<XdmfGraph> graphToPartition = domain->getGraph(0);
+        partitioner->partition(graphToPartition,
+                               numberOfPartitions);
+        newDomain->insert(graphToPartition);
+      }
+    }
+
+    std::stringstream xmlFileName;
+    xmlFileName << meshName << ".xmf";
+    shared_ptr<XdmfWriter> writer = XdmfWriter::New(xmlFileName.str(),
+                                                    heavyDataWriter);
+    newDomain->accept(writer);
+
+    std::cout << "Wrote: " << xmlFileName.str() << std::endl;
+  }
+
+#endif // BUILD_EXE
diff --git a/utils/XdmfPartitioner.hpp b/utils/XdmfPartitioner.hpp
new file mode 100644
index 0000000..23676d4
--- /dev/null
+++ b/utils/XdmfPartitioner.hpp
@@ -0,0 +1,176 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfPartitioner.hpp                                                 */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFPARTITIONER_HPP_
+#define XDMFPARTITIONER_HPP_
+
+#ifdef __cplusplus
+
+// Forward Declarations
+class XdmfGraph;
+class XdmfGridCollection;
+class XdmfHeavyDataWriter;
+class XdmfSet;
+class XdmfUnstructuredGrid;
+
+// Includes
+#include <set>
+#include "XdmfUtils.hpp"
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief XdmfPartitioner partitions an XdmfGrid using the metis
+ * library.
+ *
+ * XdmfPartitioner uses the metis library to partition XdmfGrids.
+ */
+class XDMFUTILS_EXPORT XdmfPartitioner {
+
+public:
+
+  enum MetisScheme {
+    DUAL_GRAPH = 0,
+    NODAL_GRAPH = 1
+  };
+
+  /**
+   * Create a new XdmfPartitioner.
+   *
+   * @return constructed XdmfPartitioner.
+   */
+  static shared_ptr<XdmfPartitioner> New();
+
+  virtual ~XdmfPartitioner();
+
+  /**
+   * Ignore set when partitioning. Set is not partitioned or added to
+   * resulting grid.
+   *
+   * @param set the set to ignore when partitioning.
+   */
+  void ignore(const shared_ptr<const XdmfSet> set);
+  void ignore(const XdmfSet *);
+
+  /**
+   * Partitions an XdmfGraph using the metis library. An attribute
+   * named "Partition" is added to the XdmfGraph that contains
+   * partition numbers for each graph vertex.
+   *
+   * @param graphToPartition an XdmfGraph to partition.
+   * @param numberOfPartitions the number of pieces to partition the
+   * graph into.
+   */
+  void
+  partition(const shared_ptr<XdmfGraph> graphToPartition,
+            const unsigned int numberOfPartitions) const;
+
+  /**
+   * Partitions an XdmfUnstructuredGrid using the metis library.
+   *
+   * The partitioner splits the XdmfGridUnstructured and all attached
+   * XdmfAttributes and XdmfSets into their proper partition. An
+   * XdmfAttribute named "GlobalNodeId" is added to each partitioned
+   * grid to map partitioned node ids to their original unpartitioned
+   * id. An XdmfMap is added to each partitioned grid mapping shared
+   * nodes to other processors. All arrays attached to the passed
+   * gridToPartition are read from disk if not initialized.
+   *
+   * @param gridToPartition an XdmfGridUnstructured to partition.
+   * @param numberOfPartitions the number of pieces to partition the grid into.
+   * @param heavyDataWriter an XdmfHDF5Writer to write the partitioned mesh to.
+   * If no heavyDataWriter is specified, all partitioned data will remain in
+   * memory.
+   *
+   * @return a spatial collection containing partitioned grids.
+   */
+  shared_ptr<XdmfGridCollection>
+  partition(const shared_ptr<XdmfUnstructuredGrid> gridToPartition,
+            const unsigned int numberOfPartitions,
+            const MetisScheme metisScheme = DUAL_GRAPH,
+            const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter = shared_ptr<XdmfHeavyDataWriter>()) const;
+
+  /**
+   * Unpartitions an XdmfGridCollection of unstructured grids into a single
+   * XdmfUnstructuredGrid.
+   *
+   * @param gridToPartition an XdmfGridUnstructured to partition.
+   *
+   * @return a unstructured grid containing the unpartitioned grid.
+   */
+  shared_ptr<XdmfUnstructuredGrid>
+  unpartition(const shared_ptr<XdmfGridCollection> gridToUnPartition) const;
+
+  XdmfPartitioner(const XdmfPartitioner & partitioner);
+
+protected:
+
+  XdmfPartitioner();
+
+private:
+
+  void operator=(const XdmfPartitioner & partitioner);  // Not implemented.
+
+  std::set<const XdmfSet * > mIgnoredSets;
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define XDMF_PARTITIONER_SCHEME_DUAL_GRAPH  500
+#define XDMF_PARTITIONER_SCHEME_NODAL_GRAPH 501
+
+// C wrappers go here
+
+struct XDMFPARTITIONER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFPARTITIONER XDMFPARTITIONER;
+
+XDMFUTILS_EXPORT XDMFPARTITIONER * XdmfPartitionerNew();
+
+XDMFUTILS_EXPORT void XdmfPartitionerIgnore(XDMFPARTITIONER * partitioner,
+                                            XDMFSET * set);
+
+XDMFUTILS_EXPORT void XdmfPartitionerPartitionGraph(XDMFPARTITIONER * partitioner,
+                                                    XDMFGRAPH * graphToPartition,
+                                                    unsigned int numberOfPartitions);
+
+XDMFUTILS_EXPORT XDMFGRIDCOLLECTION * XdmfPartitionerPartitionUnstructuredGrid(XDMFPARTITIONER * partitioner,
+                                                                               XDMFUNSTRUCTUREDGRID * gridToPartition,
+                                                                               unsigned int numberOfPartitions,
+                                                                               int metisScheme,
+                                                                               XDMFHEAVYDATAWRITER * heavyDataWriter);
+
+XDMFUTILS_EXPORT XDMFUNSTRUCTUREDGRID * XdmfPartitionerUnpartition(XDMFPARTITIONER * partitioner,
+                                                                   XDMFGRIDCOLLECTION * gridToUnPartition);
+
+XDMFUTILS_EXPORT void XdmfPartitionerFree(XDMFPARTITIONER * partitioner);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* XDMFPARTITIONER_HPP_ */
diff --git a/utils/XdmfTopologyConverter.cpp b/utils/XdmfTopologyConverter.cpp
new file mode 100644
index 0000000..c1143da
--- /dev/null
+++ b/utils/XdmfTopologyConverter.cpp
@@ -0,0 +1,2122 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopologyConverter.cpp                                           */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#include <cmath>
+#include <map>
+#include <iostream>
+#include <vector>
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+#include "XdmfSet.hpp"
+#include "XdmfSetType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyConverter.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfError.hpp"
+
+//
+// local methods
+//
+namespace {
+  
+  typedef std::pair<std::vector<unsigned int>, 
+                    std::vector<unsigned int> > OldFaceToNewFaceMap ;
+  typedef std::vector<std::vector<OldFaceToNewFaceMap> > FaceHash;
+
+  void handleSetConversion(const shared_ptr<XdmfUnstructuredGrid> gridToConvert,
+			   const shared_ptr<XdmfUnstructuredGrid> toReturn,
+			   const std::vector<int> & oldIdToNewId,
+			   const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) 
+  {
+
+    for(unsigned int i=0; i<gridToConvert->getNumberSets(); ++i) {
+      const shared_ptr<XdmfSet> set = gridToConvert->getSet(i);
+      const shared_ptr<const XdmfSetType> setType = set->getType();
+      if(setType == XdmfSetType::Cell()) {
+	toReturn->insert(set);
+      }
+      else if(setType == XdmfSetType::Node()) {
+	bool releaseSet = false;
+	if(!set->isInitialized()) {
+	  set->read();
+	  releaseSet = true;
+	}
+	shared_ptr<XdmfSet> toReturnSet = XdmfSet::New();
+	toReturnSet->setName(set->getName());
+	toReturnSet->setType(set->getType());
+	toReturnSet->initialize(set->getArrayType(),
+				set->getSize());
+	  
+	for(unsigned int i=0; i<set->getSize(); ++i) {
+	  const unsigned int nodeId = set->getValue<unsigned int>(i);
+          const int newNodeId = oldIdToNewId[nodeId];
+	  toReturnSet->insert(i, newNodeId);
+	}
+	if(releaseSet) {
+	  set->release();
+	}
+	  
+	toReturn->insert(toReturnSet);
+	  
+	if(heavyDataWriter) {
+	  toReturnSet->accept(heavyDataWriter);
+	  toReturnSet->release();
+	}
+      }
+    }
+  }
+
+  template <unsigned int ORDER>
+  void remapTopology(shared_ptr<XdmfTopology> topology)
+  {
+    return;
+  }
+
+  template <>
+  void remapTopology<2>(shared_ptr<XdmfTopology> topology)
+  {
+    const unsigned int numberElements = topology->getNumberElements();
+    unsigned int oldElementIds[27];
+    unsigned int newElementIds[27];
+    unsigned int offset = 0;
+    for(unsigned int i=0; i<numberElements; ++i) {
+      topology->getValues(offset,
+                          oldElementIds,
+                          27);
+      newElementIds[0] = oldElementIds[0];
+      newElementIds[1] = oldElementIds[18];
+      newElementIds[2] = oldElementIds[24];
+      newElementIds[3] = oldElementIds[6];
+      newElementIds[4] = oldElementIds[2];
+      newElementIds[5] = oldElementIds[20];
+      newElementIds[6] = oldElementIds[26];
+      newElementIds[7] = oldElementIds[8];
+      newElementIds[8] = oldElementIds[9];
+      newElementIds[9] = oldElementIds[21];
+      newElementIds[10] = oldElementIds[15];
+      newElementIds[11] = oldElementIds[3];
+      newElementIds[12] = oldElementIds[11];
+      newElementIds[13] = oldElementIds[23];
+      newElementIds[14] = oldElementIds[17];
+      newElementIds[15] = oldElementIds[5];
+      newElementIds[16] = oldElementIds[1];
+      newElementIds[17] = oldElementIds[19];
+      newElementIds[18] = oldElementIds[25];
+      newElementIds[19] = oldElementIds[7];
+      newElementIds[20] = oldElementIds[4];
+      newElementIds[21] = oldElementIds[22];
+      newElementIds[22] = oldElementIds[10];
+      newElementIds[23] = oldElementIds[16];
+      newElementIds[24] = oldElementIds[12];
+      newElementIds[25] = oldElementIds[14];
+      newElementIds[26] = oldElementIds[13];
+      topology->insert(offset,
+                       newElementIds,
+                       27);
+      offset += 27;
+    }
+  }
+
+  // Classes that perform topology conversions. Converter is the root
+  // base class.  Tessellator is a subclass of Converter that deals
+  // with cases where the mesh only needs to be tessellated to carry
+  // out the conversion (e.g. Hexahedron_64 to Hexahedron).
+
+  class Converter {
+
+  public:
+
+    Converter()
+    {
+    }
+
+    virtual ~Converter()
+    {
+    }
+
+    virtual shared_ptr<XdmfUnstructuredGrid>
+    convert(const shared_ptr<XdmfUnstructuredGrid> gridToConvert,
+            const shared_ptr<const XdmfTopologyType> topologyType,
+            const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) const = 0;
+
+  };
+
+  class Tessellator : public Converter {
+
+  public:
+
+    virtual ~Tessellator()
+    {
+    }
+
+    shared_ptr<XdmfUnstructuredGrid>
+    convert(const shared_ptr<XdmfUnstructuredGrid> gridToConvert,
+            const shared_ptr<const XdmfTopologyType> topologyType,
+            const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) const
+    {
+      shared_ptr<XdmfUnstructuredGrid> toReturn =
+        XdmfUnstructuredGrid::New();
+      toReturn->setName(gridToConvert->getName());
+      toReturn->setGeometry(gridToConvert->getGeometry());
+
+      if(heavyDataWriter) {
+        if(!toReturn->getGeometry()->isInitialized()) {
+          toReturn->getGeometry()->read();
+        }
+        toReturn->getGeometry()->accept(heavyDataWriter);
+        toReturn->getGeometry()->release();
+      }
+
+      bool releaseTopology = false;
+      if(!gridToConvert->getTopology()->isInitialized()) {
+        gridToConvert->getTopology()->read();
+        releaseTopology = true;
+      }
+
+      this->tesselateTopology(gridToConvert->getTopology(),
+                              toReturn->getTopology());
+
+      if(releaseTopology) {
+        gridToConvert->getTopology()->release();
+      }
+
+      if(heavyDataWriter) {
+        toReturn->getTopology()->accept(heavyDataWriter);
+        toReturn->getTopology()->release();
+      }
+
+      for(unsigned int i=0; i<gridToConvert->getNumberAttributes(); ++i) {
+        shared_ptr<XdmfAttribute> currAttribute =
+          gridToConvert->getAttribute(i);
+        shared_ptr<XdmfAttribute> createdAttribute =
+          shared_ptr<XdmfAttribute>();
+        if(currAttribute->getCenter() == XdmfAttributeCenter::Node()) {
+          createdAttribute = currAttribute;
+        }
+        else if(currAttribute->getCenter() == XdmfAttributeCenter::Cell()) {
+          bool releaseAttribute = false;
+          if(!currAttribute->isInitialized()) {
+            currAttribute->read();
+            releaseAttribute = true;
+          }
+
+          createdAttribute = XdmfAttribute::New();
+          createdAttribute->setName(currAttribute->getName());
+          createdAttribute->setType(currAttribute->getType());
+          createdAttribute->setCenter(currAttribute->getCenter());
+          createdAttribute->initialize(currAttribute->getArrayType(),
+                                       currAttribute->getSize() * mNumTesselations);
+          for(unsigned int j=0; j<currAttribute->getSize(); ++j) {
+            createdAttribute->insert(j * mNumTesselations,
+                                     currAttribute,
+                                     j,
+                                     mNumTesselations,
+                                     1,
+                                     0);
+          }
+
+          if(releaseAttribute) {
+            currAttribute->release();
+          }
+        }
+        if(createdAttribute) {
+          toReturn->insert(createdAttribute);
+          if(heavyDataWriter) {
+            if(!createdAttribute->isInitialized()) {
+              createdAttribute->read();
+            }
+            createdAttribute->accept(heavyDataWriter);
+            createdAttribute->release();
+          }
+        }
+      }
+      return toReturn;
+    }
+
+    virtual void
+    tesselateTopology(shared_ptr<XdmfTopology> topologyToConvert,
+                      shared_ptr<XdmfTopology> topologyToReturn) const = 0;
+
+  protected:
+
+    Tessellator(const unsigned int numTesselations) :
+      mNumTesselations(numTesselations)
+    {
+    }
+
+    const unsigned int mNumTesselations;
+
+  };
+
+  template <unsigned int ORDER, bool ISSPECTRAL>
+  class HexahedronToHighOrderHexahedron : public Converter {
+
+  public:
+
+    HexahedronToHighOrderHexahedron()
+    {
+    }
+
+    virtual ~HexahedronToHighOrderHexahedron()
+    {
+    }
+
+    int
+    reorder(unsigned int & a,
+            unsigned int & b,
+            unsigned int & c,
+            unsigned int & d) const
+    {
+      
+      int tmp;
+      
+      // Reorder to get smallest id in a.
+      if (b < a && b < c && b < d) {
+        tmp = a;
+        a = b;
+        b = c;
+        c = d;
+        d = tmp;
+        return 1;
+      }
+      else if (c < a && c < b && c < d) {
+        tmp = a;
+        a = c;
+        c = tmp;
+        tmp = b;
+        b = d;
+        d = tmp;
+        return 2;
+      }
+      else if (d < a && d < b && d < c) {
+        tmp = a;
+        a = d;
+        d = c;
+        c = b;
+        b = tmp;
+        return 3;
+      }
+      
+      return 0;
+
+    }               
+
+    void
+    rotateQuad(unsigned int reorderVal,
+               const std::vector<unsigned int> & face,
+               std::vector<unsigned int> & newFace) const
+    {
+      
+      switch (reorderVal) {
+      case 0: {
+        std::copy(face.begin(),
+                  face.end(),
+                  newFace.begin());
+        return;
+      }
+      case 1: {
+        unsigned int index = 0;
+        for(unsigned int i=mNodesPerEdge; i>0; --i) {
+          for(unsigned int j=i-1; j<mNodesPerFace; j+=mNodesPerEdge) {
+            newFace[index++] = face[j];
+          }
+        }
+        return;
+      }
+      case 2: {
+        for(unsigned int i=0; i<mNodesPerFace; ++i) {
+          newFace[i] = face[mNodesPerFace - 1 - i];
+        }
+        return;
+      }
+      case 3: {
+        unsigned int index = 0;
+        for(unsigned int i=mNodesPerFace-mNodesPerEdge; i<mNodesPerFace; ++i) {
+          for(int j=i; j>=0; j-=mNodesPerEdge) {
+            newFace[index++] = face[j];
+          }
+        }
+        return;
+      }
+      }
+    }
+    
+    void
+    addEdgeToHash(unsigned int a,
+                  unsigned int b,
+                  FaceHash & hash,
+                  std::vector<unsigned int> & edge) const
+    {
+      
+      // reorder to get lowest id in a
+      bool swapped = false;
+      if(a > b) {
+        std::swap(a, b);
+        swapped = true;
+      }
+
+      std::vector<unsigned int> newEdge(edge.size());
+      if(swapped) {
+        for(unsigned int i=0; i<edge.size(); ++i) {
+          newEdge[i] = edge[edge.size() - i - 1];
+        }
+      }
+      else {
+        for(unsigned int i=0; i<edge.size(); ++i) {
+          newEdge[i] = edge[i];
+        }
+      }
+      
+      // Look for existing cell in the hash;
+      FaceHash::value_type & currHash = hash[a];
+      std::vector<unsigned int> currEdge(1);
+      currEdge[0] = b;
+      currHash.push_back(std::make_pair(currEdge, newEdge));
+      
+    }
+
+    void
+    addFaceToHash(unsigned int a,
+                  unsigned int b,
+                  unsigned int c,
+                  unsigned int d,
+                  FaceHash & hash,
+                  std::vector<unsigned int> & face) const
+    {
+      const unsigned int reorderVal = reorder(a, b, c, d);
+      
+      std::vector<unsigned int> newFace(face.size());
+      rotateQuad(reorderVal,
+                 face,
+                 newFace);
+      
+      // Look for existing cell in the hash;
+      FaceHash::value_type & currHash = hash[a];
+      std::vector<unsigned int> currFace(3);
+      currFace[0] = b;
+      currFace[1] = c;
+      currFace[2] = d;
+      currHash.push_back(std::make_pair(currFace, newFace));
+      
+    }
+    
+    std::vector<unsigned int>
+    getEdge(unsigned int a,
+            unsigned int b,
+            FaceHash & hash) const
+    {
+      
+      // reorder to get lowest id in a
+      bool swapped = false;
+      if(a > b) {
+        std::swap(a, b);
+        swapped = true;
+      }      
+      
+      // Look for existing cell in the hash;
+      FaceHash::value_type & currHash = hash[a];
+      for(FaceHash::value_type::iterator iter = currHash.begin(); 
+          iter != currHash.end(); ++iter) {
+        std::vector<unsigned int> & currEdge = iter->first;
+        if(currEdge.size() == 1) {
+          if(b == currEdge[0]) {
+            const std::vector<unsigned int> edge = iter->second;
+            std::vector<unsigned int> returnValue(edge.size());
+            if(swapped) {
+              for(unsigned int i=0; i<edge.size(); ++i) {
+                returnValue[i] = edge[edge.size() - i - 1];
+              }
+            }
+            else {
+              for(unsigned int i=0; i<edge.size(); ++i) {
+                returnValue[i] = edge[i];
+              }
+            }
+            //currHash.erase(iter);
+            return returnValue;           
+          }
+        }
+      }
+     
+      return std::vector<unsigned int>();
+            
+    }
+    
+    std::vector<unsigned int>
+    getFace(unsigned int a,
+            unsigned int b,
+            unsigned int c,
+            unsigned int d,
+            FaceHash & hash) const
+    {
+      
+      unsigned int reorderVal = reorder(a, b, c, d);   
+
+      // need to rotate opposite of what we put in
+      if(reorderVal == 1) {
+        reorderVal = 3;
+      }
+      else if(reorderVal == 3) {
+        reorderVal = 1;
+      }
+            
+      // Look for existing cell in the hash;
+      FaceHash::value_type & currHash = hash[a];
+      for(FaceHash::value_type::iterator iter = currHash.begin(); 
+          iter != currHash.end(); ++iter) {
+        std::vector<unsigned int> & currFace = iter->first;
+        // 3 because b + c + d
+        if(currFace.size() == 3) {
+          if(b == currFace[0] && d == currFace[2]) {
+            
+            const std::vector<unsigned int> & face = iter->second;
+            std::vector<unsigned int> returnValue(face.size());
+            rotateQuad(reorderVal,
+                       face,
+                       returnValue);
+            currHash.erase(iter);
+            return returnValue;
+            
+          }
+        }
+      }
+
+      return std::vector<unsigned int>();
+      
+    }
+
+    void
+    calculateIntermediatePoint(double result[3],
+                               const double point1[3],
+                               const double point2[3],
+                               int index) const
+    {
+      const double scalar = points[index];
+      for (int i=0; i<3; ++i) {
+        result[i] = point1[i]+scalar*(point2[i]-point1[i]);
+      }
+    }
+
+    shared_ptr<XdmfUnstructuredGrid>
+    convert(const shared_ptr<XdmfUnstructuredGrid> gridToConvert,
+            const shared_ptr<const XdmfTopologyType> topologyType,
+            const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) const
+    {
+
+      shared_ptr<XdmfUnstructuredGrid> toReturn = XdmfUnstructuredGrid::New();
+      toReturn->setName(gridToConvert->getName());
+
+      shared_ptr<XdmfGeometry> geometry = gridToConvert->getGeometry();
+      shared_ptr<XdmfGeometry> toReturnGeometry = toReturn->getGeometry();
+
+      toReturnGeometry->setType(geometry->getType());
+      toReturnGeometry->initialize(geometry->getArrayType());
+
+      bool releaseGeometry = false;
+      if(!geometry->isInitialized()) {
+        geometry->read();
+        releaseGeometry = true;
+      }
+
+      shared_ptr<XdmfTopology> topology = gridToConvert->getTopology();
+      shared_ptr<XdmfTopology> toReturnTopology = toReturn->getTopology();
+
+      toReturn->getTopology()->setType(topologyType);
+      toReturnTopology->initialize(topology->getArrayType());
+      toReturnTopology->reserve(topologyType->getNodesPerElement() *
+                                topology->getNumberElements());
+
+      bool releaseTopology = false;
+      if(!topology->isInitialized()) {
+        topology->read();
+        releaseTopology = true;
+      }
+
+      // allocate storage for values used in loop
+      unsigned int zeroIndex;
+      unsigned int oneIndex;
+      unsigned int twoIndex;
+      unsigned int threeIndex;
+      unsigned int fourIndex;
+      unsigned int fiveIndex;
+      unsigned int sixIndex;
+      unsigned int sevenIndex;
+      double elementCorner0[3];
+      double elementCorner1[3];
+      double elementCorner2[3];
+      double elementCorner3[3];
+      double elementCorner4[3];
+      double elementCorner5[3];
+      double elementCorner6[3];
+      double elementCorner7[3];
+      double planeCorner0[3];
+      double planeCorner1[3];
+      double planeCorner2[3];
+      double planeCorner3[3];
+      double lineEndPoint0[3];
+      double lineEndPoint1[3];
+      double (*newPoints)[3] = new double[mNumberPoints][3];
+
+      unsigned int largestId = 0;
+      for(unsigned int i=0; i<topology->getSize(); ++i) {
+        const unsigned int val = topology->getValue<unsigned int>(i);
+        largestId = std::max(val, largestId);
+      }
+
+      FaceHash hash(largestId + 1);
+      std::vector<int> oldIdToNewId(largestId + 1, -1);
+
+      unsigned int offset = 0;
+      for(unsigned int elem = 0; elem<topology->getNumberElements(); ++elem) {
+
+        // get indices of coner vertices of the element
+        zeroIndex = topology->getValue<unsigned int>(offset++);
+        oneIndex = topology->getValue<unsigned int>(offset++);
+        twoIndex = topology->getValue<unsigned int>(offset++);
+        threeIndex = topology->getValue<unsigned int>(offset++);
+        fourIndex = topology->getValue<unsigned int>(offset++);
+        fiveIndex = topology->getValue<unsigned int>(offset++);
+        sixIndex = topology->getValue<unsigned int>(offset++);
+        sevenIndex = topology->getValue<unsigned int>(offset++);       
+
+        // get previously added faces
+        std::vector<unsigned int> bottomFace = 
+          getFace(zeroIndex, threeIndex, twoIndex, oneIndex, hash);
+        std::vector<unsigned int> frontFace = 
+          getFace(zeroIndex, oneIndex, fiveIndex, fourIndex, hash);
+        std::vector<unsigned int> leftFace = 
+          getFace(zeroIndex, fourIndex, sevenIndex, threeIndex, hash);
+        std::vector<unsigned int> rightFace = 
+          getFace(oneIndex, twoIndex, sixIndex, fiveIndex, hash);
+        std::vector<unsigned int> backFace = 
+          getFace(threeIndex, sevenIndex, sixIndex, twoIndex, hash);
+        std::vector<unsigned int> topFace = 
+          getFace(fourIndex, fiveIndex, sixIndex, sevenIndex, hash);
+        
+        // get previously added edges
+        std::vector<unsigned int> bottomFrontEdge =
+          getEdge(zeroIndex, oneIndex, hash);
+        std::vector<unsigned int> bottomRightEdge =
+          getEdge(oneIndex, twoIndex, hash);
+        std::vector<unsigned int> bottomBackEdge =
+          getEdge(twoIndex, threeIndex, hash);
+        std::vector<unsigned int> bottomLeftEdge =
+          getEdge(threeIndex, zeroIndex, hash);
+        std::vector<unsigned int> topFrontEdge =
+          getEdge(fourIndex, fiveIndex, hash);
+        std::vector<unsigned int> topRightEdge =
+          getEdge(fiveIndex, sixIndex, hash);
+        std::vector<unsigned int> topBackEdge =
+          getEdge(sixIndex, sevenIndex, hash);
+        std::vector<unsigned int> topLeftEdge =
+          getEdge(sevenIndex, fourIndex, hash);
+        std::vector<unsigned int> frontLeftEdge =
+          getEdge(zeroIndex, fourIndex, hash);
+        std::vector<unsigned int> frontRightEdge =
+          getEdge(oneIndex, fiveIndex, hash);
+        std::vector<unsigned int> backRightEdge =
+          getEdge(twoIndex, sixIndex, hash);
+        std::vector<unsigned int> backLeftEdge =
+          getEdge(threeIndex, sevenIndex, hash);        
+                                             
+        // get locations of corner vertices of the element
+        geometry->getValues(zeroIndex * 3,
+                            &(elementCorner0[0]),
+                            3);
+        geometry->getValues(oneIndex * 3,
+                            &(elementCorner1[0]),
+                            3);
+        geometry->getValues(twoIndex * 3,
+                            &(elementCorner2[0]),
+                            3);
+        geometry->getValues(threeIndex * 3,
+                            &(elementCorner3[0]),
+                            3);
+        geometry->getValues(fourIndex * 3,
+                            &(elementCorner4[0]),
+                            3);
+        geometry->getValues(fiveIndex * 3,
+                            &(elementCorner5[0]),
+                            3);
+        geometry->getValues(sixIndex * 3,
+                            &(elementCorner6[0]),
+                            3);
+        geometry->getValues(sevenIndex * 3,
+                            &(elementCorner7[0]),
+                            3);
+        
+        std::vector<int> newIds(mNumberPoints, -1);
+
+        // set new ids if they have been found previously
+        newIds[mZeroIndex] = oldIdToNewId[zeroIndex];
+        newIds[mOneIndex] = oldIdToNewId[oneIndex];
+        newIds[mTwoIndex] = oldIdToNewId[twoIndex];
+        newIds[mThreeIndex] = oldIdToNewId[threeIndex];
+        newIds[mFourIndex] = oldIdToNewId[fourIndex];
+        newIds[mFiveIndex] = oldIdToNewId[fiveIndex];
+        newIds[mSixIndex] = oldIdToNewId[sixIndex];
+        newIds[mSevenIndex] = oldIdToNewId[sevenIndex];
+
+        // loop over i, j, k directions of element isolation i, j, and
+        // k planes
+        int pointIndex = 0;
+        for(unsigned int i=0; i<mNodesPerEdge; ++i){
+          // calculate corners of i plane
+          calculateIntermediatePoint(planeCorner0,
+                                     elementCorner0,
+                                     elementCorner1,
+                                     i);
+          calculateIntermediatePoint(planeCorner1,
+                                     elementCorner4,
+                                     elementCorner5,
+                                     i);
+          calculateIntermediatePoint(planeCorner2,
+                                     elementCorner3,
+                                     elementCorner2,
+                                     i);
+          calculateIntermediatePoint(planeCorner3,
+                                     elementCorner7,
+                                     elementCorner6,
+                                     i);
+          for(unsigned int j=0; j<mNodesPerEdge; ++j) {
+            // calculate endpoints of j slice of i plane
+            calculateIntermediatePoint(lineEndPoint0,
+                                       planeCorner0,
+                                       planeCorner2,
+                                       j);
+            calculateIntermediatePoint(lineEndPoint1,
+                                       planeCorner1,
+                                       planeCorner3,
+                                       j);
+            for(unsigned int k=0; k<mNodesPerEdge; ++k) {
+              // calculate point to add to mesh
+              calculateIntermediatePoint(newPoints[pointIndex++],
+                                         lineEndPoint0,
+                                         lineEndPoint1,
+                                         k);
+            }
+          }
+        }
+        
+        // put matched faces in new element
+        if(bottomFace.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNumberPoints; i+=mNodesPerEdge) {
+            newIds[i] = bottomFace[index++];
+          }
+        }
+        if(frontFace.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNodesPerEdge; ++i) {
+            for(unsigned int j=i; j<mNumberPoints; j+=mNodesPerFace) {
+              newIds[j] = frontFace[index++];
+            }
+          }
+        }
+        std::copy(leftFace.begin(),
+                  leftFace.end(),
+                  &(newIds[0]));
+        if(rightFace.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace; 
+              i<mNumberPoints - mNodesPerFace + mNodesPerEdge; ++i) {
+            for(unsigned int j=i; j<mNumberPoints; j+=mNodesPerEdge) {
+              newIds[j] = rightFace[index++];
+            }
+          }
+        }
+        if(backFace.size() > 0) {          
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerFace - mNodesPerEdge; 
+              i<mNumberPoints; i+=mNodesPerFace) {
+            for(unsigned int j=i; j<i+mNodesPerEdge; ++j) {
+              newIds[j] = backFace[index++];
+            }
+          }
+        }
+        if(topFace.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerEdge-1; 
+              i<mNodesPerFace; i+=mNodesPerEdge) {
+            for(unsigned int j=i; j<mNumberPoints; j+=mNodesPerFace) {
+              newIds[j] = topFace[index++];
+            }
+          }
+        }
+        
+        // put matched edges in new element
+        if(bottomFrontEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNumberPoints; i+=mNodesPerFace) {
+            newIds[i] = bottomFrontEdge[index++];
+          }
+        }
+        if(bottomRightEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace; 
+              i<mNumberPoints; i+=mNodesPerEdge) {
+            newIds[i] = bottomRightEdge[index++];
+          }
+        }
+        if(bottomBackEdge.size() > 0) {
+          unsigned int index = 0;
+          for(int i=mNumberPoints - mNodesPerEdge; i>0; 
+              i-=mNodesPerFace) {
+            newIds[i] = bottomBackEdge[index++];
+          }
+        }
+        if(bottomLeftEdge.size() > 0) {
+          unsigned int index = 0;
+          for(int i=mNodesPerFace - mNodesPerEdge; i>=0; 
+              i-=mNodesPerEdge) {
+            newIds[i] = bottomLeftEdge[index++];
+          }
+        }
+        if(topFrontEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerEdge - 1; 
+              i<mNumberPoints; i+=mNodesPerFace) {
+            newIds[i] = topFrontEdge[index++];
+          }
+        }
+        if(topRightEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace + mNodesPerEdge - 1;
+              i<mNumberPoints; i+=mNodesPerEdge) {
+            newIds[i] = topRightEdge[index++];
+          }
+        }
+        if(topBackEdge.size() > 0) {
+          unsigned int index = 0;
+          for(int i=mNumberPoints - 1; i>0; 
+              i-=mNodesPerFace) {
+            newIds[i] = topBackEdge[index++];
+          }
+        }
+        if(topLeftEdge.size() > 0) {
+          unsigned int index = 0;
+          for(int i=mNodesPerFace - 1; i>0; 
+              i-=mNodesPerEdge) {
+            newIds[i] = topLeftEdge[index++];
+          }
+        }
+        if(frontLeftEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNodesPerEdge; ++i) {
+            newIds[i] = frontLeftEdge[index++];
+          }
+        }
+        if(frontRightEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace; 
+              i<mNumberPoints - mNodesPerFace + mNodesPerEdge; ++i) {
+            newIds[i] = frontRightEdge[index++];
+          }
+        }
+        if(backRightEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerEdge; i<mNumberPoints; 
+              ++i) {
+            newIds[i] = backRightEdge[index++];
+          }
+        }
+        if(backLeftEdge.size() > 0) {
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerFace - mNodesPerEdge; i<mNodesPerFace; 
+              ++i) {
+            newIds[i] = backLeftEdge[index++];
+          }
+        }       
+                  
+        // finally, add the points and ids to the new topology and geometry
+        for(unsigned int i=0; i<mNumberPoints; ++i) {
+          const int id = newIds[i];
+          if(id == -1) {
+            // need to add the new point
+            const unsigned int newId = toReturnGeometry->getNumberPoints();
+            newIds[i] = newId;
+            toReturnGeometry->insert(newId * 3,
+                                     &(newPoints[i][0]),
+                                     3);
+            toReturnTopology->pushBack(newId);
+          }
+          else {
+            // point added previously, so just add the found id
+            toReturnTopology->pushBack(id);
+          }
+        }
+   
+        // add all faces to hash (mirror to match face on another element)
+        if(bottomFace.size() == 0) {
+          bottomFace.resize(mNodesPerFace);
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNodesPerFace; i+=mNodesPerEdge) {
+            for(unsigned int j=i; j<mNumberPoints; j+=mNodesPerFace) {
+              bottomFace[index++] = newIds[j];
+            }
+          }
+          addFaceToHash(zeroIndex, oneIndex, twoIndex, threeIndex, hash, 
+                        bottomFace);
+        }
+        if(frontFace.size() == 0) {
+          frontFace.resize(mNodesPerFace);
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNumberPoints; i+=mNodesPerFace) {
+            for(unsigned int j=i; j<i+mNodesPerEdge; ++j) {
+              frontFace[index++] = newIds[j];
+            }
+          }
+          addFaceToHash(zeroIndex, fourIndex, fiveIndex, oneIndex, hash, 
+                        frontFace);
+        }
+        if(leftFace.size() == 0) {
+          leftFace.resize(mNodesPerFace);
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNodesPerEdge; ++i) {
+            for(unsigned int j=i; j<mNodesPerFace; j+=mNodesPerEdge) {
+              leftFace[index++] = newIds[j];
+            }
+          }
+          addFaceToHash(zeroIndex, threeIndex, sevenIndex, fourIndex, hash, 
+                        leftFace);
+        } 
+        if(rightFace.size() == 0) {
+          rightFace.resize(mNodesPerFace);
+          std::copy(&(newIds[mOneIndex]),
+                    &(newIds[mNumberPoints]),
+                    &(rightFace[0]));
+          addFaceToHash(oneIndex, fiveIndex, sixIndex, twoIndex, hash, 
+                        rightFace);
+        }
+        if(backFace.size() == 0) {
+          backFace.resize(mNodesPerFace);
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerFace - mNodesPerEdge; 
+              i<mNodesPerFace; ++i) {
+            for(unsigned int j=i; j<mNumberPoints; j+=mNodesPerFace) {
+              backFace[index++] = newIds[j];
+            }
+          }
+          addFaceToHash(threeIndex, twoIndex, sixIndex, sevenIndex, hash, 
+                        backFace);
+        }
+        if(topFace.size() == 0) {
+          topFace.resize(mNodesPerFace);
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerEdge-1; 
+              i<mNumberPoints; i+=mNodesPerEdge) {
+            topFace[index++] = newIds[i];
+          }
+          addFaceToHash(fourIndex, sevenIndex, sixIndex, fiveIndex, hash, 
+                        topFace);
+        }
+
+        //
+        // populate edges if they were not found previously
+        //
+        if(bottomFrontEdge.size() == 0) {
+          bottomFrontEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNumberPoints; i+=mNodesPerFace) {
+            bottomFrontEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(zeroIndex, oneIndex, hash, bottomFrontEdge);
+        }
+        if(bottomRightEdge.size() == 0) {
+          bottomRightEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace; 
+              i<mNumberPoints; i+=mNodesPerEdge) {
+            bottomRightEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(oneIndex, twoIndex, hash, bottomRightEdge);
+        }
+        if(bottomBackEdge.size() == 0) {
+          bottomBackEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(int i=mNumberPoints - mNodesPerEdge; i>0; 
+              i-=mNodesPerFace) {
+            bottomBackEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(twoIndex, threeIndex, hash, bottomBackEdge);
+        }
+        if(bottomLeftEdge.size() == 0) {
+          bottomLeftEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(int i=mNodesPerFace - mNodesPerEdge; i>=0; 
+              i-=mNodesPerEdge) {
+            bottomLeftEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(threeIndex, zeroIndex, hash, bottomLeftEdge);
+        }
+        if(topFrontEdge.size() == 0) {
+          topFrontEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerEdge - 1; 
+              i<mNumberPoints; i+=mNodesPerFace) {
+            topFrontEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(fourIndex, fiveIndex, hash, topFrontEdge);
+        }
+        if(topRightEdge.size() == 0) {
+          topRightEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace + mNodesPerEdge - 1;
+              i<mNumberPoints; i+=mNodesPerEdge) {
+            topRightEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(fiveIndex, sixIndex, hash, topRightEdge);
+        }
+        if(topBackEdge.size() == 0) {
+          topBackEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(int i=mNumberPoints - 1; i>0; 
+              i-=mNodesPerFace) {
+            topBackEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(sixIndex, sevenIndex, hash, topBackEdge);
+        }
+        if(topLeftEdge.size() == 0) {
+          topLeftEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(int i=mNodesPerFace - 1; i>0; 
+              i-=mNodesPerEdge) {
+            topLeftEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(sevenIndex, fourIndex, hash, topLeftEdge);
+        }
+        if(frontLeftEdge.size() == 0) {
+          frontLeftEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=0; i<mNodesPerEdge; ++i) {
+            frontLeftEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(zeroIndex, fourIndex, hash, frontLeftEdge);
+        }
+        if(frontRightEdge.size() == 0) {
+          frontRightEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerFace; 
+              i<mNumberPoints - mNodesPerFace + mNodesPerEdge; ++i) {
+            frontRightEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(oneIndex, fiveIndex, hash, frontRightEdge);
+        }
+        if(backRightEdge.size() == 0) {
+          backRightEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=mNumberPoints - mNodesPerEdge; i<mNumberPoints; 
+              ++i) {
+            backRightEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(twoIndex, sixIndex, hash, backRightEdge);
+        }
+        if(backLeftEdge.size() == 0) {
+          backLeftEdge.resize(mNodesPerEdge);
+          unsigned int index = 0;
+          for(unsigned int i=mNodesPerFace - mNodesPerEdge; i<mNodesPerFace; 
+              ++i) {
+            backLeftEdge[index++] = newIds[i];
+          }
+          addEdgeToHash(threeIndex, sevenIndex, hash, backLeftEdge);
+        }         
+
+        // add ids to map
+        oldIdToNewId[zeroIndex] = newIds[mZeroIndex];
+        oldIdToNewId[oneIndex] = newIds[mOneIndex];
+        oldIdToNewId[twoIndex] = newIds[mTwoIndex];
+        oldIdToNewId[threeIndex] = newIds[mThreeIndex];
+        oldIdToNewId[fourIndex] = newIds[mFourIndex];
+        oldIdToNewId[fiveIndex] = newIds[mFiveIndex];
+        oldIdToNewId[sixIndex] = newIds[mSixIndex];
+        oldIdToNewId[sevenIndex] = newIds[mSevenIndex];
+   
+      }
+
+      delete [] newPoints;
+
+      if(releaseTopology) {
+        topology->release();
+      }
+      if(releaseGeometry) {
+        geometry->release();
+      }
+
+      remapTopology<ORDER>(toReturnTopology);
+
+      if(heavyDataWriter) {
+        toReturnTopology->accept(heavyDataWriter);
+        toReturnTopology->release();
+        toReturnGeometry->accept(heavyDataWriter);
+        toReturnGeometry->release();
+      }
+
+      handleSetConversion(gridToConvert,
+			  toReturn,
+			  oldIdToNewId,
+			  heavyDataWriter);
+      return toReturn;
+    }
+
+  private:
+    static const unsigned int mNodesPerEdge = ORDER + 1;
+    static const unsigned int mNodesPerFace = (ORDER + 1) * (ORDER + 1);
+    static const unsigned int mNumberPoints = 
+      (ORDER + 1) * (ORDER + 1) * (ORDER + 1);
+    static const unsigned int mZeroIndex = 
+      0;
+    static const unsigned int mOneIndex = 
+      (ORDER + 1) * (ORDER + 1) * (ORDER + 1) - (ORDER + 1) * (ORDER + 1);
+    static const unsigned int mTwoIndex = 
+      (ORDER + 1) * (ORDER + 1) * (ORDER + 1) - (ORDER + 1);
+    static const unsigned int mThreeIndex = 
+      (ORDER + 1) * (ORDER + 1) - (ORDER + 1);
+    static const unsigned int mFourIndex =
+      ORDER;
+    static const unsigned int mFiveIndex = 
+      (ORDER + 1) * (ORDER + 1) * (ORDER + 1) - (ORDER + 1) * (ORDER + 1) + 
+      ORDER;
+    static const unsigned int mSixIndex = 
+      (ORDER + 1) * (ORDER + 1) * (ORDER + 1) - 1;
+    static const unsigned int mSevenIndex =
+      (ORDER + 1) * (ORDER + 1) - 1;
+    static const double points[];
+
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<3, true>::points[] = {
+    0.0,
+    0.5-0.1*sqrt(5.0),
+    0.5+0.1*sqrt(5.0),
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<4, true>::points[] = {
+    0.0,
+    0.5-sqrt(21.0)/14.0,
+    0.5,
+    0.5+sqrt(21.0)/14.0,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<5, true>::points[] = {
+    0.0,
+    0.5-sqrt((7.0+2.0*sqrt(7.0))/84.0),
+    0.5-sqrt((7.0-2.0*sqrt(7.0))/84.0),
+    0.5+sqrt((7.0-2.0*sqrt(7.0))/84.0),
+    0.5+sqrt((7.0+2.0*sqrt(7.0))/84.0),
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<6, true>::points[] = {
+    0.0,
+    0.5-sqrt((15.0+2.0*sqrt(15.0))/132.0),
+    0.5-sqrt((15.0-2.0*sqrt(15.0))/132.0),
+    0.5,
+    0.5+sqrt((15.0-2.0*sqrt(15.0))/132.0),
+    0.5+sqrt((15.0+2.0*sqrt(15.0))/132.0),
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<7, true>::points[] = {
+    0.0,
+    0.064129925745196714,
+    0.20414990928342885,
+    0.39535039104876057,
+    0.60464960895123943,
+    0.79585009071657109,
+    0.93587007425480329,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<8, true>::points[] = {
+    0.0,
+    0.050121002294269912,
+    0.16140686024463108,
+    0.31844126808691087,
+    0.5,
+    0.68155873191308913,
+    0.83859313975536898,
+    0.94987899770573003,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<9, true>::points[] = {
+    0.0,
+    0.040233045916770627,
+    0.13061306744724743,
+    0.26103752509477773,
+    0.4173605211668065,
+    0.58263947883319345,
+    0.73896247490522227,
+    0.86938693255275257,
+    0.95976695408322943,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<10, true>::points[] = {
+    0.0,
+    0.032999284795970474,
+    0.10775826316842779,
+    0.21738233650189748,
+    0.35212093220653029,
+    0.5,
+    0.64787906779346971,
+    0.78261766349810258,
+    0.89224173683157226,
+    0.96700071520402953,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<2, false>::points[] = {
+    0.0,
+    0.5,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<3, false>::points[] = {
+    0.0,
+    1.0/3.0,
+    2.0/3.0,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<4, false>::points[] = {
+    0.0,
+    0.25,
+    0.5,
+    0.75,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<5, false>::points[] = {
+    0.0,
+    0.2,
+    0.4,
+    0.6,
+    0.8,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<6, false>::points[] = {
+    0.0,
+    1.0/6.0,
+    1.0/3.0,
+    0.5,
+    2.0/3.0,
+    5.0/6.0,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<7, false>::points[] = {
+    0.0,
+    1.0/7.0,
+    2.0/7.0,
+    3.0/7.0,
+    4.0/7.0,
+    5.0/7.0,
+    6.0/7.0,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<8, false>::points[] = {
+    0.0,
+    0.125,
+    0.25,
+    0.375,
+    0.5,
+    0.625,
+    0.75,
+    0.875,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<9, false>::points[] = {
+    0.0,
+    1.0/9.0,
+    2.0/9.0,
+    1.0/3.0,
+    4.0/9.0,
+    5.0/9.0,
+    2.0/3.0,
+    7.0/9.0,
+    8.0/9.0,
+    1.0
+  };
+
+  template <>
+  const double HexahedronToHighOrderHexahedron<10, false>::points[] = {
+    0.0,
+    0.1,
+    0.2,
+    0.3,
+    0.4,
+    0.5,
+    0.6,
+    0.7,
+    0.8,
+    0.9,
+    1.0
+  };
+
+  template <unsigned int ORDER>
+  class HighOrderHexahedronToHexahedron : public Tessellator {
+
+  public:
+
+    HighOrderHexahedronToHexahedron() :
+      Tessellator(ORDER * ORDER * ORDER)
+    {
+    }
+
+    void
+    tesselateTopology(shared_ptr<XdmfTopology> topologyToConvert,
+                      shared_ptr<XdmfTopology> topologyToReturn) const
+    {
+      topologyToReturn->setType(XdmfTopologyType::Hexahedron());
+      topologyToReturn->initialize(topologyToConvert->getArrayType(),
+                                   8 * ORDER * ORDER * ORDER * topologyToConvert->getNumberElements());
+
+      unsigned int newIndex = 0;
+      int indexA = 0;
+      int indexB = mNodesPerEdge * mNodesPerEdge;
+      int indexC = mNodesPerEdge * mNodesPerEdge + mNodesPerEdge;
+      int indexD = mNodesPerEdge;
+      for(unsigned int i=0; i<topologyToConvert->getNumberElements(); ++i) {
+        for(unsigned int j=0; j<ORDER; ++j) {
+          for(unsigned int k=0; k<ORDER; ++k) {
+            for(unsigned int l=0; l<ORDER; ++l){
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexA++);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexB++);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexC++);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexD++);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexA);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexB);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexC);
+              topologyToReturn->insert(newIndex++, topologyToConvert, indexD);
+            }
+            indexA++;
+            indexB++;
+            indexC++;
+            indexD++;
+          }
+          indexA += mNodesPerEdge;
+          indexB += mNodesPerEdge;
+          indexC += mNodesPerEdge;
+          indexD += mNodesPerEdge;
+        }
+        indexA += mNodesPerEdge * mNodesPerEdge;
+        indexB += mNodesPerEdge * mNodesPerEdge;
+        indexC += mNodesPerEdge * mNodesPerEdge;
+        indexD += mNodesPerEdge * mNodesPerEdge;
+      }
+    }
+
+  private:
+    static const unsigned int mNodesPerEdge = (ORDER + 1);
+
+  };
+
+}
+
+shared_ptr<XdmfTopologyConverter>
+XdmfTopologyConverter::New()
+{
+  shared_ptr<XdmfTopologyConverter> p(new XdmfTopologyConverter());
+  return p;
+}
+
+XdmfTopologyConverter::XdmfTopologyConverter()
+{
+}
+
+XdmfTopologyConverter::XdmfTopologyConverter(const XdmfTopologyConverter &)
+{
+}
+
+XdmfTopologyConverter::~XdmfTopologyConverter()
+{
+}
+
+shared_ptr<XdmfUnstructuredGrid>
+XdmfTopologyConverter::convert(const shared_ptr<XdmfUnstructuredGrid> gridToConvert,
+                               const shared_ptr<const XdmfTopologyType> topologyType,
+                               const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter) const
+{
+  // Make sure geometry and topology are non null
+  if(!(gridToConvert->getGeometry() && gridToConvert->getTopology())) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Current grid's geometry or topology is null "
+                       "in XdmfTopologyConverter::convert");
+  }
+
+  shared_ptr<const XdmfTopologyType> topologyTypeToConvert =
+    gridToConvert->getTopology()->getType();
+  if(topologyTypeToConvert == topologyType) {
+    // No conversion necessary
+    return gridToConvert;
+  }
+
+  if(gridToConvert->getGeometry()->getType() != XdmfGeometryType::XYZ()) {
+    XdmfError::message(XdmfError::FATAL,
+                       "Grid to convert's type is not 'XYZ' in "
+                       "XdmfTopologyConverter::convert");
+  }
+
+  Converter * converter = NULL;
+  if(topologyTypeToConvert == XdmfTopologyType::Hexahedron()) {
+    if(topologyType == XdmfTopologyType::Hexahedron_27()) {
+      converter = new HexahedronToHighOrderHexahedron<2, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_64()) {
+      converter = new HexahedronToHighOrderHexahedron<3, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_64()) {
+      converter = new HexahedronToHighOrderHexahedron<3, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_125()) {
+      converter = new HexahedronToHighOrderHexahedron<4, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_125()) {
+      converter = new HexahedronToHighOrderHexahedron<4, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_216()) {
+      converter = new HexahedronToHighOrderHexahedron<5, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_216()) {
+      converter = new HexahedronToHighOrderHexahedron<5, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_343()) {
+      converter = new HexahedronToHighOrderHexahedron<6, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_343()) {
+      converter = new HexahedronToHighOrderHexahedron<6, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_512()) {
+      converter = new HexahedronToHighOrderHexahedron<7, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_512()) {
+      converter = new HexahedronToHighOrderHexahedron<7, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_729()) {
+      converter = new HexahedronToHighOrderHexahedron<8, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_729()) {
+      converter = new HexahedronToHighOrderHexahedron<8, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_1000()) {
+      converter = new HexahedronToHighOrderHexahedron<9, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_1000()) {
+      converter = new HexahedronToHighOrderHexahedron<9, true>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_1331()) {
+      converter = new HexahedronToHighOrderHexahedron<10, false>();
+    }
+    else if(topologyType == XdmfTopologyType::Hexahedron_Spectral_1331()) {
+      converter = new HexahedronToHighOrderHexahedron<10, true>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_64() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_64()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<3>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_125() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_125()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<4>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_216() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_216()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<5>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_343() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_343()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<6>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_512() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_512()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<7>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_729() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_729()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<8>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_1000() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_1000()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<9>();
+    }
+  }
+  else if(topologyTypeToConvert == XdmfTopologyType::Hexahedron_1331() ||
+          topologyTypeToConvert == 
+          XdmfTopologyType::Hexahedron_Spectral_1331()) {
+    if(topologyType == XdmfTopologyType::Hexahedron()) {
+      converter = new HighOrderHexahedronToHexahedron<10>();
+    }
+  }
+
+  if(converter) {
+    if(heavyDataWriter) {
+      heavyDataWriter->openFile();
+    }
+
+    shared_ptr<XdmfUnstructuredGrid> toReturn =
+      converter->convert(gridToConvert,
+                         topologyType,
+                         heavyDataWriter);
+
+    if(heavyDataWriter) {
+      heavyDataWriter->closeFile();
+    }
+
+    delete converter;
+    return toReturn;
+  }
+  else {
+    XdmfError::message(XdmfError::FATAL,
+                       "Cannot convert topology type in "
+                       "XdmfTopologyConverter::convert");
+  }
+
+  // not reached
+  return shared_ptr<XdmfUnstructuredGrid>();
+
+}
+
+shared_ptr<XdmfTopology>
+XdmfTopologyConverter::getExternalFaces(const shared_ptr<XdmfTopology> convertedTopology) {
+
+  if (convertedTopology->getSize() < 
+      convertedTopology->getType()->getNodesPerElement()) {
+    XdmfError::message(XdmfError::FATAL, 
+                       "Error: Not enough nodes for GetExternalSurface");
+  }
+  
+  long largestId = convertedTopology->getValue<long>(0);
+  for (unsigned int i = 1; i < convertedTopology->getSize(); ++i) {
+    if (largestId < convertedTopology->getValue<long>(i)) {
+      largestId = convertedTopology->getValue<long>(i);
+    }
+  }
+
+  std::vector<std::vector<std::vector<long> > > hash(largestId);
+
+  if(convertedTopology->getType() == XdmfTopologyType::Tetrahedron()) {
+
+    // This loop can be generalized in a later version
+    for(unsigned int arrayOffset=0; arrayOffset<convertedTopology->getSize(); arrayOffset += convertedTopology->getType()->getNodesPerElement()) {
+      std::vector<long> faceNodes;
+      for (unsigned int i = 0; i < convertedTopology->getType()->getNodesPerElement(); ++i) {
+        faceNodes.push_back(convertedTopology->getValue<long>(arrayOffset + i));
+      }
+
+      std::vector< std::vector<long> > faceVectors;
+      // 0, 1, 3 face
+      std::vector<long> face1Vector;
+      face1Vector.push_back(faceNodes[0]);
+      face1Vector.push_back(faceNodes[1]);
+      face1Vector.push_back(faceNodes[3]);
+      faceVectors.push_back(face1Vector);
+      // 0, 2, 1 face
+      std::vector<long> face2Vector;
+      face2Vector.push_back(faceNodes[0]);
+      face2Vector.push_back(faceNodes[2]);
+      face2Vector.push_back(faceNodes[1]);
+      faceVectors.push_back(face2Vector);
+      // 0, 3, 2 face
+      std::vector<long> face3Vector;
+      face3Vector.push_back(faceNodes[0]);
+      face3Vector.push_back(faceNodes[3]);
+      face3Vector.push_back(faceNodes[2]);
+      faceVectors.push_back(face3Vector);
+      // 1, 2, 3 face
+      std::vector<long> face4Vector;
+      face4Vector.push_back(faceNodes[1]);
+      face4Vector.push_back(faceNodes[2]);
+      face4Vector.push_back(faceNodes[3]);
+      faceVectors.push_back(face4Vector);
+
+      for (unsigned int i = 0; i < faceVectors.size(); ++i) {
+        insertInHash(faceVectors[i], hash, 3);
+      }
+    }
+
+    // create new topology
+    shared_ptr<XdmfTopology> toReturn = XdmfTopology::New();
+    toReturn->setType(XdmfTopologyType::Triangle());
+    std::vector<long> newCells;
+    int index = 0;
+    for(std::vector<std::vector<std::vector<long> > >::const_iterator hashIter = hash.begin();
+        hashIter != hash.end();
+        ++hashIter, ++index)
+      {
+        const std::vector<std::vector<long> > & currHash = *hashIter;
+        for(std::vector<std::vector<long> >::const_iterator currHashIter = currHash.begin();
+            currHashIter != currHash.end();
+            ++currHashIter)
+          {
+            const std::vector<long> & currFaceIds = *currHashIter;
+            newCells.push_back(index);
+            newCells.push_back(currFaceIds[0]);
+            newCells.push_back(currFaceIds[1]);
+          }
+      }
+    toReturn->initialize(XdmfArrayType::Int64());
+    toReturn->insert(0, &newCells[0], newCells.size());
+    return toReturn;
+  }
+  else if(convertedTopology->getType() == XdmfTopologyType::Hexahedron()) {
+    for(long arrayOffset=0; arrayOffset<convertedTopology->getSize(); arrayOffset += convertedTopology->getType()->getNodesPerElement())
+      {
+        std::vector<long> faceNodes;
+        for (unsigned int i = 0; i < convertedTopology->getType()->getNodesPerElement(); ++i) {
+          faceNodes.push_back(convertedTopology->getValue<long>(arrayOffset + i));
+        }
+
+        std::vector< std::vector<long> > faceVectors;
+        // 0, 1, 5, 4 face
+        std::vector<long> face1Vector;
+        face1Vector.push_back(faceNodes[0]);
+        face1Vector.push_back(faceNodes[1]);
+        face1Vector.push_back(faceNodes[5]);
+        face1Vector.push_back(faceNodes[4]);
+        faceVectors.push_back(face1Vector);
+        // 0, 3, 2, 1 face
+        std::vector<long> face2Vector;
+        face2Vector.push_back(faceNodes[0]);
+        face2Vector.push_back(faceNodes[3]);
+        face2Vector.push_back(faceNodes[2]);
+        face2Vector.push_back(faceNodes[1]);
+        faceVectors.push_back(face2Vector);
+        // 0, 4, 7, 3 face
+        std::vector<long> face3Vector;
+        face3Vector.push_back(faceNodes[0]);
+        face3Vector.push_back(faceNodes[4]);
+        face3Vector.push_back(faceNodes[7]);
+        face3Vector.push_back(faceNodes[3]);
+        faceVectors.push_back(face3Vector);
+        // 1, 2, 6, 5 face
+        std::vector<long> face4Vector;
+        face4Vector.push_back(faceNodes[1]);
+        face4Vector.push_back(faceNodes[2]);
+        face4Vector.push_back(faceNodes[6]);
+        face4Vector.push_back(faceNodes[5]);
+        faceVectors.push_back(face4Vector);
+        // 2, 3, 7, 6 face
+        std::vector<long> face5Vector;
+        face5Vector.push_back(faceNodes[2]);
+        face5Vector.push_back(faceNodes[3]);
+        face5Vector.push_back(faceNodes[7]);
+        face5Vector.push_back(faceNodes[6]);
+        faceVectors.push_back(face5Vector);
+        // 4, 5, 6, 7 face
+        std::vector<long> face6Vector;
+        face6Vector.push_back(faceNodes[4]);
+        face6Vector.push_back(faceNodes[5]);
+        face6Vector.push_back(faceNodes[6]);
+        face6Vector.push_back(faceNodes[7]);
+        faceVectors.push_back(face6Vector);
+
+        for (unsigned int i = 0; i < faceVectors.size(); ++i) {
+          insertInHash(faceVectors[i], hash, 4);
+        }
+      }
+
+    // create new topology
+    shared_ptr<XdmfTopology> toReturn = XdmfTopology::New();
+    toReturn->setType(XdmfTopologyType::Quadrilateral());
+    std::vector<long> newCells;
+    int index = 0;
+    for(std::vector<std::vector<std::vector<long> > >::const_iterator hashIter = hash.begin();
+        hashIter != hash.end();
+        ++hashIter, ++index)
+      {
+        const std::vector<std::vector<long> > & currHash = *hashIter;
+        for(std::vector<std::vector<long> >::const_iterator currHashIter = currHash.begin();
+            currHashIter != currHash.end();
+            ++currHashIter)
+          {
+            const std::vector<long> & currFaceIds = *currHashIter;
+            newCells.push_back(index);
+            newCells.push_back(currFaceIds[0]);
+            newCells.push_back(currFaceIds[1]);
+            newCells.push_back(currFaceIds[2]);
+          }
+      }
+    toReturn->initialize(XdmfArrayType::Int64());
+    toReturn->insert(0, &newCells[0], newCells.size());
+    return toReturn;
+  }
+  else if(convertedTopology->getType() == XdmfTopologyType::Tetrahedron_10()) {
+    for(long arrayOffset=0; arrayOffset<convertedTopology->getSize(); arrayOffset += convertedTopology->getType()->getNodesPerElement())
+      {
+        std::vector<long> faceNodes;
+        for (unsigned int i = 0; i < convertedTopology->getType()->getNodesPerElement(); ++i) {
+          faceNodes.push_back(convertedTopology->getValue<long>(arrayOffset + i));
+        }
+
+        std::vector< std::vector<long> > faceVectors;
+        // 0, 1, 3, 4, 8, 7 face
+        std::vector<long> face1Vector;
+        face1Vector.push_back(faceNodes[0]);
+        face1Vector.push_back(faceNodes[1]);
+        face1Vector.push_back(faceNodes[3]);
+        face1Vector.push_back(faceNodes[4]);
+        face1Vector.push_back(faceNodes[8]);
+        face1Vector.push_back(faceNodes[7]);
+        faceVectors.push_back(face1Vector);
+        // 0, 2, 1, 6, 5, 4 face
+        std::vector<long> face2Vector;
+        face2Vector.push_back(faceNodes[0]);
+        face2Vector.push_back(faceNodes[2]);
+        face2Vector.push_back(faceNodes[1]);
+        face2Vector.push_back(faceNodes[6]);
+        face2Vector.push_back(faceNodes[5]);
+        face2Vector.push_back(faceNodes[4]);
+        faceVectors.push_back(face2Vector);
+        // 0, 3, 2, 7, 9, 6 face
+        std::vector<long> face3Vector;
+        face3Vector.push_back(faceNodes[0]);
+        face3Vector.push_back(faceNodes[3]);
+        face3Vector.push_back(faceNodes[2]);
+        face3Vector.push_back(faceNodes[7]);
+        face3Vector.push_back(faceNodes[9]);
+        face3Vector.push_back(faceNodes[6]);
+        faceVectors.push_back(face3Vector);
+        // 1, 2, 3, 5, 9, 8 face
+        std::vector<long> face4Vector;
+        face4Vector.push_back(faceNodes[1]);
+        face4Vector.push_back(faceNodes[2]);
+        face4Vector.push_back(faceNodes[3]);
+        face4Vector.push_back(faceNodes[5]);
+        face4Vector.push_back(faceNodes[9]);
+        face4Vector.push_back(faceNodes[8]);
+        faceVectors.push_back(face4Vector);
+
+        for (unsigned int i = 0; i < faceVectors.size(); ++i) {
+          insertInHash(faceVectors[i], hash, 3);
+        }
+      }
+
+    // create new topology
+    shared_ptr<XdmfTopology> toReturn = XdmfTopology::New();
+    toReturn->setType(XdmfTopologyType::Triangle_6());
+    std::vector<long> newCells;
+    int index = 0;
+    for(std::vector<std::vector<std::vector<long> > >::const_iterator hashIter = hash.begin();
+        hashIter != hash.end();
+        ++hashIter, ++index)
+      {
+        const std::vector<std::vector<long> > & currHash = *hashIter;
+        for(std::vector<std::vector<long> >::const_iterator currHashIter = currHash.begin();
+            currHashIter != currHash.end();
+            ++currHashIter)
+          {
+            const std::vector<long> & currFaceIds = *currHashIter;
+            newCells.push_back(index);
+            newCells.push_back(currFaceIds[0]);
+            newCells.push_back(currFaceIds[1]);
+            newCells.push_back(currFaceIds[2]);
+            newCells.push_back(currFaceIds[3]);
+            newCells.push_back(currFaceIds[4]);
+          }
+      }
+    toReturn->initialize(XdmfArrayType::Int64());
+    toReturn->insert(0, &newCells[0], newCells.size());
+    return toReturn;
+  }
+  else if(convertedTopology->getType() == XdmfTopologyType::Hexahedron_20()) {
+    for(long arrayOffset=0; arrayOffset<convertedTopology->getSize(); arrayOffset += convertedTopology->getType()->getNodesPerElement())
+      {
+        std::vector<long> faceNodes;
+        for (unsigned int i = 0; i < convertedTopology->getType()->getNodesPerElement(); ++i) {
+          faceNodes.push_back(convertedTopology->getValue<long>(arrayOffset + i));
+        }
+
+        std::vector< std::vector<long> > faceVectors;
+        // 0, 1, 5, 4, 8, 17, 12, 16 face
+        std::vector<long> face1Vector;
+        face1Vector.push_back(faceNodes[0]);
+        face1Vector.push_back(faceNodes[1]);
+        face1Vector.push_back(faceNodes[5]);
+        face1Vector.push_back(faceNodes[4]);
+        face1Vector.push_back(faceNodes[8]);
+        face1Vector.push_back(faceNodes[17]);
+        face1Vector.push_back(faceNodes[12]);
+        face1Vector.push_back(faceNodes[16]);
+        faceVectors.push_back(face1Vector);
+        // 0, 3, 2, 1, 11, 10, 9, 8 face
+        std::vector<long> face2Vector;
+        face2Vector.push_back(faceNodes[0]);
+        face2Vector.push_back(faceNodes[3]);
+        face2Vector.push_back(faceNodes[2]);
+        face2Vector.push_back(faceNodes[1]);
+        face2Vector.push_back(faceNodes[11]);
+        face2Vector.push_back(faceNodes[10]);
+        face2Vector.push_back(faceNodes[9]);
+        face2Vector.push_back(faceNodes[8]);
+        faceVectors.push_back(face2Vector);
+        // 0, 4, 7, 3, 16, 15, 19, 11 face
+        std::vector<long> face3Vector;
+        face3Vector.push_back(faceNodes[0]);
+        face3Vector.push_back(faceNodes[4]);
+        face3Vector.push_back(faceNodes[7]);
+        face3Vector.push_back(faceNodes[3]);
+        face3Vector.push_back(faceNodes[16]);
+        face3Vector.push_back(faceNodes[15]);
+        face3Vector.push_back(faceNodes[19]);
+        face3Vector.push_back(faceNodes[11]);
+        faceVectors.push_back(face3Vector);
+        // 1, 2, 6, 5, 9, 18, 13, 17 face
+        std::vector<long> face4Vector;
+        face4Vector.push_back(faceNodes[1]);
+        face4Vector.push_back(faceNodes[2]);
+        face4Vector.push_back(faceNodes[6]);
+        face4Vector.push_back(faceNodes[5]);
+        face4Vector.push_back(faceNodes[9]);
+        face4Vector.push_back(faceNodes[18]);
+        face4Vector.push_back(faceNodes[13]);
+        face4Vector.push_back(faceNodes[17]);
+        faceVectors.push_back(face4Vector);
+        // 2, 3, 7, 6, 10, 19, 14, 18 face
+        std::vector<long> face5Vector;
+        face5Vector.push_back(faceNodes[2]);
+        face5Vector.push_back(faceNodes[3]);
+        face5Vector.push_back(faceNodes[7]);
+        face5Vector.push_back(faceNodes[6]);
+        face5Vector.push_back(faceNodes[10]);
+        face5Vector.push_back(faceNodes[19]);
+        face5Vector.push_back(faceNodes[14]);
+        face5Vector.push_back(faceNodes[18]);
+        faceVectors.push_back(face5Vector);
+        // 4, 5, 6, 7, 12, 13, 14, 15 face
+        std::vector<long> face6Vector;
+        face6Vector.push_back(faceNodes[4]);
+        face6Vector.push_back(faceNodes[5]);
+        face6Vector.push_back(faceNodes[6]);
+        face6Vector.push_back(faceNodes[7]);
+        face6Vector.push_back(faceNodes[12]);
+        face6Vector.push_back(faceNodes[13]);
+        face6Vector.push_back(faceNodes[14]);
+        face6Vector.push_back(faceNodes[15]);
+        faceVectors.push_back(face6Vector);
+
+        for (unsigned int i = 0; i < faceVectors.size(); ++i) {
+          insertInHash(faceVectors[i], hash, 4);
+        }
+      }
+
+    // create new topology
+    shared_ptr<XdmfTopology> toReturn = XdmfTopology::New();
+    toReturn->setType(XdmfTopologyType::Quadrilateral_8());
+    std::vector<long> newCells;
+    int index = 0;
+    for(std::vector<std::vector<std::vector<long> > >::const_iterator hashIter = hash.begin();
+        hashIter != hash.end();
+        ++hashIter, ++index)
+      {
+        const std::vector<std::vector<long> > & currHash = *hashIter;
+        for(std::vector<std::vector<long> >::const_iterator currHashIter = currHash.begin();
+            currHashIter != currHash.end();
+            ++currHashIter)
+          {
+            const std::vector<long> & currFaceIds = *currHashIter;
+            newCells.push_back(index);
+            newCells.push_back(currFaceIds[0]);
+            newCells.push_back(currFaceIds[1]);
+            newCells.push_back(currFaceIds[2]);
+            newCells.push_back(currFaceIds[3]);
+            newCells.push_back(currFaceIds[4]);
+            newCells.push_back(currFaceIds[5]);
+            newCells.push_back(currFaceIds[6]);
+          }
+      }
+    toReturn->initialize(XdmfArrayType::Int64());
+    toReturn->insert(0, &newCells[0], newCells.size());
+    return toReturn;
+  }
+
+  XdmfError::message(XdmfError::FATAL, "Unsupported TopologyType when computing external surface");
+  return shared_ptr<XdmfTopology>();
+}
+
+void
+XdmfTopologyConverter::insertInHash(std::vector<long> nodes,
+                                    std::vector<std::vector<std::vector<long> > > & hash,
+                                    unsigned int numCornerNodes)
+{
+  unsigned int minIndex = 0;
+  for (unsigned int i = 0; i < numCornerNodes; ++i) {
+    if (nodes[i] < nodes[minIndex]) {
+      minIndex = i;
+    }
+  }
+  if (minIndex !=0) {
+    // If the min value is not the first value, rotate as appropriate
+    std::vector<long> sortedVector (nodes.begin()+minIndex,
+                                    nodes.begin()+numCornerNodes);
+    sortedVector.insert(sortedVector.end(),
+                        nodes.begin(),
+                        nodes.begin()+minIndex);
+    if (nodes.size() > numCornerNodes) {
+      sortedVector.insert(sortedVector.end(),
+                          nodes.begin()+numCornerNodes+minIndex,
+                          nodes.begin()+numCornerNodes+numCornerNodes);
+      sortedVector.insert(sortedVector.end(),
+                          nodes.begin()+numCornerNodes,
+                          nodes.begin()+numCornerNodes+minIndex);
+    }
+    nodes = sortedVector;
+  }
+
+  // The nodes are now sorted so that the smallest corner is first
+  // Look for existing cell in the hash;
+  std::vector<std::vector<long> > & currHash = hash[nodes[0]];
+  for(std::vector<std::vector<long> >::iterator iter =
+        currHash.begin(); iter != currHash.end();
+      ++iter) {
+    std::vector<long> & currFace = *iter;
+    // size - 1 because the first value is used elsewhere
+    if(currFace.size() == nodes.size()-1) {
+      if ((nodes[1] == currFace[0] && 
+           nodes[numCornerNodes-1] == currFace[numCornerNodes-2]) ||
+          (nodes[1] == currFace[numCornerNodes-2] &&
+           nodes[numCornerNodes-1] == currFace[0])) {
+        currHash.erase(iter);
+        return;
+      }
+    }
+  }
+
+  std::vector<long> newFace;
+  for (unsigned int i = 1; i < nodes.size(); ++i) {
+    newFace.push_back(nodes[i]);
+  }
+  currHash.push_back(newFace);
+}
+
+// C Wrappers
+
+shared_ptr<const XdmfTopologyType> convertIntToType(int type, int nodes = 0)
+{
+  switch (type) {
+    case XDMF_TOPOLOGY_TYPE_POLYVERTEX:
+      return XdmfTopologyType::Polyvertex();
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYLINE:
+      return XdmfTopologyType::Polyline(nodes);
+      break;
+    case XDMF_TOPOLOGY_TYPE_POLYGON:
+      return XdmfTopologyType::Polygon(nodes);
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE:
+      return XdmfTopologyType::Triangle();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL:
+      return XdmfTopologyType::Quadrilateral();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON:
+      return XdmfTopologyType::Tetrahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID:
+      return XdmfTopologyType::Pyramid();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE:
+      return XdmfTopologyType::Wedge();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON:
+      return XdmfTopologyType::Hexahedron();
+      break;
+    case XDMF_TOPOLOGY_TYPE_EDGE_3:
+      return XdmfTopologyType::Edge_3();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TRIANGLE_6:
+      return XdmfTopologyType::Triangle_6();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_8:
+      return XdmfTopologyType::Quadrilateral_8();
+      break;
+    case XDMF_TOPOLOGY_TYPE_QUADRILATERAL_9:
+      return XdmfTopologyType::Quadrilateral_9();
+      break;
+    case XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10:
+      return XdmfTopologyType::Tetrahedron_10();
+      break;
+    case XDMF_TOPOLOGY_TYPE_PYRAMID_13:
+      return XdmfTopologyType::Pyramid_13();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_15:
+      return XdmfTopologyType::Wedge_15();
+      break;
+    case XDMF_TOPOLOGY_TYPE_WEDGE_18:
+      return XdmfTopologyType::Wedge_18();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20:
+      return XdmfTopologyType::Hexahedron_20();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_24:
+      return XdmfTopologyType::Hexahedron_24();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_27:
+      return XdmfTopologyType::Hexahedron_27();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64:
+      return XdmfTopologyType::Hexahedron_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125:
+      return XdmfTopologyType::Hexahedron_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_216:
+      return XdmfTopologyType::Hexahedron_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_343:
+      return XdmfTopologyType::Hexahedron_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_512:
+      return XdmfTopologyType::Hexahedron_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_729:
+      return XdmfTopologyType::Hexahedron_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1000:
+      return XdmfTopologyType::Hexahedron_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_1331:
+      return XdmfTopologyType::Hexahedron_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_64:
+      return XdmfTopologyType::Hexahedron_Spectral_64();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_125:
+      return XdmfTopologyType::Hexahedron_Spectral_125();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_216:
+      return XdmfTopologyType::Hexahedron_Spectral_216();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_343:
+      return XdmfTopologyType::Hexahedron_Spectral_343();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_512:
+      return XdmfTopologyType::Hexahedron_Spectral_512();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_729:
+      return XdmfTopologyType::Hexahedron_Spectral_729();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1000:
+      return XdmfTopologyType::Hexahedron_Spectral_1000();
+      break;
+    case XDMF_TOPOLOGY_TYPE_HEXAHEDRON_SPECTRAL_1331:
+      return XdmfTopologyType::Hexahedron_Spectral_1331();
+      break;
+    case XDMF_TOPOLOGY_TYPE_MIXED:
+      return XdmfTopologyType::Mixed();
+      break;
+    default:
+      return shared_ptr<const XdmfTopologyType>();
+      break;
+  }
+}
+
+XDMFTOPOLOGYCONVERTER *
+XdmfTopologyConverterNew()
+{
+  shared_ptr<XdmfTopologyConverter> generatedConverter = XdmfTopologyConverter::New();
+  return (XDMFTOPOLOGYCONVERTER *)((void *)(new XdmfTopologyConverter(*generatedConverter.get())));
+}
+
+XDMFUNSTRUCTUREDGRID *
+XdmfTopologyConverterConvert(XDMFTOPOLOGYCONVERTER * converter,
+                             XDMFUNSTRUCTUREDGRID * gridToConvert,
+                             int topologytype,
+                             XDMFHEAVYDATAWRITER * heavyDataWriter)
+{
+  XdmfItem * tempPointer = (XdmfItem *)(gridToConvert);
+  XdmfUnstructuredGrid * gridPointer = dynamic_cast<XdmfUnstructuredGrid *>(tempPointer);
+  shared_ptr<XdmfUnstructuredGrid> tempgrid = shared_ptr<XdmfUnstructuredGrid>((XdmfUnstructuredGrid *)gridPointer, XdmfNullDeleter());
+  shared_ptr<const XdmfTopologyType> convertedType = convertIntToType(topologytype);
+  shared_ptr<XdmfHeavyDataWriter> tempwriter = shared_ptr<XdmfHeavyDataWriter>();
+  if (heavyDataWriter) {
+    tempwriter = shared_ptr<XdmfHeavyDataWriter>((XdmfHeavyDataWriter *)heavyDataWriter, XdmfNullDeleter());
+    return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*((((XdmfTopologyConverter *)converter)->convert(tempgrid, convertedType, tempwriter)).get())))));
+  }
+  else {
+    return (XDMFUNSTRUCTUREDGRID *)((void *)((XdmfItem *)(new XdmfUnstructuredGrid(*((((XdmfTopologyConverter *)converter)->convert(tempgrid, convertedType)).get())))));
+  }
+}
+
+XDMFTOPOLOGY *
+XdmfTopologyConverterGetExternalFaces(XDMFTOPOLOGYCONVERTER * converter,
+                                      XDMFTOPOLOGY * convertedTopology)
+{
+  shared_ptr<XdmfTopology> temptopo = shared_ptr<XdmfTopology>((XdmfTopology *)convertedTopology, XdmfNullDeleter());
+  return (XDMFTOPOLOGY *)((void *)(new XdmfTopology(*((((XdmfTopologyConverter *)converter)->getExternalFaces(temptopo)).get()))));
+}
+
+void
+XdmfTopologyConverterFree(XDMFTOPOLOGYCONVERTER * converter)
+{
+  if (converter != NULL) {
+    delete ((XdmfTopologyConverter *)converter);
+    converter = NULL;
+  }
+}
diff --git a/utils/XdmfTopologyConverter.hpp b/utils/XdmfTopologyConverter.hpp
new file mode 100644
index 0000000..874bd71
--- /dev/null
+++ b/utils/XdmfTopologyConverter.hpp
@@ -0,0 +1,172 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : XdmfTopologyConverter.hpp                                           */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef XDMFTOPOLOGYCONVERTER_HPP_
+#define XDMFTOPOLOGYCONVERTER_HPP_
+
+// C Compatible Includes
+#include "XdmfUtils.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfHeavyDataWriter.hpp"
+
+#ifdef __cplusplus
+
+// Forward Declarations
+//class XdmfHeavyDataWriter;
+class XdmfTopologyType;
+//class XdmfUnstructuredGrid;
+
+// Includes
+#include "XdmfSharedPtr.hpp"
+
+/**
+ * @brief Converts an unstructured grid to different topology types.
+ *
+ * Attributes and sets attached to the grid are adjusted to remain
+ * valid for the new topology type.
+ *
+ * When converting from a lower order topology to a higher order
+ * topology type (e.g. Hexahedron to Hexahedron_64) additional points
+ * are added to the mesh, no additional elements are added. When
+ * converting from a higher order topology to a lower order topology
+ * type (e.h. Hexahedron_64 to Hexahedron) elements are tesselated to
+ * form the new topology, no additional points are added.
+ *
+ * Currently supported conversions:
+ *   Hexahedron to Hexahedron_27
+ *   Hexahedron to Hexahedron_64
+ *   Hexahedron to Hexahedron_125
+ *   Hexahedron to Hexahedron_216
+ *   Hexahedron to Hexahedron_343
+ *   Hexahedron to Hexahedron_512
+ *   Hexahedron to Hexahedron_729
+ *   Hexahedron to Hexahedron_1000
+ *   Hexahedron to Hexahedron_1331
+ *   Hexahedron to Hexahedron_Spectral_64
+ *   Hexahedron to Hexahedron_Spectral_125
+ *   Hexahedron to Hexahedron_Spectral_216
+ *   Hexahedron to Hexahedron_Spectral_343
+ *   Hexahedron to Hexahedron_Spectral_512
+ *   Hexahedron to Hexahedron_Spectral_729
+ *   Hexahedron to Hexahedron_Spectral_1000
+ *   Hexahedron to Hexahedron_Spectral_1331
+ *   Hexahedron_64 to Hexahedron
+ *   Hexahedron_125 to Hexahedron
+ *   Hexahedron_216 to Hexahedron
+ *   Hexahedron_343 to Hexahedron
+ *   Hexahedron_512 to Hexahedron
+ *   Hexahedron_729 to Hexahedron
+ *   Hexahedron_1000 to Hexahedron
+ *   Hexahedron_1331 to Hexahedron
+ *   Hexahedron_Spectral_64 to Hexahedron
+ *   Hexahedron_Spectral_125 to Hexahedron
+ *   Hexahedron_Spectral_216 to Hexahedron
+ *   Hexahedron_Spectral_343 to Hexahedron
+ *   Hexahedron_Spectral_512 to Hexahedron
+ *   Hexahedron_Spectral_729 to Hexahedron
+ *   Hexahedron_Spectral_1000 to Hexahedron
+ *   Hexahedron_Spectral_1331 to Hexahedron
+ */
+class XDMFUTILS_EXPORT XdmfTopologyConverter {
+
+public:
+
+  /**
+   * Create a new XdmfTopologyConverter.
+   *
+   * @return constructed XdmfTopologyConverter.
+   */
+  static shared_ptr<XdmfTopologyConverter> New();
+
+  virtual ~XdmfTopologyConverter();
+
+  /**
+   * Converts an unstructured grid to a different topology type
+   *
+   * @param gridToConvert the unstructured grid to convert to a different
+   * topology
+   * @param topologyType the topology type to convert to.
+   * @param heavyDataWriter an heavy data writer to write the converted mesh
+   * to. If no heavyDataWriter is specified, all mesh data will remain in
+   * memory.
+   *
+   * @return the converted unstructured grid.
+   */
+  shared_ptr<XdmfUnstructuredGrid>
+  convert(const shared_ptr<XdmfUnstructuredGrid> gridToConvert,
+          const shared_ptr<const XdmfTopologyType> topologyType,
+          const shared_ptr<XdmfHeavyDataWriter> heavyDataWriter = shared_ptr<XdmfHeavyDataWriter>()) const;
+
+  /**
+   * Gets all faces within the given topology. Removing duplicates.
+   *
+   * @param     convertedTopology       The topology to be deconstructed
+   * @return                            A topology containing the faces from the deconstructed topology
+   */
+  shared_ptr<XdmfTopology>
+  getExternalFaces(const shared_ptr<XdmfTopology> convertedTopology);
+
+  XdmfTopologyConverter(const XdmfTopologyConverter &);
+
+protected:
+
+  XdmfTopologyConverter();
+
+private:
+
+  void insertInHash(std::vector<long> nodes,
+                    std::vector<std::vector<std::vector<long> > > & hash,
+                    unsigned int numCornerNodes);
+
+  void operator=(const XdmfTopologyConverter &);  // Not implemented.
+
+};
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// C wrappers go here
+
+struct XDMFTOPOLOGYCONVERTER; // Simply as a typedef to ensure correct typing
+typedef struct XDMFTOPOLOGYCONVERTER XDMFTOPOLOGYCONVERTER;
+
+XDMFUTILS_EXPORT XDMFTOPOLOGYCONVERTER * XdmfTopologyConverterNew();
+
+XDMFUTILS_EXPORT XDMFUNSTRUCTUREDGRID * XdmfTopologyConverterConvert(XDMFTOPOLOGYCONVERTER * converter,
+                                                                     XDMFUNSTRUCTUREDGRID * gridToConvert,
+                                                                     int topologytype,
+                                                                     XDMFHEAVYDATAWRITER * heavyDataWriter);
+
+XDMFUTILS_EXPORT XDMFTOPOLOGY * XdmfTopologyConverterGetExternalFaces(XDMFTOPOLOGYCONVERTER * converter,
+                                                                      XDMFTOPOLOGY * convertedTopology);
+
+XDMFUTILS_EXPORT void XdmfTopologyConverterFree(XDMFTOPOLOGYCONVERTER * converter);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* XDMFTOPOLOGYCONVERTER_HPP_ */
diff --git a/utils/XdmfUtils.hpp b/utils/XdmfUtils.hpp
new file mode 100644
index 0000000..c5b0b87
--- /dev/null
+++ b/utils/XdmfUtils.hpp
@@ -0,0 +1,77 @@
+/*****************************************************************************/
+/*                                    XDMF                                   */
+/*                       eXtensible Data Model and Format                    */
+/*                                                                           */
+/*  Id : Xdmf.hpp                                                            */
+/*                                                                           */
+/*  Author:                                                                  */
+/*     Kenneth Leiter                                                        */
+/*     kenneth.leiter at arl.army.mil                                           */
+/*     US Army Research Laboratory                                           */
+/*     Aberdeen Proving Ground, MD                                           */
+/*                                                                           */
+/*     Copyright @ 2011 US Army Research Laboratory                          */
+/*     All Rights Reserved                                                   */
+/*     See Copyright.txt for details                                         */
+/*                                                                           */
+/*     This software is distributed WITHOUT ANY WARRANTY; without            */
+/*     even the implied warranty of MERCHANTABILITY or FITNESS               */
+/*     FOR A PARTICULAR PURPOSE.  See the above copyright notice             */
+/*     for more information.                                                 */
+/*                                                                           */
+/*****************************************************************************/
+
+#ifndef _XDMFUTILS_HPP
+#define _XDMFUTILS_HPP
+
+/* Keep all our Win32 Conversions here */
+#ifdef _WIN32
+/* Used to export/import from the dlls */
+#undef XDMFCORE_EXPORT
+#define XDMFCORE_EXPORT __declspec(dllimport)
+#undef XDMFCORE_TEMPLATE
+#define XDMFCORE_TEMPLATE extern
+
+#undef XDMFDSM_EXPORT
+#define XDMFDSM_EXPORT __declspec(dllimport)
+#undef XDMFDSM_TEMPLATE
+#define XDMFDSM_TEMPLATE extern
+
+#undef XDMF_EXPORT
+#define XDMF_EXPORT __declspec(dllimport)
+#undef XDMF_TEMPLATE
+#define XDMF_TEMPLATE extern
+
+#ifdef XdmfUtils_EXPORTS
+#define XDMFUTILS_EXPORT __declspec(dllexport)
+#define XDMFUTILS_TEMPLATE
+#else /* XdmfUtils_EXPORTS */
+#define XDMFUTILS_EXPORT __declspec(dllimport)
+#define XDMFUTILS_TEMPLATE extern
+#endif /* XdmfUtils_EXPORTS */
+
+/* Compiler Warnings */
+#ifndef XDMF_DEBUG
+#pragma warning( disable : 4231 ) /* nonstandard extension used : 'extern' before template explicit instantiation */
+#pragma warning( disable : 4251 ) /* needs to have dll-interface to be used by clients (Most of these guys are in private */
+#pragma warning( disable : 4275 ) /* non dll-interface class 'std::_Container_base_aux' used as base for dll-interface class */
+#pragma warning( disable : 4373 ) /* virtual function overrides,  parameters only differed by const/volatile qualifiers */
+#pragma warning( disable : 4748 ) /* /GS can not protect parameters and local variables from local buffer overrun (turned off op)*/
+#endif /* XDMF_DEBUG */
+
+/* Compiler Optimizations will result in an 'internal compiler error', so turn them off */
+#pragma optimize("g", off)
+
+#else /* _WIN32 */
+/* We don't need to export/import since there are no dlls */
+#define XDMFCORE_EXPORT
+#define XDMFDSM_EXPORT
+#define XDMF_EXPORT
+#define XDMFUTILS_EXPORT
+#define XDMFCORE_TEMPLATE
+#define XDMFDSM_TEMPLATE
+#define XDMF_TEMPLATE
+#define XDMFUTILS_TEMPLATE
+
+#endif /* _WIN32 */
+#endif /* _XDMFUTILS_HPP */
diff --git a/utils/XdmfUtils.i b/utils/XdmfUtils.i
new file mode 100644
index 0000000..dde84f9
--- /dev/null
+++ b/utils/XdmfUtils.i
@@ -0,0 +1,246 @@
+/*
+XdmfUtilsPython.cpp:
+swig -v -c++ -python -o XdmfUtilsPython.cpp XdmfUtils.i
+*/
+
+#ifdef XDMF_BUILD_DSM
+
+%module XdmfUtils
+%{
+    // MPI includes
+    #include <mpi.h>
+
+    // XdmfCore Includes
+    #include <XdmfArray.hpp>
+    #include <XdmfArrayReference.hpp>
+    #include <XdmfArrayType.hpp>
+    #include <XdmfCoreItemFactory.hpp>
+    #include <XdmfCoreReader.hpp>
+    #include <XdmfError.hpp>
+    #include <XdmfFunction.hpp>
+    #include <XdmfDSMBuffer.hpp>
+    #include <XdmfDSMCommMPI.hpp>
+    #include <XdmfDSMItemFactory.hpp>
+    #include <XdmfHDF5Controller.hpp>
+    #include <XdmfHDF5Writer.hpp>
+    #include <XdmfHDF5ControllerDSM.hpp>
+    #include <XdmfHDF5WriterDSM.hpp>
+    #include <XdmfHeavyDataController.hpp>
+    #include <XdmfHeavyDataWriter.hpp>
+    #include <XdmfInformation.hpp>
+    #include <XdmfItem.hpp>
+    #include <XdmfItemProperty.hpp>
+    #include <XdmfSharedPtr.hpp>
+    #include <XdmfSparseMatrix.hpp>
+    #include <XdmfSubset.hpp>
+    #include <XdmfSystemUtils.hpp>
+    #include <XdmfTIFFController.hpp>
+    #include <XdmfVisitor.hpp>
+    #include <XdmfWriter.hpp>
+
+    // Xdmf Includes
+    #include <XdmfAggregate.hpp>
+    #include <XdmfAttribute.hpp>
+    #include <XdmfAttributeCenter.hpp>
+    #include <XdmfAttributeType.hpp>
+    #include <XdmfCurvilinearGrid.hpp>
+    #include <XdmfDomain.hpp>
+    #include <XdmfGeometry.hpp>
+    #include <XdmfGeometryType.hpp>
+    #include <XdmfGraph.hpp>
+    #include <XdmfGrid.hpp>
+    #include <XdmfGridCollection.hpp>
+    #include <XdmfGridCollectionType.hpp>
+    #include <XdmfItemFactory.hpp>
+    #include <XdmfMap.hpp>
+    #include <XdmfReader.hpp>
+    #include <XdmfRectilinearGrid.hpp>
+    #include <XdmfRegularGrid.hpp>
+    #include <XdmfSet.hpp>
+    #include <XdmfSetType.hpp>
+    #include <XdmfTime.hpp>
+    #include <XdmfTopology.hpp>
+    #include <XdmfTopologyType.hpp>
+    #include <XdmfUnstructuredGrid.hpp>
+
+    // XdmfUtils Includes
+    #include <XdmfUtils.hpp>
+    #include <XdmfDiff.hpp>
+    #include <XdmfExodusReader.hpp>
+    #include <XdmfExodusWriter.hpp>
+    #include <XdmfPartitioner.hpp>
+    #include <XdmfGeometryConverter.hpp>
+    #include <XdmfTopologyConverter.hpp>
+%}
+
+#else
+
+%module XdmfUtils
+%{
+    // XdmfCore Includes
+    #include <XdmfArray.hpp>
+    #include <XdmfArrayReference.hpp>
+    #include <XdmfArrayType.hpp>
+    #include <XdmfCoreItemFactory.hpp>
+    #include <XdmfCoreReader.hpp>
+    #include <XdmfError.hpp>
+    #include <XdmfFunction.hpp>
+    #include <XdmfHDF5Controller.hpp>
+    #include <XdmfHDF5Writer.hpp>
+    #include <XdmfHeavyDataController.hpp>
+    #include <XdmfHeavyDataWriter.hpp>
+    #include <XdmfInformation.hpp>
+    #include <XdmfItem.hpp>
+    #include <XdmfItemProperty.hpp>
+    #include <XdmfSharedPtr.hpp>
+    #include <XdmfSparseMatrix.hpp>
+    #include <XdmfSubset.hpp>
+    #include <XdmfSystemUtils.hpp>
+    #include <XdmfTIFFController.hpp>
+    #include <XdmfVisitor.hpp>
+    #include <XdmfWriter.hpp>
+
+    // Xdmf Includes
+    #include <XdmfAggregate.hpp>
+    #include <XdmfAttribute.hpp>
+    #include <XdmfAttributeCenter.hpp>
+    #include <XdmfAttributeType.hpp>
+    #include <XdmfCurvilinearGrid.hpp>
+    #include <XdmfDomain.hpp>
+    #include <XdmfGeometry.hpp>
+    #include <XdmfGeometryType.hpp>
+    #include <XdmfGraph.hpp>
+    #include <XdmfGrid.hpp>
+    #include <XdmfGridCollection.hpp>
+    #include <XdmfGridCollectionType.hpp>
+    #include <XdmfItemFactory.hpp>
+    #include <XdmfMap.hpp>
+    #include <XdmfReader.hpp>
+    #include <XdmfRectilinearGrid.hpp>
+    #include <XdmfRegularGrid.hpp>
+    #include <XdmfSet.hpp>
+    #include <XdmfSetType.hpp>
+    #include <XdmfTime.hpp>
+    #include <XdmfTopology.hpp>
+    #include <XdmfTopologyType.hpp>
+    #include <XdmfUnstructuredGrid.hpp>
+
+    // XdmfUtils Includes
+    #include <XdmfUtils.hpp>
+    #include <XdmfDiff.hpp>
+    #include <XdmfExodusReader.hpp>
+    #include <XdmfExodusWriter.hpp>
+    #include <XdmfPartitioner.hpp>
+    #include <XdmfGeometryConverter.hpp>
+    #include <XdmfTopologyConverter.hpp>
+%}
+
+#endif
+
+%import Xdmf.i
+
+// Ignoring C Wrappers
+
+// XdmfDiff
+
+%ignore XdmfDiffNew();
+%ignore XdmfDiffCompare(XDMFDIFF * diff, XDMFITEM * item1, XDMFITEM * item2);
+%ignore XdmfDiffGetAbsoluteTolerance(XDMFDIFF * diff);
+%ignore XdmfDiffSetAbsoluteTolerance(XDMFDIFF * diff, double tolerance);
+%ignore XdmfDiffFree(XDMFDIFF * diff);
+
+// XdmfExodusReader
+
+%ignore XdmfExodusReaderNew();
+%ignore XdmfExodusReaderRead(XDMFEXODUSREADER * reader, char * fileName, XDMFHEAVYDATAWRITER * heavyDataWriter);
+%ignore XdmfExodusReaderFree(XDMFEXODUSREADER * reader);
+
+// XdmfExodusWriter
+
+%ignore XdmfExodusWriterNew();
+%ignore XdmfExodusWriterWriteGrid(XDMFEXODUSWRITER * writer,
+                                  char * filePath,
+                                  XDMFUNSTRUCTUREDGRID * grid,
+                                  int * status);
+%ignore XdmfExodusWriterWriteGridCollection(XDMFEXODUSWRITER * writer,
+                                            char * filePath,
+                                            XDMFGRIDCOLLECTION * grid,
+                                            int * status);
+%ignore XdmfExodusWriterFree(XDMFEXODUSWRITER * writer);
+
+// XdmfGeometryConverter
+
+%ignore XdmfGeometryConverterNew();
+%ignore XdmfGeometryConverterConvertToCartesian(XDMFGEOMETRYCONVERTER * converter,
+                                                XDMFGEOMETRY * geometryToConvert);
+%ignore XdmfGeometryConverterConvertToSpherical(XDMFGEOMETRYCONVERTER * converter,
+                                                XDMFGEOMETRY * geometryToConvert);
+%ignore XdmfGeometryConverterConvertToCartesianOverwrite(XDMFGEOMETRYCONVERTER * converter,
+                                                         XDMFGEOMETRY * geometryToConvert);
+%ignore XdmfGeometryConverterConvertToSphericalOverwrite(XDMFGEOMETRYCONVERTER * converter,
+                                                         XDMFGEOMETRY * geometryToConvert);
+%ignore XdmfGeometryConverterZeroOrigin(XDMFGEOMETRYCONVERTER * converter,
+                                        XDMFGEOMETRY * geometryToConvert);
+%ignore XdmfGeometryConverterZeroOriginOverwrite(XDMFGEOMETRYCONVERTER * converter,
+                                                 XDMFGEOMETRY * geometryToConvert);
+%ignore XdmfGeometryConverterFree(XDMFGEOMETRYCONVERTER * converter);
+
+// XdmfPartitioner
+
+%ignore XdmfPartitionerNew();
+%ignore XdmfPartitionerIgnore(XDMFPARTITIONER * partitioner,
+                              XDMFSET * set);
+%ignore XdmfPartitionerPartitionGraph(XDMFPARTITIONER * partitioner,
+                                      XDMFGRAPH * graphToPartition,
+                                      unsigned int numberOfPartitions);
+%ignore XdmfPartitionerPartitionUnstructuredGrid(XDMFPARTITIONER * partitioner,
+                                                 XDMFUNSTRUCTUREDGRID * gridToPartition,
+                                                 unsigned int numberOfPartitions,
+                                                 int metisScheme,
+                                                 XDMFHEAVYDATAWRITER * heavyDataWriter);
+%ignore XdmfPartitionerUnpartition(XDMFPARTITIONER * partitioner,
+                                   XDMFGRIDCOLLECTION * gridToUnPartition);
+%ignore XdmfPartitionerFree(XDMFPARTITIONER * partitioner);
+
+// XdmfTopologyConverter
+
+%ignore XdmfTopologyConverterNew();
+%ignore XdmfTopologyConverterConvert(XDMFTOPOLOGYCONVERTER * converter,
+                                     XDMFUNSTRUCTUREDGRID * gridToConvert,
+                                     int topologytype,
+                                     XDMFHEAVYDATAWRITER * heavyDataWriter);
+%ignore XdmfTopologyConverterGetExternalFaces(XDMFTOPOLOGYCONVERTER * converter,
+                                              XDMFTOPOLOGY * convertedTopology);
+%ignore XdmfTopologyConverterFree(XDMFTOPOLOGYCONVERTER * converter);
+
+#ifdef SWIGPYTHON
+
+%pythoncode {
+    from Xdmf import *
+}
+
+#endif /* SWIGPYTHON */
+
+// Shared Pointer Templates
+%shared_ptr(XdmfDiff)
+#ifdef XDMF_BUILD_EXODUS_IO
+    %shared_ptr(XdmfExodusReader)
+    %shared_ptr(XdmfExodusWriter)
+#endif
+#ifdef XDMF_BUILD_PARTITIONER
+    %shared_ptr(XdmfPartitioner)
+#endif
+%shared_ptr(XdmfGeometryConverter)
+%shared_ptr(XdmfTopologyConverter)
+
+%include XdmfUtils.hpp
+%include XdmfDiff.hpp
+#ifdef XDMF_BUILD_EXODUS_IO
+    %include XdmfExodusReader.hpp
+    %include XdmfExodusWriter.hpp
+#endif
+#ifdef XDMF_BUILD_PARTITIONER
+    %include XdmfPartitioner.hpp
+#endif
+%include XdmfGeometryConverter.hpp
+%include XdmfTopologyConverter.hpp
diff --git a/utils/tests/C/CMakeLists.txt b/utils/tests/C/CMakeLists.txt
new file mode 100644
index 0000000..2477eee
--- /dev/null
+++ b/utils/tests/C/CMakeLists.txt
@@ -0,0 +1,40 @@
+# Include our test macros
+include(AddTestsC)
+
+# Add any dependencies that the c core tests may need
+# Note: The tests already depend on their own file
+ADD_TEST_C_DEPENDENCIES("Xdmf")
+ADD_TEST_C_DEPENDENCIES("XdmfUtils")
+
+# Add any ldpath directories that the cxx tests may need
+ADD_TEST_C_LDPATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_LDPATH("${XDMF_LIBRARY_DIRS}")
+
+# Add any path directoreis that the Cxx tests may need
+ADD_TEST_C_PATH("${CMAKE_BINARY_DIR}")
+ADD_TEST_C_PATH("${XDMF_BINARIES}")
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (ie: ADD_TEST_C(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if (XDMF_BUILD_EXODUS_IO)
+  ADD_TEST_C(CTestXdmfExodusIO)
+endif (XDMF_BUILD_EXODUS_IO)
+ADD_TEST_C(CTestXdmfDiff)
+ADD_TEST_C(CTestXdmfGeometryConverter)
+ADD_TEST_C(CTestXdmfTopologyConverter)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_C(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if (XDMF_BUILD_EXODUS_IO)
+  CLEAN_TEST_C(CTestXdmfExodusIO
+    TestXdmfExodusIO.exo)
+endif (XDMF_BUILD_EXODUS_IO)
+CLEAN_TEST_C(CTestXdmfDiff)
+CLEAN_TEST_C(CTestXdmfGeometryConverter)
+CLEAN_TEST_C(CTestXdmfTopologyConverter)
diff --git a/utils/tests/C/CTestXdmfDiff.c b/utils/tests/C/CTestXdmfDiff.c
new file mode 100644
index 0000000..d4ff77e
--- /dev/null
+++ b/utils/tests/C/CTestXdmfDiff.c
@@ -0,0 +1,140 @@
+#include <math.h>
+#include "stdio.h"
+#include "string.h"
+#include "assert.h"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfDiff.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyConverter.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+int main()
+{
+  int status = 0;
+
+  XDMFUNSTRUCTUREDGRID * grid1 = XdmfUnstructuredGridNew();
+
+  XDMFTOPOLOGY * topology1 = XdmfTopologyNew();
+
+  int connectivity[16] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
+  XdmfTopologySetType(topology1, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, &status);
+  XdmfTopologyInsertDataFromPointer(topology1, connectivity, XDMF_ARRAY_TYPE_INT32, 0, 16, 1, 1, &status);
+
+  XdmfUnstructuredGridSetTopology(grid1, topology1, 1);
+
+  XDMFGEOMETRY * geometry1 = XdmfGeometryNew();
+
+  double points[36] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                       1.1, 1.1, 1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                       0.1, -1.1, 3.1, 0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                       -1.1, 3.1, 2.1, -2.1};
+  XdmfGeometrySetType(geometry1, XDMF_GEOMETRY_TYPE_XYZ, &status);
+  XdmfGeometryInsertDataFromPointer(geometry1, points, XDMF_ARRAY_TYPE_FLOAT64, 0, 36, 1, 1, &status);
+
+  XdmfUnstructuredGridSetGeometry(grid1, geometry1, 1);
+
+  XDMFATTRIBUTE * attr1 = XdmfAttributeNew();
+
+  int nodeValues[12] = {100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600,
+                        700};
+  XdmfAttributeSetName(attr1, "Nodal Attribute", &status);
+  XdmfAttributeSetType(attr1, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(attr1, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+  XdmfAttributeInsertDataFromPointer(attr1, nodeValues, XDMF_ARRAY_TYPE_INT32, 0, 12, 1, 1, &status);
+
+  XdmfUnstructuredGridInsertAttribute(grid1, attr1, 1);
+
+  // Grid with the same structure
+
+  XDMFUNSTRUCTUREDGRID * grid2 = XdmfUnstructuredGridNew();
+
+  XDMFTOPOLOGY * topology2 = XdmfTopologyNew();
+
+  XdmfTopologySetType(topology2, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, &status);
+  XdmfTopologyInsertDataFromPointer(topology2, connectivity, XDMF_ARRAY_TYPE_INT32, 0, 16, 1, 1, &status);
+
+  XdmfUnstructuredGridSetTopology(grid2, topology2, 1);
+
+  XDMFGEOMETRY * geometry2 = XdmfGeometryNew();
+
+  XdmfGeometrySetType(geometry2, XDMF_GEOMETRY_TYPE_XYZ, &status);
+  XdmfGeometryInsertDataFromPointer(geometry2, points, XDMF_ARRAY_TYPE_FLOAT64, 0, 36, 1, 1, &status);
+
+  XdmfUnstructuredGridSetGeometry(grid2, geometry2, 1);
+
+  XDMFATTRIBUTE * attr2 = XdmfAttributeNew();
+
+  XdmfAttributeSetName(attr2, "Nodal Attribute", &status);
+  XdmfAttributeSetType(attr2, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(attr2, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+  XdmfAttributeInsertDataFromPointer(attr2, nodeValues, XDMF_ARRAY_TYPE_INT32, 0, 12, 1, 1, &status);
+
+  XdmfUnstructuredGridInsertAttribute(grid2, attr2, 1);
+
+  // Grid with structure partially off, difference of 5.
+
+  XDMFUNSTRUCTUREDGRID * grid3 = XdmfUnstructuredGridNew();
+
+  XDMFTOPOLOGY * topology3 = XdmfTopologyNew();
+
+  XdmfTopologySetType(topology3, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, &status);
+  XdmfTopologyInsertDataFromPointer(topology3, connectivity, XDMF_ARRAY_TYPE_INT32, 0, 16, 1, 1, &status);
+
+  XdmfUnstructuredGridSetTopology(grid3, topology3, 1);
+
+  XDMFGEOMETRY * geometry3 = XdmfGeometryNew();
+
+  double pointsdiff[36] = {4.1, 0.1, 1.1, 1.1, 0.1, 3.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                           1.1, 1.1, 1.1, 1.1, 6.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                           0.1, -1.1, 3.1, 3.1, -4.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                           -1.1, 3.1, 2.1, -2.1};
+  XdmfGeometrySetType(geometry3, XDMF_GEOMETRY_TYPE_XYZ, &status);
+  XdmfGeometryInsertDataFromPointer(geometry3, pointsdiff, XDMF_ARRAY_TYPE_FLOAT64, 0, 36, 1, 1, &status);
+
+  XdmfUnstructuredGridSetGeometry(grid3, geometry3, 1);
+
+  XDMFATTRIBUTE * attr3 = XdmfAttributeNew();
+
+  XdmfAttributeSetName(attr3, "Nodal Attribute", &status);
+  XdmfAttributeSetType(attr3, XDMF_ATTRIBUTE_TYPE_SCALAR, &status);
+  XdmfAttributeSetCenter(attr3, XDMF_ATTRIBUTE_CENTER_NODE, &status);
+  XdmfAttributeInsertDataFromPointer(attr3, nodeValues, XDMF_ARRAY_TYPE_INT32, 0, 12, 1, 1, &status);
+
+  XdmfUnstructuredGridInsertAttribute(grid3, attr3, 1);
+
+  // Make diff checks
+
+  XDMFDIFF * diff = XdmfDiffNew();
+
+  if (!XdmfDiffCompare(diff, (XDMFITEM *)grid1, (XDMFITEM *)grid2))
+  {
+    printf("equivalent grids are not compared correctly\n");
+  }
+  assert(XdmfDiffCompare(diff, (XDMFITEM *)grid1, (XDMFITEM *)grid2));
+
+  if (XdmfDiffCompare(diff, (XDMFITEM *)grid1, (XDMFITEM *)grid3))
+  {
+    printf("dissimilar grids are not compared correctly\n");
+  }
+  assert(!XdmfDiffCompare(diff, (XDMFITEM *)grid1, (XDMFITEM *)grid3));
+
+  printf("default tolerance = %lf\n", XdmfDiffGetAbsoluteTolerance(diff));
+
+  XdmfDiffSetAbsoluteTolerance(diff, 6);
+
+  if (!XdmfDiffCompare(diff, (XDMFITEM *)grid1, (XDMFITEM *)grid3))
+  {
+    printf("tolerance is not applied correctly\n");
+  }
+  assert(XdmfDiffCompare(diff, (XDMFITEM *)grid1, (XDMFITEM *)grid3));
+
+  return 0;
+}
diff --git a/utils/tests/C/CTestXdmfExodusIO.c b/utils/tests/C/CTestXdmfExodusIO.c
new file mode 100644
index 0000000..71eabe8
--- /dev/null
+++ b/utils/tests/C/CTestXdmfExodusIO.c
@@ -0,0 +1,126 @@
+#include "XdmfDomain.hpp"
+#include "XdmfExodusReader.hpp"
+#include "XdmfExodusWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+
+#include "string.h"
+
+int main()
+{
+  int status = 0;
+
+  XDMFEXODUSWRITER * exodusWriter = XdmfExodusWriterNew();
+  XDMFUNSTRUCTUREDGRID * hexahedron = XdmfUnstructuredGridNew();
+  XdmfUnstructuredGridSetName(hexahedron, "Hexahedron");
+
+  // Set Geometry
+  double points[36] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                     1.1, 1.1, 1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                     0.1, -1.1, 3.1, 0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                     -1.1, 3.1, 2.1, -2.1};
+  XDMFGEOMTERY * hexGeometry = XdmfUnstructuredGridGetGeometry(hexahedron);
+  XdmfGeometrySetType(hexGeometry, XDMF_GEOMETRY_TYPE_XYZ);
+  XdmfGeometryInsertDataFromPointer(hexGeometry, &points[0], XDMF_ARRAY_TYPE_FLOAT64, 0, 36, 1, 1 &status);
+
+  // Set Topology
+  int connectivity[16] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
+  XDMFTOPOLOGY * hexTopology =  XdmfUnstructuredGridGetTopology(hexahedron);
+  XdmfTopologySetType(hexTopology, XDMF_TOPOLOGY_TYPE_HEXAHEDRON);
+  XdmfTopologyInsertDataFromPointer(hexTopology, &connectivity[0], XDMF_ARRAY_TYPE_INT32, 0, 16, 1, 1 &status);
+
+  // Add Node Attribute
+  XDMFATTRIBUTE * nodalAttribute = XdmfAttributeNew();
+  int nodeValues[12] = {100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600,
+                      700};
+  XdmfAttributeSetName(nodalAttribute, "Nodal Attribute");
+  XdmfAttributeSetType(nodalAttribute, XDMF_ATTRIBUTE_TYPE_SCALAR);
+  XdmfAttributeSetCenter(nodalAttribute, XDMF_ATTRIBUTE_CENTER_NODE);
+  XdmfAttributeInsertDataFromPointer(nodalAttribute, &nodeValues[0], XDMF_ARRAY_TYPE_INT32, 0, 12, 1, 1 &status);
+
+  // Add Cell Attribute
+  XDMFATTRIBUTE * cellAttribute = XdmfAttributeNew();
+  int cellValues[2] = {100, 200};
+  XdmfAttributeSetName(cellAttribute, "Cell Attribute");
+  XdmfAttributeSetType(cellAttribute, XDMF_ATTRIBUTE_TYPE_SCALAR);
+  XdmfAttributeSetCenter(cellAttribute, XDMF_ATTRIBUTE_CENTER_CELL);
+  XdmfAttributeInsertDataFromPointer(cellAttribute, &cellValues[0], XDMF_ARRAY_TYPE_INT32, 0, 2, 1, 1 &status);
+
+  // Add Grid Attribute
+  XDMFATTRIBUTE * gridAttribute = XdmfAttributeNew();
+  int gridValues[2] = {1, 2};
+  XdmfAttributeSetName(gridAttribute, "Grid Attribute");
+  XdmfAttributeSetType(gridAttribute, XDMF_ATTRIBUTE_TYPE_VECTOR);
+  XdmfAttributeSetCenter(gridAttribute, XDMF_ATTRIBUTE_CENTER_GRID);
+  XdmfAttributeInsertDataFromPointer(gridAttribute, &gridValues[0], XDMF_ARRAY_TYPE_INT32, 0, 2, 1, 1 &status);
+
+  // Add Node Set
+  XDMFSET * nodeSet = XdmfSetNew();
+  int nodeIds[3] = {0, 1, 2};
+  XdmfSetSetName(nodeSet, "Node Set");
+  XdmfSetSetType(nodeSet, XDMF_SET_TYPE_NODE);
+  XdmfSetInsertDataFromPointer(nodeSet, &nodeIds[0], XDMF_ARRAY_TYPE_INT32, 0, 3, 1, 1, &status);
+
+  // Add Node Set Attribute
+  double nodeSetAttributeValues[3] = {10, 11, 12};
+  XDMFATTRIBUTE * nodeSetAttribute = XdmfAttributeNew();
+  XdmfAttributeSetName(nodeSetAttribute, "Node Set Attribute");
+  XdmfAttributeSetType(nodeSetAttribute, XDMF_ATTRIBUTE_TYPE_SCALAR);
+  XdmfAttributeSetCenter(nodeSetAttribute, XDMF_ATTRIBUTE_CENTER_NODE);
+  XdmfAttributeInsertDataFromPointer(nodeSetAttribute, &nodeSetAttributeValues[0], XDMF_ARRAY_TYPE_FLOAT64, 0, 3, 1, 1 &status);
+  XdmfSetInsertAttribute(nodeSet, nodeSetAttribute);
+
+  // Add Time
+  XDMFTIME * time = XdmfTimeNew(100);
+  XdmfUnstructuredGridSetTime(hexahedron, time);
+
+  XdmfUnstructuredGridInsertAttribute(hexahedron, nodalAttribute);
+  XdmfUnstructuredGridInsertAttribute(hexahedron, cellAttribute);
+  XdmfUnstructuredGridInsertAttribute(hexahedron, gridAttribute);
+  XdmfUnstructuredGridInsertAttribute(hexahedron, nodeSet);
+
+  XdmfExodusWriterWrite(exodusWriter, "TestXdmfExodusIO.exo", hexahedron);
+
+  XDMFEXODUSREADER * reader = XdmfExodusReaderNew();
+  XDMFUNSTRUCTUREDGRID * grid =
+    (XDMFUNSTRUCTUREDGRID *)XdmfExodusReaderRead(reader, "TestXdmfExodusIO.exo");
+  XDMFGEOMETRY * readGeometry = XdmfUnstructuredGridGetGeometry(grid);
+  XDMFTOPOLOGY * readTopology = XdmfUnstructuredGridGetTopology(grid);
+  assert(strcmp(XdmfUnstructuredGridGetName(grid) == XdmfUnstructuredGridGetName(hexahedron)));
+  assert(XdmfGeometryGetType(XdmfUnstructuredGridGetGeometry(grid)) ==
+         XdmfGeometryGetType(hexGeometry));
+  assert(XdmfGeometryGetNumberPoints(XdmfUnstructuredGridGetGeometry(grid)) ==
+         XdmfGeometryGetNumberPoints(hexGeometry));
+  unsigned int i = 0;
+  unsigned int j = 0;
+  unsigned int geoSize = XdmfGeometryGetSize(hexGeometry);
+  for(i = 0; i < geoSize; ++i) {//TODO
+    assert(((double *)XdmfArrayGetValue(hexGeometry, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0] ==
+           ((double *)XdmfArrayGetValue(readGeometry, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0]);
+  }
+  assert(XdmfTopologyGetType(XdmfUnstructuredGridGetTopology(grid)) ==
+         XdmfTopologyGetType(hexTopology));
+  assert(XdmfTopologyGetNumberElements(XdmfUnstructuredGridGetTopology(grid)) ==
+         XdmfTopologyGetNumberElements(hexTopology));
+  unsigned int toposize = XdmfTopologyGetSize(hexTopology);
+  for(i = 0; i < toposize; ++i) {//TODO
+    assert(((double *)XdmfArrayGetValue(hexTopology, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0] ==
+           ((double *)XdmfArrayGetValue(readTopology, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0]);
+  }
+  assert(XdmfUnstructuredGridGetNumberAttributes(hexahedron) + 2 == XdmfUnstructuredGridGetNumberAttributes(grid));
+  unsigned int numAttr = XdmfUnstructuredGridGetNumberAttributes(hexahedron);
+  for(i = 0; i < numAttr; ++i) {//TODO
+    XDMFATTRIBUTE * attribute1 = XdmfUnstructuredGridGetAttribute(hexahedron, i);
+    if(attribute1->getCenter() != XdmfAttributeCenter::Grid()) {
+      XDMFATTRIBUTE * attribute2 = XdmfUnstructuredGridGetAttributeByName(grid, XdmfAttributeGetName(attribute1));
+      assert(XdmfAttributeGetCenter(attribute1, &status) == XdmfAttributeGetCenter(attribute2, &status));
+      assert(XdmfAttributeGetType(attribute1, &status) == XdmfAttributeGetType(attribute2, &status));
+      assert(XdmfAttributeGetSize(attribute1) == XdmfAttributeGetSize(attribute2));
+      unsigned int attrSize = XdmfAttributeGetSize(attribute1);
+      for (j = 0; j < attrSize; ++j) {
+        assert(((double *)XdmfArrayGetValue(attribute1, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0] ==
+               ((double *)XdmfArrayGetValue(attribute2, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0]);
+      }
+    }
+  }
+}
diff --git a/utils/tests/C/CTestXdmfGeometryConverter.c b/utils/tests/C/CTestXdmfGeometryConverter.c
new file mode 100644
index 0000000..bb57e56
--- /dev/null
+++ b/utils/tests/C/CTestXdmfGeometryConverter.c
@@ -0,0 +1,129 @@
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGeometryConverter.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+#include "stdio.h"
+#include "math.h"
+#include "assert.h"
+
+double Pi = 3.1415926535897932384626433832795;
+
+int main()
+{
+  int status = 0;
+  unsigned int i = 0;
+
+  XDMFGEOMETRYCONVERTER * converter = XdmfGeometryConverterNew();
+
+  XDMFGEOMETRY * cartesianGeo = XdmfGeometryNew();
+
+  XdmfGeometrySetType(cartesianGeo, XDMF_GEOMETRY_TYPE_XYZ, &status);
+
+  for (i = 0; i < 3; ++i)
+  {
+    double pushval = 1;
+    XdmfGeometryPushBack(cartesianGeo, &pushval, XDMF_ARRAY_TYPE_FLOAT64, &status);
+  }
+
+  XDMFGEOMETRY * resultSphericalGeo = XdmfGeometryConverterConvertToSpherical(converter, cartesianGeo);
+
+  XDMFGEOMETRY * sphericalGeo = XdmfGeometryNew();
+
+  XdmfGeometrySetType(sphericalGeo, XDMF_GEOMETRY_TYPE_SPHERICAL, &status);
+
+  double value = sqrt(3);
+
+  XdmfGeometryPushBack(sphericalGeo, &value, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  value = asin(sqrt((double)2/3));
+
+  XdmfGeometryPushBack(sphericalGeo, &value, XDMF_ARRAY_TYPE_FLOAT64, &status); // should be equal to std::acos(1/std::sqrt(3))
+
+  value = Pi/4;
+
+  XdmfGeometryPushBack(sphericalGeo, &value, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  printf("Tolerance 10^-15\nresult\n%s\n?=\ncompare to\n%s\n", XdmfGeometryGetValuesString(resultSphericalGeo), XdmfGeometryGetValuesString(sphericalGeo));
+
+  for (i = 0; i < XdmfGeometryGetSize(sphericalGeo); ++i)
+  {
+    double val1 = ((double *)XdmfGeometryGetValue(resultSphericalGeo, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    double val2 = ((double *)XdmfGeometryGetValue(sphericalGeo, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    val1 = floor(val1 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    val2 = floor(val2 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    printf("%4.15f ?= %4.15f\n", val1, val2);
+    assert(val1 == val2);
+  }
+
+  XDMFGEOMETRY * resultCartesianGeo = XdmfGeometryConverterConvertToCartesian(converter, sphericalGeo);
+
+  printf("%s\n?=\n%s\n", XdmfGeometryGetValuesString(resultCartesianGeo), XdmfGeometryGetValuesString(cartesianGeo));
+
+  for (i = 0; i < XdmfGeometryGetSize(cartesianGeo); ++i)
+  {
+    double val1 = ((double *)XdmfGeometryGetValue(resultCartesianGeo, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    double val2 = ((double *)XdmfGeometryGetValue(cartesianGeo, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    val1 = floor(val1 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    val2 = floor(val2 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    printf("%4.15f ?= %4.15f\n", val1, val2);
+    assert(val1 == val2);
+  }
+
+  // Convert in place for geometries with a lot of references
+
+  XDMFGEOMETRY * convertedToSpherical = XdmfGeometryNew();
+
+  XdmfGeometrySetType(convertedToSpherical, XDMF_GEOMETRY_TYPE_XYZ, &status);
+
+  for (i = 0; i < 3; ++i)
+  {
+    double pushval = 1;
+    XdmfGeometryPushBack(convertedToSpherical, &pushval, XDMF_ARRAY_TYPE_FLOAT64, &status);
+  }
+
+  XdmfGeometryConverterConvertToSphericalOverwrite(converter, convertedToSpherical);
+
+  for (i = 0; i < XdmfGeometryGetSize(sphericalGeo); ++i)
+  {
+    double val1 = ((double *)XdmfGeometryGetValue(convertedToSpherical, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    double val2 = ((double *)XdmfGeometryGetValue(sphericalGeo, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    val1 = floor(val1 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    val2 = floor(val2 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    printf("%4.15f ?= %4.15f\n", val1, val2);
+    assert(val1 == val2);
+  }
+
+  XDMFGEOMETRY * convertedToCartesian = XdmfGeometryNew();
+
+  XdmfGeometrySetType(convertedToCartesian, XDMF_GEOMETRY_TYPE_SPHERICAL, &status);
+
+  value = sqrt(3);
+
+  XdmfGeometryPushBack(convertedToCartesian, &value, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  value = asin(sqrt((double)2/3));
+
+  XdmfGeometryPushBack(convertedToCartesian, &value, XDMF_ARRAY_TYPE_FLOAT64, &status); // should be equal to std::acos(1/std::sqrt(3))
+
+  value = Pi/4;
+
+  XdmfGeometryPushBack(convertedToCartesian, &value, XDMF_ARRAY_TYPE_FLOAT64, &status);
+
+  XdmfGeometryConverterConvertToCartesianOverwrite(converter, convertedToCartesian);
+
+  for (i = 0; i < XdmfGeometryGetSize(cartesianGeo); ++i)
+  {
+    double val1 = ((double *)XdmfGeometryGetValue(convertedToCartesian, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    double val2 = ((double *)XdmfGeometryGetValue(cartesianGeo, i, XDMF_ARRAY_TYPE_FLOAT64, &status))[0];
+    val1 = floor(val1 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    val2 = floor(val2 * pow((double)10, (double)15) + 0.5) / pow((double)10, (double)15);
+    printf("%4.15f ?= %4.15f\n", val1, val2);
+    assert(val1 == val2);
+  }
+
+  return 0;
+}
diff --git a/utils/tests/C/CTestXdmfTopologyConverter.c b/utils/tests/C/CTestXdmfTopologyConverter.c
new file mode 100644
index 0000000..f9ea5ef
--- /dev/null
+++ b/utils/tests/C/CTestXdmfTopologyConverter.c
@@ -0,0 +1,178 @@
+#include <math.h>
+#include "stdio.h"
+#include "string.h"
+#include "assert.h"
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyConverter.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+int main()
+{
+  int status = 0;
+  unsigned int i = 0;
+
+  XDMFTOPOLOGYCONVERTER * converter =
+    XdmfTopologyConverterNew();
+
+  // Create Hexahedron Grid
+  XDMFUNSTRUCTUREDGRID * hexGrid =
+    XdmfUnstructuredGridNew();
+  double hexPoints[24] = {0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0,
+                          1, 1, 1, 1, 0, 1, 1};
+  int hexdims[1] = {24};
+  XDMFGEOMETRY * hexGeometry = XdmfUnstructuredGridGetGeometry(hexGrid);
+  XdmfGeometrySetType(hexGeometry, XDMF_GEOMETRY_TYPE_XYZ, &status);
+  XdmfGeometryResize(hexGeometry, hexdims, 1, XDMF_ARRAY_TYPE_FLOAT64, &status);
+  XdmfGeometryInsertDataFromPointer(hexGeometry, hexPoints, XDMF_ARRAY_TYPE_FLOAT64, 0, 24, 1, 1, &status);
+  XDMFTOPOLOGY * hexTopology = XdmfUnstructuredGridGetTopology(hexGrid);
+  unsigned int hexConn[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+  hexdims[0] = 8;
+  XdmfTopologySetType(hexTopology, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, &status);
+  XdmfTopologyResize(hexTopology, hexdims, 1, XDMF_ARRAY_TYPE_UINT32, &status);
+  XdmfTopologyInsertDataFromPointer(hexTopology, hexConn, XDMF_ARRAY_TYPE_UINT32, 0, 8, 1, 1, &status);
+
+  /*
+   * Hexahedron to Hexahedron_64
+   */
+  XDMFUNSTRUCTUREDGRID * hex64Grid =
+    XdmfTopologyConverterConvert(converter, hexGrid, XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64, NULL);
+  XDMFGEOMETRY * hex64Geometry = XdmfUnstructuredGridGetGeometry(hex64Grid);
+  assert(XdmfGeometryGetType(hex64Geometry) == XDMF_GEOMETRY_TYPE_XYZ);
+  assert(XdmfGeometryGetNumberPoints(hex64Geometry) == 64);
+  XDMFTOPOLOGY * hex64Topology = XdmfUnstructuredGridGetTopology(hex64Grid);
+  assert(XdmfTopologyGetType(hex64Topology) ==
+         XDMF_TOPOLOGY_TYPE_HEXAHEDRON_64);
+  assert(XdmfTopologyGetNumberElements(hex64Topology, &status) == 1);
+  for(i = 0; i < 64; ++i) {
+    assert(i == ((unsigned int *)XdmfTopologyGetValue(hex64Topology, i, XDMF_ARRAY_TYPE_UINT32, &status))[0]);
+  }
+
+  /*
+   * Hexahedron to Hexahedron_125
+   */
+  XDMFUNSTRUCTUREDGRID * hex125Grid =
+    XdmfTopologyConverterConvert(converter, hexGrid, XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125, NULL);
+
+  XDMFGEOMETRY * hex125Geometry = XdmfUnstructuredGridGetGeometry(hex125Grid);
+  assert(XdmfGeometryGetType(hex125Geometry) == XDMF_GEOMETRY_TYPE_XYZ);
+  assert(XdmfGeometryGetNumberPoints(hex125Geometry) == 125);
+  XDMFTOPOLOGY * hex125Topology = XdmfUnstructuredGridGetTopology(hex125Grid);
+  assert(XdmfTopologyGetType(hex125Topology) ==
+         XDMF_TOPOLOGY_TYPE_HEXAHEDRON_125);  
+  assert(XdmfTopologyGetNumberElements(hex125Topology, &status) == 1);
+  for(i=0; i<125; ++i) {
+    assert(i == ((unsigned int *)XdmfTopologyGetValue(hex125Topology, i, XDMF_ARRAY_TYPE_UINT32, &status))[0]);
+  }
+
+  /*
+   * Hexahedron_64 to Hexahedron
+   */
+  XDMFUNSTRUCTUREDGRID * newHexGrid =
+    XdmfTopologyConverterConvert(converter, hex64Grid, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, NULL);
+
+  XDMFGEOMETRY * newHexGeometry = XdmfUnstructuredGridGetGeometry(newHexGrid);
+  assert(XdmfGeometryGetType(newHexGeometry) == XDMF_GEOMETRY_TYPE_XYZ);
+  assert(XdmfGeometryGetNumberPoints(newHexGeometry) == 64);
+  XDMFTOPOLOGY * newHexTopology = XdmfUnstructuredGridGetTopology(newHexGrid);
+  assert(XdmfTopologyGetType(newHexTopology) ==
+         XDMF_TOPOLOGY_TYPE_HEXAHEDRON);
+  assert(XdmfTopologyGetNumberElements(newHexTopology, &status) == 27);
+
+
+  XDMFTOPOLOGY * faceTopology;
+
+  /**
+   * Tetrahedron to Triangle
+   */
+  XDMFTOPOLOGY * tetTopology = XdmfTopologyNew();
+  XdmfTopologySetType(tetTopology, XDMF_TOPOLOGY_TYPE_TETRAHEDRON, &status);
+  long tetValues[8] = {0, 1, 2, 3, 0, 1, 2, 4};// temporary
+  XdmfTopologyInsertDataFromPointer(tetTopology, tetValues, XDMF_ARRAY_TYPE_INT64, 0, 8, 1, 1, &status);
+  printf("tetrahedrons prior to splitting into faces \n%s\n", XdmfTopologyGetValuesString(tetTopology));
+  faceTopology = XdmfTopologyConverterGetExternalFaces(converter, tetTopology);
+  printf("after splitting into faces\n%s\n", XdmfTopologyGetValuesString(faceTopology));
+  assert(strcmp(XdmfTopologyGetValuesString(faceTopology), "0 1 3 "
+                                                           "0 3 2 "
+                                                           "0 1 4 "
+                                                           "0 4 2 "
+                                                           "1 2 3 "
+                                                           "1 2 4") == 0);
+
+  XdmfTopologyFree(faceTopology);
+
+  /**
+   * Tetrahedron_10 to Triangle_6
+   */
+  XDMFTOPOLOGY * tet10Topology = XdmfTopologyNew();
+  XdmfTopologySetType(tet10Topology, XDMF_TOPOLOGY_TYPE_TETRAHEDRON_10, &status);
+  long tet10Values[20] = {0, 1, 2, 3, 5, 6,  7,  8,  9,  10,
+                          0, 1, 2, 4, 9, 10, 11, 12, 13, 14};// temporary
+  XdmfTopologyInsertDataFromPointer(tet10Topology, tet10Values, XDMF_ARRAY_TYPE_INT64, 0, 20, 1, 1, &status);
+  printf("tetrahedron_10s prior to splitting into faces \n%s\n", XdmfTopologyGetValuesString(tetTopology));
+  faceTopology = XdmfTopologyConverterGetExternalFaces(converter, tet10Topology);
+  printf("after splitting into faces\n%s\n", XdmfTopologyGetValuesString(faceTopology));
+  assert(strcmp(XdmfTopologyGetValuesString(faceTopology), "0 1 3 5 9 8 "
+                                                           "0 3 2 8 10 7 "
+                                                           "0 1 4 9 13 12 "
+                                                           "0 4 2 12 14 11 "
+                                                           "1 2 3 6 10 9 "
+                                                           "1 2 4 10 14 13") == 0);
+
+  XdmfTopologyFree(faceTopology);
+
+  /**
+   * Hexahedron to Quadrilateral
+   */
+  XDMFTOPOLOGY * baseHexTopology = XdmfTopologyNew();
+  XdmfTopologySetType(baseHexTopology, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, &status);
+  long hexValues[16] = {0, 1, 2, 3, 4, 5, 6, 7,
+                         0, 1, 2, 3, 8, 9, 10, 11};// temporary
+  XdmfTopologyInsertDataFromPointer(baseHexTopology, hexValues, XDMF_ARRAY_TYPE_INT64, 0, 16, 1, 1, &status);
+  printf("Hexahedrons prior to splitting into faces \n%s\n", XdmfTopologyGetValuesString(baseHexTopology));
+  faceTopology = XdmfTopologyConverterGetExternalFaces(converter, baseHexTopology);
+  printf("after splitting into faces\n%s\n", XdmfTopologyGetValuesString(faceTopology));
+  assert(strcmp(XdmfTopologyGetValuesString(faceTopology), "0 1 5 4 "
+                                                           "0 4 7 3 "
+                                                           "0 1 9 8 "
+                                                           "0 8 11 3 "
+                                                           "1 2 6 5 "
+                                                           "1 2 10 9 "
+                                                           "2 3 7 6 "
+                                                           "2 3 11 10 "
+                                                           "4 5 6 7 "
+                                                           "8 9 10 11") == 0);
+
+  XdmfTopologyFree(faceTopology);
+
+  /**
+   * Hexahedron_20 to Quadrilateral_8
+   */
+  XDMFTOPOLOGY * hex20Topology = XdmfTopologyNew();
+  XdmfTopologySetType(hex20Topology, XDMF_TOPOLOGY_TYPE_HEXAHEDRON_20, &status);
+  long hex20Values[40] = {0, 1, 2, 3, 4, 5, 6,  7,  12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+                           0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};// temporary
+  XdmfTopologyInsertDataFromPointer(hex20Topology, hex20Values, XDMF_ARRAY_TYPE_INT64, 0, 40, 1, 1, &status);
+  printf("Hexahedron_20s prior to splitting into faces \n%s\n", XdmfTopologyGetValuesString(hex20Topology));
+  faceTopology = XdmfTopologyConverterGetExternalFaces(converter, hex20Topology);
+  printf("after splitting into faces\n%s\n", XdmfTopologyGetValuesString(faceTopology));
+  assert(strcmp(XdmfTopologyGetValuesString(faceTopology), "0 1 5 4 12 21 16 20 "
+                                                           "0 4 7 3 20 19 23 15 "
+                                                           "0 1 9 8 24 33 28 32 "
+                                                           "0 8 11 3 32 31 35 27 "
+                                                           "1 2 6 5 13 22 17 21 "
+                                                           "1 2 10 9 25 34 29 33 "
+                                                           "2 3 7 6 14 23 18 22 "
+                                                           "2 3 11 10 26 35 30 34 "
+                                                           "4 5 6 7 16 17 18 19 "
+                                                           "8 9 10 11 28 29 30 31") == 0);
+
+  XdmfTopologyFree(faceTopology);
+
+  return 0;
+}
diff --git a/utils/tests/CMakeLists.txt b/utils/tests/CMakeLists.txt
new file mode 100644
index 0000000..5d1653c
--- /dev/null
+++ b/utils/tests/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_subdirectory(C)
+add_subdirectory(Cxx)
+if(XDMF_WRAP_PYTHON)
+  add_subdirectory(Python)
+endif(XDMF_WRAP_PYTHON)
+# Fortran detection doesn't work properly for CMake
+# When BUILD_SHARED_LIBS is off
+if(XDMF_BUILD_FORTRAN AND BUILD_SHARED_LIBS)
+  add_subdirectory(Fortran)
+endif(XDMF_BUILD_FORTRAN AND BUILD_SHARED_LIBS)
diff --git a/utils/tests/Cxx/CMakeLists.txt b/utils/tests/Cxx/CMakeLists.txt
new file mode 100644
index 0000000..aadeac0
--- /dev/null
+++ b/utils/tests/Cxx/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Add any dependencies that the cxx tests may need
+# Note: The tests already depend on their own file
+SET_PROPERTY(GLOBAL APPEND PROPERTY CXX_TEST_DEPENDENCIES
+  "XdmfUtils")
+
+# Include XdmfTestDataGenerator from non-util tests
+include_directories(${CMAKE_SOURCE_DIR}/tests/Cxx/)
+
+# Include XdmfTestDataGenerator from non-util tests
+include_directories(${CMAKE_SOURCE_DIR}/tests/Cxx/)
+
+# Include our test macros
+include(AddTestsCxx)
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (id: ADD_TEST_CXX(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+ADD_TEST_CXX(TestXdmfDiff)
+ADD_TEST_CXX(TestXdmfGeometryConverter)
+ADD_TEST_CXX(TestXdmfTopologyConverter)
+if(XDMF_BUILD_EXODUS_IO)
+  ADD_TEST_CXX(TestXdmfExodusIO)
+endif(XDMF_BUILD_EXODUS_IO)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_CXX(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_CXX(TestXdmfDiff)
+CLEAN_TEST_CXX(TestXdmfGeometryConverter)
+CLEAN_TEST_CXX(TestXdmfTopologyConverter)
+if(XDMF_BUILD_EXODUS_IO)
+  CLEAN_TEST_CXX(TestXdmfExodusIO
+    TestXdmfExodusIO.exo)
+endif(XDMF_BUILD_EXODUS_IO)
diff --git a/utils/tests/Cxx/TestXdmfDiff.cpp b/utils/tests/Cxx/TestXdmfDiff.cpp
new file mode 100644
index 0000000..c9b29df
--- /dev/null
+++ b/utils/tests/Cxx/TestXdmfDiff.cpp
@@ -0,0 +1,149 @@
+#include <math.h>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfAttribute.hpp"
+#include "XdmfAttributeCenter.hpp"
+#include "XdmfAttributeType.hpp"
+#include "XdmfDiff.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGridCollection.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyConverter.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfUnstructuredGrid> grid1 = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topology1 = XdmfTopology::New();
+
+  int connectivity[] = {0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10};
+  topology1->setType(XdmfTopologyType::Hexahedron());
+  topology1->insert(0, &connectivity[0], 16);
+
+  grid1->setTopology(topology1);
+
+  shared_ptr<XdmfGeometry> geometry1 = XdmfGeometry::New();
+
+  double points[] = {0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                     1.1, 1.1, 1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                     0.1, -1.1, 3.1, 0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                     -1.1, 3.1, 2.1, -2.1};
+  geometry1->setType(XdmfGeometryType::XYZ());
+  geometry1->insert(0, &points[0], 36);
+
+  grid1->setGeometry(geometry1);
+
+  shared_ptr<XdmfAttribute> attr1 = XdmfAttribute::New();
+
+  int nodeValues[] = {100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600,
+                      700};
+  attr1->setName("Nodal Attribute");
+  attr1->setType(XdmfAttributeType::Scalar());
+  attr1->setCenter(XdmfAttributeCenter::Node());
+  attr1->insert(0, &nodeValues[0], 12);
+
+  grid1->insert(attr1);
+
+  // Grid with the same structure
+
+  shared_ptr<XdmfUnstructuredGrid> grid2 = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topology2 = XdmfTopology::New();
+
+  topology2->setType(XdmfTopologyType::Hexahedron());
+  topology2->insert(0, &connectivity[0], 16);
+
+  grid2->setTopology(topology2);
+
+  shared_ptr<XdmfGeometry> geometry2 = XdmfGeometry::New();
+
+  geometry2->setType(XdmfGeometryType::XYZ());
+  geometry2->insert(0, &points[0], 36);
+
+  grid2->setGeometry(geometry2);
+
+  shared_ptr<XdmfAttribute> attr2 = XdmfAttribute::New();
+
+  attr2->setName("Nodal Attribute");
+  attr2->setType(XdmfAttributeType::Scalar());
+  attr2->setCenter(XdmfAttributeCenter::Node());
+  attr2->insert(0, &nodeValues[0], 12);
+
+  grid2->insert(attr2);
+
+  // Grid with structure partially off, difference of 5.
+
+  shared_ptr<XdmfUnstructuredGrid> grid3 = XdmfUnstructuredGrid::New();
+
+  shared_ptr<XdmfTopology> topology3 = XdmfTopology::New();
+
+  topology3->setType(XdmfTopologyType::Hexahedron());
+  topology3->insert(0, &connectivity[0], 16);
+
+  grid3->setTopology(topology3);
+
+  shared_ptr<XdmfGeometry> geometry3 = XdmfGeometry::New();
+
+  double pointsdiff[] = {4.1, 0.1, 1.1, 1.1, 0.1, 3.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                         1.1, 1.1, 1.1, 1.1, 6.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                         0.1, -1.1, 3.1, 3.1, -4.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                         -1.1, 3.1, 2.1, -2.1};
+  geometry3->setType(XdmfGeometryType::XYZ());
+  geometry3->insert(0, &pointsdiff[0], 36);
+
+  grid3->setGeometry(geometry3);
+
+  shared_ptr<XdmfAttribute> attr3 = XdmfAttribute::New();
+
+  attr3->setName("Nodal Attribute");
+  attr3->setType(XdmfAttributeType::Scalar());
+  attr3->setCenter(XdmfAttributeCenter::Node());
+  attr3->insert(0, &nodeValues[0], 12);
+
+  grid3->insert(attr3);
+
+  // Make diff checks
+
+  shared_ptr<XdmfDiff> diff = XdmfDiff::New();
+
+  if (!diff->compare(grid1, grid2))
+  {
+    std::cout << "equivalent grids are not compared correctly" << std::endl;
+  }
+  else
+  {
+    std::cout << "equivalent grids are compared correctly" << std::endl;
+  }
+  assert(diff->compare(grid1, grid2));
+
+  if (diff->compare(grid1, grid3))
+  {
+    std::cout << "dissimilar grids are not compared correctly" << std::endl;
+  }
+  else
+  {
+    std::cout << "dissimilar grids are compared correctly" << std::endl;
+  }
+  assert(!diff->compare(grid1, grid3));
+
+  std::cout << "default tolerance = " << diff->getAbsoluteTolerance() << std::endl;
+
+  diff->setAbsoluteTolerance(6);
+
+  if (!diff->compare(grid1, grid3))
+  {
+    std::cout << "tolerance is not applied correctly" << std::endl;
+  }
+  else
+  {
+    std::cout << "tolerance is applied correctly" << std::endl;
+  }
+  assert(diff->compare(grid1, grid3));
+
+  return 0;
+}
diff --git a/utils/tests/Cxx/TestXdmfExodusIO.cpp b/utils/tests/Cxx/TestXdmfExodusIO.cpp
new file mode 100644
index 0000000..2551e90
--- /dev/null
+++ b/utils/tests/Cxx/TestXdmfExodusIO.cpp
@@ -0,0 +1,51 @@
+#include "XdmfDomain.hpp"
+#include "XdmfExodusReader.hpp"
+#include "XdmfExodusWriter.hpp"
+#include "XdmfHDF5Writer.hpp"
+#include "XdmfWriter.hpp"
+
+#include "XdmfTestDataGenerator.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfExodusWriter> exodusWriter = XdmfExodusWriter::New();
+  shared_ptr<XdmfUnstructuredGrid> hexahedron =
+    XdmfTestDataGenerator::createHexahedron();
+  exodusWriter->write("TestXdmfExodusIO.exo", hexahedron);
+
+  shared_ptr<XdmfExodusReader> reader = XdmfExodusReader::New();
+  shared_ptr<XdmfUnstructuredGrid> grid =
+    reader->read("TestXdmfExodusIO.exo");
+  assert(grid->getName() == hexahedron->getName());
+  assert(grid->getGeometry()->getType() ==
+         hexahedron->getGeometry()->getType());
+  assert(grid->getGeometry()->getNumberPoints() ==
+         hexahedron->getGeometry()->getNumberPoints());
+  for(unsigned int i=0; i<grid->getGeometry()->getSize(); ++i) {
+    assert(grid->getGeometry()->getValue<double>(i) ==
+           hexahedron->getGeometry()->getValue<double>(i));
+  }
+  assert(grid->getTopology()->getType() ==
+         hexahedron->getTopology()->getType());
+  assert(grid->getTopology()->getNumberElements() ==
+         hexahedron->getTopology()->getNumberElements());
+  for(unsigned int i=0; i<grid->getTopology()->getSize(); ++i) {
+    assert(grid->getTopology()->getValue<double>(i) ==
+           hexahedron->getTopology()->getValue<double>(i));
+  }
+  assert(hexahedron->getNumberAttributes() + 2 == grid->getNumberAttributes());
+  for(unsigned int i=0; i<hexahedron->getNumberAttributes(); ++i) {
+    shared_ptr<XdmfAttribute> attribute1 = hexahedron->getAttribute(i);
+    if(attribute1->getCenter() != XdmfAttributeCenter::Grid()) {
+      shared_ptr<XdmfAttribute> attribute2 =
+        grid->getAttribute(attribute1->getName());
+      assert(attribute1->getCenter() == attribute2->getCenter());
+      assert(attribute1->getType() == attribute2->getType());
+      assert(attribute1->getSize() == attribute2->getSize());
+      for(unsigned int j=0; j<attribute1->getSize(); ++j) {
+        assert(attribute1->getValue<double>(i) ==
+               attribute2->getValue<double>(i));
+      }
+    }
+  }
+}
diff --git a/utils/tests/Cxx/TestXdmfGeometryConverter.cpp b/utils/tests/Cxx/TestXdmfGeometryConverter.cpp
new file mode 100644
index 0000000..7f95a8b
--- /dev/null
+++ b/utils/tests/Cxx/TestXdmfGeometryConverter.cpp
@@ -0,0 +1,110 @@
+#include <cmath>
+#include <iostream>
+#include <iomanip>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfGeometryConverter.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+double Pi = 3.1415926535897932384626433832795;
+
+int main(int, char **)
+{
+  shared_ptr<XdmfGeometryConverter> converter =
+    XdmfGeometryConverter::New();
+
+  shared_ptr<XdmfGeometry> cartesianGeo = XdmfGeometry::New();
+
+  cartesianGeo->setType(XdmfGeometryType::XYZ());
+
+  for (unsigned int i = 0; i < 3; ++i)
+  {
+    cartesianGeo->pushBack(1);
+  }
+
+  shared_ptr<XdmfGeometry> resultSphericalGeo = converter->convertToSpherical(cartesianGeo);
+
+  shared_ptr<XdmfGeometry> sphericalGeo = XdmfGeometry::New();
+
+  sphericalGeo->setType(XdmfGeometryType::Spherical());
+
+  sphericalGeo->pushBack(std::sqrt(3));
+  sphericalGeo->pushBack(std::asin(std::sqrt((double)2/3))); // should be equal to std::acos(1/std::sqrt(3))
+//  sphericalGeo->pushBack(std::acos(1/std::sqrt(3))); // should be equal to std::asin(std::sqrt((double)2/3))
+  sphericalGeo->pushBack(Pi/4);
+
+  std::cout << "Tolerance 10^-15\nresult\n" << resultSphericalGeo->getValuesString() << "\n?=\ncompare to\n" << sphericalGeo->getValuesString() << std::endl;
+
+  for (unsigned int i = 0; i < sphericalGeo->getSize(); ++i)
+  {
+    double val1 = resultSphericalGeo->getValue<double>(i);
+    double val2 = sphericalGeo->getValue<double>(i);
+    val1 = std::floor(val1 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    val2 = std::floor(val2 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    std::cout << std::fixed << std::setprecision(15) << val1 << " ?= " << std::fixed << std::setprecision(15) << val2 << std::endl;
+    assert(val1 == val2);
+  }
+
+  shared_ptr<XdmfGeometry> resultCartesianGeo = converter->convertToCartesian(sphericalGeo);
+
+  std::cout << resultCartesianGeo->getValuesString() << "\n?=\n" << cartesianGeo->getValuesString() << std::endl;
+
+  for (unsigned int i = 0; i < cartesianGeo->getSize(); ++i)
+  {
+    double val1 = resultCartesianGeo->getValue<double>(i);
+    double val2 = cartesianGeo->getValue<double>(i);
+    val1 = std::floor(val1 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    val2 = std::floor(val2 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    std::cout << std::fixed << std::setprecision(15) << val1 << " ?= " << std::fixed << std::setprecision(15) << val2 << std::endl;
+    assert(val1 == val2);
+  }
+
+  // Convert in place for geometries with a lot of references
+
+  shared_ptr<XdmfGeometry> convertedToSpherical = XdmfGeometry::New();
+
+  convertedToSpherical->setType(XdmfGeometryType::XYZ());
+
+  for (unsigned int i = 0; i < 3; ++i)
+  {
+    convertedToSpherical->pushBack(1);
+  }
+
+  converter->convertToSphericalOverwrite(convertedToSpherical);
+
+  for (unsigned int i = 0; i < sphericalGeo->getSize(); ++i)
+  {
+    double val1 = convertedToSpherical->getValue<double>(i);
+    double val2 = sphericalGeo->getValue<double>(i);
+    val1 = std::floor(val1 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    val2 = std::floor(val2 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    std::cout << std::fixed << std::setprecision(15) << val1 << " ?= " << std::fixed << std::setprecision(15) << val2 << std::endl;
+    assert(val1 == val2);
+  }
+
+  shared_ptr<XdmfGeometry> convertedToCartesian = XdmfGeometry::New();
+
+  convertedToCartesian->setType(XdmfGeometryType::Spherical());
+
+  convertedToCartesian->pushBack(std::sqrt(3));
+  convertedToCartesian->pushBack(std::asin(std::sqrt((double)2/3))); // should be equal to std::acos(1/std::sqrt(3))
+//  sphericalGeo->pushBack(std::acos(1/std::sqrt(3))); // should be equal to std::asin(std::sqrt((double)2/3))
+  convertedToCartesian->pushBack(Pi/4);
+
+  converter->convertToCartesianOverwrite(convertedToCartesian);
+
+  for (unsigned int i = 0; i < cartesianGeo->getSize(); ++i)
+  {
+    double val1 = convertedToCartesian->getValue<double>(i);
+    double val2 = cartesianGeo->getValue<double>(i);
+    val1 = std::floor(val1 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    val2 = std::floor(val2 * std::pow((double)10, (double)15) + 0.5) / std::pow((double)10, (double)15);
+    std::cout << std::fixed << std::setprecision(15) << val1 << " ?= " << std::fixed << std::setprecision(15) << val2 << std::endl;
+    assert(val1 == val2);
+  }
+
+  return 0;
+}
diff --git a/utils/tests/Cxx/TestXdmfTopologyConverter.cpp b/utils/tests/Cxx/TestXdmfTopologyConverter.cpp
new file mode 100644
index 0000000..4448e9f
--- /dev/null
+++ b/utils/tests/Cxx/TestXdmfTopologyConverter.cpp
@@ -0,0 +1,163 @@
+#include <math.h>
+#include <iostream>
+#include "XdmfArray.hpp"
+#include "XdmfArrayType.hpp"
+#include "XdmfGeometry.hpp"
+#include "XdmfGeometryType.hpp"
+#include "XdmfTopology.hpp"
+#include "XdmfTopologyConverter.hpp"
+#include "XdmfTopologyType.hpp"
+#include "XdmfUnstructuredGrid.hpp"
+#include "XdmfWriter.hpp"
+
+int main(int, char **)
+{
+  shared_ptr<XdmfTopologyConverter> converter =
+    XdmfTopologyConverter::New();
+
+  // Create Hexahedron Grid
+  shared_ptr<XdmfUnstructuredGrid> hexGrid =
+    XdmfUnstructuredGrid::New();
+  double hexPoints[24] = {0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0,
+                          1, 1, 1, 1, 0, 1, 1};
+  hexGrid->getGeometry()->setType(XdmfGeometryType::XYZ());
+  hexGrid->getGeometry()->resize<double>(24, 0);
+  hexGrid->getGeometry()->insert(0, hexPoints, 24);
+  unsigned int hexConn[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+  hexGrid->getTopology()->setType(XdmfTopologyType::Hexahedron());
+  hexGrid->getTopology()->resize<unsigned int>(8, 0);
+  hexGrid->getTopology()->insert(0, hexConn, 8);
+
+  /*
+   * Hexahedron to Hexahedron_64
+   */
+  shared_ptr<XdmfUnstructuredGrid> hex64Grid =
+    converter->convert(hexGrid, XdmfTopologyType::Hexahedron_64());
+
+  assert(hex64Grid->getGeometry()->getType() == XdmfGeometryType::XYZ());
+  assert(hex64Grid->getGeometry()->getNumberPoints() == 64);
+  assert(hex64Grid->getTopology()->getType() ==
+         XdmfTopologyType::Hexahedron_64());
+  assert(hex64Grid->getTopology()->getNumberElements() == 1);
+  for(unsigned int i=0; i<64; ++i) {
+    assert(i == hex64Grid->getTopology()->getValue<unsigned int>(i));
+  }
+
+  /*
+   * Hexahedron to Hexahedron_125
+   */
+  shared_ptr<XdmfUnstructuredGrid> hex125Grid =
+    converter->convert(hexGrid, XdmfTopologyType::Hexahedron_125());
+
+  assert(hex125Grid->getGeometry()->getType() == XdmfGeometryType::XYZ());
+  assert(hex125Grid->getGeometry()->getNumberPoints() == 125);
+  assert(hex125Grid->getTopology()->getType() ==
+         XdmfTopologyType::Hexahedron_125());
+  assert(hex125Grid->getTopology()->getNumberElements() == 1);
+  for(unsigned int i=0; i<125; ++i) {
+    assert(i == hex125Grid->getTopology()->getValue<unsigned int>(i));
+  }
+
+  /*
+   * Hexahedron_64 to Hexahedron
+   */
+  shared_ptr<XdmfUnstructuredGrid> newHexGrid =
+    converter->convert(hex64Grid, XdmfTopologyType::Hexahedron());
+  assert(newHexGrid->getGeometry()->getType() == XdmfGeometryType::XYZ());
+  assert(newHexGrid->getGeometry()->getNumberPoints() == 64);
+  assert(newHexGrid->getTopology()->getType() ==
+         XdmfTopologyType::Hexahedron());
+  assert(newHexGrid->getTopology()->getNumberElements() == 27);
+
+
+  shared_ptr<XdmfTopology> faceTopology;
+
+  /**
+   * Tetrahedron to Triangle
+   */
+  shared_ptr<XdmfTopology> tetTopology = XdmfTopology::New();
+  tetTopology->setType(XdmfTopologyType::Tetrahedron());
+  long tetValues[8] = {0, 1, 2, 3, 0, 1, 2, 4};// temporary
+  tetTopology->insert(0, tetValues, 8);
+  std::cout << "tetrahedrons prior to splitting into faces " << std::endl
+            << tetTopology->getValuesString() << std::endl;
+  faceTopology = converter->getExternalFaces(tetTopology);
+  std::cout << "after splitting into faces" << std::endl
+            << faceTopology->getValuesString() << std::endl;
+  assert(faceTopology->getValuesString().compare("0 1 3 "
+                                                 "0 3 2 "
+                                                 "0 1 4 "
+                                                 "0 4 2 "
+                                                 "1 2 3 "
+                                                 "1 2 4") == 0);
+
+  /**
+   * Tetrahedron_10 to Triangle_6
+   */
+  shared_ptr<XdmfTopology> tet10Topology = XdmfTopology::New();
+  tet10Topology->setType(XdmfTopologyType::Tetrahedron_10());
+  long tet10Values[20] = {0, 1, 2, 3, 5, 6,  7,  8,  9,  10,
+                          0, 1, 2, 4, 9, 10, 11, 12, 13, 14};// temporary
+  tet10Topology->insert(0, tet10Values, 20);
+  std::cout << "tetrahedron_10s prior to splitting into faces " << std::endl
+            << tet10Topology->getValuesString() << std::endl;
+  faceTopology = converter->getExternalFaces(tet10Topology);
+  std::cout << "after splitting into faces" << std::endl
+            << faceTopology->getValuesString() << std::endl;
+  assert(faceTopology->getValuesString().compare("0 1 3 5 9 8 "
+                                                 "0 3 2 8 10 7 "
+                                                 "0 1 4 9 13 12 "
+                                                 "0 4 2 12 14 11 "
+                                                 "1 2 3 6 10 9 "
+                                                 "1 2 4 10 14 13") == 0);
+
+  /**
+   * Hexahedron to Quadrilateral
+   */
+  shared_ptr<XdmfTopology> hexTopology = XdmfTopology::New();
+  hexTopology->setType(XdmfTopologyType::Hexahedron());
+  long hexValues[16] = {0, 1, 2, 3, 4, 5, 6, 7,
+                         0, 1, 2, 3, 8, 9, 10, 11};// temporary
+  hexTopology->insert(0, hexValues, 16);
+  std::cout << "Hexahedrons prior to splitting into faces " << std::endl
+            << hexTopology->getValuesString() << std::endl;
+  faceTopology = converter->getExternalFaces(hexTopology);
+  std::cout << "after splitting into faces" << std::endl
+            << faceTopology->getValuesString() << std::endl;
+  assert(faceTopology->getValuesString().compare("0 1 5 4 "
+                                                 "0 4 7 3 "
+                                                 "0 1 9 8 "
+                                                 "0 8 11 3 "
+                                                 "1 2 6 5 "
+                                                 "1 2 10 9 "
+                                                 "2 3 7 6 "
+                                                 "2 3 11 10 "
+                                                 "4 5 6 7 "
+                                                 "8 9 10 11") == 0);
+
+  /**
+   * Hexahedron_20 to Quadrilateral_8
+   */
+  shared_ptr<XdmfTopology> hex20Topology = XdmfTopology::New();
+  hex20Topology->setType(XdmfTopologyType::Hexahedron_20());
+  long hex20Values[40] = {0, 1, 2, 3, 4, 5, 6,  7,  12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+                           0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35};// temporary
+  hex20Topology->insert(0, hex20Values, 40);
+  std::cout << "Hexahedron_20s prior to splitting into faces " << std::endl
+            << hex20Topology->getValuesString() << std::endl;
+  faceTopology = converter->getExternalFaces(hex20Topology);
+  std::cout << "after splitting into faces" << std::endl
+            << faceTopology->getValuesString() << std::endl;
+  assert(faceTopology->getValuesString().compare("0 1 5 4 12 21 16 20 "
+                                                 "0 4 7 3 20 19 23 15 "
+                                                 "0 1 9 8 24 33 28 32 "
+                                                 "0 8 11 3 32 31 35 27 "
+                                                 "1 2 6 5 13 22 17 21 "
+                                                 "1 2 10 9 25 34 29 33 "
+                                                 "2 3 7 6 14 23 18 22 "
+                                                 "2 3 11 10 26 35 30 34 "
+                                                 "4 5 6 7 16 17 18 19 "
+                                                 "8 9 10 11 28 29 30 31") == 0);
+
+  return 0;
+}
diff --git a/utils/tests/Fortran/AcceptDSMFortran.f90 b/utils/tests/Fortran/AcceptDSMFortran.f90
new file mode 100644
index 0000000..a7de75d
--- /dev/null
+++ b/utils/tests/Fortran/AcceptDSMFortran.f90
@@ -0,0 +1,64 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Andrew Burns (andrew.j.burns2 at us.army.mil)
+!!
+!!     A test of the XdmfDSM capabilities using the fortran interface.
+!!     This part of the program sets up the server to be used by the DSM.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+  INCLUDE 'mpif.h'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  INTEGER id, commsize, buffersize
+  INTEGER intraID, intraSize
+  INTEGER ierr
+
+  INTEGER interComm
+
+  filename = 'nested_output.xmf'//CHAR(0)
+
+  if (buffersize < 1) then
+    buffersize = 1
+  endif
+
+  CALL MPI_INIT (ierr)
+
+  CALL XDMFINIT(obj, filename)
+
+  CALL MPI_COMM_RANK(MPI_COMM_WORLD, id, ierr)
+  CALL MPI_COMM_SIZE(MPI_COMM_WORLD, commsize, ierr)
+
+  buffersize = 16/commsize
+
+!! Cores 1 to size-1 are blocked by the initialization of the server.
+!! When the server finishes they are released and allowed to progress.
+  CALL XDMFINITDSMSERVER(obj, "dsm"//CHAR(0), MPI_COMM_WORLD, bufferSize, 1, commsize-1)
+
+  if (id == 0) then
+    CALL XDMFACCEPTDSM(obj, 2)
+  endif
+
+  CALL XDMFGETDSMINTERCOMM(obj, interComm)
+
+!! Wait for other processes to finish before closing
+
+  CALL MPI_BARRIER(interComm, ierr)
+
+  if (id == 0) then
+    CALL XDMFCLOSEDSMPORT(obj)
+  endif
+
+  CALL XDMFCLOSE(obj)
+
+  CALL MPI_FINALIZE(ierr)
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/CMakeLists.txt b/utils/tests/Fortran/CMakeLists.txt
new file mode 100644
index 0000000..aeb0eeb
--- /dev/null
+++ b/utils/tests/Fortran/CMakeLists.txt
@@ -0,0 +1,70 @@
+# Add any dependencies that the cxx tests may need
+# Note: The tests already depend on their own file
+SET_PROPERTY(GLOBAL APPEND PROPERTY FORTRAN_TEST_DEPENDENCIES
+  "XdmfUtils")
+
+# Include XdmfTestDataGenerator from non-util tests
+include_directories(${CMAKE_SOURCE_DIR}/tests/Fortran/)
+
+# Include our test macros
+include(AddTestsFortran)
+
+# Add any cxx tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have extra arguments (id: ADD_TEST_CXX(testname inputfile))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+if ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+  if (MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+    EXECUTE_PROCESS(
+      COMMAND ${MPIEXEC} --version
+      OUTPUT_VARIABLE MPI_TYPE_OUTPUT
+      ERROR_VARIABLE MPI_TYPE_ERROR
+    )
+    STRING(REGEX MATCH "Open" IS_OPENMPI "${MPI_TYPE_ERROR}")
+    IF ("${IS_OPENMPI}" STREQUAL "")
+      ADD_MPI_TEST_FORTRAN(ConnectDSMFortran.sh AcceptDSMFortran,ConnectDSMFortran2,ConnectDSMFortran)
+    ENDIF ("${IS_OPENMPI}" STREQUAL "")
+  endif(MPIEXEC_MAX_NUMPROCS STRGREATER 5)
+endif ("${XDMF_DSM_IS_CRAY}" STREQUAL "")
+SET_SOURCE_FILES_PROPERTIES(BinaryFortran.f90 PROPERTIES COMPILE_FLAGS -fno-range-check)
+ADD_TEST_FORTRAN(OutputTestXdmfFortran)
+ADD_TEST_FORTRAN(EditTestXdmfFortran)
+ADD_TEST_FORTRAN(TestXdmfFortran)
+ADD_TEST_FORTRAN(NestedInfoFortran)
+#if GCC
+STRING(REGEX MATCH "gfortran" IS_GCC "${CMAKE_Fortran_COMPILER}")
+IF ("${IS_GCC}" STREQUAL "gfortran")
+  SET_SOURCE_FILES_PROPERTIES(FixedOutputTestXdmfFortran.f90 PROPERTIES COMPILE_FLAGS "-ffixed-form")
+ENDIF ("${IS_GCC}" STREQUAL "gfortran")
+#if Intel
+STRING(REGEX MATCH "ifort" IS_INTEL "${CMAKE_Fortran_COMPILER}")
+IF ("${IS_INTEL}" STREQUAL "ifort")
+  SET_SOURCE_FILES_PROPERTIES(FixedOutputTestXdmfFortran.f90 PROPERTIES COMPILE_FLAGS "-fixed")
+ENDIF ("${IS_INTEL}" STREQUAL "ifort")
+ADD_TEST_FORTRAN(FixedOutputTestXdmfFortran)
+ADD_TEST_FORTRAN(FunctionTestXdmfFortran)
+ADD_TEST_FORTRAN(SubsetTestXdmfFortran)
+
+# Add any cxx cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#       have multiple files (ie: CLEAN_TEST_CXX(testname outputfile1 ...))
+#       Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_FORTRAN(OutputTestXdmfFortran)
+CLEAN_TEST_FORTRAN(TestXdmfFortran
+  my_output.h5
+  my_output.xmf)
+CLEAN_TEST_FORTRAN(NestedInfoFortran
+  nested_output.xmf
+  nested_output.h5)
+CLEAN_TEST_FORTRAN(EditTestXdmfFortran
+  edited_output.xmf
+  edited_output.h5)
+CLEAN_TEST_FORTRAN(FixedOutputTestXdmfFortran)
+CLEAN_TEST_FORTRAN(FunctionTestXdmfFortran
+  function_output.h5
+  function_output.xmf)
+CLEAN_TEST_FORTRAN(SubsetTestXdmfFortran
+  subset_output.h5
+  subset_output.xmf)
diff --git a/utils/tests/Fortran/ConnectDSMFortran.f90 b/utils/tests/Fortran/ConnectDSMFortran.f90
new file mode 100644
index 0000000..507919d
--- /dev/null
+++ b/utils/tests/Fortran/ConnectDSMFortran.f90
@@ -0,0 +1,124 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Andrew Burns (andrew.j.burns2 at us.army.mil)
+!!
+!!     A test of the XdmfDSM capabilities using the fortran interface.
+!!     This part of the program sets up the server to be used by the DSM.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+  INCLUDE 'mpif.h'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  INTEGER i
+  INTEGER id, commsize, buffersize, statusval(MPI_STATUS_SIZE)
+  INTEGER intraID, intraSize
+  INTEGER interID, interSize
+  INTEGER ierr
+  INTEGER writeloopcontrol
+
+  INTEGER interComm, intraComm
+
+  REAL*8 dataArray(4)
+
+  filename = 'nested_output.xmf'//CHAR(0)
+
+  writeloopcontrol = 0
+
+  CALL MPI_INIT (ierr)
+
+  CALL XDMFINIT(obj, filename)
+
+  CALL MPI_COMM_RANK(MPI_COMM_WORLD, id, ierr)
+  CALL MPI_COMM_SIZE(MPI_COMM_WORLD, commsize, ierr)
+
+  i = 1
+
+  do while (i <= 4)
+    dataArray(i) = (id + 1) * i
+    i = i + 1
+  enddo
+
+  CALL XDMFCONNECTDSM(obj, "dsm"//CHAR(0), MPI_COMM_WORLD)
+
+  CALL XDMFGETDSMINTRACOMM(obj, intraComm)
+
+  CALL MPI_COMM_RANK(intraComm, intraID, ierr)
+  CALL MPI_COMM_SIZE(intraComm, intraSize, ierr)
+
+  CALL XDMFGETDSMINTERCOMM(obj, interComm)
+
+  CALL MPI_COMM_RANK(interComm, interID, ierr)
+  CALL MPI_COMM_SIZE(interComm, interSize, ierr)
+
+  i = 0
+  do while (i < commsize)
+    if (i == id) then
+      print *, "core " , id, "array = ", dataArray
+    endif
+    i = i + 1
+    CALL MPI_BARRIER(intraComm, ierr)
+  enddo
+
+  if (id == 0) then
+    print *, ""
+  endif
+
+!! Work section goes here
+
+  do while (writeloopcontrol < 3)
+
+    CALL MPI_BARRIER(intraComm, ierr)
+
+    CALL XDMFWRITETODSM(obj, "Data"//CHAR(0), XDMF_ARRAY_TYPE_FLOAT64, dataArray, id*4, 1, 4, 4*commsize)
+
+    if (id == commsize - 1) then
+      CALL MPI_SEND(writeloopcontrol, 1, MPI_INT, interID + 1, 0, interComm, ierr)
+      CALL MPI_RECV(writeloopcontrol, 1, MPI_INT, interID + 1, 0, interComm, statusval, ierr)
+    endif
+
+    CALL MPI_BARRIER(intraComm, ierr)
+
+    CALL XDMFREADFROMDSM(obj, "Data"//CHAR(0), XDMF_ARRAY_TYPE_FLOAT64, dataArray, (commsize - id - 1)*4, 1, 4, 4*commsize)
+
+    i = 0
+    do while (i < commsize)
+      if (i == id) then 
+        print *, "core " , id, "array = ", dataArray
+      endif
+      i = i + 1
+      CALL MPI_BARRIER(intraComm, ierr)
+    enddo
+
+    if (id == 0) then
+      print *, ""
+    endif
+
+    writeloopcontrol = writeloopcontrol + 1
+
+  enddo
+
+  CALL MPI_BARRIER(intraComm, ierr)
+
+  if (id == 0) then
+    CALL XDMFSTOPDSM(obj)
+  endif
+!!/Work section
+
+!! Wait for other processes to finish before closing
+
+  CALL MPI_BARRIER(interComm, ierr)
+
+  CALL XDMFCLOSE(obj)
+
+  CALL MPI_FINALIZE(ierr)
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/ConnectDSMFortran.sh b/utils/tests/Fortran/ConnectDSMFortran.sh
new file mode 100755
index 0000000..685e1d3
--- /dev/null
+++ b/utils/tests/Fortran/ConnectDSMFortran.sh
@@ -0,0 +1,11 @@
+# Intel MPI requires a minimum of 2 cores per process
+
+$MPIEXEC -n 2 ./AcceptDSMFortran &
+
+sleep 5
+
+$MPIEXEC -n 2 ./ConnectDSMFortran &
+
+sleep 5
+
+$MPIEXEC -n 2 ./ConnectDSMFortran2
diff --git a/utils/tests/Fortran/ConnectDSMFortran2.f90 b/utils/tests/Fortran/ConnectDSMFortran2.f90
new file mode 100644
index 0000000..5ac1d78
--- /dev/null
+++ b/utils/tests/Fortran/ConnectDSMFortran2.f90
@@ -0,0 +1,90 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Andrew Burns (andrew.j.burns2 at us.army.mil)
+!!
+!!     A test of the XdmfDSM capabilities using the fortran interface.
+!!     This part of the program sets up the server to be used by the DSM.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+  INCLUDE 'mpif.h'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  INTEGER id, commsize, buffersize, statusval(MPI_STATUS_SIZE)
+  INTEGER intraID, intraSize
+  INTEGER interID, interSize
+  INTEGER ierr
+  INTEGER writeloopcontrol, i
+  REAL*8 dataArray(4)
+
+  INTEGER interComm, intraComm
+
+  filename = 'nested_output.xmf'//CHAR(0)
+
+  writeloopcontrol = 0
+
+  CALL MPI_INIT (ierr)
+
+  CALL XDMFINIT(obj, filename)
+
+  CALL MPI_COMM_RANK(MPI_COMM_WORLD, id, ierr)
+  CALL MPI_COMM_SIZE(MPI_COMM_WORLD, commsize, ierr)
+
+  CALL XDMFCONNECTDSM(obj, "dsm"//CHAR(0), MPI_COMM_WORLD)
+
+  CALL XDMFGETDSMINTRACOMM(obj, intraComm)
+
+  CALL MPI_COMM_RANK(intraComm, intraID, ierr)
+  CALL MPI_COMM_SIZE(intraComm, intraSize, ierr)
+
+  CALL MPI_BARRIER(intraComm, ierr)
+
+  CALL XDMFGETDSMINTERCOMM(obj, interComm)
+
+  CALL MPI_COMM_RANK(interComm, interID, ierr)
+  CALL MPI_COMM_SIZE(interComm, interSize, ierr)
+
+!! Work is done here
+
+  do while (writeloopcontrol < 3)
+
+    if (id == 0) then
+      CALL MPI_RECV(writeloopcontrol, 1, MPI_INT, interID - 1, 0, interComm, statusval, ierr)
+    endif
+
+    CALL XDMFREADFROMDSM(obj, "Data"//CHAR(0), XDMF_ARRAY_TYPE_FLOAT64, dataArray, id*4, 1, 4, 4*commsize)
+
+    i = 1
+
+    do while (i <= 4)
+      dataArray(i) = dataArray(i) * 2
+      i = i + 1
+    enddo
+
+    CALL XDMFWRITETODSM(obj, "Data"//CHAR(0), XDMF_ARRAY_TYPE_FLOAT64, dataArray, id*4, 1, 4, 4*commsize)
+
+    if (id == 0) then
+      CALL MPI_SEND(writeloopcontrol, 1, MPI_INT, interID - 1, 0, interComm, ierr)
+    endif
+
+    writeloopcontrol = writeloopcontrol + 1
+
+  enddo
+
+!! Wait for other processes to finish before closing
+
+  CALL MPI_BARRIER(interComm, ierr)
+
+  CALL XDMFCLOSE(obj)
+
+  CALL MPI_FINALIZE(ierr)
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/EditTestXdmfFortran.f90 b/utils/tests/Fortran/EditTestXdmfFortran.f90
new file mode 100644
index 0000000..7cf8c9b
--- /dev/null
+++ b/utils/tests/Fortran/EditTestXdmfFortran.f90
@@ -0,0 +1,333 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Andrew Burns (andrew.j.burns2 at us.army.mil)
+!!
+!!     Read the first hexahedron from the file generated by the
+!!     OutputTestXdmfFortran program, then print the results for comparison.
+!!     
+!!     Link against the XdmfUtils library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+PROGRAM XdmfFortranExample
+  
+  IMPLICIT NONE
+  INCLUDE 'Xdmf.f'
+
+  INTEGER*8 obj
+  character*256 infilename, outfilename, itemName, itemKey, itemValue, itemTag
+  REAL*4 myPointsOutput(36)
+  INTEGER myConnectionsOutput(16)
+  INTEGER myMappedNodes(3), myDimensions(3)
+  REAL*8 myCellAttributeOutput(4), myNodeAttributeOutput(12), mySetOutput(12), myTestTime, myBrick(3), myOrigin(3)
+  INTEGER numContained, typeHolder
+
+  
+  infilename = 'my_output.xmf'//CHAR(0)
+
+  outfilename = 'edited_output.xmf'//CHAR(0)
+  
+  CALL XDMFINIT(obj)
+  CALL XDMFREAD(obj, infilename)
+
+  PRINT *, 'Load From: ', TRIM(infilename)
+  PRINT *, 'Domain Properties'
+  CALL XDMFRETRIEVEDOMAINNUMPROPERTIES(obj, numContained)
+  PRINT *, 'number of Properties: ', numContained
+  CALL XDMFRETRIEVEDOMAINTAG(obj, itemTag, 256)
+  PRINT *, 'Domain Tag: ', itemTag
+  CALL XDMFRETRIEVENUMDOMAINGRIDCOLLECTIONS(obj, numContained)
+  PRINT *, 'Number of Grid Collections: ',   numContained
+  CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)
+  CALL XDMFRETRIEVENUMINFORMATION(obj, numContained)
+  PRINT *, 'Number of Information for Grid: ', numContained
+  PRINT *, 'Information 0'
+  CALL XDMFRETRIEVEINFORMATIONNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEINFORMATIONPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Information Tag: ', itemTag
+  CALL XDMFRETRIEVEINFORMATION(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEINFORMATIONBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEGRIDCOLLECTIONNUMGRIDS(obj, XDMF_GRID_TYPE_UNSTRUCTURED,  numContained)
+  PRINT *, 'Number of Grids contained in the Grid Collection: ', numContained
+  CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 1, 1, 1, 1)
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDNAME(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0,  itemName, 256)
+  PRINT *, "Grid Name: ", itemName
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDTAG(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, itemTag, 256)
+  PRINT *, "Grid Tag: ", itemTag
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDNUMPROPERTIES(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  PRINT *, "Grid Properties: "
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDPROPERTY(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDPROPERTYBYKEY(obj, XDMF_GRID_TYPE_UNSTRUCTURED,  0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVETIME(obj, myTestTime)
+  PRINT *, 'Grid Time: ', myTestTime
+  CALL XDMFRETRIEVEGRIDCOLLECTIONTYPE(obj, typeHolder)
+  PRINT *, 'Grid Collection Type: ', typeHolder
+  CALL XDMFRETRIEVENUMATTRIBUTES(obj, numContained)
+  PRINT *, 'Number of Grid Attributes: ', numContained
+  PRINT *, 'Map'
+  CALL XDMFRETRIEVEMAPNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, 'Number of Properties: ', numContained
+  CALL XDMFRETRIEVEMAPPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEMAPPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEREMOTENODEIDS(obj, 0, 1, 3, myMappedNodes)
+  PRINT *, 'Nodes: ', myMappedNodes
+!!!! Unstructured and Curvilinear only
+  PRINT *, 'Geometry'
+  CALL XDMFRETRIEVEGEOMETRYNUMPROPERTIES(obj, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEGEOMETRYPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEGEOMETRYPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEGEOMETRYTAG(obj, itemTag, 256)
+  PRINT *, 'Geometry Tag: ', itemTag
+  CALL XDMFRETRIEVEGEOMETRYTYPE(obj, typeHolder)
+  PRINT *, 'Geometry Type: ', typeHolder
+  CALL XDMFRETRIEVEGEOMETRYVALUETYPE(obj, typeHolder)
+  PRINT *, 'Geometry Value Type: ', typeHolder
+  CALL XDMFRETRIEVEGEOMETRYSIZE(obj, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVEGEOMETRYNUMPOINTS(obj, numContained)
+  PRINT *, 'Geometry Number of Points: ', numContained
+  CALL XDMFRETRIEVEGEOMETRYVALUES(obj, myPointsOutput, XDMF_ARRAY_TYPE_FLOAT32, 36, 0, 1, 1)
+  PRINT 1,  myPointsOutput
+1 FORMAT (' ', 3F5.1, '\n ', 3F5.1, '\n ', 3F5.1, '\n')
+!!!! / Unstructured and Curvilinear Grid only
+!!!! Unstructured Grid only
+  PRINT *, 'Topology'
+  CALL XDMFRETRIEVETOPOLOGYNUMPROPERTIES(obj, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVETOPOLOGYPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVETOPOLOGYPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVETOPOLOGYTAG(obj, itemTag, 256)
+  PRINT *, 'Topology Tag: ', itemTag
+  CALL XDMFRETRIEVETOPOLOGYTYPE(obj, typeHolder)
+  PRINT *, 'Topology Type: ', typeHolder
+  CALL XDMFRETRIEVETOPOLOGYVALUETYPE(obj, typeHolder)
+  PRINT *, 'Topology Value Type: ', typeHolder
+  CALL XDMFRETRIEVETOPOLOGYSIZE(obj, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVETOPOLOGYNUMELEMENTS(obj, numContained)
+  PRINT *, 'Topology Number of elements: ', numContained
+  CALL XDMFRETRIEVETOPOLOGYVALUES(obj, myConnectionsOutput, XDMF_ARRAY_TYPE_INT32, 16, 0, 1, 1)
+  PRINT 2, myConnectionsOutput
+2 FORMAT (' ', 8I3)
+!!!! /Unstructured Grid Only
+!!!! Curvilinear and Regular only
+!!  PRINT *, 'Dimensions'
+!!  CALL XDMFRETRIEVEDIMENSIONSNUMPROPERTIES(obj, numContained)
+!!  PRINT *, 'Number of Properties: ', numContained
+!!  CALL XDMFRETRIEVEDIMENSIONSPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, "Key: ", itemKey
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEDIMENSIONSPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEDIMENSIONSTAG(obj, itemTag, 256)
+!!  PRINT *, "Dimension Tag: ", itemTag
+!!  CALL XDMFRETRIEVEDIMENSIONSVALUETYPE(obj, typeHolder)
+!!  PRINT *, "Dimension Value Type: ", typeHolder
+!!  CALL XDMFRETRIEVEDIMENSIONSSIZE(obj, numContained)
+!!  PRINT *, "Number of Values: ", numContained
+!!  CALL XDMFRETRIEVEDIMENSIONSVALUES(obj, myDimensions, XDMF_ARRAY_TYPE_INT32, 3, 0, 1, 1)
+!!  PRINT *, myDimensions
+!!!! /Curvilinear and Regular only
+!!!! Rectilinear Only
+!!  PRINT *, 'Coordinates'
+!!  CALL XDMFRETRIEVENUMCOORDINATES(obj, numContained)
+!!  PRINT *, 'Number of Coordinates: ', numContained
+!!  CALL XDMFRETRIEVECOORDINATEVALUETYPE(obj, 0, typeHolder)
+!!  PRINT *, 'Coordinate Value Type', typeHolder
+!!  CALL XDMFRETRIEVECOORDINATENUMPROPERTIES(obj, 0, numContained)
+!!  PRINT *, 'Number of Properties', numContained
+!!  CALL XDMFRETRIEVECOORDINATEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, 'Key: ', itemKey
+!!  PRINT *, 'Value: ', itemValue
+!!  CALL XDMFRETRIEVECOORDINATEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+!!  PRINT *, 'Value: ', itemValue
+!!  CALL XDMFRETRIEVECOORDINATESIZE(obj, 0, numContained)
+!!  PRINT *, 'Size of Coordinate 0', numContained
+!!  CALL XDMFRETRIEVECOORDINATESIZE(obj, 1, numContained)
+!!  PRINT *, 'Size of Coordinate 1', numContained
+!!  CALL XDMFRETRIEVECOORDINATESIZE(obj, 2, numContained)
+!!  PRINT *, 'Size of Coordinate 2', numContained
+!!  CALL XDMFRETRIEVECOORDINATEVALUES(obj, 0, myPointsOutput(1), XDMF_ARRAY_TYPE_FLOAT32, 12, 0, 1, 1)
+!!  CALL XDMFRETRIEVECOORDINATEVALUES(obj, 0, myPointsOutput(13), XDMF_ARRAY_TYPE_FLOAT32, 12, 0, 1, 1)
+!!  CALL XDMFRETRIEVECOORDINATEVALUES(obj, 0, myPointsOutput(25), XDMF_ARRAY_TYPE_FLOAT32, 12, 0, 1, 1)
+!!  PRINT 1, myPointsOutput
+!!!! /Rectilinear Only
+!!!! Regular Grid Only
+!! Brick and Origin
+!!  PRINT *, 'Brick'
+!!  CALL XDMFRETRIEVEBRICKNUMPROPERTIES(obj, numContained)
+!!  PRINT *, 'Number of Properties: ', numContained
+!!  CALL XDMFRETRIEVEBRICKPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, "Key: ", itemKey
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEBRICKPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEBRICKTAG(obj, itemTag, 256)
+!!  PRINT *, "Brick Tag: ", itemTag
+!!  CALL XDMFRETRIEVEBRICKVALUETYPE(obj, typeHolder)
+!!  PRINT *, "Brick Value Type: ", typeHolder
+!!  CALL XDMFRETRIEVEBRICKSIZE(obj, numContained)
+!!  PRINT *, "Number of Values: ", numContained
+!!  CALL XDMFRETRIEVEBRICKVALUES(obj, myBrick, XDMF_ARRAY_TYPE_FLOAT64, 3, 0, 1, 1)
+!!  PRINT *, myBrick
+!!  PRINT *, 'Origin'
+!!  CALL XDMFRETRIEVEORIGINNUMPROPERTIES(obj, numContained)
+!!  PRINT *, 'Number of Properties: ', numContained
+!!  CALL XDMFRETRIEVEORIGINPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, "Key: ", itemKey
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEORIGINPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEORIGINTAG(obj, itemTag, 256)
+!!  PRINT *, "Origin Tag: ", itemTag
+!!  CALL XDMFRETRIEVEORIGINVALUETYPE(obj, typeHolder)
+!!  PRINT *, "Origin Value Type: ", typeHolder
+!!  CALL XDMFRETRIEVEORIGINSIZE(obj, numContained)
+!!  PRINT *, "Number of Values: ", numContained
+!!  CALL XDMFRETRIEVEORIGINVALUES(obj, myOrigin, XDMF_ARRAY_TYPE_FLOAT64, 3, 0, 1, 1)
+!!  PRINT *, myOrigin
+!!!! /Regular Grid Only
+  CALL XDMFRETRIEVENUMSETS(obj, numContained)
+  PRINT *, '\nNumber of Sets:', numContained
+  PRINT *, '\nSet 0'
+  CALL XDMFRETRIEVESETNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, 'Number of Properties: ', numContained
+  CALL XDMFRETRIEVESETPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVESETPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVESETTYPE(obj, 0, typeHolder)
+  PRINT *, 'Set Type: ', typeHolder
+  CALL XDMFRETRIEVESETVALUETYPE(obj, 0, typeHolder)
+  PRINT *, 'Set Value Type: ', typeHolder
+  CALL XDMFRETRIEVESETNAME(obj, 0, itemName, 256)
+  PRINT *, 'Set Name: ', itemName
+  CALL XDMFRETRIEVESETTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Set Tag: ', itemTag
+  CALL XDMFRETRIEVESETVALUES(obj, 0, mySetOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
+  PRINT 3, mySetOutput
+  PRINT *, '\nAttribute 0'
+  CALL XDMFRETRIEVEATTRIBUTENAME(obj, 0, itemName, 256)
+  PRINT *, 'Attribute Name: ', itemName
+  CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTETAG(obj, 0, itemTag, 256)
+  PRINT *, 'Attribute Tag: ', itemTag
+  CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 0, typeHolder)
+  PRINT *, 'Attribute Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 0, typeHolder)
+  PRINT *, 'Attribute Center: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 0, typeHolder)
+  PRINT *, 'Attribute Value Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 0, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, myNodeAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
+  PRINT 3, myNodeAttributeOutput
+3 FORMAT (' ', 3F6.1)
+  CALL XDMFOPENATTRIBUTE(obj, 0)
+  CALL XDMFRETRIEVENUMINFORMATION(obj, numContained)
+  PRINT *, 'Number of Information for Grid and Attribute 0: ', numContained
+  PRINT *, 'Information 0'
+  CALL XDMFRETRIEVEINFORMATIONNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEINFORMATIONPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Information Tag: ', itemTag
+  CALL XDMFRETRIEVEINFORMATION(obj, 1, itemKey, 256, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEINFORMATIONBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, 'Value: ', itemValue
+  PRINT *, '\nAttribute 1'
+  CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 1, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 1, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 1, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTENAME(obj, 1, itemName, 256)
+  PRINT *, 'Attribute Name: ', itemName
+  CALL XDMFRETRIEVEATTRIBUTETAG(obj, 1, itemTag, 256)
+  PRINT *, 'Attribute Tag: ', itemTag
+  CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 1, typeHolder)
+  PRINT *, 'Attribute Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 1, typeHolder)
+  PRINT *, 'Attribute Center: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 1, typeHolder)
+  PRINT *, 'Attribute Value Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 1, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 1, myCellAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 4, 0, 1, 1)
+  PRINT 4, myCellAttributeOutput
+4 FORMAT (' ', F6.1)
+  CALL XDMFOPENATTRIBUTE(obj, 1)
+  CALL XDMFRETRIEVENUMINFORMATION(obj, numContained)
+  PRINT *, 'Number of Information for Grid and Attribute 0: ', numContained
+  PRINT *, 'Information 0'
+  CALL XDMFRETRIEVEINFORMATIONNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEINFORMATIONPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Information Tag: ', itemTag
+  CALL XDMFRETRIEVEINFORMATION(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEINFORMATIONBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+
+
+
+  CALL XDMFCLEARINFORMATIONS(obj)
+  CALL XDMFCLEARATTRIBUTES(obj)  
+  CALL XDMFREPLACESET(obj, 0, 'EditedSet'//CHAR(0), XDMF_SET_TYPE_NODE, mySetOutput, 12, XDMF_ARRAY_TYPE_FLOAT64)
+  PRINT *, 'Set Edited'
+  CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 0, 1, 0, 0)
+  CALL XDMFREPLACEATTRIBUTE(obj, 1, 'Edited Attribute'//CHAR(0), XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, &
+     4, XDMF_ARRAY_TYPE_FLOAT64, myNodeAttributeOutput)
+  CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 0, 0, 1, 0)
+  CALL XDMFREPLACEINFORMATION(obj, 0, 'Edited Key'//CHAR(0), 'Edited Value'//CHAR(0))
+  CALL XDMFREPLACEGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 'Edited Grid'//CHAR(0))
+  PRINT *, 'Grid Replaced'
+  CALL XDMFWRITE(obj, outfilename, 10, .TRUE.)
+  CALL XDMFCLOSE(obj)
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/FixedOutputTestXdmfFortran.f90 b/utils/tests/Fortran/FixedOutputTestXdmfFortran.f90
new file mode 100644
index 0000000..b540001
--- /dev/null
+++ b/utils/tests/Fortran/FixedOutputTestXdmfFortran.f90
@@ -0,0 +1,202 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Kenneth Leiter (kenneth.leiter at arl.army.mil)
+!!
+!!     Use the Xdmf Fortran Bindings to write out a simple mesh consisting of
+!!     two hexahedrons.  Link against the XdmfUtils library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+       PROGRAM XdmfFortranExample
+ 
+         Implicit none
+         INCLUDE 'Xdmf.f'
+
+  
+
+       INTEGER*8 obj
+       character*256 filename
+       REAL*4 myPoints(3,3,4)
+       INTEGER myConnections(8,2), myDimensions(3)
+       REAL*8 myCellAttribute(2), myNodeAttribute(3,4),                 &
+     &         mySmallerNode(3,2), myTime, myOrigin(3), myBrick(3)
+       INTEGER nodeAttributeId, nodeSmallAttributeId, cellAttributeId,  &
+     &         testSetID, testMapID, tempID
+
+       filename = 'my_fixed_form_output.xmf'//CHAR(0)
+  
+       myPoints(1,1,1) = 0
+       myPoints(2,1,1) = 0
+       myPoints(3,1,1) = 1
+       myPoints(1,2,1) = 1
+       myPoints(2,2,1) = 0
+       myPoints(3,2,1) = 1
+       myPoints(1,3,1) = 3
+       myPoints(2,3,1) = 0
+       myPoints(3,3,1) = 2
+       myPoints(1,1,2) = 0
+       myPoints(2,1,2) = 1
+       myPoints(3,1,2) = 1
+       myPoints(1,2,2) = 1
+       myPoints(2,2,2) = 1
+       myPoints(3,2,2) = 1
+       myPoints(1,3,2) = 3
+       myPoints(2,3,2) = 2
+       myPoints(3,3,2) = 2
+       myPoints(1,1,3) = 0
+       myPoints(2,1,3) = 0
+       myPoints(3,1,3) = -1
+       myPoints(1,2,3) = 1
+       myPoints(2,2,3) = 0
+       myPoints(3,2,3) = -1
+       myPoints(1,3,3) = 3
+       myPoints(2,3,3) = 0
+       myPoints(3,3,3) = -2
+       myPoints(1,1,4) = 0
+       myPoints(2,1,4) = 1
+       myPoints(3,1,4) = -1
+       myPoints(1,2,4) = 1
+       myPoints(2,2,4) = 1
+       myPoints(3,2,4) = -1
+       myPoints(1,3,4) = 3
+       myPoints(2,3,4) = 2
+       myPoints(3,3,4) = -2
+  
+       myConnections(1,1) = 0
+       myConnections(2,1) = 1
+       myConnections(3,1) = 7
+       myConnections(4,1) = 6
+       myConnections(5,1) = 3
+       myConnections(6,1) = 4
+       myConnections(7,1) = 10
+       myConnections(8,1) = 9
+       myConnections(1,2) = 1
+       myConnections(2,2) = 2
+       myConnections(3,2) = 8
+       myConnections(4,2) = 7
+       myConnections(5,2) = 4
+       myConnections(6,2) = 5
+       myConnections(7,2) = 11
+       myConnections(8,2) = 10
+  
+       myNodeAttribute(1,1) = 100
+       myNodeAttribute(1,2) = 300
+       myNodeAttribute(1,3) = 300
+       myNodeAttribute(1,4) = 500
+       myNodeAttribute(2,1) = 200
+       myNodeAttribute(2,2) = 400
+       myNodeAttribute(2,3) = 400
+       myNodeAttribute(2,4) = 600
+       myNodeAttribute(3,1) = 300
+       myNodeAttribute(3,2) = 500
+       myNodeAttribute(3,3) = 500
+       myNodeAttribute(3,4) = 700
+  
+        myCellAttribute(1) = 100
+        myCellAttribute(2) = 200
+
+        myDimensions(1) = 12
+        myDimensions(2) = 12
+        myDimensions(3) = 12
+
+        myOrigin(1) = 0
+        myOrigin(2) = 0
+        myOrigin(3) = 0
+
+        myBrick(1) = 12
+        myBrick(2) = 12
+        myBrick(3) = 12
+
+        myTime = 1.0
+
+        CALL XDMFINIT(obj, filename)
+
+        CALL XDMFSETMAXFILESIZE(obj, 1)
+        CALL XDMFSETALLOWSETSPLITTING(obj, .TRUE.)
+        CALL XDMFINITHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
+
+        tempID = XDMFADDINFORMATION(obj, 'GridCollection1'//CHAR(0),    &
+     &    'This is Grid collection 1'//CHAR(0))
+        CALL XDMFADDGRIDCOLLECTION(obj, "Temporal"//CHAR(0),            &
+     &       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
+        CALL XDMFADDMAP(obj, "TestMap"//CHAR(0))
+        CALL XDMFADDREMOTENODEID(obj, 0, 1, 2, 3)
+        CALL XDMFADDREMOTENODEID(obj, 0, 1, 2, 4)
+        CALL XDMFADDREMOTENODEID(obj, 0, 1, 3, 3)
+        CALL XDMFADDREMOTENODEID(obj, 0, 1, 3, 5)
+        testMapID = XDMFSTOREMAP(obj, 0)
+        CALL XDMFADDREMOTENODEID(obj, 0, 1, 3, 8)
+        CALL XDMFSETTIME(obj, myTime)
+!! Unstructured Only
+        tempID = XDMFSETTOPOLOGY(obj, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, 16,&
+     &       XDMF_ARRAY_TYPE_INT32, myConnections, 0)
+!! /Unstructured Only
+!! Curvilinear and Rectilinear Only
+        tempID = XDMFSETDIMENSIONS(obj, 3, XDMF_ARRAY_TYPE_INT32,       &
+     &    myDimensions)
+!! /Curvilinear and Rectilinear Only
+!! Unstructured and Curvilinear Only
+        tempID = XDMFSETGEOMETRY(obj, XDMF_GEOMETRY_TYPE_XYZ, 36,       &
+     &    XDMF_ARRAY_TYPE_FLOAT32, myPoints)
+!! /Unstructured and Curvilinear Only
+!! Rectilinear Only
+        tempID = XDMFADDCOORDINATE(obj, "XCoordinates"//CHAR(0), 12,    &
+     &    XDMF_ARRAY_TYPE_FLOAT32, myPoints(1,1,1))
+        tempID = XDMFADDCOORDINATE(obj, "YCoordinates"//CHAR(0), 12,    &
+     &    XDMF_ARRAY_TYPE_FLOAT32, myPoints(1,2,2))
+        tempID = XDMFADDCOORDINATE(obj, "ZCoordinates"//CHAR(0), 12,    &
+     &    XDMF_ARRAY_TYPE_FLOAT32, myPoints(1,3,3))
+!! /Rectilinear Only
+!! Regular Only
+        tempID = XDMFSETORIGIN(obj, 3, XDMF_ARRAY_TYPE_FLOAT64,         &
+     &    myOrigin)
+        tempID = XDMFSETBRICK(obj, 3, XDMF_ARRAY_TYPE_FLOAT64, myBrick)
+!! /Regular Only
+        testSetID = XDMFADDSET(obj, 'TestSet'//CHAR(0),                 &
+     &    XDMF_SET_TYPE_NODE, myNodeAttribute,  12,                     &
+     &    XDMF_ARRAY_TYPE_FLOAT64)
+        tempID =  XDMFADDINFORMATION(obj, 'Attrib1'//CHAR(0),           &
+     &    'This is Attribute 1'//CHAR(0))
+        nodeAttributeId = XDMFADDATTRIBUTE(obj, 'NodeValues'//CHAR(0),  &
+     &       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12,&
+     &       XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
+        PRINT *, 'Node Attribute ID: ', nodeAttributeId
+        CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, mySmallerNode,         &
+     &    XDMF_ARRAY_TYPE_FLOAT64, 6, 0, 1, 1)
+        tempID =  XDMFADDINFORMATION(obj, 'Attrib2'//CHAR(0),           &
+     &    'This is Attribute 2'//CHAR(0))
+        cellAttributeId = XDMFADDATTRIBUTE(obj, 'CellValues'//CHAR(0),  &
+     &       XDMF_ATTRIBUTE_CENTER_CELL, XDMF_ATTRIBUTE_TYPE_SCALAR, 2, &
+     &       XDMF_ARRAY_TYPE_FLOAT64, myCellAttribute)
+        PRINT *, 'Cell Attribute ID: ', cellAttributeId
+        nodeSmallAttributeId = XDMFADDATTRIBUTE(obj,                    &
+     &   'SmallNodeValues'//CHAR(0), XDMF_ATTRIBUTE_CENTER_NODE,        &
+     &    XDMF_ATTRIBUTE_TYPE_SCALAR, 6, XDMF_ARRAY_TYPE_FLOAT64,       &
+     &    mySmallerNode)
+        PRINT *, 'Node Attribute ID: ', nodeSmallAttributeId
+        tempID = XDMFADDINFORMATION(obj, 'Grid1'//CHAR(0),              &
+     &    'This is Grid 1'//CHAR(0))
+        tempID = XDMFADDINFORMATION(obj, 'SubInformation'//CHAR(0),     &
+     &    'This is an information inside an information'//CHAR(0))
+        CALL XDMFADDINFORMATIONARRAY(obj, 1, "Array"//CHAR(0), myBrick, &
+     &    3, XDMF_ARRAY_TYPE_FLOAT64)
+        CALL XDMFMODIFYINFORMATIONARRAY(obj, 1, 0, myBrick,             &
+     &    XDMF_ARRAY_TYPE_FLOAT64, 3, 3, 1, 1)
+        CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+        CALL XDMFADDGRID(obj, 'TestGrid'//CHAR(0), .FALSE.)
+        myTime = 2.0
+
+        CALL XDMFSETTIME(obj, myTime)
+        CALL XDMFADDPREVIOUSATTRIBUTE(obj, cellAttributeId)
+        CALL XDMFADDPREVIOUSMAP(obj, testMapID)
+        CALL XDMFADDPREVIOUSSET(obj, testSetID)
+        CALL XDMFADDPREVIOUSATTRIBUTE(obj, nodeAttributeId)
+        CALL XDMFADDGRID(obj, 'Identical'//CHAR(0), .FALSE.)
+        CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
+!!  CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
+        CALL XDMFWRITE(obj, filename, 30, .TRUE.)
+        CALL XDMFCLOSE(obj)
+
+
+        END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/FunctionTestXdmfFortran.f90 b/utils/tests/Fortran/FunctionTestXdmfFortran.f90
new file mode 100644
index 0000000..b401188
--- /dev/null
+++ b/utils/tests/Fortran/FunctionTestXdmfFortran.f90
@@ -0,0 +1,144 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Kenneth Leiter (kenneth.leiter at arl.army.mil)
+!!
+!!     Use the Xdmf Fortran Bindings to write out a simple mesh consisting of
+!!     two hexahedrons.  Link against the XdmfUtils library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  REAL*4 myPoints(3,3,4)
+  INTEGER myConnections(8,2)
+  REAL*8 myCellAttribute(2), myNodeAttribute(3,4), mySmallerNode(3,2), myTime
+  INTEGER nodeAttributeId, nodeSmallAttributeId, cellAttributeId, testSetID, tempID, variableID(3)
+
+  filename = 'function_output.xmf'//CHAR(0)
+  
+  myPoints(1,1,1) = 0
+  myPoints(2,1,1) = 0
+  myPoints(3,1,1) = 1
+  myPoints(1,2,1) = 1
+  myPoints(2,2,1) = 0
+  myPoints(3,2,1) = 1
+  myPoints(1,3,1) = 3
+  myPoints(2,3,1) = 0
+  myPoints(3,3,1) = 2
+  myPoints(1,1,2) = 0
+  myPoints(2,1,2) = 1
+  myPoints(3,1,2) = 1
+  myPoints(1,2,2) = 1
+  myPoints(2,2,2) = 1
+  myPoints(3,2,2) = 1
+  myPoints(1,3,2) = 3
+  myPoints(2,3,2) = 2
+  myPoints(3,3,2) = 2
+  myPoints(1,1,3) = 0
+  myPoints(2,1,3) = 0
+  myPoints(3,1,3) = -1
+  myPoints(1,2,3) = 1
+  myPoints(2,2,3) = 0
+  myPoints(3,2,3) = -1
+  myPoints(1,3,3) = 3
+  myPoints(2,3,3) = 0
+  myPoints(3,3,3) = -2
+  myPoints(1,1,4) = 0
+  myPoints(2,1,4) = 1
+  myPoints(3,1,4) = -1
+  myPoints(1,2,4) = 1
+  myPoints(2,2,4) = 1
+  myPoints(3,2,4) = -1
+  myPoints(1,3,4) = 3
+  myPoints(2,3,4) = 2
+  myPoints(3,3,4) = -2
+  
+  myConnections(1,1) = 0
+  myConnections(2,1) = 1
+  myConnections(3,1) = 7
+  myConnections(4,1) = 6
+  myConnections(5,1) = 3
+  myConnections(6,1) = 4
+  myConnections(7,1) = 10
+  myConnections(8,1) = 9
+  myConnections(1,2) = 1
+  myConnections(2,2) = 2
+  myConnections(3,2) = 8
+  myConnections(4,2) = 7
+  myConnections(5,2) = 4
+  myConnections(6,2) = 5
+  myConnections(7,2) = 11
+  myConnections(8,2) = 10
+  
+  myNodeAttribute(1,1) = 100
+  myNodeAttribute(1,2) = 300
+  myNodeAttribute(1,3) = 300
+  myNodeAttribute(1,4) = 500
+  myNodeAttribute(2,1) = 200
+  myNodeAttribute(2,2) = 400
+  myNodeAttribute(2,3) = 400
+  myNodeAttribute(2,4) = 600
+  myNodeAttribute(3,1) = 300
+  myNodeAttribute(3,2) = 500
+  myNodeAttribute(3,3) = 500
+  myNodeAttribute(3,4) = 700
+  
+  myCellAttribute(1) = 100
+  myCellAttribute(2) = 200
+
+  myTime = 1.0
+
+  CALL XDMFINIT(obj, filename)
+
+  CALL XDMFADDGRIDCOLLECTION(obj, "Temporal"//CHAR(0), &
+       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
+  CALL XDMFSETTIME(obj, myTime)
+
+!! Create an InformationArrays to serve as a variable
+  variableID(1) = XDMFADDINFORMATION(obj, 'Variable A'//CHAR(0), 'Initializes Variable A'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 0, 'Variable Definition A'//CHAR(0), myPoints, 36, XDMF_ARRAY_TYPE_FLOAT64)
+
+  CALL XDMFSETINFORMATIONARRAYASVARIABLE(obj, 'A'//CHAR(0), 0, 0)
+
+  variableID(2) = XDMFADDINFORMATION(obj, 'Variable B'//CHAR(0), 'Initializes Variable B'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 1, 'Variable Definition B'//CHAR(0), myConnections, 16, XDMF_ARRAY_TYPE_INT32)
+
+  CALL XDMFSETINFORMATIONARRAYASVARIABLE(obj, 'B'//CHAR(0), 1, 0)
+
+  variableID(3) = XDMFADDINFORMATION(obj, 'Variable C'//CHAR(0), 'Initializes Variable C'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 2, 'Variable Definition C'//CHAR(0), myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64)
+
+  CALL XDMFSETINFORMATIONARRAYASVARIABLE(obj, 'C'//CHAR(0), 2, 0)
+
+  CALL XdmfClearInformations(obj)
+
+  tempID = XDMFSETFUNCTIONASTOPOLOGY(obj, "B", XDMF_TOPOLOGY_TYPE_HEXAHEDRON, 0)
+
+  tempID = XDMFSETFUNCTIONASGEOMETRY(obj, 'A+1'//CHAR(0), XDMF_GEOMETRY_TYPE_XYZ)
+
+  testSetID = XDMFADDFUNCTIONASSET(obj, 'C+5'//CHAR(0), 'TestSet'//CHAR(0), XDMF_SET_TYPE_NODE)
+  tempID =  XDMFADDINFORMATION(obj, 'Attrib1'//CHAR(0), 'This is Attribute 1'//CHAR(0))
+  nodeAttributeId = XDMFADDFUNCTIONASATTRIBUTE(obj, 'C+3'//CHAR(0), 'NodeValues'//CHAR(0), &
+       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR)
+  PRINT *, 'Node Attribute ID: ', nodeAttributeId
+  tempID = XDMFADDINFORMATION(obj, 'Grid1'//CHAR(0), 'This is Grid 1'//CHAR(0))
+  tempID = XDMFADDINFORMATION(obj, 'SubInformation'//CHAR(0), 'This is an information inside an information'//CHAR(0))
+  CALL XDMFADDFUNCTIONASINFORMATIONARRAY(obj, 'A|A'//CHAR(0), 1, 'Array'//CHAR(0))
+  CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(1))
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(2))
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(3))
+  CALL XDMFADDGRID(obj, 'TestGrid'//CHAR(0), .FALSE.)
+  CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
+  CALL XDMFWRITE(obj, filename, 10, .TRUE.)
+  CALL XDMFCLOSE(obj)
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/NestedInfoFortran.f90 b/utils/tests/Fortran/NestedInfoFortran.f90
new file mode 100644
index 0000000..9d4d29c
--- /dev/null
+++ b/utils/tests/Fortran/NestedInfoFortran.f90
@@ -0,0 +1,41 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Andrew Burns (andrew.j.burns2 at us.army.mil)
+!!
+!!     Use the Xdmf Fortran Bindings to write out several links to 
+!!     data structures in different files.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  INTEGER tempID;
+
+  filename = 'nested_output.xmf'//CHAR(0)
+
+  CALL XDMFINIT(obj, filename)
+
+  tempID = XDMFADDINFORMATION(obj, 'XIncludes'//CHAR(0), '3'//CHAR(0))
+  tempID = XDMFADDINFORMATION(obj, "testoutput.xmf"//CHAR(0), "xpointer(//Xdmf/Domain/Grid[1])"//CHAR(0))
+  tempID = XDMFADDINFORMATION(obj, "testoutput2.xmf"//CHAR(0), "xpointer(//Xdmf/Domain/Grid[1])"//CHAR(0))
+  tempID = XDMFADDINFORMATION(obj, "editedtestoutput.xmf"//CHAR(0), "xpointer(//Xdmf/Domain/Grid[1])"//CHAR(0))
+  CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+  CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+  CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+!! The Information will be added to the Grid Collection
+  CALL XDMFADDGRIDCOLLECTION(obj, "MultiFile Reference"//CHAR(0), &
+                             XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
+  CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
+  CALL XDMFWRITE(obj, filename, 10, .TRUE.)
+  CALL XDMFCLOSE(obj)
+
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/OutputTestXdmfFortran.f90 b/utils/tests/Fortran/OutputTestXdmfFortran.f90
new file mode 100644
index 0000000..8705d0f
--- /dev/null
+++ b/utils/tests/Fortran/OutputTestXdmfFortran.f90
@@ -0,0 +1,196 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Kenneth Leiter (kenneth.leiter at arl.army.mil)
+!!
+!!     Use the Xdmf Fortran Bindings to write out a simple mesh consisting of
+!!     two hexahedrons.  Link against the XdmfUtils library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  REAL*4 myPoints(3,3,4)
+  INTEGER myConnections(8,2), myDimensions(3)
+  REAL*8 myCellAttribute(2), myNodeAttribute(3,4), mySmallerNode(3,2), myTime, myOrigin(3), myBrick(3)
+  INTEGER nodeAttributeId, nodeSmallAttributeId, cellAttributeId, testSetID, testMapID, tempID
+
+  filename = 'my_output.xmf'//CHAR(0)
+  
+  myPoints(1,1,1) = 0
+  myPoints(2,1,1) = 0
+  myPoints(3,1,1) = 1
+  myPoints(1,2,1) = 1
+  myPoints(2,2,1) = 0
+  myPoints(3,2,1) = 1
+  myPoints(1,3,1) = 3
+  myPoints(2,3,1) = 0
+  myPoints(3,3,1) = 2
+  myPoints(1,1,2) = 0
+  myPoints(2,1,2) = 1
+  myPoints(3,1,2) = 1
+  myPoints(1,2,2) = 1
+  myPoints(2,2,2) = 1
+  myPoints(3,2,2) = 1
+  myPoints(1,3,2) = 3
+  myPoints(2,3,2) = 2
+  myPoints(3,3,2) = 2
+  myPoints(1,1,3) = 0
+  myPoints(2,1,3) = 0
+  myPoints(3,1,3) = -1
+  myPoints(1,2,3) = 1
+  myPoints(2,2,3) = 0
+  myPoints(3,2,3) = -1
+  myPoints(1,3,3) = 3
+  myPoints(2,3,3) = 0
+  myPoints(3,3,3) = -2
+  myPoints(1,1,4) = 0
+  myPoints(2,1,4) = 1
+  myPoints(3,1,4) = -1
+  myPoints(1,2,4) = 1
+  myPoints(2,2,4) = 1
+  myPoints(3,2,4) = -1
+  myPoints(1,3,4) = 3
+  myPoints(2,3,4) = 2
+  myPoints(3,3,4) = -2
+  
+  myConnections(1,1) = 0
+  myConnections(2,1) = 1
+  myConnections(3,1) = 7
+  myConnections(4,1) = 6
+  myConnections(5,1) = 3
+  myConnections(6,1) = 4
+  myConnections(7,1) = 10
+  myConnections(8,1) = 9
+  myConnections(1,2) = 1
+  myConnections(2,2) = 2
+  myConnections(3,2) = 8
+  myConnections(4,2) = 7
+  myConnections(5,2) = 4
+  myConnections(6,2) = 5
+  myConnections(7,2) = 11
+  myConnections(8,2) = 10
+  
+  myNodeAttribute(1,1) = 100
+  myNodeAttribute(1,2) = 300
+  myNodeAttribute(1,3) = 300
+  myNodeAttribute(1,4) = 500
+  myNodeAttribute(2,1) = 200
+  myNodeAttribute(2,2) = 400
+  myNodeAttribute(2,3) = 400
+  myNodeAttribute(2,4) = 600
+  myNodeAttribute(3,1) = 300
+  myNodeAttribute(3,2) = 500
+  myNodeAttribute(3,3) = 500
+  myNodeAttribute(3,4) = 700
+  
+  myCellAttribute(1) = 100
+  myCellAttribute(2) = 200
+
+  myDimensions(1) = 12
+  myDimensions(2) = 12
+  myDimensions(3) = 12
+
+  myOrigin(1) = 0
+  myOrigin(2) = 0
+  myOrigin(3) = 0
+
+  myBrick(1) = 12
+  myBrick(2) = 12
+  myBrick(3) = 12
+
+  myTime = 1.0
+
+  CALL XDMFINIT(obj, filename)
+
+  CALL XDMFSETMAXFILESIZE(obj, 1)
+  CALL XDMFSETALLOWSETSPLITTING(obj, .TRUE.)
+  CALL XDMFINITHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
+
+  tempID = XDMFADDINFORMATION(obj, 'GridCollection1'//CHAR(0), 'This is Grid collection 1'//CHAR(0))
+  CALL XDMFADDGRIDCOLLECTION(obj, "Temporal"//CHAR(0), &
+       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
+  CALL XDMFADDMAP(obj, "TestMap"//CHAR(0))
+  CALL XDMFADDREMOTENODEID(obj, 0, 1, 2, 3)
+  CALL XDMFADDREMOTENODEID(obj, 0, 1, 2, 4)
+  CALL XDMFADDREMOTENODEID(obj, 0, 1, 3, 3)
+  CALL XDMFADDREMOTENODEID(obj, 0, 1, 3, 5)
+  testMapID = XDMFSTOREMAP(obj, 0)
+  CALL XDMFADDREMOTENODEID(obj, 0, 1, 3, 8)
+  CALL XDMFSETTIME(obj, myTime)
+!! Unstructured Only
+  tempID = XDMFSETTOPOLOGY(obj, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, 16, &
+       XDMF_ARRAY_TYPE_INT32, myConnections, 0)
+  CALL XDMFSETTOPOLOGYHDF5(obj, 'my_output.h5'//CHAR(0), 'Topology'//CHAR(0), 0, 1, 16, 16)
+!! /Unstructured Only
+!! Curvilinear and Rectilinear Only
+  tempID = XDMFSETDIMENSIONS(obj, 3, XDMF_ARRAY_TYPE_INT32, myDimensions)
+  CALL XDMFSETDIMENSIONSHDF5(obj, 'my_output.h5'//CHAR(0), 'Dimensions'//CHAR(0), 0, 1, 3, 3)
+!! /Curvilinear and Rectilinear Only
+!! Unstructured and Curvilinear Only
+  tempID = XDMFSETGEOMETRY(obj, XDMF_GEOMETRY_TYPE_XYZ, 36, &
+       XDMF_ARRAY_TYPE_FLOAT32, myPoints)
+  CALL XDMFSETGEOMETRYHDF5(obj, 'my_output.h5'//CHAR(0), 'Geometry'//CHAR(0), 0, 1, 36, 36)
+!! /Unstructured and Curvilinear Only
+!! Rectilinear Only
+  tempID = XDMFADDCOORDINATE(obj, "XCoordinates"//CHAR(0), 12, XDMF_ARRAY_TYPE_FLOAT32, myPoints(1,1,1))
+  tempID = XDMFADDCOORDINATE(obj, "YCoordinates"//CHAR(0), 12, XDMF_ARRAY_TYPE_FLOAT32, myPoints(1,2,2))
+  tempID = XDMFADDCOORDINATE(obj, "ZCoordinates"//CHAR(0), 12, XDMF_ARRAY_TYPE_FLOAT32, myPoints(1,3,3))
+  CALL XDMFSETCOORDINATEHDF5(obj, 0, 'my_output.h5'//CHAR(0), 'XCoordinate'//CHAR(0), 0, 1, 12, 12)
+  CALL XDMFSETCOORDINATEHDF5(obj, 1, 'my_output.h5'//CHAR(0), 'YCoordinate'//CHAR(0), 0, 1, 12, 12)
+  CALL XDMFSETCOORDINATEHDF5(obj, 2, 'my_output.h5'//CHAR(0), 'ZCoordinate'//CHAR(0), 0, 1, 12, 12)
+!! /Rectilinear Only
+!! Regular Only
+  tempID = XDMFSETORIGIN(obj, 3, XDMF_ARRAY_TYPE_FLOAT64, myOrigin)
+  CALL XDMFSETORIGINHDF5(obj, 'my_output.h5'//CHAR(0), 'Origin'//CHAR(0), 0, 1, 3, 3)
+  tempID = XDMFSETBRICK(obj, 3, XDMF_ARRAY_TYPE_FLOAT64, myBrick)
+  CALL XDMFSETBRICKHDF5(obj, 'my_output.h5'//CHAR(0), 'Brick'//CHAR(0), 0, 1, 3, 3)
+!! /Regular Only
+  testSetID = XDMFADDSET(obj, 'TestSet'//CHAR(0), XDMF_SET_TYPE_NODE, myNodeAttribute,  12, XDMF_ARRAY_TYPE_FLOAT64)
+  tempID =  XDMFADDINFORMATION(obj, 'Attrib1'//CHAR(0), 'This is Attribute 1'//CHAR(0))
+  nodeAttributeId = XDMFADDATTRIBUTE(obj, 'NodeValues'//CHAR(0), &
+       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 12, &
+       XDMF_ARRAY_TYPE_FLOAT64, myNodeAttribute)
+  CALL XDMFSETATTRIBUTEHDF5(obj, 0, 'my_output.h5'//CHAR(0), 'NodeAttr'//CHAR(0), 0, 1, 12, 12)
+  PRINT *, 'Node Attribute ID: ', nodeAttributeId
+  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, mySmallerNode, XDMF_ARRAY_TYPE_FLOAT64, 6, 0, 1, 1)
+  tempID =  XDMFADDINFORMATION(obj, 'Attrib2'//CHAR(0), 'This is Attribute 2'//CHAR(0))
+  cellAttributeId = XDMFADDATTRIBUTE(obj, 'CellValues'//CHAR(0), &
+       XDMF_ATTRIBUTE_CENTER_CELL, XDMF_ATTRIBUTE_TYPE_SCALAR, 2, &
+       XDMF_ARRAY_TYPE_FLOAT64, myCellAttribute)
+  CALL XDMFSETATTRIBUTEHDF5(obj, 1, 'my_output.h5'//CHAR(0), 'CellAttr'//CHAR(0), 0, 1, 2, 2)
+  PRINT *, 'Cell Attribute ID: ', cellAttributeId
+  nodeSmallAttributeId = XDMFADDATTRIBUTE(obj, 'SmallNodeValues'//CHAR(0), &
+       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR, 6, &
+       XDMF_ARRAY_TYPE_FLOAT64, mySmallerNode)
+  CALL XDMFSETATTRIBUTEHDF5(obj, 2, 'my_output.h5'//CHAR(0), 'SmallNodeAttr'//CHAR(0), 0, 1, 6, 6)
+  PRINT *, 'Node Attribute ID: ', nodeSmallAttributeId
+  tempID = XDMFADDINFORMATION(obj, 'Grid1'//CHAR(0), 'This is Grid 1'//CHAR(0))
+  tempID = XDMFADDINFORMATION(obj, 'SubInformation'//CHAR(0), 'This is an information inside an information'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 1, 'Array'//CHAR(0), myBrick, 3, XDMF_ARRAY_TYPE_FLOAT64)
+  CALL XDMFMODIFYINFORMATIONARRAY(obj, 1, 0, myBrick, XDMF_ARRAY_TYPE_FLOAT64, 3, 3, 1, 1)
+  CALL XDMFSETINFORMATIONARRAYHDF5(obj, 1, 0, 'my_output.h5'//CHAR(0), 'Info Array'//CHAR(0), 0, 1, 3, 3)
+  CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+  CALL XDMFADDGRID(obj, 'TestGrid'//CHAR(0), .FALSE.)
+  myTime = 2.0
+
+  CALL XDMFSETTIME(obj, myTime)
+  CALL XDMFADDPREVIOUSATTRIBUTE(obj, cellAttributeId)
+  CALL XDMFADDPREVIOUSMAP(obj, testMapID)
+  CALL XDMFADDPREVIOUSSET(obj, testSetID)
+  CALL XDMFADDPREVIOUSATTRIBUTE(obj, nodeAttributeId)
+  CALL XDMFADDGRID(obj, 'Identical'//CHAR(0), .FALSE.)
+  CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
+!!  CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0), .TRUE.)
+  CALL XDMFWRITE(obj, filename, 10, .TRUE.)
+  CALL XDMFCLOSE(obj)
+
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/SubsetTestXdmfFortran.f90 b/utils/tests/Fortran/SubsetTestXdmfFortran.f90
new file mode 100644
index 0000000..e9e41cf
--- /dev/null
+++ b/utils/tests/Fortran/SubsetTestXdmfFortran.f90
@@ -0,0 +1,169 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Kenneth Leiter (kenneth.leiter at arl.army.mil)
+!!
+!!     Use the Xdmf Fortran Bindings to write out a simple mesh consisting of
+!!     two hexahedrons.  Link against the XdmfUtils library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+
+PROGRAM XdmfFortranExample
+ 
+  Implicit none
+  INCLUDE 'Xdmf.f'
+
+  
+
+  INTEGER*8 obj
+  character*256 filename
+  REAL*4 myPoints(3,3,4)
+  INTEGER myConnections(8,2)
+  REAL*8 myCellAttribute(2), myNodeAttribute(3,4), mySmallerNode(3,2), myTime
+  INTEGER nodeAttributeId, nodeSmallAttributeId, cellAttributeId, testSetID, tempID, variableID(3)
+
+  filename = 'subset_output.xmf'//CHAR(0)
+  
+  myPoints(1,1,1) = 0
+  myPoints(2,1,1) = 0
+  myPoints(3,1,1) = 1
+  myPoints(1,2,1) = 1
+  myPoints(2,2,1) = 0
+  myPoints(3,2,1) = 1
+  myPoints(1,3,1) = 3
+  myPoints(2,3,1) = 0
+  myPoints(3,3,1) = 2
+  myPoints(1,1,2) = 0
+  myPoints(2,1,2) = 1
+  myPoints(3,1,2) = 1
+  myPoints(1,2,2) = 1
+  myPoints(2,2,2) = 1
+  myPoints(3,2,2) = 1
+  myPoints(1,3,2) = 3
+  myPoints(2,3,2) = 2
+  myPoints(3,3,2) = 2
+  myPoints(1,1,3) = 0
+  myPoints(2,1,3) = 0
+  myPoints(3,1,3) = -1
+  myPoints(1,2,3) = 1
+  myPoints(2,2,3) = 0
+  myPoints(3,2,3) = -1
+  myPoints(1,3,3) = 3
+  myPoints(2,3,3) = 0
+  myPoints(3,3,3) = -2
+  myPoints(1,1,4) = 0
+  myPoints(2,1,4) = 1
+  myPoints(3,1,4) = -1
+  myPoints(1,2,4) = 1
+  myPoints(2,2,4) = 1
+  myPoints(3,2,4) = -1
+  myPoints(1,3,4) = 3
+  myPoints(2,3,4) = 2
+  myPoints(3,3,4) = -2
+  
+  myConnections(1,1) = 0
+  myConnections(2,1) = 1
+  myConnections(3,1) = 7
+  myConnections(4,1) = 6
+  myConnections(5,1) = 3
+  myConnections(6,1) = 4
+  myConnections(7,1) = 10
+  myConnections(8,1) = 9
+  myConnections(1,2) = 1
+  myConnections(2,2) = 2
+  myConnections(3,2) = 8
+  myConnections(4,2) = 7
+  myConnections(5,2) = 4
+  myConnections(6,2) = 5
+  myConnections(7,2) = 11
+  myConnections(8,2) = 10
+  
+  myNodeAttribute(1,1) = 100
+  myNodeAttribute(1,2) = 300
+  myNodeAttribute(1,3) = 300
+  myNodeAttribute(1,4) = 500
+  myNodeAttribute(2,1) = 200
+  myNodeAttribute(2,2) = 400
+  myNodeAttribute(2,3) = 400
+  myNodeAttribute(2,4) = 600
+  myNodeAttribute(3,1) = 300
+  myNodeAttribute(3,2) = 500
+  myNodeAttribute(3,3) = 500
+  myNodeAttribute(3,4) = 700
+  
+  myCellAttribute(1) = 100
+  myCellAttribute(2) = 200
+
+  myTime = 1.0
+
+  CALL XDMFINIT(obj, filename)
+
+  CALL XDMFADDGRIDCOLLECTION(obj, "Temporal"//CHAR(0), &
+       XDMF_GRID_COLLECTION_TYPE_TEMPORAL)
+  CALL XDMFSETTIME(obj, myTime)
+
+!! Create an InformationArrays to serve as a variable
+  variableID(1) = XDMFADDINFORMATION(obj, 'Variable A'//CHAR(0), 'Initializes Variable A'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 0, 'Variable Definition A'//CHAR(0), myPoints, 36, XDMF_ARRAY_TYPE_FLOAT64)
+
+  CALL XDMFSETINFORMATIONARRAYASVARIABLE(obj, 'A'//CHAR(0), 0, 0)
+
+  variableID(2) = XDMFADDINFORMATION(obj, 'Variable B'//CHAR(0), 'Initializes Variable B'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 1, 'Variable Definition B'//CHAR(0), myConnections, 16, XDMF_ARRAY_TYPE_INT32)
+
+  CALL XDMFSETINFORMATIONARRAYASVARIABLE(obj, 'B'//CHAR(0), 1, 0)
+
+  variableID(3) = XDMFADDINFORMATION(obj, 'Variable C'//CHAR(0), 'Initializes Variable C'//CHAR(0))
+  CALL XDMFADDINFORMATIONARRAY(obj, 2, 'Variable Definition C'//CHAR(0), myNodeAttribute, 12, XDMF_ARRAY_TYPE_FLOAT64)
+
+  CALL XDMFSETINFORMATIONARRAYASVARIABLE(obj, 'C'//CHAR(0), 2, 0)
+
+  CALL XdmfClearInformations(obj)
+
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(2))
+
+  CALL XDMFSETINFORMATIONARRAYASSUBSETREFERENCE(obj, 0, 0)
+
+  CALL XdmfClearInformations(obj)
+
+  tempID = XDMFSETSUBSETASTOPOLOGY(obj, 0, 1, 12, XDMF_TOPOLOGY_TYPE_HEXAHEDRON, 0)
+
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(1))
+
+  CALL XDMFSETINFORMATIONARRAYASSUBSETREFERENCE(obj, 0, 0)
+
+  CALL XdmfClearInformations(obj)
+
+  tempID = XDMFSETSUBSETASGEOMETRY(obj, 0, 1, 36, XDMF_GEOMETRY_TYPE_XYZ)
+
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(3))
+
+  CALL XDMFSETINFORMATIONARRAYASSUBSETREFERENCE(obj, 0, 0)
+
+  CALL XdmfClearInformations(obj)
+
+  testSetID = XDMFADDSUBSETASSET(obj, 0, 1, 12, 'TestSet'//CHAR(0), XDMF_SET_TYPE_NODE)
+  tempID =  XDMFADDINFORMATION(obj, 'Attrib1'//CHAR(0), 'This is Attribute 1'//CHAR(0))
+  nodeAttributeId = XDMFADDSUBSETASATTRIBUTE(obj, 0, 1, 12, 'NodeValues'//CHAR(0), &
+       XDMF_ATTRIBUTE_CENTER_NODE, XDMF_ATTRIBUTE_TYPE_SCALAR)
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(1))
+
+  CALL XDMFSETINFORMATIONARRAYASSUBSETREFERENCE(obj, 0, 0)
+
+  CALL XdmfClearInformations(obj)
+
+  PRINT *, 'Node Attribute ID: ', nodeAttributeId
+  tempID = XDMFADDINFORMATION(obj, 'Grid1'//CHAR(0), 'This is Grid 1'//CHAR(0))
+  tempID = XDMFADDINFORMATION(obj, 'SubInformation'//CHAR(0), 'This is an information inside an information'//CHAR(0))
+  CALL XDMFADDSUBSETASINFORMATIONARRAY(obj, 0, 1, 36, 1, 'Array'//CHAR(0))
+  CALL XDMFINSERTINFORMATIONINTOINFORMATION(obj, 0, 1, .TRUE.)
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(1))
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(2))
+  CALL XDMFADDPREVIOUSINFORMATION(obj, variableID(3))
+  CALL XDMFADDGRID(obj, 'TestGrid'//CHAR(0), .FALSE.)
+  CALL XDMFCLOSEGRIDCOLLECTION(obj, .TRUE.)
+  CALL XDMFWRITE(obj, filename, 10, .TRUE.)
+  CALL XDMFCLOSE(obj)
+
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Fortran/TestXdmfFortran.f90 b/utils/tests/Fortran/TestXdmfFortran.f90
new file mode 100644
index 0000000..b468b71
--- /dev/null
+++ b/utils/tests/Fortran/TestXdmfFortran.f90
@@ -0,0 +1,318 @@
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+!!
+!!     AUTHOR: Andrew Burns (andrew.j.burns2 at us.army.mil)
+!!
+!!     Read the first hexahedron from the file generated by the
+!!     OutputTestXdmfFortran program, then print the results for comparison.
+!!     
+!!     Link against the XdmfUtils library to compile.
+!!
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+PROGRAM XdmfFortranExample
+  
+  IMPLICIT NONE
+  INCLUDE 'Xdmf.f'
+
+  INTEGER*8 obj
+  character*256 infilename, itemName, itemKey, itemValue, itemTag
+  REAL*4 myPointsOutput(36)
+  INTEGER myConnectionsOutput(16)
+  INTEGER myMappedNodes(3), myDimensions(3)
+  REAL*8 myCellAttributeOutput(4), myNodeAttributeOutput(12), mySetOutput(12), myTestTime, myBrick(3), myOrigin(3)
+  INTEGER numContained, typeHolder
+
+  
+  infilename = 'my_output.xmf'//CHAR(0)
+  
+  CALL XDMFINIT(obj)
+  CALL XDMFREAD(obj, infilename)
+
+  PRINT *, 'Load From: ', TRIM(infilename)
+  PRINT *, 'Domain Properties'
+  CALL XDMFRETRIEVEDOMAINNUMPROPERTIES(obj, numContained)
+  PRINT *, 'number of Properties: ', numContained
+  CALL XDMFRETRIEVEDOMAINTAG(obj, itemTag, 256)
+  PRINT *, 'Domain Tag: ', itemTag
+  CALL XDMFRETRIEVENUMDOMAINGRIDCOLLECTIONS(obj, numContained)
+  PRINT *, 'Number of Grid Collections: ',   numContained
+  CALL XDMFOPENDOMAINGRIDCOLLECTION(obj, 0, 1, 1, 1, 1)
+  CALL XDMFRETRIEVENUMINFORMATION(obj, numContained)
+  PRINT *, 'Number of Information for Grid: ', numContained
+  PRINT *, 'Information 0'
+  CALL XDMFRETRIEVEINFORMATIONNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEINFORMATIONPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Information Tag: ', itemTag
+  CALL XDMFRETRIEVEINFORMATION(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEINFORMATIONBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEGRIDCOLLECTIONNUMGRIDS(obj, XDMF_GRID_TYPE_UNSTRUCTURED,  numContained)
+  PRINT *, 'Number of Grids contained in the Grid Collection: ', numContained
+  CALL XDMFOPENGRIDCOLLECTIONGRID(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 1, 1, 1, 1)
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDNAME(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0,  itemName, 256)
+  PRINT *, "Grid Name: ", itemName
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDTAG(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, itemTag, 256)
+  PRINT *, "Grid Tag: ", itemTag
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDNUMPROPERTIES(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  PRINT *, "Grid Properties: "
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDPROPERTY(obj, XDMF_GRID_TYPE_UNSTRUCTURED, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEGRIDCOLLECTIONGRIDPROPERTYBYKEY(obj, XDMF_GRID_TYPE_UNSTRUCTURED,  0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVETIME(obj, myTestTime)
+  PRINT *, 'Grid Time: ', myTestTime
+  CALL XDMFRETRIEVEGRIDCOLLECTIONTYPE(obj, typeHolder)
+  PRINT *, 'Grid Collection Type: ', typeHolder
+  CALL XDMFRETRIEVENUMATTRIBUTES(obj, numContained)
+  PRINT *, 'Number of Grid Attributes: ', numContained
+  PRINT *, 'Map'
+  CALL XDMFRETRIEVEMAPNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, 'Number of Properties: ', numContained
+  CALL XDMFRETRIEVEMAPPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEMAPPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEREMOTENODEIDS(obj, 0, 1, 3, myMappedNodes)
+  PRINT *, 'Nodes: ', myMappedNodes
+!!!! Unstructured and Curvilinear only
+  PRINT *, 'Geometry'
+  CALL XDMFRETRIEVEGEOMETRYNUMPROPERTIES(obj, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEGEOMETRYPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEGEOMETRYPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEGEOMETRYTAG(obj, itemTag, 256)
+  PRINT *, 'Geometry Tag: ', itemTag
+  CALL XDMFRETRIEVEGEOMETRYTYPE(obj, typeHolder)
+  PRINT *, 'Geometry Type: ', typeHolder
+  CALL XDMFRETRIEVEGEOMETRYVALUETYPE(obj, typeHolder)
+  PRINT *, 'Geometry Value Type: ', typeHolder
+  CALL XDMFRETRIEVEGEOMETRYSIZE(obj, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVEGEOMETRYNUMPOINTS(obj, numContained)
+  PRINT *, 'Geometry Number of Points: ', numContained
+  CALL XDMFRETRIEVEGEOMETRYVALUES(obj, myPointsOutput, XDMF_ARRAY_TYPE_FLOAT32, 36, 0, 1, 1)
+  PRINT 1,  myPointsOutput
+1 FORMAT (' ', 3F5.1, '\n ', 3F5.1, '\n ', 3F5.1, '\n')
+!!!! / Unstructured and Curvilinear Grid only
+!!!! Unstructured Grid only
+  PRINT *, 'Topology'
+  CALL XDMFRETRIEVETOPOLOGYNUMPROPERTIES(obj, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVETOPOLOGYPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVETOPOLOGYPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVETOPOLOGYTAG(obj, itemTag, 256)
+  PRINT *, 'Topology Tag: ', itemTag
+  CALL XDMFRETRIEVETOPOLOGYTYPE(obj, typeHolder)
+  PRINT *, 'Topology Type: ', typeHolder
+  CALL XDMFRETRIEVETOPOLOGYVALUETYPE(obj, typeHolder)
+  PRINT *, 'Topology Value Type: ', typeHolder
+  CALL XDMFRETRIEVETOPOLOGYSIZE(obj, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVETOPOLOGYNUMELEMENTS(obj, numContained)
+  PRINT *, 'Topology Number of elements: ', numContained
+  CALL XDMFRETRIEVETOPOLOGYVALUES(obj, myConnectionsOutput, XDMF_ARRAY_TYPE_INT32, 16, 0, 1, 1)
+  PRINT 2, myConnectionsOutput
+2 FORMAT (' ', 8I3)
+!!!! /Unstructured Grid Only
+!!!! Curvilinear and Regular only
+!!  PRINT *, 'Dimensions'
+!!  CALL XDMFRETRIEVEDIMENSIONSNUMPROPERTIES(obj, numContained)
+!!  PRINT *, 'Number of Properties: ', numContained
+!!  CALL XDMFRETRIEVEDIMENSIONSPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, "Key: ", itemKey
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEDIMENSIONSPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEDIMENSIONSTAG(obj, itemTag, 256)
+!!  PRINT *, "Dimension Tag: ", itemTag
+!!  CALL XDMFRETRIEVEDIMENSIONSVALUETYPE(obj, typeHolder)
+!!  PRINT *, "Dimension Value Type: ", typeHolder
+!!  CALL XDMFRETRIEVEDIMENSIONSSIZE(obj, numContained)
+!!  PRINT *, "Number of Values: ", numContained
+!!  CALL XDMFRETRIEVEDIMENSIONSVALUES(obj, myDimensions, XDMF_ARRAY_TYPE_INT32, 3, 0, 1, 1)
+!!  PRINT *, myDimensions
+!!!! /Curvilinear and Regular only
+!!!! Rectilinear Only
+!!  PRINT *, 'Coordinates'
+!!  CALL XDMFRETRIEVENUMCOORDINATES(obj, numContained)
+!!  PRINT *, 'Number of Coordinates: ', numContained
+!!  CALL XDMFRETRIEVECOORDINATEVALUETYPE(obj, 0, typeHolder)
+!!  PRINT *, 'Coordinate Value Type', typeHolder
+!!  CALL XDMFRETRIEVECOORDINATENUMPROPERTIES(obj, 0, numContained)
+!!  PRINT *, 'Number of Properties', numContained
+!!  CALL XDMFRETRIEVECOORDINATEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, 'Key: ', itemKey
+!!  PRINT *, 'Value: ', itemValue
+!!  CALL XDMFRETRIEVECOORDINATEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+!!  PRINT *, 'Value: ', itemValue
+!!  CALL XDMFRETRIEVECOORDINATESIZE(obj, 0, numContained)
+!!  PRINT *, 'Size of Coordinate 0', numContained
+!!  CALL XDMFRETRIEVECOORDINATESIZE(obj, 1, numContained)
+!!  PRINT *, 'Size of Coordinate 1', numContained
+!!  CALL XDMFRETRIEVECOORDINATESIZE(obj, 2, numContained)
+!!  PRINT *, 'Size of Coordinate 2', numContained
+!!  CALL XDMFRETRIEVECOORDINATEVALUES(obj, 0, myPointsOutput(1), XDMF_ARRAY_TYPE_FLOAT32, 12, 0, 1, 1)
+!!  CALL XDMFRETRIEVECOORDINATEVALUES(obj, 0, myPointsOutput(13), XDMF_ARRAY_TYPE_FLOAT32, 12, 0, 1, 1)
+!!  CALL XDMFRETRIEVECOORDINATEVALUES(obj, 0, myPointsOutput(25), XDMF_ARRAY_TYPE_FLOAT32, 12, 0, 1, 1)
+!!  PRINT 1, myPointsOutput
+!!!! /Rectilinear Only
+!!!! Regular Grid Only
+!! Brick and Origin
+!!  PRINT *, 'Brick'
+!!  CALL XDMFRETRIEVEBRICKNUMPROPERTIES(obj, numContained)
+!!  PRINT *, 'Number of Properties: ', numContained
+!!  CALL XDMFRETRIEVEBRICKPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, "Key: ", itemKey
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEBRICKPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEBRICKTAG(obj, itemTag, 256)
+!!  PRINT *, "Brick Tag: ", itemTag
+!!  CALL XDMFRETRIEVEBRICKVALUETYPE(obj, typeHolder)
+!!  PRINT *, "Brick Value Type: ", typeHolder
+!!  CALL XDMFRETRIEVEBRICKSIZE(obj, numContained)
+!!  PRINT *, "Number of Values: ", numContained
+!!  CALL XDMFRETRIEVEBRICKVALUES(obj, myBrick, XDMF_ARRAY_TYPE_FLOAT64, 3, 0, 1, 1)
+!!  PRINT *, myBrick
+!!  PRINT *, 'Origin'
+!!  CALL XDMFRETRIEVEORIGINNUMPROPERTIES(obj, numContained)
+!!  PRINT *, 'Number of Properties: ', numContained
+!!  CALL XDMFRETRIEVEORIGINPROPERTY(obj, 0, itemKey, 256, itemValue, 256)
+!!  PRINT *, "Key: ", itemKey
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEORIGINPROPERTYBYKEY(obj, itemKey, itemValue, 256)
+!!  PRINT *, "Value: ", itemValue
+!!  CALL XDMFRETRIEVEORIGINTAG(obj, itemTag, 256)
+!!  PRINT *, "Origin Tag: ", itemTag
+!!  CALL XDMFRETRIEVEORIGINVALUETYPE(obj, typeHolder)
+!!  PRINT *, "Origin Value Type: ", typeHolder
+!!  CALL XDMFRETRIEVEORIGINSIZE(obj, numContained)
+!!  PRINT *, "Number of Values: ", numContained
+!!  CALL XDMFRETRIEVEORIGINVALUES(obj, myOrigin, XDMF_ARRAY_TYPE_FLOAT64, 3, 0, 1, 1)
+!!  PRINT *, myOrigin
+!!!! /Regular Grid Only
+  CALL XDMFRETRIEVENUMSETS(obj, numContained)
+  PRINT *, '\nNumber of Sets:', numContained
+  PRINT *, '\nSet 0'
+  CALL XDMFRETRIEVESETNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, 'Number of Properties: ', numContained
+  CALL XDMFRETRIEVESETPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVESETPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVESETTYPE(obj, 0, typeHolder)
+  PRINT *, 'Set Type: ', typeHolder
+  CALL XDMFRETRIEVESETVALUETYPE(obj, 0, typeHolder)
+  PRINT *, 'Set Value Type: ', typeHolder
+  CALL XDMFRETRIEVESETNAME(obj, 0, itemName, 256)
+  PRINT *, 'Set Name: ', itemName
+  CALL XDMFRETRIEVESETTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Set Tag: ', itemTag
+  CALL XDMFRETRIEVESETVALUES(obj, 0, mySetOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
+  PRINT 3, mySetOutput
+  PRINT *, '\nAttribute 0'
+  CALL XDMFRETRIEVEATTRIBUTENAME(obj, 0, itemName, 256)
+  PRINT *, 'Attribute Name: ', itemName
+  CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTETAG(obj, 0, itemTag, 256)
+  PRINT *, 'Attribute Tag: ', itemTag
+  CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 0, typeHolder)
+  PRINT *, 'Attribute Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 0, typeHolder)
+  PRINT *, 'Attribute Center: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 0, typeHolder)
+  PRINT *, 'Attribute Value Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 0, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 0, myNodeAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 12, 0, 1, 1)
+  PRINT 3, myNodeAttributeOutput
+3 FORMAT (' ', 3F6.1)
+  CALL XDMFOPENATTRIBUTE(obj, 0)
+  CALL XDMFRETRIEVENUMINFORMATION(obj, numContained)
+  PRINT *, 'Number of Information for Grid and Attribute 0: ', numContained
+  PRINT *, 'Information 0'
+  CALL XDMFRETRIEVEINFORMATIONNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEINFORMATIONPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Information Tag: ', itemTag
+  CALL XDMFRETRIEVEINFORMATION(obj, 1, itemKey, 256, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEINFORMATIONBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, 'Value: ', itemValue
+  PRINT *, '\nAttribute 1'
+  CALL XDMFRETRIEVEATTRIBUTENUMPROPERTIES(obj, 1, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTY(obj, 1, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTEPROPERTYBYKEY(obj, 1, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEATTRIBUTENAME(obj, 1, itemName, 256)
+  PRINT *, 'Attribute Name: ', itemName
+  CALL XDMFRETRIEVEATTRIBUTETAG(obj, 1, itemTag, 256)
+  PRINT *, 'Attribute Tag: ', itemTag
+  CALL XDMFRETRIEVEATTRIBUTETYPE(obj, 1, typeHolder)
+  PRINT *, 'Attribute Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTECENTER(obj, 1, typeHolder)
+  PRINT *, 'Attribute Center: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTEVALUETYPE(obj, 1, typeHolder)
+  PRINT *, 'Attribute Value Type: ', typeHolder
+  CALL XDMFRETRIEVEATTRIBUTESIZE(obj, 1, numContained)
+  PRINT *, 'Number of Values: ', numContained
+  CALL XDMFRETRIEVEATTRIBUTEVALUES(obj, 1, myCellAttributeOutput, XDMF_ARRAY_TYPE_FLOAT64, 4, 0, 1, 1)
+  PRINT 4, myCellAttributeOutput
+4 FORMAT (' ', F6.1)
+  CALL XDMFOPENATTRIBUTE(obj, 1)
+  CALL XDMFRETRIEVENUMINFORMATION(obj, numContained)
+  PRINT *, 'Number of Information for Grid and Attribute 0: ', numContained
+  PRINT *, 'Information 0'
+  CALL XDMFRETRIEVEINFORMATIONNUMPROPERTIES(obj, 0, numContained)
+  PRINT *, "Number of Properties: ", numContained
+  CALL XDMFRETRIEVEINFORMATIONPROPERTY(obj, 0, 0, itemKey, 256, itemValue, 256)
+  PRINT *, "Key: ", itemKey
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONPROPERTYBYKEY(obj, 0, itemKey, itemValue, 256)
+  PRINT *, "Value: ", itemValue
+  CALL XDMFRETRIEVEINFORMATIONTAG(obj, 0, itemTag, 256)
+  PRINT *, 'Information Tag: ', itemTag
+  CALL XDMFRETRIEVEINFORMATION(obj, 0, itemKey, 256, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+  CALL XDMFRETRIEVEINFORMATIONBYKEY(obj, itemKey, itemValue, 256)
+  PRINT *, 'Key: ', itemKey
+  PRINT *, 'Value: ', itemValue
+
+
+  CALL XDMFCLOSE(obj)
+
+END PROGRAM XdmfFortranExample
diff --git a/utils/tests/Python/CMakeLists.txt b/utils/tests/Python/CMakeLists.txt
new file mode 100644
index 0000000..6da0538
--- /dev/null
+++ b/utils/tests/Python/CMakeLists.txt
@@ -0,0 +1,31 @@
+include(AddTestsPython)
+
+# Add any dependencies that the python tests may need
+# Note: The tests already depend on their own file
+#	PYTHON_TEST_DEPENDENCIES is also set in core
+ADD_TEST_PYTHON_DEPENDENCIES("")
+
+# Add any pythonpath directories that the python tests may need
+# Note: PYTHON_TEST_PYTHONPATH is also set in core
+ADD_TEST_PYTHON_PYTHONPATH("${PYTHON_INCLUDE_MPI4PY_DIR}/../..")
+
+# Add any python tests here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have extra arguments (ie: ADD_TEST_PYTHON(testname inputfile))
+#	Read UsePythonTest.cmake for more information
+# -----------------------
+ADD_TEST_PYTHON(XdmfTestDiff)
+ADD_TEST_PYTHON(XdmfTestGeometryConverter)
+ADD_TEST_PYTHON(XdmfTestTopologyConverter)
+
+# Add any python cleanup here:
+# Note: We don't want to use a foreach loop to test the files incase we
+#	have multiple files (ie: CLEAN_TEST_PYTHON(testname outputfile1 ...))
+#	Read UseCxxTest.cmake for more information
+# ---------------------------------------
+CLEAN_TEST_PYTHON(XdmfTestDiff)
+CLEAN_TEST_PYTHON(XdmfTestGeometryConverter)
+CLEAN_TEST_PYTHON(XdmfTestTopologyConverter)
+
+# Add a custom target for all python tests
+CREATE_TARGET_TEST_PYTHON()
diff --git a/utils/tests/Python/XdmfTestDiff.py b/utils/tests/Python/XdmfTestDiff.py
new file mode 100644
index 0000000..d6604c9
--- /dev/null
+++ b/utils/tests/Python/XdmfTestDiff.py
@@ -0,0 +1,122 @@
+from Xdmf import *
+from XdmfUtils import *
+
+if __name__ == "__main__":
+  grid1 = XdmfUnstructuredGrid.New()
+
+  topology1 = XdmfTopology.New()
+
+  connectivity = [0, 1, 7, 6, 3, 4, 10, 9, 1, 2, 8, 7, 4, 5, 11, 10]
+  topology1.setType(XdmfTopologyType.Hexahedron())
+  topology1.insertAsInt32(0, connectivity, 0, 16, 1, 1)
+
+  grid1.setTopology(topology1)
+
+  geometry1 = XdmfGeometry.New();
+
+  points = [0.1, 0.1, 1.1, 1.1, 0.1, 1.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+            1.1, 1.1, 1.1, 1.1, 3.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+            0.1, -1.1, 3.1, 0.1, -2.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+            -1.1, 3.1, 2.1, -2.1]
+  geometry1.setType(XdmfGeometryType.XYZ())
+  geometry1.insertAsFloat64(0, points, 0, 36, 1, 1)
+
+  grid1.setGeometry(geometry1)
+
+  attr1 = XdmfAttribute.New()
+
+  nodeValues = [100, 200, 300, 300, 400, 500, 300, 400, 500, 500, 600,
+                700]
+  attr1.setName("Nodal Attribute")
+  attr1.setType(XdmfAttributeType.Scalar())
+  attr1.setCenter(XdmfAttributeCenter.Node())
+  attr1.insertAsInt32(0, nodeValues, 0, 12, 1, 1)
+
+  grid1.insert(attr1)
+
+  # Grid with the same structure
+
+  grid2 = XdmfUnstructuredGrid.New()
+
+  topology2 = XdmfTopology.New()
+
+  topology2.setType(XdmfTopologyType.Hexahedron())
+  topology2.insertAsInt32(0, connectivity, 0, 16, 1, 1)
+
+  grid2.setTopology(topology2)
+
+  geometry2 = XdmfGeometry.New()
+
+  geometry2.setType(XdmfGeometryType.XYZ())
+  geometry2.insertAsFloat64(0, points, 0, 36, 1, 1)
+
+  grid2.setGeometry(geometry2)
+
+  attr2 = XdmfAttribute.New()
+
+  attr2.setName("Nodal Attribute")
+  attr2.setType(XdmfAttributeType.Scalar())
+  attr2.setCenter(XdmfAttributeCenter.Node())
+  attr2.insertAsInt32(0, nodeValues, 0, 12, 1, 1)
+
+  grid2.insert(attr2)
+
+  # Grid with structure partially off, difference of 5.
+
+  grid3 = XdmfUnstructuredGrid.New()
+
+  topology3 = XdmfTopology.New()
+
+  topology3.setType(XdmfTopologyType.Hexahedron());
+  topology3.insertAsInt32(0, connectivity, 0, 16, 1, 1)
+
+  grid3.setTopology(topology3)
+
+  geometry3 = XdmfGeometry.New();
+
+  pointsdiff = [4.1, 0.1, 1.1, 1.1, 0.1, 3.1, 3.1, 0.1, 2.1, 0.1, 1.1,
+                1.1, 1.1, 1.1, 1.1, 6.1, 2.1, 2.1, 0.1, 0.1, -1.1, 1.1,
+                0.1, -1.1, 3.1, 3.1, -4.1, 0.1, 1.1, -1.1, 1.1, 1.1,
+                -1.1, 3.1, 2.1, -2.1]
+  geometry3.setType(XdmfGeometryType.XYZ());
+  geometry3.insertAsFloat64(0, pointsdiff, 0, 36, 1, 1);
+
+  grid3.setGeometry(geometry3)
+
+  attr3 = XdmfAttribute.New()
+
+  attr3.setName("Nodal Attribute")
+  attr3.setType(XdmfAttributeType.Scalar())
+  attr3.setCenter(XdmfAttributeCenter.Node())
+  attr3.insertAsInt32(0, nodeValues, 0, 12, 1, 1)
+
+  grid3.insert(attr3)
+
+  # Make diff checks
+
+  diff = XdmfDiff.New()
+
+  if not diff.compare(grid1, grid2):
+    print "equivalent grids are not compared correctly"
+  else:
+    print "equivalent grids are compared correctly"
+
+  assert(diff.compare(grid1, grid2))
+
+  if diff.compare(grid1, grid3):
+    print "dissimilar grids are not compared correctly"
+  else:
+    print "dissimilar grids are compared correctly"
+
+  assert(not diff.compare(grid1, grid3))
+
+  print "default tolerance = " , str(diff.getAbsoluteTolerance())
+
+  diff.setAbsoluteTolerance(6)
+
+  if not diff.compare(grid1, grid3):
+    print "tolerance is not applied correctly"
+  else:
+    print "tolerance is applied correctly"
+
+  assert(diff.compare(grid1, grid3))
diff --git a/utils/tests/Python/XdmfTestGeometryConverter.py b/utils/tests/Python/XdmfTestGeometryConverter.py
new file mode 100644
index 0000000..0c71112
--- /dev/null
+++ b/utils/tests/Python/XdmfTestGeometryConverter.py
@@ -0,0 +1,84 @@
+from Xdmf import *
+from XdmfUtils import *
+from math import *
+
+if __name__ == "__main__":
+  Pi = 3.1415926535897932384626433832795
+
+  converter = XdmfGeometryConverter.New()
+
+  cartesianGeo = XdmfGeometry.New()
+
+  cartesianGeo.setType(XdmfGeometryType.XYZ())
+
+  for i in range(3):
+    cartesianGeo.pushBackAsFloat64(1)
+
+  resultSphericalGeo = converter.convertToSpherical(cartesianGeo)
+
+  sphericalGeo = XdmfGeometry.New()
+
+  sphericalGeo.setType(XdmfGeometryType.Spherical())
+
+  sphericalGeo.pushBackAsFloat64(sqrt(3));
+  sphericalGeo.pushBackAsFloat64(asin(sqrt(2.0/3.0))); # should be equal to acos(1/sqrt(3))
+  sphericalGeo.pushBackAsFloat64(Pi/4);
+
+  print "Tolerance 10^-15\nresult\n" , resultSphericalGeo.getValuesString(), "\n?=\ncompare to\n", sphericalGeo.getValuesString()
+
+  for i in range(sphericalGeo.getSize()):
+    val1 = resultSphericalGeo.getValueAsFloat64(i)
+    val2 = sphericalGeo.getValueAsFloat64(i)
+    val1 = floor(val1 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0);
+    val2 = floor(val2 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0);
+    print val1, " ?= ", val2
+    assert(val1 == val2)
+
+  resultCartesianGeo = converter.convertToCartesian(sphericalGeo)
+
+  print resultCartesianGeo.getValuesString(), "\n?=\n", cartesianGeo.getValuesString()
+
+  for i in range(cartesianGeo.getSize()):
+    val1 = resultCartesianGeo.getValueAsFloat64(i);
+    val2 = cartesianGeo.getValueAsFloat64(i);
+    val1 = floor(val1 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0)
+    val2 = floor(val2 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0)
+    print val1, " ?= ", val2
+    assert(val1 == val2)
+
+  # Convert in place for geometries with a lot of references
+
+  convertedToSpherical = XdmfGeometry.New()
+
+  convertedToSpherical.setType(XdmfGeometryType.XYZ())
+
+  for i in range(3):
+    convertedToSpherical.pushBackAsFloat64(1)
+
+  converter.convertToSphericalOverwrite(convertedToSpherical)
+
+  for i in range(sphericalGeo.getSize()):
+    val1 = convertedToSpherical.getValueAsFloat64(i)
+    val2 = sphericalGeo.getValueAsFloat64(i)
+    val1 = floor(val1 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0)
+    val2 = floor(val2 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0)
+    print val1, " ?= ", val2
+    assert(val1 == val2)
+
+  convertedToCartesian = XdmfGeometry.New()
+
+  convertedToCartesian.setType(XdmfGeometryType.Spherical())
+
+  convertedToCartesian.pushBackAsFloat64(sqrt(3))
+  convertedToCartesian.pushBackAsFloat64(asin(sqrt(2.0/3))) # should be equal to acos(1/sqrt(3))
+  convertedToCartesian.pushBackAsFloat64(Pi/4)
+
+  converter.convertToCartesianOverwrite(convertedToCartesian)
+
+  for i in range(cartesianGeo.getSize()):
+    val1 = convertedToCartesian.getValueAsFloat64(i)
+    val2 = cartesianGeo.getValueAsFloat64(i)
+    val1 = floor(val1 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0)
+    val2 = floor(val2 * pow(10.0, 15.0) + 0.5) / pow(10.0, 15.0)
+    print val1, " ?= ", val2
+    assert(val1 == val2)
diff --git a/utils/tests/Python/XdmfTestTopologyConverter.py b/utils/tests/Python/XdmfTestTopologyConverter.py
new file mode 100644
index 0000000..afb8b26
--- /dev/null
+++ b/utils/tests/Python/XdmfTestTopologyConverter.py
@@ -0,0 +1,142 @@
+from Xdmf import *
+from XdmfUtils import *
+
+if __name__ == "__main__":
+  converter = XdmfTopologyConverter.New()
+
+  # Create Hexahedron Grid
+  hexGrid = XdmfUnstructuredGrid.New();
+  hexPoints = [0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0,
+               1, 1, 1, 1, 0, 1, 1]
+  hexGrid.getGeometry().setType(XdmfGeometryType.XYZ())
+  hexGrid.getGeometry().resizeAsFloat64(24, 0)
+  hexGrid.getGeometry().insertAsFloat64(0, hexPoints)
+  hexConn = [0, 1, 2, 3, 4, 5, 6, 7]
+  hexGrid.getTopology().setType(XdmfTopologyType.Hexahedron())
+  hexGrid.getTopology().resizeAsUInt32(8, 0)
+  hexGrid.getTopology().insertAsUInt32(0, hexConn)
+
+  #
+  # Hexahedron to Hexahedron_64
+  #
+  hex64Grid = converter.convert(hexGrid, XdmfTopologyType.Hexahedron_64())
+
+  assert(hex64Grid.getGeometry().getType() == XdmfGeometryType.XYZ())
+  assert(hex64Grid.getGeometry().getNumberPoints() == 64)
+  assert(hex64Grid.getTopology().getType() ==
+         XdmfTopologyType.Hexahedron_64())
+  assert(hex64Grid.getTopology().getNumberElements() == 1)
+  for i in range(64):
+    assert(i == hex64Grid.getTopology().getValueAsUInt32(i))
+
+
+  #
+  # Hexahedron to Hexahedron_125
+  #
+  hex125Grid = converter.convert(hexGrid, XdmfTopologyType.Hexahedron_125())
+
+  assert(hex125Grid.getGeometry().getType() == XdmfGeometryType.XYZ())
+  assert(hex125Grid.getGeometry().getNumberPoints() == 125)
+  assert(hex125Grid.getTopology().getType() ==
+         XdmfTopologyType.Hexahedron_125())
+  assert(hex125Grid.getTopology().getNumberElements() == 1)
+  for i in range(125):
+    assert(i == hex125Grid.getTopology().getValueAsUInt32(i))
+
+
+  #
+  # Hexahedron_64 to Hexahedron
+  #
+  newHexGrid = converter.convert(hex64Grid, XdmfTopologyType.Hexahedron())
+  assert(newHexGrid.getGeometry().getType() == XdmfGeometryType.XYZ());
+  assert(newHexGrid.getGeometry().getNumberPoints() == 64);
+  assert(newHexGrid.getTopology().getType() ==
+         XdmfTopologyType.Hexahedron());
+  assert(newHexGrid.getTopology().getNumberElements() == 27);
+
+  #
+  # Tetrahedron to Triangle
+  #
+  tetTopology = XdmfTopology.New()
+  tetTopology.setType(XdmfTopologyType.Tetrahedron())
+  tetValues = [0, 1, 2, 3, 0, 1, 2, 4] # temporary
+  tetTopology.insertAsInt64(0, tetValues)
+  print "tetrahedrons prior to splitting into faces"
+  print tetTopology.getValuesString()
+  faceTopology = converter.getExternalFaces(tetTopology)
+  print "after splitting into faces"
+  print faceTopology.getValuesString()
+  assert(faceTopology.getValuesString() == "0 1 3 "
+                                           "0 3 2 "
+                                           "0 1 4 "
+                                           "0 4 2 "
+                                           "1 2 3 "
+                                           "1 2 4");
+
+  #
+  # Tetrahedron_10 to Triangle_6
+  #
+  tet10Topology = XdmfTopology.New()
+  tet10Topology.setType(XdmfTopologyType.Tetrahedron_10())
+  tet10Values = [0, 1, 2, 3, 5, 6,  7,  8,  9,  10,
+                 0, 1, 2, 4, 9, 10, 11, 12, 13, 14] # temporary
+  tet10Topology.insertAsInt64(0, tet10Values);
+  print "tetrahedron_10s prior to splitting into faces "
+  print tet10Topology.getValuesString()
+  faceTopology = converter.getExternalFaces(tet10Topology)
+  print "after splitting into faces"
+  print faceTopology.getValuesString()
+  assert(faceTopology.getValuesString() == "0 1 3 5 9 8 "
+                                           "0 3 2 8 10 7 "
+                                           "0 1 4 9 13 12 "
+                                           "0 4 2 12 14 11 "
+                                           "1 2 3 6 10 9 "
+                                           "1 2 4 10 14 13");
+
+  #
+  # Hexahedron to Quadrilateral
+  #
+  hexTopology = XdmfTopology.New()
+  hexTopology.setType(XdmfTopologyType.Hexahedron())
+  hexValues = [0, 1, 2, 3, 4, 5, 6, 7,
+               0, 1, 2, 3, 8, 9, 10, 11] # temporary
+  hexTopology.insertAsInt64(0, hexValues)
+  print "Hexahedrons prior to splitting into faces"
+  print hexTopology.getValuesString()
+  faceTopology = converter.getExternalFaces(hexTopology)
+  print "after splitting into faces"
+  print faceTopology.getValuesString()
+  assert(faceTopology.getValuesString() == "0 1 5 4 "
+                                           "0 4 7 3 "
+                                           "0 1 9 8 "
+                                           "0 8 11 3 "
+                                           "1 2 6 5 "
+                                           "1 2 10 9 "
+                                           "2 3 7 6 "
+                                           "2 3 11 10 "
+                                           "4 5 6 7 "
+                                           "8 9 10 11")
+
+  #
+  # Hexahedron_20 to Quadrilateral_8
+  #
+  hex20Topology = XdmfTopology.New()
+  hex20Topology.setType(XdmfTopologyType.Hexahedron_20())
+  hex20Values = [0, 1, 2, 3, 4, 5, 6,  7,  12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+                 0, 1, 2, 3, 8, 9, 10, 11, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35] # temporary
+  hex20Topology.insertAsInt64(0, hex20Values)
+  print "Hexahedron_20s prior to splitting into faces"
+  print hex20Topology.getValuesString()
+  faceTopology = converter.getExternalFaces(hex20Topology)
+  print "after splitting into faces"
+  print faceTopology.getValuesString()
+  assert(faceTopology.getValuesString() == "0 1 5 4 12 21 16 20 "
+                                           "0 4 7 3 20 19 23 15 "
+                                           "0 1 9 8 24 33 28 32 "
+                                           "0 8 11 3 32 31 35 27 "
+                                           "1 2 6 5 13 22 17 21 "
+                                           "1 2 10 9 25 34 29 33 "
+                                           "2 3 7 6 14 23 18 22 "
+                                           "2 3 11 10 26 35 30 34 "
+                                           "4 5 6 7 16 17 18 19 "
+                                           "8 9 10 11 28 29 30 31")

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/xdmf.git



More information about the debian-science-commits mailing list