diff --git a/resources/3rdparty/cudd-3.0.0/cudd/cudd.h b/resources/3rdparty/cudd-3.0.0/cudd/cudd.h
index 20acf5854..6f63f7a70 100644
--- a/resources/3rdparty/cudd-3.0.0/cudd/cudd.h
+++ b/resources/3rdparty/cudd-3.0.0/cudd/cudd.h
@@ -503,6 +503,9 @@ typedef void (*DD_TOHFP)(DdManager *, void *);
 extern "C" {
 #endif
 
+// Make this visible to the outside.
+extern DdNode * cuddUniqueInter(DdManager *unique, int index, DdNode *T, DdNode *E);
+    
 extern DdNode * Cudd_addNewVar(DdManager *dd);
 extern DdNode * Cudd_addNewVarAtLevel(DdManager *dd, int level);
 extern DdNode * Cudd_bddNewVar(DdManager *dd);
diff --git a/src/storm/abstraction/AbstractionInformation.cpp b/src/storm/abstraction/AbstractionInformation.cpp
index c74cb60cb..5e25b5530 100644
--- a/src/storm/abstraction/AbstractionInformation.cpp
+++ b/src/storm/abstraction/AbstractionInformation.cpp
@@ -499,7 +499,7 @@ namespace storm {
             allSuccessorLocationVariables.insert(newMetaVariable.second);
             successorVariables.insert(newMetaVariable.second);
             extendedPredicateDdVariables.emplace_back(newMetaVariable);
-            allLocationIdentities &= ddManager->template getIdentity<uint64_t>(newMetaVariable.first).equals(ddManager->template getIdentity<uint64_t>(newMetaVariable.second)) && ddManager->getRange(newMetaVariable.first) && ddManager->getRange(newMetaVariable.second);
+            allLocationIdentities &= ddManager->getIdentity(newMetaVariable.first, newMetaVariable.second);
             return std::make_pair(locationVariablePairs.back(), locationVariablePairs.size() - 1);
         }
         
diff --git a/src/storm/builder/DdJaniModelBuilder.cpp b/src/storm/builder/DdJaniModelBuilder.cpp
index f019b2505..6f1e67252 100644
--- a/src/storm/builder/DdJaniModelBuilder.cpp
+++ b/src/storm/builder/DdJaniModelBuilder.cpp
@@ -368,8 +368,8 @@ namespace storm {
                     
                     // Add the identity and ranges of the location variables to the ones of the automaton.
                     std::pair<storm::expressions::Variable, storm::expressions::Variable> const& locationVariables = result.automatonToLocationDdVariableMap[automaton.getName()];
-                    storm::dd::Add<Type, ValueType> variableIdentity = result.manager->template getIdentity<ValueType>(locationVariables.first).equals(result.manager->template getIdentity<ValueType>(locationVariables.second)).template toAdd<ValueType>() * result.manager->getRange(locationVariables.first).template toAdd<ValueType>() * result.manager->getRange(locationVariables.second).template toAdd<ValueType>();
-                    identity &= variableIdentity.toBdd();
+                    storm::dd::Bdd<Type> variableIdentity = result.manager->getIdentity(locationVariables.first, locationVariables.second);
+                    identity &= variableIdentity;
                     range &= result.manager->getRange(locationVariables.first);
                     
                     // Then create variables for the variables of the automaton.
@@ -420,8 +420,8 @@ namespace storm {
                 result.columnMetaVariables.insert(variablePair.second);
                 result.variableToColumnMetaVariableMap->emplace(variable.getExpressionVariable(), variablePair.second);
                 
-                storm::dd::Add<Type, ValueType> variableIdentity = result.manager->template getIdentity<ValueType>(variablePair.first).equals(result.manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>() * result.manager->getRange(variablePair.first).template toAdd<ValueType>() * result.manager->getRange(variablePair.second).template toAdd<ValueType>();
-                result.variableToIdentityMap.emplace(variable.getExpressionVariable(), variableIdentity);
+                storm::dd::Bdd<Type> variableIdentity = result.manager->getIdentity(variablePair.first, variablePair.second);
+                result.variableToIdentityMap.emplace(variable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>());
                 result.rowColumnMetaVariablePairs.push_back(variablePair);
                 result.variableToRangeMap.emplace(variablePair.first, result.manager->getRange(variablePair.first));
                 result.variableToRangeMap.emplace(variablePair.second, result.manager->getRange(variablePair.second));
@@ -440,8 +440,8 @@ namespace storm {
                 result.columnMetaVariables.insert(variablePair.second);
                 result.variableToColumnMetaVariableMap->emplace(variable.getExpressionVariable(), variablePair.second);
                 
-                storm::dd::Add<Type, ValueType> variableIdentity = result.manager->template getIdentity<ValueType>(variablePair.first).equals(result.manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>();
-                result.variableToIdentityMap.emplace(variable.getExpressionVariable(), variableIdentity);
+                storm::dd::Bdd<Type> variableIdentity = result.manager->getIdentity(variablePair.first, variablePair.second);
+                result.variableToIdentityMap.emplace(variable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>());
                 
                 result.variableToRangeMap.emplace(variablePair.first, result.manager->getRange(variablePair.first));
                 result.variableToRangeMap.emplace(variablePair.second, result.manager->getRange(variablePair.second));
diff --git a/src/storm/builder/DdPrismModelBuilder.cpp b/src/storm/builder/DdPrismModelBuilder.cpp
index 4bd31733a..149fc8936 100644
--- a/src/storm/builder/DdPrismModelBuilder.cpp
+++ b/src/storm/builder/DdPrismModelBuilder.cpp
@@ -189,8 +189,8 @@ namespace storm {
                     columnMetaVariables.insert(variablePair.second);
                     variableToColumnMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.second);
                     
-                    storm::dd::Add<Type, ValueType> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>() * manager->getRange(variablePair.first).template toAdd<ValueType>() * manager->getRange(variablePair.second).template toAdd<ValueType>();
-                    variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity);
+                    storm::dd::Bdd<Type> variableIdentity = manager->getIdentity(variablePair.first, variablePair.second);
+                    variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>());
                     rowColumnMetaVariablePairs.push_back(variablePair);
                     
                     allGlobalVariables.insert(integerVariable.getExpressionVariable());
@@ -206,8 +206,8 @@ namespace storm {
                     columnMetaVariables.insert(variablePair.second);
                     variableToColumnMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.second);
                     
-                    storm::dd::Add<Type, ValueType> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)).template toAdd<ValueType>();
-                    variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity);
+                    storm::dd::Bdd<Type> variableIdentity = manager->getIdentity(variablePair.first, variablePair.second);
+                    variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>());
                     
                     rowColumnMetaVariablePairs.push_back(variablePair);
                     allGlobalVariables.insert(booleanVariable.getExpressionVariable());
