diff --git a/src/storage/expressions/BaseExpression.h b/src/storage/expressions/BaseExpression.h
index 85b521726..54102464e 100644
--- a/src/storage/expressions/BaseExpression.h
+++ b/src/storage/expressions/BaseExpression.h
@@ -2,6 +2,7 @@
 #define STORM_STORAGE_EXPRESSIONS_BASEEXPRESSION_H_
 
 #include "src/storage/expressions/Valuation.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
 
 namespace storm {
     namespace expressions {
@@ -12,13 +13,15 @@ namespace storm {
              */
             enum ReturnType {undefined, bool_, int_, double_};
             
-            std::unique_ptr<BaseExpression> substitute() const = 0;
+            virtual int_fast64_t evaluateAsInt(Valuation const& evaluation) const = 0;
             
-            virtual int_fast64_t evaluateAsInt(Evaluation const& evaluation) const = 0;
+            virtual bool evaluateAsBool(Valuation const& evaluation) const = 0;
             
-            virtual bool evaluateAsBool(Evaluation const& evaluation) const = 0;
+            virtual double evaluateAsDouble(Valuation const& evaluation) const = 0;
             
-            virtual double evaluateAsDouble(Evaluation const& evaluation) const = 0;
+            virtual std::unique_ptr<BaseExpression> operator+(BaseExpression const& other) const = 0;
+            
+            virtual void visit(ExpressionVisitor* visitor) const = 0;
         };
     }
 }
