diff --git a/examples/ellipt.cc b/examples/ellipt.cc
index 6e0adb2bd55f444ee4e7337055985154e38f70fd..885da9cadfa8f07c9461f8ba40b97a1918847a7d 100644
--- a/examples/ellipt.cc
+++ b/examples/ellipt.cc
@@ -52,7 +52,7 @@ int main(int argc, char** argv)
   std::vector<double> errH1; errH1.reserve(numLevels);
   std::vector<double> widths; widths.reserve(numLevels);
   for (int i = 0; i < numLevels; ++i) {
-    prob.grid().globalRefine(1);
+    prob.grid()->globalRefine(1);
     auto gridView = prob.gridView();
 
     double h = 0;
@@ -60,8 +60,8 @@ int main(int argc, char** argv)
       h = std::max(h, e.geometry().volume());
     widths.push_back(h);
 
-    prob.globalBasis().update(gridView);
-    prob.solutionVector().compress();
+    prob.globalBasis()->update(gridView);
+    prob.solutionVector()->compress();
     prob.assemble(adaptInfo);
     prob.solve(adaptInfo);
 
diff --git a/src/amdis/ProblemInstat.hpp b/src/amdis/ProblemInstat.hpp
index fe25972a9f897263d73a8ddb0fda49fa822b41c8..2542913a0519f0cf13b9cae78496301db853bc88 100644
--- a/src/amdis/ProblemInstat.hpp
+++ b/src/amdis/ProblemInstat.hpp
@@ -54,11 +54,11 @@ namespace AMDiS
     ProblemType const& problemStat() const { return *problemStat_; }
 
     /// Returns const-ref of \ref oldSolution.
-    SystemVector const& oldSolutionVector() const
+    std::unique_ptr<SystemVector const> oldSolutionVector() const
     {
       test_exit_dbg(bool(oldSolution_),
         "OldSolution need to be created. Call initialize with INIT_UH_OLD.");
-      return *oldSolution_;
+      return oldSolution_;
     }
 
     /// Return a const view to a oldSolution component
diff --git a/src/amdis/ProblemInstat.inc.hpp b/src/amdis/ProblemInstat.inc.hpp
index 1b3a29dd5d057805ede3ac8e5eb8ef58dc76ea1c..0daf5aefb0549a873fb1aabfa1ee549be2cb28cd 100644
--- a/src/amdis/ProblemInstat.inc.hpp
+++ b/src/amdis/ProblemInstat.inc.hpp
@@ -45,7 +45,7 @@ void ProblemInstat<Traits>::createUhOld()
   if (oldSolution_)
     warning("oldSolution already created\n");
   else // create oldSolution
-    oldSolution_.reset(new SystemVector(problemStat_->globalBasis(), INTERPOLATE));
+    oldSolution_.reset(new SystemVector(*problemStat_->globalBasis(), INTERPOLATE));
 }
 
 
@@ -53,7 +53,7 @@ template <class Traits>
 void ProblemInstat<Traits>::initTimestep(AdaptInfo&)
 {
   if (oldSolution_)
-    *oldSolution_ = problemStat_->solutionVector();
+    *oldSolution_ = *problemStat_->solutionVector();
 }
 
 } // end namespace AMDiS
diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp
index 452c26be6a6c40315f27a7ed49ff6a001fc61774..050ef6af48ea3c6ef80ddb579ec5c93e9a677e4a 100644
--- a/src/amdis/ProblemStat.hpp
+++ b/src/amdis/ProblemStat.hpp
@@ -282,37 +282,35 @@ namespace AMDiS
 
 
     /// Return a reference to the grid, \ref grid
-    Grid&       grid()       { return *grid_; }
-    Grid const& grid() const { return *grid_; }
+    std::shared_ptr<Grid>       grid()       { return grid_; }
+    std::shared_ptr<Grid const> grid() const { return grid_; }
 
     /// Return the gridView of the leaf-level
-    GridView const& gridView() const { return globalBasis_->gridView(); }
+    GridView gridView() const { return globalBasis_->gridView(); }
 
     /// Return the boundary manager to identify boundary segments
-    BoundaryManager<Grid>&       boundaryManager()       { return *boundaryManager_; }
-    BoundaryManager<Grid> const& boundaryManager() const { return *boundaryManager_; }
-
-    auto const& boundaryManagerPtr() { return boundaryManager_; }
+    std::shared_ptr<BoundaryManager<Grid>>       boundaryManager()       { return boundaryManager_; }
+    std::shared_ptr<BoundaryManager<Grid> const> boundaryManager() const { return boundaryManager_; }
 
     /// Return the \ref globalBasis_
-    GlobalBasis&       globalBasis()       { return *globalBasis_; }
-    GlobalBasis const& globalBasis() const { return *globalBasis_; }
+    std::shared_ptr<GlobalBasis>       globalBasis()       { return globalBasis_; }
+    std::shared_ptr<GlobalBasis const> globalBasis() const { return globalBasis_; }
 
     /// Return a reference to the linear solver, \ref linearSolver
-    LinearSolverType&       solver()       { return *linearSolver_; }
-    LinearSolverType const& solver() const { return *linearSolver_; }
+    std::shared_ptr<LinearSolverType>       solver()       { return linearSolver_; }
+    std::shared_ptr<LinearSolverType const> solver() const { return linearSolver_; }
 
     /// Returns a reference to system-matrix, \ref systemMatrix_
-    SystemMatrix&       systemMatrix()       { return *systemMatrix_; }
-    SystemMatrix const& systemMatrix() const { return *systemMatrix_; }
+    std::shared_ptr<SystemMatrix>       systemMatrix()       { return systemMatrix_; }
+    std::shared_ptr<SystemMatrix const> systemMatrix() const { return systemMatrix_; }
 
     /// Returns a reference to the solution vector, \ref solution_
