diff --git a/src/language/modules/CoreModule.cpp b/src/language/modules/CoreModule.cpp
index 02bf902c96d1fc4b8a92b76fcb7df7b57eb1cf35..7f894d406bc5886144a189df49741f5fe8d24df0 100644
--- a/src/language/modules/CoreModule.cpp
+++ b/src/language/modules/CoreModule.cpp
@@ -37,8 +37,8 @@
 #include <utils/RandomEngine.hpp>
 #include <utils/checkpointing/Checkpoint.hpp>
 #include <utils/checkpointing/CheckpointUtils.hpp>
+#include <utils/checkpointing/ReadOStream.hpp>
 #include <utils/checkpointing/Resume.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
 #include <utils/checkpointing/ResumingManager.hpp>
 
 #include <random>
diff --git a/src/language/modules/MeshModule.cpp b/src/language/modules/MeshModule.cpp
index e696c074ddaea2575f78fa57e092c4d82bd81e67..56d893f71c8c1797423355ca23da8cde86f240a7 100644
--- a/src/language/modules/MeshModule.cpp
+++ b/src/language/modules/MeshModule.cpp
@@ -36,7 +36,16 @@
 #include <mesh/SubItemValuePerItemVariant.hpp>
 #include <utils/Exceptions.hpp>
 #include <utils/checkpointing/CheckpointUtils.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
+
+#include <utils/checkpointing/ReadIBoundaryDescriptor.hpp>
+#include <utils/checkpointing/ReadIInterfaceDescriptor.hpp>
+#include <utils/checkpointing/ReadIZoneDescriptor.hpp>
+#include <utils/checkpointing/ReadItemArrayVariant.hpp>
+#include <utils/checkpointing/ReadItemType.hpp>
+#include <utils/checkpointing/ReadItemValueVariant.hpp>
+#include <utils/checkpointing/ReadMesh.hpp>
+#include <utils/checkpointing/ReadSubItemArrayPerItemVariant.hpp>
+#include <utils/checkpointing/ReadSubItemValuePerItemVariant.hpp>
 
 #include <Kokkos_Core.hpp>
 