@@ -230,7 +230,7 @@ namespace storm {
                         columnMetaVariables.insert(variablePair.second);
                         variableToColumnMetaVariableMap->emplace(integerVariable.getExpressionVariable(), variablePair.second);
                         
-                        storm::dd::Bdd<Type> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)) && manager->getRange(variablePair.first) && manager->getRange(variablePair.second);
+                        storm::dd::Bdd<Type> variableIdentity = manager->getIdentity(variablePair.first, variablePair.second);
                         variableToIdentityMap.emplace(integerVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>());
                         moduleIdentity &= variableIdentity;
                         moduleRange &= manager->getRange(variablePair.first);
@@ -247,7 +247,7 @@ namespace storm {
                         columnMetaVariables.insert(variablePair.second);
                         variableToColumnMetaVariableMap->emplace(booleanVariable.getExpressionVariable(), variablePair.second);
                         
-                        storm::dd::Bdd<Type> variableIdentity = manager->template getIdentity<ValueType>(variablePair.first).equals(manager->template getIdentity<ValueType>(variablePair.second)) && manager->getRange(variablePair.first) && manager->getRange(variablePair.second);
+                        storm::dd::Bdd<Type> variableIdentity = manager->getIdentity(variablePair.first, variablePair.second);
                         variableToIdentityMap.emplace(booleanVariable.getExpressionVariable(), variableIdentity.template toAdd<ValueType>());
                         moduleIdentity &= variableIdentity;
                         moduleRange &= manager->getRange(variablePair.first);
diff --git a/src/storm/models/symbolic/Model.cpp b/src/storm/models/symbolic/Model.cpp
index 61f9932f4..686a1e9e5 100644
--- a/src/storm/models/symbolic/Model.cpp
+++ b/src/storm/models/symbolic/Model.cpp
@@ -208,7 +208,7 @@ namespace storm {
             
             template<storm::dd::DdType Type, typename ValueType>
             storm::dd::Add<Type, ValueType> Model<Type, ValueType>::getRowColumnIdentity() const {
-                return storm::utility::dd::getRowColumnDiagonal<Type, ValueType>(this->getManager(), this->getRowColumnMetaVariablePairs());
+                return (storm::utility::dd::getRowColumnDiagonal<Type>(this->getManager(), this->getRowColumnMetaVariablePairs()) && this->getReachableStates()).template toAdd<ValueType>();
             }
             
             template<storm::dd::DdType Type, typename ValueType>
diff --git a/src/storm/storage/dd/DdManager.cpp b/src/storm/storage/dd/DdManager.cpp
index 58d6f20f6..dbba10a29 100644
--- a/src/storm/storage/dd/DdManager.cpp
+++ b/src/storm/storage/dd/DdManager.cpp
@@ -122,15 +122,20 @@ namespace storm {
         template<DdType LibraryType>
         Bdd<LibraryType> DdManager<LibraryType>::getRange(storm::expressions::Variable const& variable) const {
             storm::dd::DdMetaVariable<LibraryType> const& metaVariable = this->getMetaVariable(variable);
-            STORM_LOG_THROW(metaVariable.hasHigh(), storm::exceptions::InvalidOperationException, "Cannot create range for meta variable.");
-            
-            Bdd<LibraryType> result = this->getBddZero();
-            
-            for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
-                result |= this->getEncoding(variable, value);
+
+            if (metaVariable.hasHigh()) {
+                return Bdd<LibraryType>(*this, internalDdManager.getBddEncodingLessOrEqualThan(static_cast<uint64_t>(metaVariable.getHigh() - metaVariable.getLow()), metaVariable.getCube().getInternalBdd(), metaVariable.getNumberOfDdVariables()), {variable});
+//                Bdd<LibraryType> result = this->getBddZero();
+//                for (int_fast64_t value = metaVariable.getLow(); value <= metaVariable.getHigh(); ++value) {
+//                    result |= this->getEncoding(variable, value);
+//                }
+//                return result;
+            } else {
+                // If there is no upper bound on this variable, the whole range is valid.
+                Bdd<LibraryType> result = this->getBddOne();
+                result.addMetaVariable(variable);
+                return result;
             }
-            
-            return result;
         }
 
         template<DdType LibraryType>
@@ -146,6 +151,33 @@ namespace storm {
             return result;
         }
 		
+        template<DdType LibraryType>
+        Bdd<LibraryType> DdManager<LibraryType>::getIdentity(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& variablePairs, bool restrictToFirstRange) const {
+            auto result = this->getBddOne();
+            for (auto const& pair : variablePairs) {
+                result &= this->getIdentity(pair.first, pair.second, restrictToFirstRange);
+            }
+            return result;
+        }
+        
+        template<DdType LibraryType>
+        Bdd<LibraryType> DdManager<LibraryType>::getIdentity(storm::expressions::Variable const& first, storm::expressions::Variable const& second, bool restrictToFirstRange) const {
+            auto const& firstMetaVariable = this->getMetaVariable(first);
+            auto const& secondMetaVariable = this->getMetaVariable(second);
+            
+            STORM_LOG_THROW(firstMetaVariable.getNumberOfDdVariables() == secondMetaVariable.getNumberOfDdVariables(), storm::exceptions::InvalidOperationException, "Mismatching sizes of meta variables.");
+            
+            auto const& firstDdVariables = firstMetaVariable.getDdVariables();
+            auto const& secondDdVariables = secondMetaVariable.getDdVariables();
+
+            auto result = restrictToFirstRange ? this->getRange(first) : this->getBddOne();
+            for (auto it1 = firstDdVariables.begin(), it2 = secondDdVariables.begin(), ite1 = firstDdVariables.end(); it1 != ite1; ++it1, ++it2) {
+                result &= it1->iff(*it2);
+            }
+            
+            return result;
+        }
+        
         template<DdType LibraryType>
         Bdd<LibraryType> DdManager<LibraryType>::getCube(storm::expressions::Variable const& variable) const {
             return getCube({variable});
diff --git a/src/storm/storage/dd/DdManager.h b/src/storm/storage/dd/DdManager.h
index 3332d1b88..055bbfb1a 100644
--- a/src/storm/storage/dd/DdManager.h
+++ b/src/storm/storage/dd/DdManager.h
@@ -131,6 +131,23 @@ namespace storm {
             template<typename ValueType>
             Add<LibraryType, ValueType> getIdentity(storm::expressions::Variable const& variable) const;
             
+            /*!
+             * Retrieves a BDD in which an encoding is mapped to true iff the meta variables of each pair encode the same value.
+             *
+             * @param variablePairs The variable pairs for which to compute the identity.
+             * @param restrictToFirstRange If set, the identity will be restricted to the legal range of the first variable.
+             */
+            Bdd<LibraryType> getIdentity(std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& variablePairs, bool restrictToFirstRange = true) const;
+
+            /*!
+             * Retrieves a BDD in which an encoding is mapped to true iff the two meta variables encode the same value.
+             * 
+             * @param first The first meta variable in the identity.
+             * @param second The second meta variable in the identity.
+             * @param restrictToFirstRange If set, the identity will be restricted to the legal range of the first variable.
+             */
+            Bdd<LibraryType> getIdentity(storm::expressions::Variable const& first, storm::expressions::Variable const& second, bool restrictToFirstRange = true) const;
+
             /*!
              * Retrieves a BDD that is the cube of the variables representing the given meta variable.
              *
diff --git a/src/storm/storage/dd/bisimulation/SignatureRefiner.cpp b/src/storm/storage/dd/bisimulation/SignatureRefiner.cpp
index 73db85e4a..5e5e3a3c8 100644
--- a/src/storm/storage/dd/bisimulation/SignatureRefiner.cpp
+++ b/src/storm/storage/dd/bisimulation/SignatureRefiner.cpp
@@ -198,18 +198,13 @@ namespace storm {
                             result = thenResult;
                         } else {
                             // Get the node to connect the subresults.
-                            DdNode* var = Cudd_addIthVar(ddman, Cudd_NodeReadIndex(nonBlockVariablesNode) + offset);
-                            Cudd_Ref(var);
-                            result = Cudd_addIte(ddman, var, thenResult, elseResult);
-                            Cudd_Ref(result);
-                            Cudd_RecursiveDeref(ddman, var);
+                            result = cuddUniqueInter(ddman, Cudd_NodeReadIndex(nonBlockVariablesNode) + offset, thenResult, elseResult);
                             Cudd_Deref(thenResult);
                             Cudd_Deref(elseResult);
                         }
                         
                         // Store the result in the cache.
                         signatureCache[nodePair] = result;
-                        Cudd_Deref(result);
                         
                         return result;
                     }
diff --git a/src/storm/storage/dd/cudd/InternalCuddDdManager.cpp b/src/storm/storage/dd/cudd/InternalCuddDdManager.cpp
index 952c7199c..58223d739 100644
--- a/src/storm/storage/dd/cudd/InternalCuddDdManager.cpp
+++ b/src/storm/storage/dd/cudd/InternalCuddDdManager.cpp
@@ -57,6 +57,42 @@ namespace storm {
             return InternalBdd<DdType::CUDD>(this, cuddManager.bddZero());
         }
         
+        InternalBdd<DdType::CUDD> InternalDdManager<DdType::CUDD>::getBddEncodingLessOrEqualThan(uint64_t bound, InternalBdd<DdType::CUDD> const& cube, uint64_t numberOfDdVariables) const {
+            DdNodePtr node = this->getBddEncodingLessOrEqualThanRec(0, (1ull << numberOfDdVariables) - 1, bound, cube.getCuddDdNode(), numberOfDdVariables);
+            STORM_LOG_ASSERT(node != nullptr, "Wut?");
+            FILE* fp = fopen("range.dot", "w");
+            Cudd_DumpDot(cuddManager.getManager(), 1, &node, nullptr, nullptr, fp);
+            fclose(fp);
+            
+            auto tmp = cudd::BDD(cuddManager, node);
+            return InternalBdd<DdType::CUDD>(this, tmp);
+        }
+        
+        DdNodePtr InternalDdManager<DdType::CUDD>::getBddEncodingLessOrEqualThanRec(uint64_t minimalValue, uint64_t maximalValue, uint64_t bound, DdNodePtr cube, uint64_t remainingDdVariables) const {
+            std::cout << minimalValue << " / " << maximalValue << " -> " << bound << std::endl;
+            if (maximalValue <= bound) {
+                return Cudd_ReadOne(cuddManager.getManager());
+            } else if (minimalValue > bound) {
+                return Cudd_ReadLogicZero(cuddManager.getManager());
+            }
+            
+            STORM_LOG_ASSERT(remainingDdVariables > 0, "Expected more remaining DD variables.");
+            STORM_LOG_ASSERT(!Cudd_IsConstant(cube), "Expected non-constant cube.");
+            uint64_t newRemainingDdVariables = remainingDdVariables - 1;
+            DdNodePtr elseResult = getBddEncodingLessOrEqualThanRec(minimalValue, maximalValue & ~(1ull << newRemainingDdVariables), bound, Cudd_T(cube), newRemainingDdVariables);
+            Cudd_Ref(elseResult);
+            DdNodePtr thenResult = getBddEncodingLessOrEqualThanRec(minimalValue | (1ull << newRemainingDdVariables), maximalValue, bound, Cudd_T(cube), newRemainingDdVariables);
+            Cudd_Ref(thenResult);
+            STORM_LOG_ASSERT(thenResult != elseResult, "Expected different results.");
+            
+            std::cout << "creating " << Cudd_NodeReadIndex(cube) << " -> " << thenResult << " / " << elseResult << std::endl;
+            DdNodePtr result = cuddUniqueInter(cuddManager.getManager(), Cudd_NodeReadIndex(cube), thenResult, elseResult);
+            std::cout << "result " << result << std::endl;
+            Cudd_Deref(thenResult);
+            Cudd_Deref(elseResult);
+            return result;
+        }
+        
         template<typename ValueType>
         InternalAdd<DdType::CUDD, ValueType> InternalDdManager<DdType::CUDD>::getAddZero() const {
             return InternalAdd<DdType::CUDD, ValueType>(this, cuddManager.addZero());
diff --git a/src/storm/storage/dd/cudd/InternalCuddDdManager.h b/src/storm/storage/dd/cudd/InternalCuddDdManager.h
index 44efef0c5..3b1c74e16 100644
--- a/src/storm/storage/dd/cudd/InternalCuddDdManager.h
+++ b/src/storm/storage/dd/cudd/InternalCuddDdManager.h
@@ -59,6 +59,13 @@ namespace storm {
              */
             InternalBdd<DdType::CUDD> getBddZero() const;
             
+            /*!
+             * Retrieves a BDD that maps to true iff the encoding is less or equal than the given bound.
+             *
+             * @return A BDD with encodings corresponding to values less or equal than the bound.
+             */
+            InternalBdd<DdType::CUDD> getBddEncodingLessOrEqualThan(uint64_t bound, InternalBdd<DdType::CUDD> const& cube, uint64_t numberOfDdVariables) const;
+            
             /*!
              * Retrieves an ADD representing the constant zero function.
              *
@@ -146,6 +153,9 @@ namespace storm {
             cudd::Cudd const& getCuddManager() const;
 
         private:
+            // Helper function to create the BDD whose encodings are below a given bound.
+            DdNodePtr getBddEncodingLessOrEqualThanRec(uint64_t minimalValue, uint64_t maximalValue, uint64_t bound, DdNodePtr cube, uint64_t remainingDdVariables) const;
+            
             // The manager responsible for the DDs created/modified with this DdManager.
             cudd::Cudd cuddManager;
             
diff --git a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp
index 4586e9890..29f9a3208 100644
--- a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp
+++ b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.cpp
@@ -129,6 +129,28 @@ namespace storm {
             return InternalBdd<DdType::Sylvan>(this, sylvan::Bdd::bddZero());
         }
         
+        InternalBdd<DdType::Sylvan> InternalDdManager<DdType::Sylvan>::getBddEncodingLessOrEqualThan(uint64_t bound, InternalBdd<DdType::Sylvan> const& cube, uint64_t numberOfDdVariables) const {
+            return InternalBdd<DdType::Sylvan>(this, sylvan::Bdd(this->getBddEncodingLessOrEqualThanRec(0, (1ull << numberOfDdVariables) - 1, bound, cube.getSylvanBdd().GetBDD(), numberOfDdVariables)));
+        }
+        
+        BDD InternalDdManager<DdType::Sylvan>::getBddEncodingLessOrEqualThanRec(uint64_t minimalValue, uint64_t maximalValue, uint64_t bound, BDD cube, uint64_t remainingDdVariables) const {
+            if (maximalValue <= bound) {
+                return sylvan_true;
+            } else if (minimalValue > bound) {
+                return sylvan_false;
+            }
+            
+            STORM_LOG_ASSERT(remainingDdVariables > 0, "Expected more remaining DD variables.");
+            uint64_t newRemainingDdVariables = remainingDdVariables - 1;
+            BDD elseResult = getBddEncodingLessOrEqualThanRec(minimalValue, maximalValue & ~(1ull << newRemainingDdVariables), bound, sylvan_high(cube), newRemainingDdVariables);
+            bdd_refs_push(elseResult);
+            BDD thenResult = getBddEncodingLessOrEqualThanRec(minimalValue | (1ull << newRemainingDdVariables), maximalValue, bound, sylvan_high(cube), newRemainingDdVariables);
+            bdd_refs_push(elseResult);
+            BDD result = sylvan_makenode(sylvan_var(cube), elseResult, thenResult);
+            bdd_refs_pop(2);
+            return result;
+        }
+        
         template<>
         InternalAdd<DdType::Sylvan, double> InternalDdManager<DdType::Sylvan>::getAddZero() const {
             return InternalAdd<DdType::Sylvan, double>(this, sylvan::Mtbdd::doubleTerminal(storm::utility::zero<double>()));
diff --git a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.h b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.h
index c10915145..408817965 100644
--- a/src/storm/storage/dd/sylvan/InternalSylvanDdManager.h
+++ b/src/storm/storage/dd/sylvan/InternalSylvanDdManager.h
@@ -60,6 +60,13 @@ namespace storm {
              */
             InternalBdd<DdType::Sylvan> getBddZero() const;
             
+            /*!
+             * Retrieves a BDD that maps to true iff the encoding is less or equal than the given bound.
+             *
+             * @return A BDD with encodings corresponding to values less or equal than the bound.
+             */
+            InternalBdd<DdType::Sylvan> getBddEncodingLessOrEqualThan(uint64_t bound, InternalBdd<DdType::Sylvan> const& cube, uint64_t numberOfDdVariables) const;
+
             /*!
              * Retrieves an ADD representing the constant zero function.
              *
@@ -133,6 +140,9 @@ namespace storm {
             uint_fast64_t getNumberOfDdVariables() const;
             
         private:
+            // Helper function to create the BDD whose encodings are below a given bound.
+            BDD getBddEncodingLessOrEqualThanRec(uint64_t minimalValue, uint64_t maximalValue, uint64_t bound, BDD cube, uint64_t remainingDdVariables) const;
+            
             // A counter for the number of instances of this class. This is used to determine when to initialize and
             // quit the sylvan. This is because Sylvan does not know the concept of managers but implicitly has a
             // 'global' manager.
diff --git a/src/storm/utility/dd.cpp b/src/storm/utility/dd.cpp
index b4b74a19a..47d15347e 100644
--- a/src/storm/utility/dd.cpp
+++ b/src/storm/utility/dd.cpp
@@ -45,38 +45,17 @@ namespace storm {
                 return reachableStates;
             }
             
-            template <storm::dd::DdType Type, typename ValueType>
-            storm::dd::Add<Type, ValueType> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) {
-                storm::dd::Add<Type, ValueType> result = ddManager.template getAddOne<ValueType>();
-                for (auto const& pair : rowColumnMetaVariablePairs) {
-                    result *= ddManager.template getIdentity<ValueType>(pair.first).equals(ddManager.template getIdentity<ValueType>(pair.second)).template toAdd<ValueType>();
-                    result *= ddManager.getRange(pair.first).template toAdd<ValueType>() * ddManager.getRange(pair.second).template toAdd<ValueType>();
-                }
-                return result;
-            }
-            
             template <storm::dd::DdType Type>
             storm::dd::Bdd<Type> getRowColumnDiagonal(storm::dd::DdManager<Type> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs) {
-                storm::dd::Bdd<Type> diagonal = ddManager.getBddOne();
-                for (auto const& pair : rowColumnMetaVariablePairs) {
-                    diagonal &= ddManager.template getIdentity<uint64_t>(pair.first).equals(ddManager.template getIdentity<uint64_t>(pair.second));
-                    diagonal &= ddManager.getRange(pair.first) && ddManager.getRange(pair.second);
-                }
-                return diagonal;
+                return ddManager.getIdentity(rowColumnMetaVariablePairs);
             }
             
             template storm::dd::Bdd<storm::dd::DdType::CUDD> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::CUDD> const& initialStates, storm::dd::Bdd<storm::dd::DdType::CUDD> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables);
             template storm::dd::Bdd<storm::dd::DdType::Sylvan> computeReachableStates(storm::dd::Bdd<storm::dd::DdType::Sylvan> const& initialStates, storm::dd::Bdd<storm::dd::DdType::Sylvan> const& transitions, std::set<storm::expressions::Variable> const& rowMetaVariables, std::set<storm::expressions::Variable> const& columnMetaVariables);
 
-            template storm::dd::Add<storm::dd::DdType::CUDD, double> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::CUDD> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs);
-            template storm::dd::Add<storm::dd::DdType::Sylvan, double> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs);
-
             template storm::dd::Bdd<storm::dd::DdType::CUDD> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::CUDD> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs);
             template storm::dd::Bdd<storm::dd::DdType::Sylvan> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs);
 
-            template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalNumber> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs);
-            template storm::dd::Add<storm::dd::DdType::Sylvan, storm::RationalFunction> getRowColumnDiagonal(storm::dd::DdManager<storm::dd::DdType::Sylvan> const& ddManager, std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> const& rowColumnMetaVariablePairs);
-
         }
     }
 }
diff --git a/src/test/storm/storage/CuddDdTest.cpp b/src/test/storm/storage/CuddDdTest.cpp
index 7cfac18a5..499be2a12 100644
--- a/src/test/storm/storage/CuddDdTest.cpp
+++ b/src/test/storm/storage/CuddDdTest.cpp
@@ -414,7 +414,7 @@ TEST(CuddDd, RangeTest) {
     
     storm::dd::Bdd<storm::dd::DdType::CUDD> range;
     ASSERT_NO_THROW(range = manager->getRange(x.first));
-    
+        
     EXPECT_EQ(9ul, range.getNonZeroCount());
     EXPECT_EQ(1ul, range.getLeafCount());
     EXPECT_EQ(5ul, range.getNodeCount());