-    SystemVector&       solutionVector()       { return *solution_; }
-    SystemVector const& solutionVector() const { return *solution_; }
+    std::shared_ptr<SystemVector>       solutionVector()       { return solution_; }
+    std::shared_ptr<SystemVector const> solutionVector() const { return solution_; }
 
     /// Return a reference to the rhs system-vector, \ref rhs
-    SystemVector&       rhsVector()       { return *rhs_; }
-    SystemVector const& rhsVector() const { return *rhs_; }
+    std::shared_ptr<SystemVector>       rhsVector()       { return rhs_; }
+    std::shared_ptr<SystemVector const> rhsVector() const { return rhs_; }
 
 
     /// Return a mutable view to a solution component
diff --git a/src/amdis/linearalgebra/DOFVectorBase.hpp b/src/amdis/linearalgebra/DOFVectorBase.hpp
index f4752b162330c7a59ab522948f5d4f61e6350ebb..3dc723eddd86722aceee872f11af0e495f50a3fb 100644
--- a/src/amdis/linearalgebra/DOFVectorBase.hpp
+++ b/src/amdis/linearalgebra/DOFVectorBase.hpp
@@ -190,15 +190,15 @@ namespace AMDiS
     void assemble();
 
     /// Return the associated DataTransfer object
-    DataTransfer const& dataTransfer() const
+    std::shared_ptr<DataTransfer const> dataTransfer() const
     {
-      return *dataTransfer_;
+      return dataTransfer_;
     }
 
     /// Return the associated DataTransfer object
-    DataTransfer& dataTransfer()
+    std::shared_ptr<DataTransfer> dataTransfer()
     {
-      return *dataTransfer_;
+      return dataTransfer_;
     }
 
     /// Create a new DataTransfer object based on the operation type
diff --git a/test/DataTransferTest.hpp b/test/DataTransferTest.hpp
index 7006d3cd9156d2f1c0c260b955f4c8da79eeacc7..5502b105d153371d1704d0ede277229beacbab1e 100644
--- a/test/DataTransferTest.hpp
+++ b/test/DataTransferTest.hpp
@@ -63,7 +63,7 @@ auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts
   Problem prob("test", grid);
   prob.initialize(INIT_ALL);
 
-  auto& globalBasis = prob.globalBasis();
+  auto& globalBasis = *prob.globalBasis();
   auto localView = globalBasis.localView();
 
   // interpolate given function to initial grid
@@ -80,7 +80,7 @@ auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts
 template <class Problem, class Fcts>
 double calcError(Problem const& prob, Fcts const& funcs)
 {
-  auto& globalBasis = prob.globalBasis();
+  auto& globalBasis = *prob.globalBasis();
   auto localView = globalBasis.localView();
   auto sol = prob.solution().coefficients();
   std::vector<double> ref;
diff --git a/test/DiscreteFunctionTest.cpp b/test/DiscreteFunctionTest.cpp
index ae1ba4a64b945425b20551a77dadf470e4e505f9..93b6d39e7add91c4792d1ae5dfa882b03f32d2d1 100644
--- a/test/DiscreteFunctionTest.cpp
+++ b/test/DiscreteFunctionTest.cpp
@@ -41,9 +41,9 @@ int main(int argc, char** argv)
   prob.initialize(INIT_ALL);
 
   // create 3 copies of the solution vector
-  auto U0 = prob.solutionVector();
-  auto U1 = prob.solutionVector();
-  auto U2 = prob.solutionVector();
+  auto U0 = *prob.solutionVector();
+  auto U1 = *prob.solutionVector();
+  auto U2 = *prob.solutionVector();
 
   auto u0 = makeDOFVectorView(U0);
   auto u1 = makeDOFVectorView(U1);
@@ -97,7 +97,7 @@ int main(int argc, char** argv)
     dlocalFct.unbind();
   }
 
-  auto V0 = makeDOFVector<double>(prob.globalBasis());
+  auto V0 = makeDOFVector<double>(*prob.globalBasis());
   auto v0 = makeDOFVectorView(V0);
   v0 << expr;
 
@@ -105,22 +105,22 @@ int main(int argc, char** argv)
   int preTP1 = 0;
   std::integral_constant<std::size_t, 0> preTP2;
   auto tp = treepath(preTP1);
-  auto W0 = prob.solutionVector();
-  auto W1 = prob.solutionVector();
-  auto W2 = prob.solutionVector();
+  auto W0 = *prob.solutionVector();
+  auto W1 = *prob.solutionVector();
+  auto W2 = *prob.solutionVector();
   auto w0 = makeDiscreteFunction(W0, preTP1);
   auto w1 = makeDiscreteFunction(W1, preTP2);
   auto w2 = makeDiscreteFunction(W2, tp);
 
   // test makeDOFVectorView with (pre)treepath argument
-  auto W3 = prob.solutionVector();
-  auto W4 = prob.solutionVector();
-  auto W5 = prob.solutionVector();
+  auto W3 = *prob.solutionVector();
+  auto W4 = *prob.solutionVector();
+  auto W5 = *prob.solutionVector();
   auto w3 = makeDOFVectorView(W3, preTP1);
   auto w4 = makeDOFVectorView(W4, preTP2);
   auto w5 = makeDOFVectorView(W5, tp);
   auto w6 = prob.solution(tp);
-  auto& W6 = prob.solutionVector();
+  auto& W6 = *prob.solutionVector();
   w3 << expr;
   w4 << expr;
   w5 << expr;