@@ -308,7 +317,6 @@ void
 MeshModule::registerCheckpointResume() const
 {
 #ifdef PUGS_HAS_HDF5
-
   CheckpointResumeRepository::instance()
     .addCheckpointResume(ast_node_data_type_from<std::shared_ptr<const MeshVariant>>,
                          std::function([](const std::string& symbol_name, const EmbeddedData& embedded_data,
diff --git a/src/language/modules/SchemeModule.cpp b/src/language/modules/SchemeModule.cpp
index a43b2942a16c02cc28494236931448e60801763d..6c022fba01e159fc487553e78fa5330a50143c98 100644
--- a/src/language/modules/SchemeModule.cpp
+++ b/src/language/modules/SchemeModule.cpp
@@ -5,6 +5,8 @@
 #include <analysis/GaussQuadratureDescriptor.hpp>
 #include <language/modules/BinaryOperatorRegisterForVh.hpp>
 #include <language/modules/MathFunctionRegisterForVh.hpp>
+#include <language/modules/MeshModuleTypes.hpp>
+#include <language/modules/SocketModuleTypes.hpp>
 #include <language/modules/UnaryOperatorRegisterForVh.hpp>
 #include <language/utils/BinaryOperatorProcessorBuilder.hpp>
 #include <language/utils/BuiltinFunctionEmbedder.hpp>
@@ -45,11 +47,14 @@
 #include <scheme/SymmetryBoundaryConditionDescriptor.hpp>
 #include <scheme/VariableBCDescriptor.hpp>
 #include <utils/Socket.hpp>
-#include <utils/checkpointing/CheckpointUtils.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
 
-#include <language/modules/MeshModule.hpp>
-#include <language/modules/SocketModule.hpp>
+#include <utils/checkpointing/ReadDiscreteFunctionVariant.hpp>
+#include <utils/checkpointing/ReadIBoundaryConditionDescriptor.hpp>
+#include <utils/checkpointing/ReadIDiscreteFunctionDescriptor.hpp>
+#include <utils/checkpointing/ReadIQuadratureDescriptor.hpp>
+#include <utils/checkpointing/ReadVariableBCDescriptor.hpp>
+
+#include <utils/checkpointing/CheckpointUtils.hpp>
 
 #include <memory>
 
@@ -690,7 +695,6 @@ void
 SchemeModule::registerCheckpointResume() const
 {
 #ifdef PUGS_HAS_HDF5
-
   CheckpointResumeRepository::instance()
     .addCheckpointResume(ast_node_data_type_from<std::shared_ptr<const DiscreteFunctionVariant>>,
                          std::function([](const std::string& symbol_name, const EmbeddedData& embedded_data,
diff --git a/src/language/modules/WriterModule.cpp b/src/language/modules/WriterModule.cpp
index b5c3f020fd61de04e46b630608d9c98aa05b7cb3..03ea6268ff1a8c5571db3a88c4fb977d262a967f 100644
--- a/src/language/modules/WriterModule.cpp
+++ b/src/language/modules/WriterModule.cpp
@@ -19,7 +19,9 @@
 #include <output/VTKWriter.hpp>
 #include <scheme/DiscreteFunctionVariant.hpp>
 #include <utils/checkpointing/CheckpointUtils.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
+
+#include <utils/checkpointing/ReadINamedDiscreteData.hpp>
+#include <utils/checkpointing/ReadIWriter.hpp>
 
 WriterModule::WriterModule()
 {
diff --git a/src/utils/checkpointing/CMakeLists.txt b/src/utils/checkpointing/CMakeLists.txt
index cc46732096e78f577f9567258ead2861e5174379..d16895ad9fcf8a0eca7b174b8c068ae12c2708b1 100644
--- a/src/utils/checkpointing/CMakeLists.txt
+++ b/src/utils/checkpointing/CMakeLists.txt
@@ -13,13 +13,23 @@ list(APPEND checkpointing_SOURCES
 if(PUGS_HAS_HDF5)
   list(APPEND checkpointing_SOURCES
     CheckpointUtils.cpp
+    ReadDiscreteFunctionVariant.cpp
     ReadIBoundaryConditionDescriptor.cpp
     ReadIBoundaryDescriptor.cpp
+    ReadIDiscreteFunctionDescriptor.cpp
+    ReadIInterfaceDescriptor.cpp
+    ReadINamedDiscreteData.cpp
+    ReadIQuadratureDescriptor.cpp
     ReadItemArrayVariant.cpp
+    ReadItemType.cpp
     ReadItemValueVariant.cpp
+    ReadIWriter.cpp
+    ReadIZoneDescriptor.cpp
+    ReadMesh.cpp
+    ReadOStream.cpp
     ReadSubItemArrayPerItemVariant.cpp
     ReadSubItemValuePerItemVariant.cpp
-    ResumeUtils.cpp
+    ReadVariableBCDescriptor.cpp
     ResumingData.cpp
   )
 endif(PUGS_HAS_HDF5)
diff --git a/src/utils/checkpointing/Checkpoint.cpp b/src/utils/checkpointing/Checkpoint.cpp
index 32171cefa7a30fb8c82bcb709fa13928a41ab792..ed53a690c1dc4f32f4b1ee61aac4fc407f5e5e65 100644
--- a/src/utils/checkpointing/Checkpoint.cpp
+++ b/src/utils/checkpointing/Checkpoint.cpp
@@ -4,36 +4,29 @@
 
 #ifdef PUGS_HAS_HDF5
 
-#include <utils/HighFivePugsUtils.hpp>
-
-#include <language/ast/ASTExecutionStack.hpp>
-#include <language/utils/SymbolTable.hpp>
-
-#include <iostream>
-#include <map>
-#endif   // PUGS_HAS_HDF5
-
-#include <language/utils/ASTCheckpointsInfo.hpp>
-#include <utils/Exceptions.hpp>
-#include <utils/ExecutionStatManager.hpp>
-#include <utils/checkpointing/ResumingManager.hpp>
-
-#ifdef PUGS_HAS_HDF5
-
 #include <algebra/LinearSolverOptions.hpp>
 #include <dev/ParallelChecker.hpp>
+#include <language/ast/ASTExecutionStack.hpp>
+#include <language/utils/ASTCheckpointsInfo.hpp>
 #include <language/utils/ASTNodeDataTypeTraits.hpp>
 #include <language/utils/CheckpointResumeRepository.hpp>
 #include <language/utils/DataHandler.hpp>
+#include <language/utils/SymbolTable.hpp>
 #include <mesh/DualConnectivityManager.hpp>
 #include <mesh/DualMeshManager.hpp>
 #include <mesh/MeshVariant.hpp>
+#include <utils/Exceptions.hpp>
+#include <utils/ExecutionStatManager.hpp>
 #include <utils/GlobalVariableManager.hpp>
+#include <utils/HighFivePugsUtils.hpp>
 #include <utils/RandomEngine.hpp>
-
 #include <utils/checkpointing/DualMeshTypeHFType.hpp>
 #include <utils/checkpointing/LinearSolverOptionsHFType.hpp>
 #include <utils/checkpointing/ParallelCheckerHFType.hpp>
+#include <utils/checkpointing/ResumingManager.hpp>
+
+#include <iostream>
+#include <map>
 
 void
 checkpoint()
diff --git a/src/utils/checkpointing/ReadArray.hpp b/src/utils/checkpointing/ReadArray.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9aad33efed359a62ddaaba08440488c63253ec1c
--- /dev/null
+++ b/src/utils/checkpointing/ReadArray.hpp
@@ -0,0 +1,47 @@
+#ifndef READ_ARRAY_HPP
+#define READ_ARRAY_HPP
+
+#include <mesh/CellType.hpp>
+#include <mesh/ItemId.hpp>
+#include <utils/Array.hpp>
+#include <utils/HighFivePugsUtils.hpp>
+#include <utils/Messenger.hpp>
+
+template <typename DataType>
+PUGS_INLINE Array<DataType>
+readArray(const HighFive::Group& group, const std::string& name)
+{
+  auto get_address = [](auto& x) { return (x.size() > 0) ? &(x[0]) : nullptr; };
+
+  using data_type = std::remove_const_t<DataType>;
+
+  auto dataset = group.getDataSet(name);
+
+  std::vector<size_t> size_per_rank = dataset.getAttribute("size_per_rank").read<std::vector<size_t>>();
+
+  if (size_per_rank.size() != parallel::size()) {
+    throw NormalError("cannot change number of processes");
+  }
+
+  std::vector<size_t> offset{0, 0ul};
+  for (size_t i = 0; i < parallel::rank(); ++i) {
+    offset[0] += size_per_rank[i];
+  }
+  std::vector<size_t> count{size_per_rank[parallel::rank()]};
+
+  Array<DataType> array(size_per_rank[parallel::rank()]);
+  if constexpr (std::is_same_v<CellType, data_type>) {
+    using base_type = std::underlying_type_t<CellType>;
+    dataset.select(offset, count).read_raw(reinterpret_cast<base_type*>(get_address(array)));
+  } else if constexpr ((std::is_same_v<CellId, data_type>) or (std::is_same_v<FaceId, data_type>) or
+                       (std::is_same_v<EdgeId, data_type>) or (std::is_same_v<NodeId, data_type>)) {
+    using base_type = typename data_type::base_type;
+    dataset.select(offset, count).read_raw(reinterpret_cast<base_type*>(get_address(array)));
+  } else {
+    dataset.select(offset, count).read_raw(get_address(array));
+  }
+
+  return array;
+}
+
+#endif   // READ_ARRAY_HPP
diff --git a/src/utils/checkpointing/ReadDiscreteFunctionVariant.cpp b/src/utils/checkpointing/ReadDiscreteFunctionVariant.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aea937d8795e75fa775bc25b3ed2875a150213b4
--- /dev/null
+++ b/src/utils/checkpointing/ReadDiscreteFunctionVariant.cpp
@@ -0,0 +1,93 @@
+#include <utils/checkpointing/ReadDiscreteFunctionVariant.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <scheme/DiscreteFunctionVariant.hpp>
+#include <utils/checkpointing/DiscreteFunctionTypeHFType.hpp>
+#include <utils/checkpointing/ReadItemArray.hpp>
+#include <utils/checkpointing/ReadItemValue.hpp>
+#include <utils/checkpointing/ResumingData.hpp>
+
+std::shared_ptr<DiscreteFunctionVariant>
+readDiscreteFunctionVariant(const HighFive::Group& discrete_function_group)
+{
+  DiscreteFunctionType type = discrete_function_group.getAttribute("Vh_type").read<DiscreteFunctionType>();
+  size_t mesh_id            = discrete_function_group.getAttribute("mesh_id").read<size_t>();
+
+  std::shared_ptr<const MeshVariant> mesh_v = ResumingData::instance().meshVariant(mesh_id);
+
+  const std::string data_type = discrete_function_group.getAttribute("data_type").read<std::string>();
+
+  std::shared_ptr<DiscreteFunctionVariant> p_discrete_function;
+  switch (type) {
+  case DiscreteFunctionType::P0: {
+    if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const double>(mesh_v,
+                                         readItemValue<double, ItemType::cell>(discrete_function_group, "values",
+                                                                               mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<1>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyVector<1>>(mesh_v,
+                                                readItemValue<TinyVector<1>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<2>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyVector<2>>(mesh_v,
+                                                readItemValue<TinyVector<2>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<3>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyVector<3>>(mesh_v,
+                                                readItemValue<TinyVector<3>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<1>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyMatrix<1>>(mesh_v,
+                                                readItemValue<TinyMatrix<1>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<2>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyMatrix<2>>(mesh_v,
+                                                readItemValue<TinyMatrix<2>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<3>>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0<const TinyMatrix<3>>(mesh_v,
+                                                readItemValue<TinyMatrix<3>, ItemType::cell>(discrete_function_group,
+                                                                                             "values",
+                                                                                             mesh_v->connectivity())));
+    } else {
+      throw UnexpectedError("unexpected discrete function data type: " + data_type);
+    }
+    break;
+  }
+  case DiscreteFunctionType::P0Vector: {
+    if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
+      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
+        DiscreteFunctionP0Vector<const double>(mesh_v,
+                                               readItemArray<double, ItemType::cell>(discrete_function_group, "values",
+                                                                                     mesh_v->connectivity())));
+    } else {
+      throw UnexpectedError("unexpected discrete function vector data type: " + data_type);
+    }
+    break;
+  }
+  }
+  return p_discrete_function;
+}
+
+EmbeddedData
+readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group discrete_function_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+
+  std::shared_ptr<DiscreteFunctionVariant> p_discrete_function = readDiscreteFunctionVariant(discrete_function_group);
+
+  return {std::make_shared<DataHandler<const DiscreteFunctionVariant>>(p_discrete_function)};
+}
diff --git a/src/utils/checkpointing/ReadDiscreteFunctionVariant.hpp b/src/utils/checkpointing/ReadDiscreteFunctionVariant.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..0564d5de3181d6d6eff48dc5368af9e846ff2eab
--- /dev/null
+++ b/src/utils/checkpointing/ReadDiscreteFunctionVariant.hpp
@@ -0,0 +1,13 @@
+#ifndef READ_DISCRETE_FUNCTION_VARIANT_HPP
+#define READ_DISCRETE_FUNCTION_VARIANT_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class DiscreteFunctionVariant;
+class EmbeddedData;
+
+std::shared_ptr<DiscreteFunctionVariant> readDiscreteFunctionVariant(const HighFive::Group& discrete_function_group);
+
+EmbeddedData readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_DISCRETE_FUNCTION_VARIANT_HPP
diff --git a/src/utils/checkpointing/ReadIBoundaryDescriptor.hpp b/src/utils/checkpointing/ReadIBoundaryDescriptor.hpp
index 86883f873a5628c3ed383725f9c5efaee3e3905e..19c55c32341c4e0f4967b1ad4c84e27190731e69 100644
--- a/src/utils/checkpointing/ReadIBoundaryDescriptor.hpp
+++ b/src/utils/checkpointing/ReadIBoundaryDescriptor.hpp
@@ -8,7 +8,6 @@ class EmbeddedData;
 
 std::shared_ptr<const IBoundaryDescriptor> readIBoundaryDescriptor(const HighFive::Group& iboundarydescriptor_group);
 
-EmbeddedData readIBoundaryConditionDescriptor(const std::string& symbol_name,
-                                              const HighFive::Group& symbol_table_group);
+EmbeddedData readIBoundaryDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
 
 #endif   // READ_IBOUNDARY_DESCRIPTOR_HPP
diff --git a/src/utils/checkpointing/ReadIDiscreteFunctionDescriptor.cpp b/src/utils/checkpointing/ReadIDiscreteFunctionDescriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..16609443323dbdb4af274f59849cf7dec4953acf
--- /dev/null
+++ b/src/utils/checkpointing/ReadIDiscreteFunctionDescriptor.cpp
@@ -0,0 +1,30 @@
+#include <utils/checkpointing/ReadIDiscreteFunctionDescriptor.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <scheme/DiscreteFunctionDescriptorP0.hpp>
+#include <scheme/DiscreteFunctionDescriptorP0Vector.hpp>
+#include <utils/checkpointing/DiscreteFunctionTypeHFType.hpp>
+
+EmbeddedData
+readIDiscreteFunctionDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group idiscrete_function_descriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  const DiscreteFunctionType discrete_function_type =
+    idiscrete_function_descriptor_group.getAttribute("discrete_function_type").read<DiscreteFunctionType>();
+
+  std::shared_ptr<const IDiscreteFunctionDescriptor> idiscrete_function_descriptor;
+
+  switch (discrete_function_type) {
+  case DiscreteFunctionType::P0: {
+    idiscrete_function_descriptor = std::make_shared<const DiscreteFunctionDescriptorP0>();
+    break;
+  }
+  case DiscreteFunctionType::P0Vector: {
+    idiscrete_function_descriptor = std::make_shared<const DiscreteFunctionDescriptorP0Vector>();
+    break;
+  }
+  }
+
+  return {std::make_shared<DataHandler<const IDiscreteFunctionDescriptor>>(idiscrete_function_descriptor)};
+}
diff --git a/src/utils/checkpointing/ReadIDiscreteFunctionDescriptor.hpp b/src/utils/checkpointing/ReadIDiscreteFunctionDescriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..89f63e5df47c11ff122d9fc25a5689c38ed32662
--- /dev/null
+++ b/src/utils/checkpointing/ReadIDiscreteFunctionDescriptor.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_IDISCRETE_FUNCTION_DESCRIPTOR_HPP
+#define READ_IDISCRETE_FUNCTION_DESCRIPTOR_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readIDiscreteFunctionDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_IDISCRETE_FUNCTION_DESCRIPTOR_HPP
diff --git a/src/utils/checkpointing/ReadIInterfaceDescriptor.cpp b/src/utils/checkpointing/ReadIInterfaceDescriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c3a1f5c899103d7ee4c8786970f0a7cf92839b38
--- /dev/null
+++ b/src/utils/checkpointing/ReadIInterfaceDescriptor.cpp
@@ -0,0 +1,31 @@
+#include <utils/checkpointing/ReadIInterfaceDescriptor.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <mesh/NamedInterfaceDescriptor.hpp>
+#include <mesh/NumberedInterfaceDescriptor.hpp>
+#include <utils/checkpointing/IInterfaceDescriptorHFType.hpp>
+
+EmbeddedData
+readIInterfaceDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group iinterfacedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  const IInterfaceDescriptor::Type iinterface_descriptor_type =
+    iinterfacedescriptor_group.getAttribute("iinterface_descriptor_type").read<IInterfaceDescriptor::Type>();
+
+  std::shared_ptr<const IInterfaceDescriptor> iinterface_descriptor;
+
+  switch (iinterface_descriptor_type) {
+  case IInterfaceDescriptor::Type::named: {
+    const std::string name = iinterfacedescriptor_group.getAttribute("name").read<std::string>();
+    iinterface_descriptor  = std::make_shared<const NamedInterfaceDescriptor>(name);
+    break;
+  }
+  case IInterfaceDescriptor::Type::numbered: {
+    const unsigned int number = iinterfacedescriptor_group.getAttribute("number").read<unsigned int>();
+    iinterface_descriptor     = std::make_shared<const NumberedInterfaceDescriptor>(number);
+    break;
+  }
+  }
+  return {std::make_shared<DataHandler<const IInterfaceDescriptor>>(iinterface_descriptor)};
+}
diff --git a/src/utils/checkpointing/ReadIInterfaceDescriptor.hpp b/src/utils/checkpointing/ReadIInterfaceDescriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..43b93d5c19fe1277b87d22c8d835469600e58ebb
--- /dev/null
+++ b/src/utils/checkpointing/ReadIInterfaceDescriptor.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_IINTERFACE_DESCRIPTOR_HPP
+#define READ_IINTERFACE_DESCRIPTOR_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readIInterfaceDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_IINTERFACE_DESCRIPTOR_HPP
diff --git a/src/utils/checkpointing/ReadINamedDiscreteData.cpp b/src/utils/checkpointing/ReadINamedDiscreteData.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ed85949bf17a70a4c0defc3230591b4edf67bf98
--- /dev/null
+++ b/src/utils/checkpointing/ReadINamedDiscreteData.cpp
@@ -0,0 +1,45 @@
+#include <utils/checkpointing/ReadINamedDiscreteData.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <output/NamedDiscreteFunction.hpp>
+#include <output/NamedItemArrayVariant.hpp>
+#include <output/NamedItemValueVariant.hpp>
+#include <utils/checkpointing/INamedDiscreteDataHFType.hpp>
+#include <utils/checkpointing/ReadDiscreteFunctionVariant.hpp>
+#include <utils/checkpointing/ReadItemArrayVariant.hpp>
+#include <utils/checkpointing/ReadItemValueVariant.hpp>
+
+EmbeddedData
+readINamedDiscreteData(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group inamed_discrete_data_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+
+  const INamedDiscreteData::Type& type =
+    inamed_discrete_data_group.getAttribute("named_discrete_data_type").read<INamedDiscreteData::Type>();
+
+  const std::string name = inamed_discrete_data_group.getAttribute("named_discrete_data_name").read<std::string>();
+
+  std::shared_ptr<const INamedDiscreteData> inamed_discrete_data;
+
+  switch (type) {
+  case INamedDiscreteData::Type::discrete_function: {
+    HighFive::Group discrete_function_group = inamed_discrete_data_group.getGroup("discrete_function_variant");
+    inamed_discrete_data =
+      std::make_shared<const NamedDiscreteFunction>(readDiscreteFunctionVariant(discrete_function_group), name);
+    break;
+  }
+  case INamedDiscreteData::Type::item_array: {
+    HighFive::Group item_array_group = inamed_discrete_data_group.getGroup("item_array_variant");
+    inamed_discrete_data = std::make_shared<const NamedItemArrayVariant>(readItemArrayVariant(item_array_group), name);
+    break;
+  }
+  case INamedDiscreteData::Type::item_value: {
+    HighFive::Group item_value_group = inamed_discrete_data_group.getGroup("item_value_variant");
+    inamed_discrete_data = std::make_shared<const NamedItemValueVariant>(readItemValueVariant(item_value_group), name);
+    break;
+  }
+  }
+
+  return {std::make_shared<DataHandler<const INamedDiscreteData>>(inamed_discrete_data)};
+}
diff --git a/src/utils/checkpointing/ReadINamedDiscreteData.hpp b/src/utils/checkpointing/ReadINamedDiscreteData.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ee08ff275f1667d49db839a3039710f2402ef1ce
--- /dev/null
+++ b/src/utils/checkpointing/ReadINamedDiscreteData.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_INAMED_DISCRETE_DATA_HPP
+#define READ_INAMED_DISCRETE_DATA_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readINamedDiscreteData(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_INAMED_DISCRETE_DATA_HPP
diff --git a/src/utils/checkpointing/ReadIQuadratureDescriptor.cpp b/src/utils/checkpointing/ReadIQuadratureDescriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..56398f8d684aaf23385bf83104899688ffdb103f
--- /dev/null
+++ b/src/utils/checkpointing/ReadIQuadratureDescriptor.cpp
@@ -0,0 +1,36 @@
+#include <utils/checkpointing/ReadIQuadratureDescriptor.hpp>
+
+#include <analysis/GaussLegendreQuadratureDescriptor.hpp>
+#include <analysis/GaussLobattoQuadratureDescriptor.hpp>
+#include <analysis/GaussQuadratureDescriptor.hpp>
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <utils/checkpointing/QuadratureTypeHFType.hpp>
+
+EmbeddedData
+readIQuadratureDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group iquadraturedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  const QuadratureType quadrature_type =
+    iquadraturedescriptor_group.getAttribute("quadrature_type").read<QuadratureType>();
+  const size_t degree = iquadraturedescriptor_group.getAttribute("quadrature_degree").read<size_t>();
+
+  std::shared_ptr<const IQuadratureDescriptor> iquadrature_descrptor;
+
+  switch (quadrature_type) {
+  case QuadratureType::Gauss: {
+    iquadrature_descrptor = std::make_shared<const GaussQuadratureDescriptor>(degree);
+    break;
+  }
+  case QuadratureType::GaussLegendre: {
+    iquadrature_descrptor = std::make_shared<const GaussLegendreQuadratureDescriptor>(degree);
+    break;
+  }
+  case QuadratureType::GaussLobatto: {
+    iquadrature_descrptor = std::make_shared<const GaussLobattoQuadratureDescriptor>(degree);
+    break;
+  }
+  }
+
+  return {std::make_shared<DataHandler<const IQuadratureDescriptor>>(iquadrature_descrptor)};
+}
diff --git a/src/utils/checkpointing/ReadIQuadratureDescriptor.hpp b/src/utils/checkpointing/ReadIQuadratureDescriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..ad22dc4e0083c52cf0aa0b9647e6128f9e68f4ec
--- /dev/null
+++ b/src/utils/checkpointing/ReadIQuadratureDescriptor.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_IQUADRATURE_DESCRIPTOR_HPP
+#define READ_IQUADRATURE_DESCRIPTOR_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readIQuadratureDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_IQUADRATURE_DESCRIPTOR_HPP
diff --git a/src/utils/checkpointing/ReadIWriter.cpp b/src/utils/checkpointing/ReadIWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c8a25fd8a59da2f28788fd5274b8d7a7a0acee4a
--- /dev/null
+++ b/src/utils/checkpointing/ReadIWriter.cpp
@@ -0,0 +1,52 @@
+#include <utils/checkpointing/ReadIWriter.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <output/GnuplotWriter.hpp>
+#include <output/GnuplotWriter1D.hpp>
+#include <output/VTKWriter.hpp>
+#include <utils/checkpointing/IWriterHFType.hpp>
+
+EmbeddedData
+readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group iwriter_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+
+  std::shared_ptr<WriterBase> p_writer;
+
+  IWriter::Type type = iwriter_group.getAttribute("iwriter_type").read<IWriter::Type>();
+
+  std::string base_filename = iwriter_group.getAttribute("base_filename").read<std::string>();
+
+  switch (type) {
+  case IWriter::Type::gnuplot: {
+    p_writer = std::make_shared<GnuplotWriter>(base_filename);
+    break;
+  }
+  case IWriter::Type::gnuplot_1d: {
+    p_writer = std::make_shared<GnuplotWriter1D>(base_filename);
+    break;
+  }
+  case IWriter::Type::vtk: {
+    p_writer = std::make_shared<VTKWriter>(base_filename);
+    break;
+  }
+  }
+
+  if (iwriter_group.exist("period_manager")) {
+    HighFive::Group period_manager_group = iwriter_group.getGroup("period_manager");
+
+    const double time_period = period_manager_group.getAttribute("time_period").read<double>();
+    const double next_time   = period_manager_group.getAttribute("next_time").read<double>();
+    const std::vector<double> saved_times =
+      period_manager_group.getAttribute("saved_times").read<std::vector<double>>();
+
+    p_writer->m_period_manager.emplace(WriterBase::PeriodManager(time_period, next_time, saved_times));
+  }
+
+  if (iwriter_group.hasAttribute("signature")) {
+    p_writer->m_signature = iwriter_group.getAttribute("signature").read<std::string>();
+  }
+
+  return {std::make_shared<DataHandler<const IWriter>>(p_writer)};
+}
diff --git a/src/utils/checkpointing/ReadIWriter.hpp b/src/utils/checkpointing/ReadIWriter.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b37c4c8133f6578cc652e11eee0a96546da06807
--- /dev/null
+++ b/src/utils/checkpointing/ReadIWriter.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_IWRITER_HPP
+#define READ_IWRITER_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_IWRITER_HPP
diff --git a/src/utils/checkpointing/ReadIZoneDescriptor.cpp b/src/utils/checkpointing/ReadIZoneDescriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1d4b90255a816e527cff2ede8b1df03baca70d2f
--- /dev/null
+++ b/src/utils/checkpointing/ReadIZoneDescriptor.cpp
@@ -0,0 +1,32 @@
+#include <utils/checkpointing/ReadIZoneDescriptor.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <mesh/NamedZoneDescriptor.hpp>
+#include <mesh/NumberedZoneDescriptor.hpp>
+#include <utils/checkpointing/IZoneDescriptorHFType.hpp>
+
+EmbeddedData
+readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group izonedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  const IZoneDescriptor::Type izone_descriptor_type =
+    izonedescriptor_group.getAttribute("izone_descriptor_type").read<IZoneDescriptor::Type>();
+
+  std::shared_ptr<const IZoneDescriptor> izone_descriptor;
+
+  switch (izone_descriptor_type) {
+  case IZoneDescriptor::Type::named: {
+    const std::string name = izonedescriptor_group.getAttribute("name").read<std::string>();
+    izone_descriptor       = std::make_shared<const NamedZoneDescriptor>(name);
+    break;
+  }
+  case IZoneDescriptor::Type::numbered: {
+    const unsigned int number = izonedescriptor_group.getAttribute("number").read<unsigned int>();
+    izone_descriptor          = std::make_shared<const NumberedZoneDescriptor>(number);
+    break;
+  }
+  }
+
+  return {std::make_shared<DataHandler<const IZoneDescriptor>>(izone_descriptor)};
+}
diff --git a/src/utils/checkpointing/ReadIZoneDescriptor.hpp b/src/utils/checkpointing/ReadIZoneDescriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2791285e2066bbb2d72fc5dd3c5fc321bb4e44cc
--- /dev/null
+++ b/src/utils/checkpointing/ReadIZoneDescriptor.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_IZONE_DESCRIPTOR_HPP
+#define READ_IZONE_DESCRIPTOR_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_IZONE_DESCRIPTOR_HPP
diff --git a/src/utils/checkpointing/ReadItemArray.hpp b/src/utils/checkpointing/ReadItemArray.hpp
index bddd9799ca85274d2d8e74ed3390f39758ca0c35..f22fdad60643f59eef912796457f1f05d3838324 100644
--- a/src/utils/checkpointing/ReadItemArray.hpp
+++ b/src/utils/checkpointing/ReadItemArray.hpp
@@ -3,8 +3,7 @@
 
 #include <mesh/ItemArray.hpp>
 #include <utils/HighFivePugsUtils.hpp>
-
-#include <utils/checkpointing/ResumeUtils.hpp>
+#include <utils/checkpointing/ReadTable.hpp>
 
 template <typename T, ItemType item_type>
 ItemArray<T, item_type>
diff --git a/src/utils/checkpointing/ReadItemType.cpp b/src/utils/checkpointing/ReadItemType.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e699173c6b2c22904173d7bec856608032812ff0
--- /dev/null
+++ b/src/utils/checkpointing/ReadItemType.cpp
@@ -0,0 +1,14 @@
+#include <utils/checkpointing/ReadItemType.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <utils/checkpointing/ItemTypeHFType.hpp>
+
+EmbeddedData
+readItemType(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group item_type_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+  const ItemType item_type              = item_type_group.getAttribute("item_type").read<ItemType>();
+
+  return {std::make_shared<DataHandler<const ItemType>>(std::make_shared<const ItemType>(item_type))};
+}
diff --git a/src/utils/checkpointing/ReadItemType.hpp b/src/utils/checkpointing/ReadItemType.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..3239f08ef6de658d3ea1406d8620ba7da301a236
--- /dev/null
+++ b/src/utils/checkpointing/ReadItemType.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_ITEM_TYPE_HPP
+#define READ_ITEM_TYPE_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readItemType(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_ITEM_TYPE_HPP
diff --git a/src/utils/checkpointing/ReadItemValue.hpp b/src/utils/checkpointing/ReadItemValue.hpp
index 6d3d9013c4a87fc53521299fbc4b3147ac39e10b..5444ec1b958f046dbbfe6c0887238f5bc85f0406 100644
--- a/src/utils/checkpointing/ReadItemValue.hpp
+++ b/src/utils/checkpointing/ReadItemValue.hpp
@@ -3,8 +3,7 @@
 
 #include <mesh/ItemValue.hpp>
 #include <utils/HighFivePugsUtils.hpp>
-
-#include <utils/checkpointing/ResumeUtils.hpp>
+#include <utils/checkpointing/ReadArray.hpp>
 
 template <typename T, ItemType item_type>
 ItemValue<T, item_type>
diff --git a/src/utils/checkpointing/ReadMesh.cpp b/src/utils/checkpointing/ReadMesh.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8f018faa56da3097f5f70629287000a39d9c825d
--- /dev/null
+++ b/src/utils/checkpointing/ReadMesh.cpp
@@ -0,0 +1,17 @@
+#include <utils/checkpointing/ReadMesh.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <mesh/MeshVariant.hpp>
+#include <utils/checkpointing/ItemTypeHFType.hpp>
+#include <utils/checkpointing/ResumingData.hpp>
+
+EmbeddedData
+readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group mesh_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+
+  const size_t mesh_id = mesh_group.getAttribute("id").read<uint64_t>();
+
+  return {std::make_shared<DataHandler<const MeshVariant>>(ResumingData::instance().meshVariant(mesh_id))};
+}
diff --git a/src/utils/checkpointing/ReadMesh.hpp b/src/utils/checkpointing/ReadMesh.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..f55fad1d99761e7bf178211dce2c075c1d108873
--- /dev/null
+++ b/src/utils/checkpointing/ReadMesh.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_MESH_HPP
+#define READ_MESH_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_MESH_HPP
diff --git a/src/utils/checkpointing/ReadOStream.cpp b/src/utils/checkpointing/ReadOStream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d7c99ce9756162e490a270c5ab75bbcab6325fd6
--- /dev/null
+++ b/src/utils/checkpointing/ReadOStream.cpp
@@ -0,0 +1,30 @@
+#include <utils/checkpointing/ReadOStream.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <language/utils/OFStream.hpp>
+#include <utils/checkpointing/OStreamTypeHFType.hpp>
+
+EmbeddedData
+readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group ostream_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+
+  const OStream::Type ostream_type = ostream_group.getAttribute("ostream_type").read<OStream::Type>();
+
+  std::shared_ptr<const OStream> p_ostream;
+
+  switch (ostream_type) {
+  case OStream::Type::std_ofstream: {
+    std::string filename = ostream_group.getAttribute("filename").read<std::string>();
+
+    p_ostream = std::make_shared<OFStream>(filename, true);
+    break;
+  }
+  case OStream::Type::std_ostream: {
+    throw NotImplementedError("std::ostream resume");
+  }
+  }
+
+  return {std::make_shared<DataHandler<const OStream>>(p_ostream)};
+}
diff --git a/src/utils/checkpointing/ReadOStream.hpp b/src/utils/checkpointing/ReadOStream.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..9de6e6f7a47170f859290256178b6ac43289cfb3
--- /dev/null
+++ b/src/utils/checkpointing/ReadOStream.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_OSTREAM_HPP
+#define READ_OSTREAM_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_OSTREAM_HPP
diff --git a/src/utils/checkpointing/ReadSubItemArrayPerItemVariant.cpp b/src/utils/checkpointing/ReadSubItemArrayPerItemVariant.cpp
index 3a1c1d4e528c2cd27aabd295a7d4fff141dcef26..1dd826418d2164cdb9ec5b25bdd55c68dfac6081 100644
--- a/src/utils/checkpointing/ReadSubItemArrayPerItemVariant.cpp
+++ b/src/utils/checkpointing/ReadSubItemArrayPerItemVariant.cpp
@@ -6,7 +6,7 @@
 #include <mesh/Connectivity.hpp>
 #include <mesh/SubItemArrayPerItemVariant.hpp>
 #include <utils/checkpointing/ItemTypeHFType.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
+#include <utils/checkpointing/ReadTable.hpp>
 #include <utils/checkpointing/ResumingData.hpp>
 
 template <typename T, ItemType item_type, ItemType sub_item_type>
diff --git a/src/utils/checkpointing/ReadSubItemValuePerItemVariant.cpp b/src/utils/checkpointing/ReadSubItemValuePerItemVariant.cpp
index 6c690f9bfdc91c83aaaacb9b6f73a3b8a50a6c8a..e3983d82b90ffbcb4c086d369cf77a302e76b9b2 100644
--- a/src/utils/checkpointing/ReadSubItemValuePerItemVariant.cpp
+++ b/src/utils/checkpointing/ReadSubItemValuePerItemVariant.cpp
@@ -6,7 +6,7 @@
 #include <mesh/Connectivity.hpp>
 #include <mesh/SubItemValuePerItemVariant.hpp>
 #include <utils/checkpointing/ItemTypeHFType.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
+#include <utils/checkpointing/ReadArray.hpp>
 #include <utils/checkpointing/ResumingData.hpp>
 
 template <typename T, ItemType item_type, ItemType sub_item_type>
diff --git a/src/utils/checkpointing/ReadTable.hpp b/src/utils/checkpointing/ReadTable.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a78978a2d06dc33149ab0e5d0ea06ff925edb854
--- /dev/null
+++ b/src/utils/checkpointing/ReadTable.hpp
@@ -0,0 +1,45 @@
+#ifndef READ_TABLE_HPP
+#define READ_TABLE_HPP
+
+#include <mesh/CellType.hpp>
+#include <mesh/ItemId.hpp>
+#include <utils/HighFivePugsUtils.hpp>
+#include <utils/Messenger.hpp>
+#include <utils/Table.hpp>
+
+template <typename DataType>
+PUGS_INLINE Table<DataType>
+readTable(const HighFive::Group& group, const std::string& name)
+{
+  auto get_address = [](auto& t) { return (t.numberOfRows() * t.numberOfColumns() > 0) ? &(t(0, 0)) : nullptr; };
+
+  using data_type = std::remove_const_t<DataType>;
+
+  auto dataset = group.getDataSet(name);
+
+  const size_t number_of_columns = dataset.getAttribute("number_of_columns").read<size_t>();
+  const std::vector<size_t> number_of_rows_per_rank =
+    dataset.getAttribute("number_of_rows_per_rank").read<std::vector<size_t>>();
+
+  std::vector<size_t> offset{0, 0ul};
+  for (size_t i = 0; i < parallel::rank(); ++i) {
+    offset[0] += number_of_rows_per_rank[i] * number_of_columns;
+  }
+  std::vector<size_t> count{number_of_rows_per_rank[parallel::rank()]};
+
+  Table<DataType> table(number_of_rows_per_rank[parallel::rank()], number_of_columns);
+  if constexpr (std::is_same_v<CellType, data_type>) {
+    using base_type = std::underlying_type_t<CellType>;
+    dataset.select(offset, count).read_raw(reinterpret_cast<base_type*>(get_address(table)));
+  } else if constexpr ((std::is_same_v<CellId, data_type>) or (std::is_same_v<FaceId, data_type>) or
+                       (std::is_same_v<EdgeId, data_type>) or (std::is_same_v<NodeId, data_type>)) {
+    using base_type = typename data_type::base_type;
+    dataset.select(offset, count).read_raw<base_type>(reinterpret_cast<base_type*>(get_address(table)));
+  } else {
+    dataset.select(offset, count).read_raw<data_type>(get_address(table));
+  }
+
+  return table;
+}
+
+#endif   // READ_TABLE_HPP
diff --git a/src/utils/checkpointing/ReadVariableBCDescriptor.cpp b/src/utils/checkpointing/ReadVariableBCDescriptor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..05b7deb29da36d73c7fcd0d0098917a4ae0a9807
--- /dev/null
+++ b/src/utils/checkpointing/ReadVariableBCDescriptor.cpp
@@ -0,0 +1,30 @@
+#include <utils/checkpointing/ReadVariableBCDescriptor.hpp>
+
+#include <language/utils/DataHandler.hpp>
+#include <language/utils/EmbeddedData.hpp>
+#include <scheme/VariableBCDescriptor.hpp>
+#include <utils/checkpointing/ReadDiscreteFunctionVariant.hpp>
+#include <utils/checkpointing/ReadIBoundaryConditionDescriptor.hpp>
+
+EmbeddedData
+readVariableBCDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
+{
+  const HighFive::Group variable_bc_descriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
+
+  HighFive::Group discrete_function_group = variable_bc_descriptor_group.getGroup("discrete_function");
+
+  std::shared_ptr<const DiscreteFunctionVariant> discrete_function =
+    readDiscreteFunctionVariant(discrete_function_group);
+
+  HighFive::Group bc_descriptor_list_group = variable_bc_descriptor_group.getGroup("bc_descriptor_list");
+  std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>> bc_descriptor_list;
+  for (size_t i = 0; i < bc_descriptor_list_group.getNumberObjects(); ++i) {
+    HighFive::Group bc_descriptor_group = bc_descriptor_list_group.getGroup(std::to_string(i));
+    bc_descriptor_list.push_back(readIBoundaryConditionDescriptor(bc_descriptor_group));
+  }
+
+  std::shared_ptr<const VariableBCDescriptor> p_variable_bc_descriptor =
+    std::make_shared<const VariableBCDescriptor>(discrete_function, bc_descriptor_list);
+
+  return {std::make_shared<DataHandler<const VariableBCDescriptor>>(p_variable_bc_descriptor)};
+}
diff --git a/src/utils/checkpointing/ReadVariableBCDescriptor.hpp b/src/utils/checkpointing/ReadVariableBCDescriptor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..188cfc799d3f2a5299813287d80ba893dc97dedd
--- /dev/null
+++ b/src/utils/checkpointing/ReadVariableBCDescriptor.hpp
@@ -0,0 +1,10 @@
+#ifndef READ_VARIABLE_BC_DESCRIPTOR_HPP
+#define READ_VARIABLE_BC_DESCRIPTOR_HPP
+
+#include <utils/HighFivePugsUtils.hpp>
+
+class EmbeddedData;
+
+EmbeddedData readVariableBCDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
+
+#endif   // READ_VARIABLE_BC_DESCRIPTOR_HPP
diff --git a/src/utils/checkpointing/Resume.cpp b/src/utils/checkpointing/Resume.cpp
index b7ee29441743a35ecc30a3d9c56b20a0fc69e3c7..563b47ff0fc2a3a665c42967f1fd09155613aee0 100644
--- a/src/utils/checkpointing/Resume.cpp
+++ b/src/utils/checkpointing/Resume.cpp
@@ -4,33 +4,22 @@
 
 #ifdef PUGS_HAS_HDF5
 
-#include <utils/HighFivePugsUtils.hpp>
-
+#include <algebra/LinearSolverOptions.hpp>
 #include <language/ast/ASTExecutionStack.hpp>
-#include <language/utils/SymbolTable.hpp>
-
-#include <iostream>
-#endif   // PUGS_HAS_HDF5
-
 #include <language/utils/ASTCheckpointsInfo.hpp>
-#include <utils/Exceptions.hpp>
-
-#ifdef PUGS_HAS_HDF5
-
-#include <algebra/LinearSolverOptions.hpp>
+#include <language/utils/CheckpointResumeRepository.hpp>
+#include <language/utils/SymbolTable.hpp>
 #include <mesh/Connectivity.hpp>
+#include <utils/Exceptions.hpp>
 #include <utils/ExecutionStatManager.hpp>
+#include <utils/HighFivePugsUtils.hpp>
 #include <utils/RandomEngine.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
-#include <utils/checkpointing/ResumingData.hpp>
-#include <utils/checkpointing/ResumingManager.hpp>
-
 #include <utils/checkpointing/LinearSolverOptionsHFType.hpp>
 #include <utils/checkpointing/ParallelCheckerHFType.hpp>
+#include <utils/checkpointing/ResumingData.hpp>
+#include <utils/checkpointing/ResumingManager.hpp>
 
-#include <language/utils/CheckpointResumeRepository.hpp>
-
-#include <map>
+#include <iostream>
 
 void
 resume()
diff --git a/src/utils/checkpointing/ResumeUtils.cpp b/src/utils/checkpointing/ResumeUtils.cpp
deleted file mode 100644
index 9f057a35dd396e0e971fa0c824e2aa8ad36761bc..0000000000000000000000000000000000000000
--- a/src/utils/checkpointing/ResumeUtils.cpp
+++ /dev/null
@@ -1,376 +0,0 @@
-#include <utils/checkpointing/ResumeUtils.hpp>
-
-#include <analysis/GaussLegendreQuadratureDescriptor.hpp>
-#include <analysis/GaussLobattoQuadratureDescriptor.hpp>
-#include <analysis/GaussQuadratureDescriptor.hpp>
-#include <language/utils/DataHandler.hpp>
-#include <language/utils/OFStream.hpp>
-#include <language/utils/SymbolTable.hpp>
-#include <mesh/ItemArrayVariant.hpp>
-#include <mesh/ItemValueVariant.hpp>
-#include <mesh/NamedInterfaceDescriptor.hpp>
-#include <mesh/NamedZoneDescriptor.hpp>
-#include <mesh/NumberedInterfaceDescriptor.hpp>
-#include <mesh/NumberedZoneDescriptor.hpp>
-#include <mesh/SubItemArrayPerItemVariant.hpp>
-#include <mesh/SubItemValuePerItemVariant.hpp>
-#include <output/GnuplotWriter.hpp>
-#include <output/GnuplotWriter1D.hpp>
-#include <output/NamedDiscreteFunction.hpp>
-#include <output/NamedItemArrayVariant.hpp>
-#include <output/NamedItemValueVariant.hpp>
-#include <output/VTKWriter.hpp>
-#include <scheme/DiscreteFunctionDescriptorP0.hpp>
-#include <scheme/DiscreteFunctionDescriptorP0Vector.hpp>
-#include <scheme/DiscreteFunctionP0.hpp>
-#include <scheme/DiscreteFunctionVariant.hpp>
-#include <scheme/VariableBCDescriptor.hpp>
-#include <utils/checkpointing/DiscreteFunctionTypeHFType.hpp>
-#include <utils/checkpointing/IBoundaryConditionDescriptorHFType.hpp>
-#include <utils/checkpointing/IBoundaryDescriptorHFType.hpp>
-#include <utils/checkpointing/IInterfaceDescriptorHFType.hpp>
-#include <utils/checkpointing/INamedDiscreteDataHFType.hpp>
-#include <utils/checkpointing/IWriterHFType.hpp>
-#include <utils/checkpointing/IZoneDescriptorHFType.hpp>
-#include <utils/checkpointing/ItemTypeHFType.hpp>
-#include <utils/checkpointing/OStreamTypeHFType.hpp>
-#include <utils/checkpointing/QuadratureTypeHFType.hpp>
-#include <utils/checkpointing/ReadItemArray.hpp>
-#include <utils/checkpointing/ReadItemArrayVariant.hpp>
-#include <utils/checkpointing/ReadItemValue.hpp>
-#include <utils/checkpointing/ReadItemValueVariant.hpp>
-#include <utils/checkpointing/ResumingData.hpp>
-
-#include <utils/checkpointing/ReadIBoundaryConditionDescriptor.hpp>
-
-EmbeddedData
-readIDiscreteFunctionDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group idiscrete_function_descriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-  const DiscreteFunctionType discrete_function_type =
-    idiscrete_function_descriptor_group.getAttribute("discrete_function_type").read<DiscreteFunctionType>();
-
-  std::shared_ptr<const IDiscreteFunctionDescriptor> idiscrete_function_descriptor;
-
-  switch (discrete_function_type) {
-  case DiscreteFunctionType::P0: {
-    idiscrete_function_descriptor = std::make_shared<const DiscreteFunctionDescriptorP0>();
-    break;
-  }
-  case DiscreteFunctionType::P0Vector: {
-    idiscrete_function_descriptor = std::make_shared<const DiscreteFunctionDescriptorP0Vector>();
-    break;
-  }
-  }
-
-  return {std::make_shared<DataHandler<const IDiscreteFunctionDescriptor>>(idiscrete_function_descriptor)};
-}
-
-EmbeddedData
-readIInterfaceDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group iinterfacedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-  const IInterfaceDescriptor::Type iinterface_descriptor_type =
-    iinterfacedescriptor_group.getAttribute("iinterface_descriptor_type").read<IInterfaceDescriptor::Type>();
-
-  std::shared_ptr<const IInterfaceDescriptor> iinterface_descriptor;
-
-  switch (iinterface_descriptor_type) {
-  case IInterfaceDescriptor::Type::named: {
-    const std::string name = iinterfacedescriptor_group.getAttribute("name").read<std::string>();
-    iinterface_descriptor  = std::make_shared<const NamedInterfaceDescriptor>(name);
-    break;
-  }
-  case IInterfaceDescriptor::Type::numbered: {
-    const unsigned int number = iinterfacedescriptor_group.getAttribute("number").read<unsigned int>();
-    iinterface_descriptor     = std::make_shared<const NumberedInterfaceDescriptor>(number);
-    break;
-  }
-  }
-  return {std::make_shared<DataHandler<const IInterfaceDescriptor>>(iinterface_descriptor)};
-}
-
-std::shared_ptr<DiscreteFunctionVariant> readDiscreteFunctionVariant(const HighFive::Group& discrete_function_group);
-
-EmbeddedData
-readINamedDiscreteData(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group inamed_discrete_data_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-
-  const INamedDiscreteData::Type& type =
-    inamed_discrete_data_group.getAttribute("named_discrete_data_type").read<INamedDiscreteData::Type>();
-
-  const std::string name = inamed_discrete_data_group.getAttribute("named_discrete_data_name").read<std::string>();
-
-  std::shared_ptr<const INamedDiscreteData> inamed_discrete_data;
-
-  switch (type) {
-  case INamedDiscreteData::Type::discrete_function: {
-    HighFive::Group discrete_function_group = inamed_discrete_data_group.getGroup("discrete_function_variant");
-    inamed_discrete_data =
-      std::make_shared<const NamedDiscreteFunction>(readDiscreteFunctionVariant(discrete_function_group), name);
-    break;
-  }
-  case INamedDiscreteData::Type::item_array: {
-    HighFive::Group item_array_group = inamed_discrete_data_group.getGroup("item_array_variant");
-    inamed_discrete_data = std::make_shared<const NamedItemArrayVariant>(readItemArrayVariant(item_array_group), name);
-    break;
-  }
-  case INamedDiscreteData::Type::item_value: {
-    HighFive::Group item_value_group = inamed_discrete_data_group.getGroup("item_value_variant");
-    inamed_discrete_data = std::make_shared<const NamedItemValueVariant>(readItemValueVariant(item_value_group), name);
-    break;
-  }
-  }
-
-  return {std::make_shared<DataHandler<const INamedDiscreteData>>(inamed_discrete_data)};
-}
-
-EmbeddedData
-readIQuadratureDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group iquadraturedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-  const QuadratureType quadrature_type =
-    iquadraturedescriptor_group.getAttribute("quadrature_type").read<QuadratureType>();
-  const size_t degree = iquadraturedescriptor_group.getAttribute("quadrature_degree").read<size_t>();
-
-  std::shared_ptr<const IQuadratureDescriptor> iquadrature_descrptor;
-
-  switch (quadrature_type) {
-  case QuadratureType::Gauss: {
-    iquadrature_descrptor = std::make_shared<const GaussQuadratureDescriptor>(degree);
-    break;
-  }
-  case QuadratureType::GaussLegendre: {
-    iquadrature_descrptor = std::make_shared<const GaussLegendreQuadratureDescriptor>(degree);
-    break;
-  }
-  case QuadratureType::GaussLobatto: {
-    iquadrature_descrptor = std::make_shared<const GaussLobattoQuadratureDescriptor>(degree);
-    break;
-  }
-  }
-
-  return {std::make_shared<DataHandler<const IQuadratureDescriptor>>(iquadrature_descrptor)};
-}
-
-std::shared_ptr<ItemArrayVariant> readItemArrayVariant(const HighFive::Group& item_array_variant_group);
-
-EmbeddedData
-readItemType(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group item_type_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-  const ItemType item_type              = item_type_group.getAttribute("item_type").read<ItemType>();
-
-  return {std::make_shared<DataHandler<const ItemType>>(std::make_shared<const ItemType>(item_type))};
-}
-
-EmbeddedData
-readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group iwriter_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-
-  std::shared_ptr<WriterBase> p_writer;
-
-  IWriter::Type type = iwriter_group.getAttribute("iwriter_type").read<IWriter::Type>();
-
-  std::string base_filename = iwriter_group.getAttribute("base_filename").read<std::string>();
-
-  switch (type) {
-  case IWriter::Type::gnuplot: {
-    p_writer = std::make_shared<GnuplotWriter>(base_filename);
-    break;
-  }
-  case IWriter::Type::gnuplot_1d: {
-    p_writer = std::make_shared<GnuplotWriter1D>(base_filename);
-    break;
-  }
-  case IWriter::Type::vtk: {
-    p_writer = std::make_shared<VTKWriter>(base_filename);
-    break;
-  }
-  }
-
-  if (iwriter_group.exist("period_manager")) {
-    HighFive::Group period_manager_group = iwriter_group.getGroup("period_manager");
-
-    const double time_period = period_manager_group.getAttribute("time_period").read<double>();
-    const double next_time   = period_manager_group.getAttribute("next_time").read<double>();
-    const std::vector<double> saved_times =
-      period_manager_group.getAttribute("saved_times").read<std::vector<double>>();
-
-    p_writer->m_period_manager.emplace(WriterBase::PeriodManager(time_period, next_time, saved_times));
-  }
-
-  if (iwriter_group.hasAttribute("signature")) {
-    p_writer->m_signature = iwriter_group.getAttribute("signature").read<std::string>();
-  }
-
-  return {std::make_shared<DataHandler<const IWriter>>(p_writer)};
-}
-
-EmbeddedData
-readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group izonedescriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-  const IZoneDescriptor::Type izone_descriptor_type =
-    izonedescriptor_group.getAttribute("izone_descriptor_type").read<IZoneDescriptor::Type>();
-
-  std::shared_ptr<const IZoneDescriptor> izone_descriptor;
-
-  switch (izone_descriptor_type) {
-  case IZoneDescriptor::Type::named: {
-    const std::string name = izonedescriptor_group.getAttribute("name").read<std::string>();
-    izone_descriptor       = std::make_shared<const NamedZoneDescriptor>(name);
-    break;
-  }
-  case IZoneDescriptor::Type::numbered: {
-    const unsigned int number = izonedescriptor_group.getAttribute("number").read<unsigned int>();
-    izone_descriptor          = std::make_shared<const NumberedZoneDescriptor>(number);
-    break;
-  }
-  }
-
-  return {std::make_shared<DataHandler<const IZoneDescriptor>>(izone_descriptor)};
-}
-
-EmbeddedData
-readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group mesh_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-
-  const size_t mesh_id = mesh_group.getAttribute("id").read<uint64_t>();
-
-  return {std::make_shared<DataHandler<const MeshVariant>>(ResumingData::instance().meshVariant(mesh_id))};
-}
-
-std::shared_ptr<DiscreteFunctionVariant>
-readDiscreteFunctionVariant(const HighFive::Group& discrete_function_group)
-{
-  DiscreteFunctionType type = discrete_function_group.getAttribute("Vh_type").read<DiscreteFunctionType>();
-  size_t mesh_id            = discrete_function_group.getAttribute("mesh_id").read<size_t>();
-
-  std::shared_ptr<const MeshVariant> mesh_v = ResumingData::instance().meshVariant(mesh_id);
-
-  const std::string data_type = discrete_function_group.getAttribute("data_type").read<std::string>();
-
-  std::shared_ptr<DiscreteFunctionVariant> p_discrete_function;
-  switch (type) {
-  case DiscreteFunctionType::P0: {
-    if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const double>(mesh_v,
-                                         readItemValue<double, ItemType::cell>(discrete_function_group, "values",
-                                                                               mesh_v->connectivity())));
-    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<1>>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const TinyVector<1>>(mesh_v,
-                                                readItemValue<TinyVector<1>, ItemType::cell>(discrete_function_group,
-                                                                                             "values",
-                                                                                             mesh_v->connectivity())));
-    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<2>>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const TinyVector<2>>(mesh_v,
-                                                readItemValue<TinyVector<2>, ItemType::cell>(discrete_function_group,
-                                                                                             "values",
-                                                                                             mesh_v->connectivity())));
-    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyVector<3>>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const TinyVector<3>>(mesh_v,
-                                                readItemValue<TinyVector<3>, ItemType::cell>(discrete_function_group,
-                                                                                             "values",
-                                                                                             mesh_v->connectivity())));
-    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<1>>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const TinyMatrix<1>>(mesh_v,
-                                                readItemValue<TinyMatrix<1>, ItemType::cell>(discrete_function_group,
-                                                                                             "values",
-                                                                                             mesh_v->connectivity())));
-    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<2>>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const TinyMatrix<2>>(mesh_v,
-                                                readItemValue<TinyMatrix<2>, ItemType::cell>(discrete_function_group,
-                                                                                             "values",
-                                                                                             mesh_v->connectivity())));
-    } else if (data_type == dataTypeName(ast_node_data_type_from<TinyMatrix<3>>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0<const TinyMatrix<3>>(mesh_v,
-                                                readItemValue<TinyMatrix<3>, ItemType::cell>(discrete_function_group,
-                                                                                             "values",
-                                                                                             mesh_v->connectivity())));
-    } else {
-      throw UnexpectedError("unexpected discrete function data type: " + data_type);
-    }
-    break;
-  }
-  case DiscreteFunctionType::P0Vector: {
-    if (data_type == dataTypeName(ast_node_data_type_from<double>)) {
-      p_discrete_function = std::make_shared<DiscreteFunctionVariant>(
-        DiscreteFunctionP0Vector<const double>(mesh_v,
-                                               readItemArray<double, ItemType::cell>(discrete_function_group, "values",
-                                                                                     mesh_v->connectivity())));
-    } else {
-      throw UnexpectedError("unexpected discrete function vector data type: " + data_type);
-    }
-    break;
-  }
-  }
-  return p_discrete_function;
-}
-
-EmbeddedData
-readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group discrete_function_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-
-  std::shared_ptr<DiscreteFunctionVariant> p_discrete_function = readDiscreteFunctionVariant(discrete_function_group);
-
-  return {std::make_shared<DataHandler<const DiscreteFunctionVariant>>(p_discrete_function)};
-}
-
-EmbeddedData
-readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group ostream_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-
-  const OStream::Type ostream_type = ostream_group.getAttribute("ostream_type").read<OStream::Type>();
-
-  std::shared_ptr<const OStream> p_ostream;
-
-  switch (ostream_type) {
-  case OStream::Type::std_ofstream: {
-    std::string filename = ostream_group.getAttribute("filename").read<std::string>();
-
-    p_ostream = std::make_shared<OFStream>(filename, true);
-    break;
-  }
-  case OStream::Type::std_ostream: {
-    throw NotImplementedError("std::ostream resume");
-  }
-  }
-
-  return {std::make_shared<DataHandler<const OStream>>(p_ostream)};
-}
-
-EmbeddedData
-readVariableBCDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group)
-{
-  const HighFive::Group variable_bc_descriptor_group = symbol_table_group.getGroup("embedded/" + symbol_name);
-
-  HighFive::Group discrete_function_group = variable_bc_descriptor_group.getGroup("discrete_function");
-
-  std::shared_ptr<const DiscreteFunctionVariant> discrete_function =
-    readDiscreteFunctionVariant(discrete_function_group);
-
-  HighFive::Group bc_descriptor_list_group = variable_bc_descriptor_group.getGroup("bc_descriptor_list");
-  std::vector<std::shared_ptr<const IBoundaryConditionDescriptor>> bc_descriptor_list;
-  for (size_t i = 0; i < bc_descriptor_list_group.getNumberObjects(); ++i) {
-    HighFive::Group bc_descriptor_group = bc_descriptor_list_group.getGroup(std::to_string(i));
-    bc_descriptor_list.push_back(readIBoundaryConditionDescriptor(bc_descriptor_group));
-  }
-
-  std::shared_ptr<const VariableBCDescriptor> p_variable_bc_descriptor =
-    std::make_shared<const VariableBCDescriptor>(discrete_function, bc_descriptor_list);
-
-  return {std::make_shared<DataHandler<const VariableBCDescriptor>>(p_variable_bc_descriptor)};
-}
diff --git a/src/utils/checkpointing/ResumeUtils.hpp b/src/utils/checkpointing/ResumeUtils.hpp
deleted file mode 100644
index 06bc7e97e6b6ca5a616a067f9a681fdfeda43882..0000000000000000000000000000000000000000
--- a/src/utils/checkpointing/ResumeUtils.hpp
+++ /dev/null
@@ -1,107 +0,0 @@
-#ifndef RESUME_UTILS_HPP
-#define RESUME_UTILS_HPP
-
-#include <utils/HighFivePugsUtils.hpp>
-
-#include <language/utils/SymbolTable.hpp>
-#include <mesh/CellType.hpp>
-#include <mesh/ItemArray.hpp>
-#include <mesh/ItemValue.hpp>
-#include <utils/Messenger.hpp>
-
-#ifdef PUGS_HAS_HDF5
-
-template <typename DataType>
-PUGS_INLINE Array<DataType>
-readArray(const HighFive::Group& group, const std::string& name)
-{
-  auto get_address = [](auto& x) { return (x.size() > 0) ? &(x[0]) : nullptr; };
-
-  using data_type = std::remove_const_t<DataType>;
-
-  auto dataset = group.getDataSet(name);
-
-  std::vector<size_t> size_per_rank = dataset.getAttribute("size_per_rank").read<std::vector<size_t>>();
-
-  if (size_per_rank.size() != parallel::size()) {
-    throw NormalError("cannot change number of processes");
-  }
-
-  std::vector<size_t> offset{0, 0ul};
-  for (size_t i = 0; i < parallel::rank(); ++i) {
-    offset[0] += size_per_rank[i];
-  }
-  std::vector<size_t> count{size_per_rank[parallel::rank()]};
-
-  Array<DataType> array(size_per_rank[parallel::rank()]);
-  if constexpr (std::is_same_v<CellType, data_type>) {
-    using base_type = std::underlying_type_t<CellType>;
-    dataset.select(offset, count).read_raw(reinterpret_cast<base_type*>(get_address(array)));
-  } else if constexpr ((std::is_same_v<CellId, data_type>) or (std::is_same_v<FaceId, data_type>) or
-                       (std::is_same_v<EdgeId, data_type>) or (std::is_same_v<NodeId, data_type>)) {
-    using base_type = typename data_type::base_type;
-    dataset.select(offset, count).read_raw(reinterpret_cast<base_type*>(get_address(array)));
-  } else {
-    dataset.select(offset, count).read_raw(get_address(array));
-  }
-
-  return array;
-}
-
-template <typename DataType>
-PUGS_INLINE Table<DataType>
-readTable(const HighFive::Group& group, const std::string& name)
-{
-  auto get_address = [](auto& t) { return (t.numberOfRows() * t.numberOfColumns() > 0) ? &(t(0, 0)) : nullptr; };
-
-  using data_type = std::remove_const_t<DataType>;
-
-  auto dataset = group.getDataSet(name);
-
-  const size_t number_of_columns = dataset.getAttribute("number_of_columns").read<size_t>();
-  const std::vector<size_t> number_of_rows_per_rank =
-    dataset.getAttribute("number_of_rows_per_rank").read<std::vector<size_t>>();
-
-  std::vector<size_t> offset{0, 0ul};
-  for (size_t i = 0; i < parallel::rank(); ++i) {
-    offset[0] += number_of_rows_per_rank[i] * number_of_columns;
-  }
-  std::vector<size_t> count{number_of_rows_per_rank[parallel::rank()]};
-
-  Table<DataType> table(number_of_rows_per_rank[parallel::rank()], number_of_columns);
-  if constexpr (std::is_same_v<CellType, data_type>) {
-    using base_type = std::underlying_type_t<CellType>;
-    dataset.select(offset, count).read_raw(reinterpret_cast<base_type*>(get_address(table)));
-  } else if constexpr ((std::is_same_v<CellId, data_type>) or (std::is_same_v<FaceId, data_type>) or
-                       (std::is_same_v<EdgeId, data_type>) or (std::is_same_v<NodeId, data_type>)) {
-    using base_type = typename data_type::base_type;
-    dataset.select(offset, count).read_raw<base_type>(reinterpret_cast<base_type*>(get_address(table)));
-  } else {
-    dataset.select(offset, count).read_raw<data_type>(get_address(table));
-  }
-
-  return table;
-}
-
-#endif   // PUGS_HAS_HDF5
-
-EmbeddedData readDiscreteFunctionVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readIBoundaryConditionDescriptor(const std::string& symbol_name,
-                                              const HighFive::Group& symbol_table_group);
-EmbeddedData readIBoundaryDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readIDiscreteFunctionDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readIInterfaceDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readINamedDiscreteData(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readIQuadratureDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readItemArrayVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readItemType(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readItemValueVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readIWriter(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readIZoneDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readMesh(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readOStream(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readSubItemArrayPerItemVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readSubItemValuePerItemVariant(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-EmbeddedData readVariableBCDescriptor(const std::string& symbol_name, const HighFive::Group& symbol_table_group);
-
-#endif   // RESUME_UTILS_HPP
diff --git a/src/utils/checkpointing/ResumingData.cpp b/src/utils/checkpointing/ResumingData.cpp
index d0e51c4a5ff81de59f633b7eaa58a3035fbad2eb..edf1728757d94ef0726951cd36b3f44215124794 100644
--- a/src/utils/checkpointing/ResumingData.cpp
+++ b/src/utils/checkpointing/ResumingData.cpp
@@ -7,8 +7,8 @@
 #include <mesh/Mesh.hpp>
 #include <utils/Exceptions.hpp>
 #include <utils/checkpointing/DualMeshTypeHFType.hpp>
+#include <utils/checkpointing/ReadArray.hpp>
 #include <utils/checkpointing/RefItemListHFType.hpp>
-#include <utils/checkpointing/ResumeUtils.hpp>
 
 ResumingData* ResumingData::m_instance = nullptr;
 
diff --git a/src/utils/checkpointing/ResumingUtils.cpp b/src/utils/checkpointing/ResumingUtils.cpp
index 82e6610519a12710de96ac661d62f1590fc0277f..28a782b49f4bc4c38132e1eab0ae9cd6eeb56f02 100644
--- a/src/utils/checkpointing/ResumingUtils.cpp
+++ b/src/utils/checkpointing/ResumingUtils.cpp
@@ -18,7 +18,7 @@ resumingDatafile(const std::string& filename)
 #else   // PUGS_HAS_HDF5
 
 std::string
-resumingDatafile(const std::string& filename)
+resumingDatafile(const std::string&)
 {
   throw NormalError("Resuming requires HDF5");
 }