diff --git a/AMDiS/src/io/ArhReader.cc b/AMDiS/src/io/ArhReader.cc
index 9642cb4ed725d8a99f91efe6d024778d8544b7d5..6747b1b2c5ffbcd9412753ff38a32d7426af5a56 100644
--- a/AMDiS/src/io/ArhReader.cc
+++ b/AMDiS/src/io/ArhReader.cc
@@ -1,7 +1,7 @@
 //
 // Software License for AMDiS
 //
-// Copyright (c) 2010 Dresden University of Technology 
+// Copyright (c) 2010 Dresden University of Technology
 // All rights reserved.
 // Authors: Simon Vey, Thomas Witkowski et al.
 //
@@ -20,12 +20,12 @@
 #include "DOFVector.h"
 
 namespace AMDiS {
-  
+
   using namespace std;
 
 
   void ArhReader::read(string filename, Mesh *mesh,
-		       DOFVector<double>* vec0, 
+		       DOFVector<double>* vec0,
 		       DOFVector<double>* vec1,
 		       DOFVector<double>* vec2,
 		       bool writeParallel,
@@ -41,12 +41,12 @@ namespace AMDiS {
       vecs.push_back(vec2);
     for (size_t i = 3; i < nValueVectors; i++)
       vecs.push_back(NULL);
-    
+
     ArhReader::read(filename, mesh, vecs, writeParallel, nProcs);
   }
 
 
-  void ArhReader::read(string filename, Mesh *mesh, 
+  void ArhReader::read(string filename, Mesh *mesh,
 		       vector<DOFVector<double>*> vecs,
 		       bool writeParallel,
 		       int nProcs)
@@ -57,9 +57,9 @@ namespace AMDiS {
       using boost::lexical_cast;
       int sPos = filename.find(".arh");
       TEST_EXIT(sPos >= 0)("Failed to find file postfix!\n");
-      string name = filename.substr(0, sPos);      
+      string name = filename.substr(0, sPos);
 
-      if (nProcs == -1) {     
+      if (nProcs == -1) {
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 	string procFilename = name + "-p" + lexical_cast<string>(MPI::COMM_WORLD.Get_rank()) + "-.arh";
 	readFile(procFilename, mesh, vecs);
@@ -78,8 +78,8 @@ namespace AMDiS {
     MSG("ARH file read from: %s\n", filename.c_str());
   }
 
-  
-  void ArhReader::readFile(string filename, 
+
+  void ArhReader::readFile(string filename,
 			   Mesh *mesh,
 			   vector<DOFVector<double>*> vecs)
   {
@@ -90,7 +90,7 @@ namespace AMDiS {
     for (std::deque<MacroElement*>::iterator it = mesh->getMacroElements().begin();
 	 it != mesh->getMacroElements().end(); ++it)
       macroInMesh.insert((*it)->getIndex());
-    
+
 
     RefinementManager *refManager = NULL;
     switch (mesh->getDim()) {
@@ -121,7 +121,7 @@ namespace AMDiS {
     file.read(reinterpret_cast<char*>(&nAllValues), 4);
 
     TEST_EXIT(nValueVectors == vecs.size())
-      ("File %s has %d vectors, but %d DOFVectors are provided!\n", 
+      ("File %s has %d vectors, but %d DOFVectors are provided!\n",
        filename.c_str(), nValueVectors, vecs.size());
 
     for (unsigned int i = 0; i < nMacroElements; i++) {
@@ -141,15 +141,17 @@ namespace AMDiS {
       if (macroInMesh.count(elIndex) == 1)
 	elementStructure.fitMeshToStructure(mesh, refManager, false, elIndex);
 
-      uint32_t nValuesPerVector = 0;
-      file.read(reinterpret_cast<char*>(&nValuesPerVector), 4);
+      if(nValueVectors > 0){
+	uint32_t nValuesPerVector = 0;
+	file.read(reinterpret_cast<char*>(&nValuesPerVector), 4);
 
-      for (unsigned int j = 0; j < nValueVectors; j++) {
-	vector<double> values(nValuesPerVector);
-	file.read(reinterpret_cast<char*>(&(values[0])), 8 * nValuesPerVector);
-	if (vecs[j] != NULL) {
-	  if (macroInMesh.count(elIndex) == 1)
-	    setDofValues(elIndex, mesh, values, vecs[j]);
+	for (unsigned int j = 0; j < nValueVectors; j++) {
+	  vector<double> values(nValuesPerVector);
+	  file.read(reinterpret_cast<char*>(&(values[0])), 8 * nValuesPerVector);
+	  if (vecs[j] != NULL) {
+	    if (macroInMesh.count(elIndex) == 1)
+	      setDofValues(elIndex, mesh, values, vecs[j]);
+	  }
 	}
       }
     }
@@ -174,7 +176,7 @@ namespace AMDiS {
       if (!macroElement) {
 	Element *mEl = elInfo->getMacroElement()->getElement();
 	for (int i = 0; i < mesh->getGeo(VERTEX); i++)
-	  (*vec)[mEl->getDof(i, 0)] = values[valuePos++];	
+	  (*vec)[mEl->getDof(i, 0)] = values[valuePos++];
 	macroElement = true;
       }
 
@@ -185,4 +187,130 @@ namespace AMDiS {
       elInfo = stack.traverseNext(elInfo);
     }
   }
+
+
+  //the following three functions are identical to read/readfile except that they read from
+  //a block of memory instead of from a file
+  void ArhReader::readFromMemoryBlock(vector<char> &data, Mesh *mesh,
+           DOFVector<double>* vec0,
+           DOFVector<double>* vec1,
+           DOFVector<double>* vec2,
+           bool writeParallel,
+           int nProcs)
+  {
+    uint32_t nValueVectors;
+    memcpy(reinterpret_cast<char*>(&nValueVectors), &data[8], 4);
+    vector<DOFVector<double>*> vecs(0);
+    if (nValueVectors > 0)
+      vecs.push_back(vec0);
+    if (nValueVectors > 1)
+      vecs.push_back(vec1);
+    if (nValueVectors > 2)
+      vecs.push_back(vec2);
+    for (uint32_t i = 3; i < nValueVectors; i++)
+      vecs.push_back(NULL);
+
+    readFromMemoryBlock(data, mesh, vecs, writeParallel, nProcs);
+  }
+
+
+  void ArhReader::readFromMemoryBlock(vector<char> &data, Mesh *mesh,
+           vector<DOFVector<double>*> vecs,
+           bool writeParallel,
+           int nProcs)
+  {
+    FUNCNAME("ArhReader::readFromMemoryBlock()");
+
+    if (writeParallel) {
+      ERROR_EXIT("Reading a hierarchy from several memory blocks is not implemented yet!\n");
+    } else {
+      readBlock(data, mesh, vecs);
+    }
+  }
+
+
+  void ArhReader::readBlock(vector<char> &data,
+         Mesh *mesh,
+         vector<DOFVector<double>*> vecs)
+  {
+    FUNCNAME("ArhReader::readBlock()");
+
+    // === Get set of all macro elements in mesh. ===
+    std::set<int> macroInMesh;
+    for (std::deque<MacroElement*>::iterator it = mesh->getMacroElements().begin();
+                                         it != mesh->getMacroElements().end(); ++it)
+      macroInMesh.insert((*it)->getIndex());
+
+
+    RefinementManager *refManager = NULL;
+    switch (mesh->getDim()) {
+    case 2:
+      refManager = new RefinementManager2d();
+      break;
+    case 3:
+      refManager = new RefinementManager3d();
+      break;
+    default:
+      ERROR_EXIT("Should not happen!\n");
+    }
+
+    string typeId = "";
+    uint32_t nMacroElements = 0;
+    uint32_t nValueVectors = 0;
+    uint32_t nAllValues = 0;
+    uint32_t mem_index = 0;
+
+    memcpy(const_cast<char*>(typeId.data()), &data[mem_index], 4);
+    mem_index += 4;
+    memcpy(reinterpret_cast<char*>(&nMacroElements), &data[mem_index], 4);
+    mem_index += 4;
+    memcpy(reinterpret_cast<char*>(&nValueVectors), &data[mem_index], 4);
+    mem_index += 4;
+    memcpy(reinterpret_cast<char*>(&nAllValues), &data[mem_index], 4);
+    mem_index += 4;
+
+    TEST_EXIT(nValueVectors == vecs.size())
+      ("data has %d vectors, but %d DOFVectors are provided!\n", nValueVectors, vecs.size());
+
+    for (unsigned int i = 0; i < nMacroElements; i++) {
+      uint32_t elIndex = 0;
+      uint32_t nStructureCodes = 0;
+      uint32_t codeSize = 0;
+
+      memcpy(reinterpret_cast<char*>(&elIndex), &data[mem_index], 4);
+      mem_index += 4;
+      memcpy(reinterpret_cast<char*>(&nStructureCodes), &data[mem_index], 4);
+      mem_index += 4;
+      memcpy(reinterpret_cast<char*>(&codeSize), &data[mem_index], 4);
+      mem_index += 4;
+
+      vector<uint64_t> structureCode(nStructureCodes);
+      memcpy(reinterpret_cast<char*>(&structureCode[0]), &data[mem_index], 8 * nStructureCodes);
+      mem_index += 8 * nStructureCodes;
+
+      MeshStructure elementStructure;
+      elementStructure.init(structureCode, codeSize);
+      if (macroInMesh.count(elIndex) == 1)
+        elementStructure.fitMeshToStructure(mesh, refManager, false, elIndex);
+
+      if(nValueVectors > 0){
+        uint32_t nValuesPerVector = 0;
+        memcpy(reinterpret_cast<char*>(&nValuesPerVector), &data[mem_index], 4);
+        mem_index += 4;
+
+        for (unsigned int j = 0; j < nValueVectors; j++) {
+          vector<double> values(nValuesPerVector);
+          memcpy(reinterpret_cast<char*>(&values[0]), &data[mem_index], 8 * nValuesPerVector);
+          mem_index += 8 * nValuesPerVector;
+          if (vecs[j] != NULL) {
+            if (macroInMesh.count(elIndex) == 1)
+              setDofValues(elIndex, mesh, values, vecs[j]);
+          }
+        }
+      }
+    }
+
+    delete refManager;
+  }
+
 }
diff --git a/AMDiS/src/io/ArhReader.h b/AMDiS/src/io/ArhReader.h
index 800564ef1ae49781cc56c1b38c8d21afa184e71c..5614d2b913f5a1a295d062bb6070194922dd9d12 100644
--- a/AMDiS/src/io/ArhReader.h
+++ b/AMDiS/src/io/ArhReader.h
@@ -8,7 +8,7 @@
 //
 // Software License for AMDiS
 //
-// Copyright (c) 2010 Dresden University of Technology 
+// Copyright (c) 2010 Dresden University of Technology
 // All rights reserved.
 // Authors: Simon Vey, Thomas Witkowski et al.
 //
@@ -33,9 +33,9 @@ namespace AMDiS {
   {
   public:
     static void read(string filename, Mesh *mesh,
-		     DOFVector<double>* vec0 = NULL, 
+		     DOFVector<double>* vec0 = NULL,
 		     DOFVector<double>* vec1 = NULL,
-		     DOFVector<double>* vec2 = NULL,		     
+		     DOFVector<double>* vec2 = NULL,
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 		     bool writeParallel = true,
 #else
@@ -43,7 +43,7 @@ namespace AMDiS {
 #endif
 		     int nProcs = -1);
 
-    static void read(string filename, Mesh *mesh, 
+    static void read(string filename, Mesh *mesh,
 		     vector<DOFVector<double>*> vecs,
 #ifdef HAVE_PARALLEL_DOMAIN_AMDIS
 		     bool writeParallel = true,
@@ -52,34 +52,59 @@ namespace AMDiS {
 #endif
 		     int nProcs = -1);
 
+    static void readFromMemoryBlock(vector<char> &data, Mesh *mesh,
+           DOFVector<double>* vec0 = NULL,
+           DOFVector<double>* vec1 = NULL,
+           DOFVector<double>* vec2 = NULL,
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+           bool writeParallel = true,
+#else
+           bool writeParallel = false,
+#endif
+           int nProcs = -1);
+
+    static void readFromMemoryBlock(vector<char> &data, Mesh *mesh,
+           vector<DOFVector<double>*> vecs,
+#ifdef HAVE_PARALLEL_DOMAIN_AMDIS
+           bool writeParallel = true,
+#else
+           bool writeParallel = false,
+#endif
+           int nProcs = -1);
+
     static int getNumValueVectors(string filename)
-    {    
+    {
       ifstream file;
       file.open(filename.c_str(), ios::in | ios::binary);
 
       string typeId = "";
       uint32_t nMacroElements = 0;
       uint32_t nValueVectors = 0;
-      uint32_t nAllValues = 0;
+      //uint32_t nAllValues = 0;
 
       file.read(const_cast<char*>(typeId.data()), 4);
       file.read(reinterpret_cast<char*>(&nMacroElements), 4);
       file.read(reinterpret_cast<char*>(&nValueVectors), 4);
-      file.read(reinterpret_cast<char*>(&nAllValues), 4);
+      //file.read(reinterpret_cast<char*>(&nAllValues), 4);
 
       file.close();
-      
+
       return nValueVectors;
     }
-    
+
   private:
 
-    static void readFile(string filename, 
+    static void readFile(string filename,
 			 Mesh *mesh,
 			 vector<DOFVector<double>*> vecs);
 
-    static void setDofValues(int macroElIndex, Mesh *mesh, 
+    static void setDofValues(int macroElIndex, Mesh *mesh,
 			     vector<double>& values, DOFVector<double>* vec);
+
+    static void readBlock(vector<char> &data,
+         Mesh *mesh,
+         vector<DOFVector<double>*> vecs);
+
   };
 }
 
diff --git a/AMDiS/src/io/ArhWriter.cc b/AMDiS/src/io/ArhWriter.cc
index c06406f7beb9009ecc0601c374d28eda7a2f9bf3..b16c5f46233cd811a4f7f85747fe589b83665690 100644
--- a/AMDiS/src/io/ArhWriter.cc
+++ b/AMDiS/src/io/ArhWriter.cc
@@ -140,11 +140,13 @@ namespace AMDiS {
     file.write(reinterpret_cast<char*>(&(const_cast<vector<uint64_t>&>(code.getCode())[0])), 
 	       8 * nStructureCodes);
 
-    uint32_t nValuesPerVector = (values.size() > 0 ? values[0].size() : 0);
-    file.write(reinterpret_cast<char*>(&nValuesPerVector), 4);
+    if(values.size() > 0){
+      uint32_t nValuesPerVector = values[0].size();
+      file.write(reinterpret_cast<char*>(&nValuesPerVector), 4);
 
-    for (unsigned int i = 0; i < values.size(); i++)
-      file.write(reinterpret_cast<char*>(&(values[i][0])), 8 * nValuesPerVector);
+      for (unsigned int i = 0; i < values.size(); i++)
+        file.write(reinterpret_cast<char*>(&(values[i][0])), 8 * nValuesPerVector);
+    }
   }
 
 }