diff --git a/src/storage/expressions/Expression.cpp b/src/storage/expressions/Expression.cpp
index 335fa3ca7..7ca4e23bf 100644
--- a/src/storage/expressions/Expression.cpp
+++ b/src/storage/expressions/Expression.cpp
@@ -1,13 +1,29 @@
+#include <map>
+#include <unordered_map>
+
 #include "src/storage/expressions/Expression.h"
 
 namespace storm {
     namespace expressions {
-        virtual Expression Expression::operator+(Expression const& other) {
+        Expression::Expression(std::unique_ptr<BaseExpression>&& expressionPtr) : expressionPtr(std::move(expressionPtr)) {
+            // Intentionally left empty.
+        }
+        
+        template<template<typename... Arguments> class MapType>
+        Expression Expression::substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const {
+            SubstitutionVisitor visitor;
+            return visitor.substitute(this->getBaseExpression(), identifierToExpressionMap);
+        }
+
+        Expression Expression::operator+(Expression const& other) {
             return Expression(this->getBaseExpression() + other.getBaseExpression());
         }
         
-        BaseExpression const& getBaseExpression() const {
+        BaseExpression const& Expression::getBaseExpression() const {
             return *this->expressionPtr;
         }
+        
+        template Expression Expression::substitute<std::map>(std::map<std::string, storm::expressions::Expression> const&) const;
+        template Expression Expression::substitute<std::unordered_map>(std::unordered_map<std::string, storm::expressions::Expression> const&) const;
     }
 }
diff --git a/src/storage/expressions/Expression.h b/src/storage/expressions/Expression.h
index c44219736..a780a0819 100644
--- a/src/storage/expressions/Expression.h
+++ b/src/storage/expressions/Expression.h
@@ -1,6 +1,10 @@
 #ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 #define STORM_STORAGE_EXPRESSIONS_EXPRESSION_H_
 
+#include <functional>
+
+#include "src/storage/expressions/BaseExpression.h"
+
 namespace storm {
     namespace expressions {
         class Expression {
@@ -12,19 +16,25 @@ namespace storm {
             virtual Expression operator+(Expression const& other);
             
             /*!
-             * Substitutes all occurrences of identifiers according to the given substitution. Note that this
-             * substitution is done simultaneously, i.e., identifiers appearing in the expressions that were "plugged
-             * in" are not substituted.
-             *
-             * @param substitutionFilter A function that returns true iff the given identifier is supposed to be
+             * Substitutes all occurrences of identifiers according to the given map. Note that this substitution is
+             * done simultaneously, i.e., identifiers appearing in the expressions that were "plugged in" are not
              * substituted.
-             * @param substitution A substitution that returns for each identifier an expression that is supposed to
-             * replace the identifier.
-             * @return An expression in which all identifiers
+             *
+             * @param identifierToExpressionMap A mapping from identifiers to the expression they are substituted with.
+             * @return An expression in which all identifiers in the key set of the mapping are replaced by the
+             * expression they are mapped to.
              */
-            Expression substitute(std::function<Expression (std::string const&)> const& substitution) const;
+            template<template<typename... Arguments> class MapType>
+            Expression substitute(MapType<std::string, Expression> const& identifierToExpressionMap) const;
             
         private:
+            /*!
+             * Creates an expression with the given underlying base expression.
+             *
+             * @param expressionPtr A pointer to the underlying base expression.
+             */
+            Expression(std::unique_ptr<BaseExpression>&& expressionPtr);
+            
             /*!
              * Retrieves the base expression underlying this expression object. Note that prior to calling this, the
              * expression object must be properly initialized.
diff --git a/src/storage/expressions/ExpressionVisitor.h b/src/storage/expressions/ExpressionVisitor.h
new file mode 100644
index 000000000..e145826b6
--- /dev/null
+++ b/src/storage/expressions/ExpressionVisitor.h
@@ -0,0 +1,12 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_
+
+namespace storm {
+    namespace expressions {
+        class ExpressionVisitor {
+            
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSIONVISITOR_H_ */
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.cpp b/src/storage/expressions/SimpleValuation.cpp
index 20c9f9f2f..ea829557e 100644
--- a/src/storage/expressions/SimpleValuation.cpp
+++ b/src/storage/expressions/SimpleValuation.cpp
@@ -14,16 +14,31 @@ namespace storm {
             (*this->identifierToIndexMap)[name] = index;
         }
         
+        void SimpleValuation::setBooleanValue(std::string const& name, bool value) {
+            this->booleanValues[(*this->identifierToIndexMap)[name]] = value;
+        }
+        
+        void SimpleValuation::setIntegerValue(std::string const& name, int_fast64_t value) {
+            this->integerValues[(*this->identifierToIndexMap)[name]] = value;
+        }
+        
+        void SimpleValuation::setDoubleValue(std::string const& name, double value) {
+            this->doubleValues[(*this->identifierToIndexMap)[name]] = value;
+        }
+        
         bool SimpleValuation::getBooleanValue(std::string const& name) const {
-            return false;
+            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            return this->booleanValues[nameIndexPair->second];
         }
         
         int_fast64_t SimpleValuation::getIntegerValue(std::string const& name) const {
-            return 0;
+            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            return this->integerValues[nameIndexPair->second];
         }
         
         double SimpleValuation::getDoubleValue(std::string const& name) const {
-            return 0.0;
+            auto const& nameIndexPair = this->identifierToIndexMap->find(name);
+            return this->doubleValues[nameIndexPair->second];
         }
     }
 }
\ No newline at end of file
diff --git a/src/storage/expressions/SimpleValuation.h b/src/storage/expressions/SimpleValuation.h
index fd7d3c8b0..399a6d7f4 100644
--- a/src/storage/expressions/SimpleValuation.h
+++ b/src/storage/expressions/SimpleValuation.h
@@ -24,6 +24,10 @@ namespace storm {
             
             void setIdentifierIndex(std::string const& name, uint_fast64_t index);
             
+            void setBooleanValue(std::string const& name, bool value);
+            void setIntegerValue(std::string const& name, int_fast64_t value);
+            void setDoubleValue(std::string const& name, double value);
+            
             virtual bool getBooleanValue(std::string const& name) const override;
             virtual int_fast64_t getIntegerValue(std::string const& name) const override;
             virtual double getDoubleValue(std::string const& name) const override;
diff --git a/src/storage/expressions/SubstitutionVisitor.h b/src/storage/expressions/SubstitutionVisitor.h
new file mode 100644
index 000000000..217b07b23
--- /dev/null
+++ b/src/storage/expressions/SubstitutionVisitor.h
@@ -0,0 +1,17 @@
+#ifndef STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
+#define STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_
+
+#include "src/storage/expressions/BaseExpression.h"
+#include "src/storage/expressions/ExpressionVisitor.h"
+
+namespace storm {
+    namespace expressions {
+        class SubstitutionVisitor : public ExpressionVisitor {
+        public:
+            template<template<typename... Arguments> class MapType>
+            Expression substitute(BaseExpression const* expression, MapType<std::string, Expression> const& identifierToExpressionMap);
+        };
+    }
+}
+
+#endif /* STORM_STORAGE_EXPRESSIONS_SUBSTITUTIONVISITOR_H_ */
\ No newline at end of file