diff --git a/src/storage/dft/DFT.h b/src/storage/dft/DFT.h
index 408a7a535..9762def61 100644
--- a/src/storage/dft/DFT.h
+++ b/src/storage/dft/DFT.h
@@ -15,6 +15,7 @@
 #include "SymmetricUnits.h"
 #include "../../utility/math.h"
 #include "src/utility/macros.h"
+#include "DFTStateGenerationInfo.h"
 
 namespace storm {
     namespace storage {
@@ -35,96 +36,6 @@ namespace storm {
         template<typename T> class DFTColouring;
 
         
-        class DFTStateGenerationInfo {
-        private:
-            const size_t mUsageInfoBits;
-            std::map<size_t, size_t> mSpareUsageIndex; // id spare -> index first bit in state
-            std::map<size_t, size_t> mSpareActivationIndex; // id spare representative -> index in state
-            std::vector<size_t> mIdToStateIndex; // id -> index first bit in state
-            std::map<size_t, size_t> mRestrictedItems;
-            std::vector<std::pair<size_t, std::vector<size_t>>> mSymmetries; // pair (lenght of symmetry group, vector indicating the starting points of the symmetry groups)
-
-        public:
-            
-            DFTStateGenerationInfo(size_t nrElements, size_t maxSpareChildCount) : mUsageInfoBits(storm::utility::math::uint64_log2(maxSpareChildCount) + 1), mIdToStateIndex(nrElements) {
-                assert(maxSpareChildCount < pow(2, mUsageInfoBits));
-            }
-
-            size_t usageInfoBits() const {
-                return mUsageInfoBits;
-            }
-            
-            void addStateIndex(size_t id, size_t index) {
-                assert(id < mIdToStateIndex.size());
-                mIdToStateIndex[id] = index;
-            }
-
-            void addSpareActivationIndex(size_t id, size_t index) {
-                mSpareActivationIndex[id] = index;
-            }
-
-            void addSpareUsageIndex(size_t id, size_t index) {
-                mSpareUsageIndex[id] = index;
-            }
-
-            size_t getStateIndex(size_t id) const {
-                assert(id < mIdToStateIndex.size());
-                return mIdToStateIndex[id];
-            }
-            
-            size_t getSpareUsageIndex(size_t id) const {
-                assert(mSpareUsageIndex.count(id) > 0);
-                return mSpareUsageIndex.at(id);
-            }
-            
-            size_t getSpareActivationIndex(size_t id) const {
-                assert(mSpareActivationIndex.count(id) > 0);
-                return mSpareActivationIndex.at(id);
-            }
-            
-            void addSymmetry(size_t length, std::vector<size_t>& startingIndices) {
-                mSymmetries.push_back(std::make_pair(length, startingIndices));
-            }
-            
-            size_t getSymmetrySize() const {
-                return mSymmetries.size();
-            }
-            
-            size_t getSymmetryLength(size_t pos) const {
-                assert(pos < mSymmetries.size());
-                return mSymmetries[pos].first;
-            }
-            
-            std::vector<size_t> const& getSymmetryIndices(size_t pos) const {
-                assert(pos < mSymmetries.size());
-                return mSymmetries[pos].second;
-            }
-            
-            friend std::ostream& operator<<(std::ostream& os, DFTStateGenerationInfo const& info) {
-                os << "Id to state index:" << std::endl;
-                for (size_t id = 0; id < info.mIdToStateIndex.size(); ++id) {
-                    os << id << " -> " << info.getStateIndex(id) << std::endl;
-                }
-                os << "Spare usage index with usage InfoBits of size " << info.mUsageInfoBits << ":" << std::endl;
-                for (auto pair : info.mSpareUsageIndex) {
-                    os << pair.first << " -> " << pair.second << std::endl;
-                }
-                os << "Spare activation index:" << std::endl;
-                for (auto pair : info.mSpareActivationIndex) {
-                    os << pair.first << " -> " << pair.second << std::endl;
-                }
-                os << "Symmetries:" << std::endl;
-                for (auto pair : info.mSymmetries) {
-                    os << "Length: " << pair.first << ", starting indices: ";
-                    for (size_t index : pair.second) {
-                        os << index << ", ";
-                    }
-                    os << std::endl;
-                }
-                return os;
-            }
-            
-        };
         
 
         /**
diff --git a/src/storage/dft/DFTElements.h b/src/storage/dft/DFTElements.h
index dc07505bd..49bc5cc53 100644
--- a/src/storage/dft/DFTElements.h
+++ b/src/storage/dft/DFTElements.h
@@ -1,1024 +1,12 @@
-#ifndef DFTELEMENTS_H
-#define	DFTELEMENTS_H
-
-#include <set>
-#include <vector>
-#include <memory>
-#include <string>
-#include <cassert>
-#include <cstdlib>
-#include <iostream>
-#include <functional>
-
-#include "DFTElementType.h"
-#include "DFTState.h"
-#include "DFTStateSpaceGenerationQueues.h"
-#include "src/utility/constants.h"
-#include "src/adapters/CarlAdapter.h"
-
-using std::size_t;
-
-namespace storm {
-    namespace storage {
-
-        template<typename ValueType>
-        class DFTGate;
-        
-        template<typename ValueType>
-        class DFTDependency;
-        template<typename ValueType>
-        class DFTRestriction;
-
-        template<typename ValueType>
-        class DFTElement {
-
-            using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
-            using DFTGateVector = std::vector<DFTGatePointer>;
-            using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
-            using DFTDependencyVector = std::vector<DFTDependencyPointer>;
-            using DFTRestrictionPointer = std::shared_ptr<DFTRestriction<ValueType>>;
-            using DFTRestrictionVector = std::vector<DFTRestrictionPointer>;
-
-
-        protected:
-            size_t mId;
-            std::string mName;
-            size_t mRank = -1;
-            DFTGateVector mParents;
-            DFTDependencyVector mOutgoingDependencies;
-            DFTRestrictionVector mRestrictions;
-
-
-        public:
-            DFTElement(size_t id, std::string const& name) :
-                    mId(id), mName(name)
-            {}
-
-            virtual ~DFTElement() {}
-
-            /**
-             * Returns the id
-             */
-            virtual size_t id() const {
-                return mId;
-            }
-
-            virtual DFTElementType type() const = 0;
-
-            virtual void setRank(size_t rank) {
-                mRank = rank;
-            }
-            
-            virtual size_t rank() const {
-                return mRank;
-            }
-            
-            virtual bool isConstant() const {
-                return false;
-            }
-            
-            virtual bool isGate() const {
-                return false;
-            }
-
-            /**
-             *  Returns true if the element is a BE
-             */
-            virtual bool isBasicElement() const {
-                return false;
-            }
-            
-            virtual bool isColdBasicElement() const {
-                return false;
-            }
-
-            /**
-             * Returns true if the element is a spare gate
-             */
-            virtual bool isSpareGate() const {
-                return false;
-            }
-
-            virtual bool isDependency() const {
-                return false;
-            }
-            
-            virtual bool isRestriction() const {
-                return false;
-            }
-
-            virtual void setId(size_t newId) {
-                mId = newId;
-            }
-
-            /**
-             * Returns the name
-             */
-            virtual std::string const& name() const {
-                return mName;
-            }
-            
-            bool addParent(DFTGatePointer const& e) {
-                if(std::find(mParents.begin(), mParents.end(), e) != mParents.end()) {
-                    return false;
-                }
-                else 
-                {
-                    mParents.push_back(e);
-                    return true;
-                }
-            }
-
-            bool addRestriction(DFTRestrictionPointer const& e) {
-                if (std::find(mRestrictions.begin(), mRestrictions.end(), e) != mRestrictions.end()) {
-                    return false;
-                } else {
-                    mRestrictions.push_back(e);
-                    return true;
-                }
-            }
-
-             bool hasOnlyStaticParents() const {
-                for(auto const& parent : mParents) {
-                    if(!isStaticGateType(parent->type())) {
-                        return false;
-                    }
-                }
-                return true;
-            }
-
-            
-            bool hasParents() const {
-                return !mParents.empty();
-            }
-            
-            size_t nrParents() const {
-                return mParents.size();
-            }
-
-            DFTGateVector const& parents() const {
-                return mParents;
-            }
-            
-            bool hasRestrictions() const {
-                return !mRestrictions.empty();
-            }
-            
-            size_t nrRestrictions() const {
-                return mRestrictions.size();
-            }
-            
-            DFTRestrictionVector const& restrictions() const {
-                return mRestrictions;
-            }
-
-            std::vector<size_t> parentIds() const {
-                std::vector<size_t> res;
-                for(auto parent : parents()) {
-                    res.push_back(parent->id());
-                }
-                return res;
-            }
-            
-            bool addOutgoingDependency(DFTDependencyPointer const& e) {
-                assert(e->triggerEvent()->id() == this->id());
-                if(std::find(mOutgoingDependencies.begin(), mOutgoingDependencies.end(), e) != mOutgoingDependencies.end()) {
-                    return false;
-                }
-                else
-                {
-                    mOutgoingDependencies.push_back(e);
-                    return true;
-                }
-            }
-            
-            bool hasOutgoingDependencies() const {
-                return !mOutgoingDependencies.empty();
-            }
-            
-            size_t nrOutgoingDependencies() const {
-                return mOutgoingDependencies.size();
-            }
-            
-            std::set<DFTElement<ValueType>> restrictedItems() const {
-                std::set<DFTElement<ValueType>> result;
-                for(auto const& restr : mRestrictions) {
-                    bool foundThis = false;
-                    for(auto const& child : restr->children()) {
-                        if(!foundThis) {
-                            if(child->id() == mId) {
-                                foundThis = true;
-                            }
-                        } else if(result.count(child) == 0) {
-                            result.insert(child);
-                        }
-                    }
-                }
-            }
-            
-            std::set<DFTElement<ValueType>> restrictedItemsTC() const {
-                std::set<DFTElement<ValueType>> result;
-                for(auto const& restr : mRestrictions) {
-                    bool foundThis = false;
-                    for(auto const& child : restr->children()) {
-                        if(!foundThis) {
-                            if(child->id() == mId) {
-                                foundThis = true;
-                            }
-                        } else if(result.count(child) == 0) {
-                            result.insert(child);
-                            std::set<DFTElement<ValueType>> tmpRes = child->restrictedItemsTC();
-                            result.insert(tmpRes.begin(), tmpRes.end());
-                        }
-                    }
-                }
-            }
-            
-            DFTDependencyVector const& outgoingDependencies() const {
-                return mOutgoingDependencies;
-            }
-            
-            virtual void extendSpareModule(std::set<size_t>& elementsInModule) const;
-
-           // virtual void extendImmediateFailureCausePathEvents(std::set<size_t>& ) const;
-            
-            virtual size_t nrChildren() const = 0;
-
-            virtual std::string toString() const = 0;
-
-            virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const;
-
-            /**
-             *  Computes the independent unit of this element, that is, all elements which are direct or indirect successors of an element.
-             */
-            virtual std::vector<size_t> independentUnit() const;
-
-            /**
-             *  Helper to independent unit computation
-             *  @see independentUnit
-             */
-            virtual void extendUnit(std::set<size_t>& unit) const;
-
-            /**
-             *  Computes independent subtrees starting with this element (this), that is, all elements (x) which are connected to either
-             *  - one of the children of the element,
-             *  - a probabilistic dependency
-             *  such that there exists a  path from x to a child of this does not go through this.
-             */
-            virtual std::vector<size_t> independentSubDft(bool blockParents) const;
-            /**
-             * Helper to the independent subtree computation
-             * @see independentSubDft
-             */
-            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const;
-
-            virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const {
-                return type() == other.type();
-            }
-
-
-        protected:
-           // virtual bool checkIsomorphicSubDftHelper(DFTElement const& otherElem, std::vector<std::pair<DFTElement const&, DFTElement const&>>& mapping, std::vector<DFTElement const&> const& order ) const = 0;
-
-        };
-
-
-
-
-        template<typename ValueType>
-        class DFTGate : public DFTElement<ValueType> {
-
-            using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>;
-            using DFTElementVector = std::vector<DFTElementPointer>;
-
-        protected:
-            DFTElementVector mChildren;
-
-        public:
-            DFTGate(size_t id, std::string const& name, DFTElementVector const& children) :
-                    DFTElement<ValueType>(id, name), mChildren(children)
-            {}
-            
-            virtual ~DFTGate() {}
-            
-            void pushBackChild(DFTElementPointer elem) {
-                return mChildren.push_back(elem);
-            }
-
-            size_t nrChildren() const override {
-                return mChildren.size();
-            }
-
-            DFTElementVector const& children() const {
-                return mChildren;
-            }
-            
-            virtual bool isGate() const override {
-                return true;
-            }
-            
-            
-            virtual std::string typestring() const = 0;
-
-            virtual void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const = 0;
-
-            virtual void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const = 0;
-            
-            virtual void extendSpareModule(std::set<size_t>& elementsInSpareModule) const override {
-                if (!this->isSpareGate()) {
-                    DFTElement<ValueType>::extendSpareModule(elementsInSpareModule);
-                    for( auto const& child : mChildren) {
-                        if(elementsInSpareModule.count(child->id()) == 0) {
-                            elementsInSpareModule.insert(child->id());
-                            child->extendSpareModule(elementsInSpareModule);
-                        }
-                    }
-                }
-            }
-            
-            virtual std::vector<size_t> independentUnit() const override {
-                std::set<size_t> unit = {this->mId};
-                for(auto const& child : mChildren) {
-                    child->extendUnit(unit);
-                }
-                return std::vector<size_t>(unit.begin(), unit.end());
-            }
-
-            virtual void extendUnit(std::set<size_t>& unit) const override {
-                DFTElement<ValueType>::extendUnit(unit);
-                for(auto const& child : mChildren) {
-                    child->extendUnit(unit);
-                }
-            }
-
-            virtual std::vector<size_t> independentSubDft(bool blockParents) const override {
-                auto prelRes = DFTElement<ValueType>::independentSubDft(blockParents);
-                if(prelRes.empty()) {
-                    // No elements (especially not this->id) in the prelimanry result, so we know already that it is not a subdft.
-                    return prelRes;
-                }
-                std::set<size_t> unit(prelRes.begin(), prelRes.end());
-                std::vector<size_t> pids = this->parentIds();
-                for(auto const& child : mChildren) {
-                    child->extendSubDft(unit, pids, blockParents);
-                    if(unit.empty()) {
-                        // Parent in the subdft, ie it is *not* a subdft
-                        break;
-                    }
-                }
-                return std::vector<size_t>(unit.begin(), unit.end());
-            }
-
-            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const override {
-                if(elemsInSubtree.count(this->id()) > 0) return;
-                DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                if(elemsInSubtree.empty()) {
-                    // Parent in the subdft, ie it is *not* a subdft
-                    return;
-                }
-                for(auto const& child : mChildren) {
-                    child->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                    if(elemsInSubtree.empty()) {
-                        // Parent in the subdft, ie it is *not* a subdft
-                        return;
-                    }
-                }
-            }
-
-
-            virtual std::string toString() const override {
-                std::stringstream stream;
-                stream << "{" << this->name() << "} " << typestring() << "( ";
-                typename DFTElementVector::const_iterator it = mChildren.begin();
-                stream << (*it)->name();
-                ++it;
-                while(it != mChildren.end()) {
-                    stream <<  ", " << (*it)->name();
-                    ++it;
-                }
-                stream << ")";
-                return stream.str();
-            }
-
-            virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if(DFTElement<ValueType>::checkDontCareAnymore(state, queues)) {
-                    childrenDontCare(state, queues);
-                    return true;
-                }
-                return false;
-            }
-
-
-        protected:
-
-            void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
-                for(std::shared_ptr<DFTGate> parent : this->mParents) {
-                    if(state.isOperational(parent->id())) {
-                        queues.propagateFailure(parent);
-                    }
-                }
-                for(std::shared_ptr<DFTRestriction<ValueType>> restr : this->mRestrictions) {
-                    queues.checkRestrictionLater(restr);
-                }
-                state.setFailed(this->mId);
-                this->childrenDontCare(state, queues);
-            }
-
-            void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
-                for(std::shared_ptr<DFTGate> parent : this->mParents) {
-                    if(state.isOperational(parent->id())) {
-                        queues.propagateFailsafe(parent);
-                    }
-                }
-                state.setFailsafe(this->mId);
-                this->childrenDontCare(state, queues);
-            }
-            
-            void childrenDontCare(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
-                queues.propagateDontCare(mChildren);
-            }
-
-            bool hasFailsafeChild(DFTState<ValueType>& state) const {
-                for(auto const& child : mChildren) {
-                    if(state.isFailsafe(child->id()))
-                    {
-                        return true;
-                    }
-                }
-                return false;
-            }
-
-            bool hasFailedChild(DFTState<ValueType>& state) const {
-                for(auto const& child : mChildren) {
-                    if(state.hasFailed(child->id())) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-            
-        };
-        
-       
-
-        template<typename ValueType>
-        class DFTBE : public DFTElement<ValueType> {
-            
-            using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
-            using DFTDependencyVector = std::vector<DFTDependencyPointer>;
-
-        protected:
-            ValueType mActiveFailureRate;
-            ValueType mPassiveFailureRate;
-            DFTDependencyVector mIngoingDependencies;
-
-        public:
-            DFTBE(size_t id, std::string const& name, ValueType failureRate, ValueType dormancyFactor) :
-                    DFTElement<ValueType>(id, name), mActiveFailureRate(failureRate), mPassiveFailureRate(dormancyFactor * failureRate)
-            {}
-
-            DFTElementType type() const override {
-                return DFTElementType::BE;
-            }
-
-            virtual size_t nrChildren() const override {
-                return 0;
-            }
-
-            ValueType const& activeFailureRate() const {
-                return mActiveFailureRate;
-            }
-
-            ValueType const& passiveFailureRate() const {
-                return mPassiveFailureRate;
-            }
-            
-            bool addIngoingDependency(DFTDependencyPointer const& e) {
-                assert(e->dependentEvent()->id() == this->id());
-                if(std::find(mIngoingDependencies.begin(), mIngoingDependencies.end(), e) != mIngoingDependencies.end()) {
-                    return false;
-                }
-                else
-                {
-                    mIngoingDependencies.push_back(e);
-                    return true;
-                }
-            }
-            
-            bool hasIngoingDependencies() const {
-                return !mIngoingDependencies.empty();
-            }
-            
-            size_t nrIngoingDependencies() const {
-                return mIngoingDependencies.size();
-            }
-            
-            DFTDependencyVector const& ingoingDependencies() const {
-                return mIngoingDependencies;
-            }
-        
-            std::string toString() const override {
-                std::stringstream stream;
-                stream << *this;
-                return stream.str();
-            }
-            
-            bool isBasicElement() const override{
-                return true;
-            }
-            
-            bool isColdBasicElement() const override{
-                return storm::utility::isZero(mPassiveFailureRate);
-            }
-            
-            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const override {
-                 if(elemsInSubtree.count(this->id())) return;
-                DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                if(elemsInSubtree.empty()) {
-                    // Parent in the subdft, ie it is *not* a subdft
-                    return;
-                }
-                for(auto const& incDep : mIngoingDependencies) {
-                    incDep->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                    if(elemsInSubtree.empty()) {
-                        // Parent in the subdft, ie it is *not* a subdft
-                        return;
-                    }
-                }
-            }
-            
-            bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
-                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
-                DFTBE<ValueType> const&  otherBE = static_cast<DFTBE<ValueType> const&>(other);
-                return (mActiveFailureRate == otherBE.mActiveFailureRate) && (mPassiveFailureRate == otherBE.mPassiveFailureRate);
-            }
-            
-            virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override;
-        };
-
-        template<typename ValueType>
-        inline std::ostream& operator<<(std::ostream& os, DFTBE<ValueType> const& be) {
-            return os << "{" << be.name() << "} BE(" << be.activeFailureRate() << ", " << be.passiveFailureRate() << ")";
-        }
-
-
-
-        template<typename ValueType>
-        class DFTConst : public DFTElement<ValueType> {
-
-            bool mFailed;
-
-        public:
-            DFTConst(size_t id, std::string const& name, bool failed) :
-                    DFTElement<ValueType>(id, name), mFailed(failed)
-            {}
-
-            DFTElementType type() const override {
-                if(mFailed) {
-                    return DFTElementType::CONSTF;
-                } else {
-                    return DFTElementType::CONSTS;
-                }
-            }
-
-
-            bool failed() const {
-                return mFailed;
-            }
-            
-            virtual bool isConstant() const {
-                return true;
-            }
-            
-            virtual size_t nrChildren() const override {
-                return 0;
-            }
-            
-            
-            
-            bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
-                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
-                DFTConst<ValueType> const& otherCNST = static_cast<DFTConst<ValueType> const&>(other);
-                return (mFailed == otherCNST.mFailed);
-            }
-            
-        };
-
-
-        template<typename ValueType>
-        class DFTDependency : public DFTElement<ValueType> {
-
-            using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
-            using DFTBEPointer = std::shared_ptr<DFTBE<ValueType>>;
-            
-        protected:
-            std::string mNameTrigger;
-            std::string mNameDependent;
-            ValueType mProbability;
-            DFTGatePointer mTriggerEvent;
-            DFTBEPointer mDependentEvent;
-
-        public:
-            DFTDependency(size_t id, std::string const& name, std::string const& trigger, std::string const& dependent, ValueType probability) :
-                DFTElement<ValueType>(id, name), mNameTrigger(trigger), mNameDependent(dependent), mProbability(probability)
-            {
-            }
-
-            virtual ~DFTDependency() {}
-
-            void initialize(DFTGatePointer triggerEvent, DFTBEPointer dependentEvent) {
-                assert(triggerEvent->name() == mNameTrigger);
-                assert(dependentEvent->name() == mNameDependent);
-                mTriggerEvent = triggerEvent;
-                mDependentEvent = dependentEvent;
-            }
-
-            std::string nameTrigger() const {
-                return mNameTrigger;
-            }
-
-            std::string nameDependent() const {
-                return mNameDependent;
-            }
-
-            ValueType const& probability() const {
-                return mProbability;
-            }
-
-            DFTGatePointer const& triggerEvent() const {
-                assert(mTriggerEvent);
-                return mTriggerEvent;
-            }
-
-            DFTBEPointer const& dependentEvent() const {
-                assert(mDependentEvent);
-                return mDependentEvent;
-            }
-
-            DFTElementType type() const override {
-                return DFTElementType::PDEP;
-            }
-
-            virtual size_t nrChildren() const override {
-                return 1;
-            }
-
-            virtual bool isDependency() const override {
-                return true;
-            }
-            
-            virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
-                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
-                DFTDependency<ValueType> const& otherDEP= static_cast<DFTDependency<ValueType> const&>(other);
-                return (mProbability == otherDEP.mProbability);
-            }
-            
-
-            virtual std::vector<size_t> independentUnit() const override {
-                std::set<size_t> unit = {this->mId};
-                mDependentEvent->extendUnit(unit);
-                if(unit.count(mTriggerEvent->id()) != 0) {
-                    return {};
-                }
-                return std::vector<size_t>(unit.begin(), unit.end());
-            }
-
-            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const override {
-                 if(elemsInSubtree.count(this->id())) return;
-                DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                if(elemsInSubtree.empty()) {
-                    // Parent in the subdft, ie it is *not* a subdft
-                    return;
-                }
-                mDependentEvent->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                if(elemsInSubtree.empty()) {
-                    // Parent in the subdft, ie it is *not* a subdft
-                    return;
-                }
-                mTriggerEvent->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
-                
-                
-            }
-            
-            virtual std::string toString() const override {
-                std::stringstream stream;
-                bool fdep = storm::utility::isOne(mProbability);
-                stream << "{" << this->name() << "} " << (fdep ? "FDEP" : "PDEP") << "(" << mTriggerEvent->name() << " => " << mDependentEvent->name() << ")";
-                if (!fdep) {
-                    stream << " with probability " << mProbability;
-                }
-                return stream.str();
-            }
-
-        protected:
-
-        };
-
-
-        template<typename ValueType>
-        class DFTAnd : public DFTGate<ValueType> {
-            
-        public:
-            DFTAnd(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
-                    DFTGate<ValueType>(id, name, children)
-            {}
-
-            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if(state.isOperational(this->mId)) {
-                    for(auto const& child : this->mChildren)
-                    {
-                        if(!state.hasFailed(child->id())) {
-                            return;
-                        }
-                    }
-                    this->fail(state, queues);
-                }
-            }
-
-            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                assert(this->hasFailsafeChild(state));
-                if(state.isOperational(this->mId)) {
-                    this->failsafe(state, queues);
-                    this->childrenDontCare(state, queues);
-                }
-            }
-
-            virtual DFTElementType type() const override {
-                return DFTElementType::AND;
-            }
-            
-            std::string typestring() const override {
-                return "AND";
-            }
-        };
-
-        template<typename ValueType>
-        inline std::ostream& operator<<(std::ostream& os, DFTAnd<ValueType> const& gate) {
-            return os << gate.toString();
-        }
-
-        
-
-        template<typename ValueType>
-        class DFTOr : public DFTGate<ValueType> {
-
-        public:
-            DFTOr(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
-                    DFTGate<ValueType>(id, name, children)
-            {}
-
-            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                assert(this->hasFailedChild(state));
-                if(state.isOperational(this->mId)) {
-                    this->fail(state, queues);
-                }
-            }
-
-            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                 for(auto const& child : this->mChildren) {
-                     if(!state.isFailsafe(child->id())) {
-                         return;
-                     }
-                 }
-                 this->failsafe(state, queues);
-            }
-
-            virtual DFTElementType type() const override {
-                return DFTElementType::OR;
-            }
-            
-            std::string typestring() const override {
-                return "OR";
-            }
-        };
-
-        template<typename ValueType>
-        inline std::ostream& operator<<(std::ostream& os, DFTOr<ValueType> const& gate) {
-            return os << gate.toString();
-        }
-
-        template<typename ValueType>
-        class DFTPand : public DFTGate<ValueType> {
-
-        public:
-            DFTPand(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
-                    DFTGate<ValueType>(id, name, children)
-            {}
-
-            void checkFails(storm::storage::DFTState<ValueType>& state,  DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if(state.isOperational(this->mId)) {
-                    bool childOperationalBefore = false;
-                    for(auto const& child : this->mChildren)
-                    {
-                        if(!state.hasFailed(child->id())) {
-                            childOperationalBefore = true;
-                        } else if(childOperationalBefore && state.hasFailed(child->id())){
-                            this->failsafe(state, queues);
-                            this->childrenDontCare(state, queues);
-                            return;
-                        }
-                    }
-                    if(!childOperationalBefore) {
-                        this->fail(state, queues);
-                    }
-                }
-            }
-
-            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                assert(this->hasFailsafeChild(state));
-                if(state.isOperational(this->mId)) {
-                    this->failsafe(state, queues);
-                    this->childrenDontCare(state, queues);
-                }
-            }
-
-            virtual DFTElementType type() const override {
-                return DFTElementType::PAND;
-            }
-            
-            std::string typestring() const override {
-                return "PAND";
-            }
-        };
-        
-        template<typename ValueType>
-        inline std::ostream& operator<<(std::ostream& os, DFTPand<ValueType> const& gate) {
-             return os << gate.toString();
-        }
-
-
-
-        template<typename ValueType>
-        class DFTPor : public DFTGate<ValueType> {
-        public:
-            DFTPor(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
-                    DFTGate<ValueType>(id, name, children)
-            {}
-
-            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                 assert(false);
-            }
-
-            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                assert(false);
-            }
-
-            virtual DFTElementType type() const override {
-                return DFTElementType::POR;
-            }
-            
-            std::string  typestring() const override {
-                return "POR";
-            }
-        };
-
-        template<typename ValueType>
-        inline std::ostream& operator<<(std::ostream& os, DFTPor<ValueType> const& gate) {
-             return os << gate.toString();
-        }
-
-
-
-        template<typename ValueType>
-        class DFTVot : public DFTGate<ValueType> {
-
-        private:
-            unsigned mThreshold;
-
-        public:
-            DFTVot(size_t id, std::string const& name, unsigned threshold, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
-                    DFTGate<ValueType>(id, name, children), mThreshold(threshold)
-            {}
-
-            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if(state.isOperational(this->mId)) {
-                    unsigned nrFailedChildren = 0;
-                    for(auto const& child : this->mChildren)
-                    {
-                        if(state.hasFailed(child->id())) {
-                            ++nrFailedChildren;
-                            if(nrFailedChildren >= mThreshold) 
-                            {
-                                this->fail(state, queues);
-                                return;
-                            }
-                        }
-                    }
-                  
-                } 
-            }
-
-            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                assert(this->hasFailsafeChild(state));
-                if(state.isOperational(this->mId)) {
-                    unsigned nrFailsafeChildren = 0;
-                    for(auto const& child : this->mChildren)
-                    {
-                        if(state.isFailsafe(child->id())) {
-                            ++nrFailsafeChildren;
-                            if(nrFailsafeChildren > this->nrChildren() - mThreshold)
-                            {
-                                this->failsafe(state, queues);
-                                this->childrenDontCare(state, queues);
-                                return;
-                            }
-                        }
-                    }
-                }
-            }
-
-            virtual DFTElementType type() const override {
-                return DFTElementType::VOT;
-            }
-            
-            std::string typestring() const override{
-                return "VOT (" + std::to_string(mThreshold) + ")";
-            }
-            
-            virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
-                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
-                DFTVot<ValueType> const& otherVOT = static_cast<DFTVot<ValueType> const&>(other);
-                return (mThreshold == otherVOT.mThreshold);
-            }
-        };
-
-        template<typename ValueType>
-        inline std::ostream& operator<<(std::ostream& os, DFTVot<ValueType> const& gate) {
-            return os << gate.toString();
-        }
-
-
-
-        template<typename ValueType>
-        class DFTSpare : public DFTGate<ValueType> {
-
-        public:
-            DFTSpare(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
-                    DFTGate<ValueType>(id, name, children)
-            {}
-            
-            std::string typestring() const override {
-                return "SPARE";
-            }
-
-            virtual DFTElementType type() const override {
-                return DFTElementType::SPARE;
-            }
-
-            bool isSpareGate() const override {
-                return true;
-            }
-            
-            void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
-                DFTGate<ValueType>::fail(state, queues);
-                state.finalizeUses(this->mId);
-            }
-            
-            void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
-                DFTGate<ValueType>::failsafe(state, queues);
-                state.finalizeUses(this->mId);
-            }
-            
-            bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if (DFTGate<ValueType>::checkDontCareAnymore(state, queues)) {
-                    state.finalizeUses(this->mId);
-                    return true;
-                }
-                return false;
-            }
-            
-            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if(state.isOperational(this->mId)) {
-                    size_t uses = state.uses(this->mId);
-                    if(!state.isOperational(uses)) {
-                        bool claimingSuccessful = state.claimNew(this->mId, uses, this->mChildren);
-                        if(!claimingSuccessful) {
-                            this->fail(state, queues);
-                        }
-                    }                  
-                } 
-            }
-
-            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
-                if(state.isOperational(this->mId)) {
-                    if(state.isFailsafe(state.uses(this->mId))) {
-                        this->failsafe(state, queues);
-                        this->childrenDontCare(state, queues);
-                    }
-                }
-            }
-
-        };
-        
-        template<typename ValueType>
-        bool equalType(DFTElement<ValueType> const& e1, DFTElement<ValueType> const& e2) {
-            return e1.isTypeEqualTo(e2);
-        }
-        
-    }
-}
-
-
-
-#endif	/* DFTELEMENTS_H */
-
+#pragma once
+
+#include "elements/DFTAnd.h"
+#include "elements/DFTBE.h"
+#include "elements/DFTConst.h"
+#include "elements/DFTDependency.h"
+#include "elements/DFTOr.h"
+#include "elements/DFTPand.h"
+#include "elements/DFTPor.h"
+#include "elements/DFTRestriction.h"
+#include "elements/DFTSpare.h"
+#include "elements/DFTVot.h"
\ No newline at end of file
diff --git a/src/storage/dft/DFTStateGenerationInfo.h b/src/storage/dft/DFTStateGenerationInfo.h
new file mode 100644
index 000000000..f82d4e8af
--- /dev/null
+++ b/src/storage/dft/DFTStateGenerationInfo.h
@@ -0,0 +1,96 @@
+#pragma once
+
+namespace storm {
+    namespace storage {
+        class DFTStateGenerationInfo {
+        private:
+            const size_t mUsageInfoBits;
+            std::map<size_t, size_t> mSpareUsageIndex; // id spare -> index first bit in state
+            std::map<size_t, size_t> mSpareActivationIndex; // id spare representative -> index in state
+            std::vector<size_t> mIdToStateIndex; // id -> index first bit in state
+            std::map<size_t, size_t> mRestrictedItems;
+            std::vector<std::pair<size_t, std::vector<size_t>>> mSymmetries; // pair (lenght of symmetry group, vector indicating the starting points of the symmetry groups)
+
+        public:
+
+            DFTStateGenerationInfo(size_t nrElements, size_t maxSpareChildCount) : mUsageInfoBits(storm::utility::math::uint64_log2(maxSpareChildCount) + 1), mIdToStateIndex(nrElements) {
+                assert(maxSpareChildCount < pow(2, mUsageInfoBits));
+            }
+
+            size_t usageInfoBits() const {
+                return mUsageInfoBits;
+            }
+
+            void addStateIndex(size_t id, size_t index) {
+                assert(id < mIdToStateIndex.size());
+                mIdToStateIndex[id] = index;
+            }
+
+            void addSpareActivationIndex(size_t id, size_t index) {
+                mSpareActivationIndex[id] = index;
+            }
+
+            void addSpareUsageIndex(size_t id, size_t index) {
+                mSpareUsageIndex[id] = index;
+            }
+
+            size_t getStateIndex(size_t id) const {
+                assert(id < mIdToStateIndex.size());
+                return mIdToStateIndex[id];
+            }
+
+            size_t getSpareUsageIndex(size_t id) const {
+                assert(mSpareUsageIndex.count(id) > 0);
+                return mSpareUsageIndex.at(id);
+            }
+
+            size_t getSpareActivationIndex(size_t id) const {
+                assert(mSpareActivationIndex.count(id) > 0);
+                return mSpareActivationIndex.at(id);
+            }
+
+            void addSymmetry(size_t length, std::vector<size_t>& startingIndices) {
+                mSymmetries.push_back(std::make_pair(length, startingIndices));
+            }
+
+            size_t getSymmetrySize() const {
+                return mSymmetries.size();
+            }
+
+            size_t getSymmetryLength(size_t pos) const {
+                assert(pos < mSymmetries.size());
+                return mSymmetries[pos].first;
+            }
+
+            std::vector<size_t> const& getSymmetryIndices(size_t pos) const {
+                assert(pos < mSymmetries.size());
+                return mSymmetries[pos].second;
+            }
+
+            friend std::ostream& operator<<(std::ostream& os, DFTStateGenerationInfo const& info) {
+                os << "Id to state index:" << std::endl;
+                for (size_t id = 0; id < info.mIdToStateIndex.size(); ++id) {
+                    os << id << " -> " << info.getStateIndex(id) << std::endl;
+                }
+                os << "Spare usage index with usage InfoBits of size " << info.mUsageInfoBits << ":" << std::endl;
+                for (auto pair : info.mSpareUsageIndex) {
+                    os << pair.first << " -> " << pair.second << std::endl;
+                }
+                os << "Spare activation index:" << std::endl;
+                for (auto pair : info.mSpareActivationIndex) {
+                    os << pair.first << " -> " << pair.second << std::endl;
+                }
+                os << "Symmetries:" << std::endl;
+                for (auto pair : info.mSymmetries) {
+                    os << "Length: " << pair.first << ", starting indices: ";
+                    for (size_t index : pair.second) {
+                        os << index << ", ";
+                    }
+                    os << std::endl;
+                }
+                return os;
+            }
+
+        };
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTAnd.h b/src/storage/dft/elements/DFTAnd.h
new file mode 100644
index 000000000..5a5763166
--- /dev/null
+++ b/src/storage/dft/elements/DFTAnd.h
@@ -0,0 +1,50 @@
+#pragma once 
+#include "DFTGate.h"
+
+namespace storm {
+    namespace storage {
+        template<typename ValueType>
+        class DFTAnd : public DFTGate<ValueType> {
+            
+        public:
+            DFTAnd(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
+                    DFTGate<ValueType>(id, name, children)
+            {}
+
+            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if(state.isOperational(this->mId)) {
+                    for(auto const& child : this->mChildren)
+                    {
+                        if(!state.hasFailed(child->id())) {
+                            return;
+                        }
+                    }
+                    this->fail(state, queues);
+                }
+            }
+
+            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                assert(this->hasFailsafeChild(state));
+                if(state.isOperational(this->mId)) {
+                    this->failsafe(state, queues);
+                    this->childrenDontCare(state, queues);
+                }
+            }
+
+            virtual DFTElementType type() const override {
+                return DFTElementType::AND;
+            }
+            
+            std::string typestring() const override {
+                return "AND";
+            }
+        };
+
+        template<typename ValueType>
+        inline std::ostream& operator<<(std::ostream& os, DFTAnd<ValueType> const& gate) {
+            return os << gate.toString();
+        }
+
+              
+    }
+}
diff --git a/src/storage/dft/elements/DFTBE.h b/src/storage/dft/elements/DFTBE.h
new file mode 100644
index 000000000..5e09e965e
--- /dev/null
+++ b/src/storage/dft/elements/DFTBE.h
@@ -0,0 +1,104 @@
+#pragma once
+namespace storm {
+    namespace storage {
+        template<typename ValueType>
+        class DFTBE : public DFTElement<ValueType> {
+            
+            using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
+            using DFTDependencyVector = std::vector<DFTDependencyPointer>;
+
+        protected:
+            ValueType mActiveFailureRate;
+            ValueType mPassiveFailureRate;
+            DFTDependencyVector mIngoingDependencies;
+
+        public:
+            DFTBE(size_t id, std::string const& name, ValueType failureRate, ValueType dormancyFactor) :
+                    DFTElement<ValueType>(id, name), mActiveFailureRate(failureRate), mPassiveFailureRate(dormancyFactor * failureRate)
+            {}
+
+            DFTElementType type() const override {
+                return DFTElementType::BE;
+            }
+
+            virtual size_t nrChildren() const override {
+                return 0;
+            }
+
+            ValueType const& activeFailureRate() const {
+                return mActiveFailureRate;
+            }
+
+            ValueType const& passiveFailureRate() const {
+                return mPassiveFailureRate;
+            }
+            
+            bool addIngoingDependency(DFTDependencyPointer const& e) {
+                assert(e->dependentEvent()->id() == this->id());
+                if(std::find(mIngoingDependencies.begin(), mIngoingDependencies.end(), e) != mIngoingDependencies.end()) {
+                    return false;
+                }
+                else
+                {
+                    mIngoingDependencies.push_back(e);
+                    return true;
+                }
+            }
+            
+            bool hasIngoingDependencies() const {
+                return !mIngoingDependencies.empty();
+            }
+            
+            size_t nrIngoingDependencies() const {
+                return mIngoingDependencies.size();
+            }
+            
+            DFTDependencyVector const& ingoingDependencies() const {
+                return mIngoingDependencies;
+            }
+        
+            std::string toString() const override {
+                std::stringstream stream;
+                stream << *this;
+                return stream.str();
+            }
+            
+            bool isBasicElement() const override{
+                return true;
+            }
+            
+            bool isColdBasicElement() const override{
+                return storm::utility::isZero(mPassiveFailureRate);
+            }
+            
+            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const override {
+                 if(elemsInSubtree.count(this->id())) return;
+                DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                if(elemsInSubtree.empty()) {
+                    // Parent in the subdft, ie it is *not* a subdft
+                    return;
+                }
+                for(auto const& incDep : mIngoingDependencies) {
+                    incDep->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                    if(elemsInSubtree.empty()) {
+                        // Parent in the subdft, ie it is *not* a subdft
+                        return;
+                    }
+                }
+            }
+            
+            bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
+                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
+                DFTBE<ValueType> const&  otherBE = static_cast<DFTBE<ValueType> const&>(other);
+                return (mActiveFailureRate == otherBE.mActiveFailureRate) && (mPassiveFailureRate == otherBE.mPassiveFailureRate);
+            }
+            
+            virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override;
+        };
+
+        template<typename ValueType>
+        inline std::ostream& operator<<(std::ostream& os, DFTBE<ValueType> const& be) {
+            return os << "{" << be.name() << "} BE(" << be.activeFailureRate() << ", " << be.passiveFailureRate() << ")";
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTConst.h b/src/storage/dft/elements/DFTConst.h
new file mode 100644
index 000000000..e827e173c
--- /dev/null
+++ b/src/storage/dft/elements/DFTConst.h
@@ -0,0 +1,47 @@
+#pragma once
+
+
+#include "DFTElement.h"
+namespace storm {
+    namespace storage {
+        template<typename ValueType>
+        class DFTConst : public DFTElement<ValueType> {
+
+            bool mFailed;
+
+        public:
+            DFTConst(size_t id, std::string const& name, bool failed) :
+                    DFTElement<ValueType>(id, name), mFailed(failed)
+            {}
+
+            DFTElementType type() const override {
+                if(mFailed) {
+                    return DFTElementType::CONSTF;
+                } else {
+                    return DFTElementType::CONSTS;
+                }
+            }
+
+
+            bool failed() const {
+                return mFailed;
+            }
+            
+            virtual bool isConstant() const {
+                return true;
+            }
+            
+            virtual size_t nrChildren() const override {
+                return 0;
+            }
+            
+            
+            bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
+                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
+                DFTConst<ValueType> const& otherCNST = static_cast<DFTConst<ValueType> const&>(other);
+                return (mFailed == otherCNST.mFailed);
+            }
+
+        };
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTDependency.h b/src/storage/dft/elements/DFTDependency.h
new file mode 100644
index 000000000..c7f3f6bfd
--- /dev/null
+++ b/src/storage/dft/elements/DFTDependency.h
@@ -0,0 +1,118 @@
+#pragma once
+
+
+#include "DFTElement.h"
+namespace storm {
+    namespace storage {
+        
+        template<typename ValueType>
+        class DFTDependency : public DFTElement<ValueType> {
+
+            using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
+            using DFTBEPointer = std::shared_ptr<DFTBE<ValueType>>;
+            
+        protected:
+            std::string mNameTrigger;
+            std::string mNameDependent;
+            ValueType mProbability;
+            DFTGatePointer mTriggerEvent;
+            DFTBEPointer mDependentEvent;
+
+        public:
+            DFTDependency(size_t id, std::string const& name, std::string const& trigger, std::string const& dependent, ValueType probability) :
+                DFTElement<ValueType>(id, name), mNameTrigger(trigger), mNameDependent(dependent), mProbability(probability)
+            {
+            }
+
+            virtual ~DFTDependency() {}
+
+            void initialize(DFTGatePointer triggerEvent, DFTBEPointer dependentEvent) {
+                assert(triggerEvent->name() == mNameTrigger);
+                assert(dependentEvent->name() == mNameDependent);
+                mTriggerEvent = triggerEvent;
+                mDependentEvent = dependentEvent;
+            }
+
+            std::string nameTrigger() const {
+                return mNameTrigger;
+            }
+
+            std::string nameDependent() const {
+                return mNameDependent;
+            }
+
+            ValueType const& probability() const {
+                return mProbability;
+            }
+
+            DFTGatePointer const& triggerEvent() const {
+                assert(mTriggerEvent);
+                return mTriggerEvent;
+            }
+
+            DFTBEPointer const& dependentEvent() const {
+                assert(mDependentEvent);
+                return mDependentEvent;
+            }
+
+            DFTElementType type() const override {
+                return DFTElementType::PDEP;
+            }
+
+            virtual size_t nrChildren() const override {
+                return 1;
+            }
+
+            virtual bool isDependency() const override {
+                return true;
+            }
+            
+            virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
+                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
+                DFTDependency<ValueType> const& otherDEP= static_cast<DFTDependency<ValueType> const&>(other);
+                return (mProbability == otherDEP.mProbability);
+            }
+            
+
+            virtual std::vector<size_t> independentUnit() const override {
+                std::set<size_t> unit = {this->mId};
+                mDependentEvent->extendUnit(unit);
+                if(unit.count(mTriggerEvent->id()) != 0) {
+                    return {};
+                }
+                return std::vector<size_t>(unit.begin(), unit.end());
+            }
+
+            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const override {
+                 if(elemsInSubtree.count(this->id())) return;
+                DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                if(elemsInSubtree.empty()) {
+                    // Parent in the subdft, ie it is *not* a subdft
+                    return;
+                }
+                mDependentEvent->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                if(elemsInSubtree.empty()) {
+                    // Parent in the subdft, ie it is *not* a subdft
+                    return;
+                }
+                mTriggerEvent->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                
+                
+            }
+            
+            virtual std::string toString() const override {
+                std::stringstream stream;
+                bool fdep = storm::utility::isOne(mProbability);
+                stream << "{" << this->name() << "} " << (fdep ? "FDEP" : "PDEP") << "(" << mTriggerEvent->name() << " => " << mDependentEvent->name() << ")";
+                if (!fdep) {
+                    stream << " with probability " << mProbability;
+                }
+                return stream.str();
+            }
+
+        protected:
+
+        };
+
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTElement.h b/src/storage/dft/elements/DFTElement.h
new file mode 100644
index 000000000..d6840132a
--- /dev/null
+++ b/src/storage/dft/elements/DFTElement.h
@@ -0,0 +1,297 @@
+#pragma once 
+
+#include <string>
+#include <cassert>
+#include <cstdlib>
+#include <iostream>
+#include <functional>
+#include <set>
+#include <vector>
+#include <memory>
+
+
+
+#include "../DFTElementType.h"
+#include "../DFTState.h"
+#include "../DFTStateSpaceGenerationQueues.h"
+#include "src/utility/constants.h"
+#include "src/adapters/CarlAdapter.h"
+
+
+
+
+namespace storm {
+    namespace storage {
+        
+        using std::size_t;
+        template<typename ValueType>
+        class DFTGate;
+        
+        template<typename ValueType>
+        class DFTDependency;
+        template<typename ValueType>
+        class DFTRestriction;
+
+        
+        template<typename ValueType>
+        class DFTElement {
+
+            using DFTGatePointer = std::shared_ptr<DFTGate<ValueType>>;
+            using DFTGateVector = std::vector<DFTGatePointer>;
+            using DFTDependencyPointer = std::shared_ptr<DFTDependency<ValueType>>;
+            using DFTDependencyVector = std::vector<DFTDependencyPointer>;
+            using DFTRestrictionPointer = std::shared_ptr<DFTRestriction<ValueType>>;
+            using DFTRestrictionVector = std::vector<DFTRestrictionPointer>;
+
+
+        protected:
+            std::size_t mId;
+            std::string mName;
+            std::size_t mRank = -1;
+            DFTGateVector mParents;
+            DFTDependencyVector mOutgoingDependencies;
+            DFTRestrictionVector mRestrictions;
+
+
+        public:
+            DFTElement(size_t id, std::string const& name) :
+                    mId(id), mName(name)
+            {}
+
+            virtual ~DFTElement() {}
+
+            /**
+             * Returns the id
+             */
+            virtual size_t id() const {
+                return mId;
+            }
+
+            virtual DFTElementType type() const = 0;
+
+            virtual void setRank(size_t rank) {
+                mRank = rank;
+            }
+            
+            virtual size_t rank() const {
+                return mRank;
+            }
+            
+            virtual bool isConstant() const {
+                return false;
+            }
+            
+            virtual bool isGate() const {
+                return false;
+            }
+
+            /**
+             *  Returns true if the element is a BE
+             */
+            virtual bool isBasicElement() const {
+                return false;
+            }
+            
+            virtual bool isColdBasicElement() const {
+                return false;
+            }
+
+            /**
+             * Returns true if the element is a spare gate
+             */
+            virtual bool isSpareGate() const {
+                return false;
+            }
+
+            virtual bool isDependency() const {
+                return false;
+            }
+            
+            virtual bool isRestriction() const {
+                return false;
+            }
+
+            virtual void setId(size_t newId) {
+                mId = newId;
+            }
+
+            /**
+             * Returns the name
+             */
+            virtual std::string const& name() const {
+                return mName;
+            }
+            
+            bool addParent(DFTGatePointer const& e) {
+                if(std::find(mParents.begin(), mParents.end(), e) != mParents.end()) {
+                    return false;
+                }
+                else 
+                {
+                    mParents.push_back(e);
+                    return true;
+                }
+            }
+
+            bool addRestriction(DFTRestrictionPointer const& e) {
+                if (std::find(mRestrictions.begin(), mRestrictions.end(), e) != mRestrictions.end()) {
+                    return false;
+                } else {
+                    mRestrictions.push_back(e);
+                    return true;
+                }
+            }
+
+             bool hasOnlyStaticParents() const {
+                for(auto const& parent : mParents) {
+                    if(!isStaticGateType(parent->type())) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            
+            bool hasParents() const {
+                return !mParents.empty();
+            }
+            
+            size_t nrParents() const {
+                return mParents.size();
+            }
+
+            DFTGateVector const& parents() const {
+                return mParents;
+            }
+            
+            bool hasRestrictions() const {
+                return !mRestrictions.empty();
+            }
+            
+            size_t nrRestrictions() const {
+                return mRestrictions.size();
+            }
+            
+            DFTRestrictionVector const& restrictions() const {
+                return mRestrictions;
+            }
+
+            std::vector<size_t> parentIds() const {
+                std::vector<size_t> res;
+                for(auto parent : parents()) {
+                    res.push_back(parent->id());
+                }
+                return res;
+            }
+            
+            bool addOutgoingDependency(DFTDependencyPointer const& e) {
+                assert(e->triggerEvent()->id() == this->id());
+                if(std::find(mOutgoingDependencies.begin(), mOutgoingDependencies.end(), e) != mOutgoingDependencies.end()) {
+                    return false;
+                }
+                else
+                {
+                    mOutgoingDependencies.push_back(e);
+                    return true;
+                }
+            }
+            
+            bool hasOutgoingDependencies() const {
+                return !mOutgoingDependencies.empty();
+            }
+            
+            size_t nrOutgoingDependencies() const {
+                return mOutgoingDependencies.size();
+            }
+            
+            std::set<DFTElement<ValueType>> restrictedItems() const {
+                std::set<DFTElement<ValueType>> result;
+                for(auto const& restr : mRestrictions) {
+                    bool foundThis = false;
+                    for(auto const& child : restr->children()) {
+                        if(!foundThis) {
+                            if(child->id() == mId) {
+                                foundThis = true;
+                            }
+                        } else if(result.count(child) == 0) {
+                            result.insert(child);
+                        }
+                    }
+                }
+            }
+            
+            std::set<DFTElement<ValueType>> restrictedItemsTC() const {
+                std::set<DFTElement<ValueType>> result;
+                for(auto const& restr : mRestrictions) {
+                    bool foundThis = false;
+                    for(auto const& child : restr->children()) {
+                        if(!foundThis) {
+                            if(child->id() == mId) {
+                                foundThis = true;
+                            }
+                        } else if(result.count(child) == 0) {
+                            result.insert(child);
+                            std::set<DFTElement<ValueType>> tmpRes = child->restrictedItemsTC();
+                            result.insert(tmpRes.begin(), tmpRes.end());
+                        }
+                    }
+                }
+            }
+            
+            DFTDependencyVector const& outgoingDependencies() const {
+                return mOutgoingDependencies;
+            }
+            
+            virtual void extendSpareModule(std::set<size_t>& elementsInModule) const;
+
+           // virtual void extendImmediateFailureCausePathEvents(std::set<size_t>& ) const;
+            
+            virtual std::size_t nrChildren() const = 0;
+
+            virtual std::string toString() const = 0;
+
+            virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const;
+
+            /**
+             *  Computes the independent unit of this element, that is, all elements which are direct or indirect successors of an element.
+             */
+            virtual std::vector<size_t> independentUnit() const;
+
+            /**
+             *  Helper to independent unit computation
+             *  @see independentUnit
+             */
+            virtual void extendUnit(std::set<size_t>& unit) const;
+
+            /**
+             *  Computes independent subtrees starting with this element (this), that is, all elements (x) which are connected to either
+             *  - one of the children of the element,
+             *  - a probabilistic dependency
+             *  such that there exists a  path from x to a child of this does not go through this.
+             */
+            virtual std::vector<size_t> independentSubDft(bool blockParents) const;
+            /**
+             * Helper to the independent subtree computation
+             * @see independentSubDft
+             */
+            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const;
+
+            virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const {
+                return type() == other.type();
+            }
+
+
+        protected:
+           // virtual bool checkIsomorphicSubDftHelper(DFTElement const& otherElem, std::vector<std::pair<DFTElement const&, DFTElement const&>>& mapping, std::vector<DFTElement const&> const& order ) const = 0;
+
+        };
+        
+        
+       
+          
+        template<typename ValueType>
+        bool equalType(DFTElement<ValueType> const& e1, DFTElement<ValueType> const& e2) {
+            return e1.isTypeEqualTo(e2);
+        }
+    }
+}
diff --git a/src/storage/dft/elements/DFTGate.h b/src/storage/dft/elements/DFTGate.h
new file mode 100644
index 000000000..52f9bcd43
--- /dev/null
+++ b/src/storage/dft/elements/DFTGate.h
@@ -0,0 +1,180 @@
+#pragma once
+
+#include "DFTElement.h"
+namespace storm {
+    namespace storage {
+    template<typename ValueType>
+        class DFTGate : public DFTElement<ValueType> {
+
+            using DFTElementPointer = std::shared_ptr<DFTElement<ValueType>>;
+            using DFTElementVector = std::vector<DFTElementPointer>;
+
+        protected:
+            DFTElementVector mChildren;
+
+        public:
+            DFTGate(size_t id, std::string const& name, DFTElementVector const& children) :
+                    DFTElement<ValueType>(id, name), mChildren(children)
+            {}
+            
+            virtual ~DFTGate() {}
+            
+            void pushBackChild(DFTElementPointer elem) {
+                return mChildren.push_back(elem);
+            }
+
+            size_t nrChildren() const override {
+                return mChildren.size();
+            }
+
+            DFTElementVector const& children() const {
+                return mChildren;
+            }
+            
+            virtual bool isGate() const override {
+                return true;
+            }
+            
+            
+            virtual std::string typestring() const = 0;
+
+            virtual void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const = 0;
+
+            virtual void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const = 0;
+            
+            virtual void extendSpareModule(std::set<size_t>& elementsInSpareModule) const override {
+                if (!this->isSpareGate()) {
+                    DFTElement<ValueType>::extendSpareModule(elementsInSpareModule);
+                    for( auto const& child : mChildren) {
+                        if(elementsInSpareModule.count(child->id()) == 0) {
+                            elementsInSpareModule.insert(child->id());
+                            child->extendSpareModule(elementsInSpareModule);
+                        }
+                    }
+                }
+            }
+            
+            virtual std::vector<size_t> independentUnit() const override {
+                std::set<size_t> unit = {this->mId};
+                for(auto const& child : mChildren) {
+                    child->extendUnit(unit);
+                }
+                return std::vector<size_t>(unit.begin(), unit.end());
+            }
+
+            virtual void extendUnit(std::set<size_t>& unit) const override {
+                DFTElement<ValueType>::extendUnit(unit);
+                for(auto const& child : mChildren) {
+                    child->extendUnit(unit);
+                }
+            }
+
+            virtual std::vector<size_t> independentSubDft(bool blockParents) const override {
+                auto prelRes = DFTElement<ValueType>::independentSubDft(blockParents);
+                if(prelRes.empty()) {
+                    // No elements (especially not this->id) in the prelimanry result, so we know already that it is not a subdft.
+                    return prelRes;
+                }
+                std::set<size_t> unit(prelRes.begin(), prelRes.end());
+                std::vector<size_t> pids = this->parentIds();
+                for(auto const& child : mChildren) {
+                    child->extendSubDft(unit, pids, blockParents);
+                    if(unit.empty()) {
+                        // Parent in the subdft, ie it is *not* a subdft
+                        break;
+                    }
+                }
+                return std::vector<size_t>(unit.begin(), unit.end());
+            }
+
+            virtual void extendSubDft(std::set<size_t>& elemsInSubtree, std::vector<size_t> const& parentsOfSubRoot, bool blockParents) const override {
+                if(elemsInSubtree.count(this->id()) > 0) return;
+                DFTElement<ValueType>::extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                if(elemsInSubtree.empty()) {
+                    // Parent in the subdft, ie it is *not* a subdft
+                    return;
+                }
+                for(auto const& child : mChildren) {
+                    child->extendSubDft(elemsInSubtree, parentsOfSubRoot, blockParents);
+                    if(elemsInSubtree.empty()) {
+                        // Parent in the subdft, ie it is *not* a subdft
+                        return;
+                    }
+                }
+            }
+
+
+            virtual std::string toString() const override {
+                std::stringstream stream;
+                stream << "{" << this->name() << "} " << typestring() << "( ";
+                typename DFTElementVector::const_iterator it = mChildren.begin();
+                stream << (*it)->name();
+                ++it;
+                while(it != mChildren.end()) {
+                    stream <<  ", " << (*it)->name();
+                    ++it;
+                }
+                stream << ")";
+                return stream.str();
+            }
+
+            virtual bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if(DFTElement<ValueType>::checkDontCareAnymore(state, queues)) {
+                    childrenDontCare(state, queues);
+                    return true;
+                }
+                return false;
+            }
+
+
+        protected:
+
+            void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                for(std::shared_ptr<DFTGate> parent : this->mParents) {
+                    if(state.isOperational(parent->id())) {
+                        queues.propagateFailure(parent);
+                    }
+                }
+                for(std::shared_ptr<DFTRestriction<ValueType>> restr : this->mRestrictions) {
+                    queues.checkRestrictionLater(restr);
+                }
+                state.setFailed(this->mId);
+                this->childrenDontCare(state, queues);
+            }
+
+            void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                for(std::shared_ptr<DFTGate> parent : this->mParents) {
+                    if(state.isOperational(parent->id())) {
+                        queues.propagateFailsafe(parent);
+                    }
+                }
+                state.setFailsafe(this->mId);
+                this->childrenDontCare(state, queues);
+            }
+            
+            void childrenDontCare(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                queues.propagateDontCare(mChildren);
+            }
+
+            bool hasFailsafeChild(DFTState<ValueType>& state) const {
+                for(auto const& child : mChildren) {
+                    if(state.isFailsafe(child->id()))
+                    {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            bool hasFailedChild(DFTState<ValueType>& state) const {
+                for(auto const& child : mChildren) {
+                    if(state.hasFailed(child->id())) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+            
+        };
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTOr.h b/src/storage/dft/elements/DFTOr.h
new file mode 100644
index 000000000..93e481d35
--- /dev/null
+++ b/src/storage/dft/elements/DFTOr.h
@@ -0,0 +1,45 @@
+#pragma once 
+
+#include "DFTGate.h"
+namespace storm {
+    namespace storage {
+        template<typename ValueType>
+        class DFTOr : public DFTGate<ValueType> {
+
+        public:
+            DFTOr(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
+                    DFTGate<ValueType>(id, name, children)
+            {}
+
+            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                assert(this->hasFailedChild(state));
+                if(state.isOperational(this->mId)) {
+                    this->fail(state, queues);
+                }
+            }
+
+            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                 for(auto const& child : this->mChildren) {
+                     if(!state.isFailsafe(child->id())) {
+                         return;
+                     }
+                 }
+                 this->failsafe(state, queues);
+            }
+
+            virtual DFTElementType type() const override {
+                return DFTElementType::OR;
+            }
+            
+            std::string typestring() const override {
+                return "OR";
+            }
+        };
+
+        template<typename ValueType>
+        inline std::ostream& operator<<(std::ostream& os, DFTOr<ValueType> const& gate) {
+            return os << gate.toString();
+        }
+    }
+}
+       
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTPand.h b/src/storage/dft/elements/DFTPand.h
new file mode 100644
index 000000000..86472d76f
--- /dev/null
+++ b/src/storage/dft/elements/DFTPand.h
@@ -0,0 +1,56 @@
+#pragma once 
+
+#include "DFTGate.h"
+namespace storm {
+    namespace storage {
+          template<typename ValueType>
+        class DFTPand : public DFTGate<ValueType> {
+
+        public:
+            DFTPand(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
+                    DFTGate<ValueType>(id, name, children)
+            {}
+
+            void checkFails(storm::storage::DFTState<ValueType>& state,  DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if(state.isOperational(this->mId)) {
+                    bool childOperationalBefore = false;
+                    for(auto const& child : this->mChildren)
+                    {
+                        if(!state.hasFailed(child->id())) {
+                            childOperationalBefore = true;
+                        } else if(childOperationalBefore && state.hasFailed(child->id())){
+                            this->failsafe(state, queues);
+                            this->childrenDontCare(state, queues);
+                            return;
+                        }
+                    }
+                    if(!childOperationalBefore) {
+                        this->fail(state, queues);
+                    }
+                }
+            }
+
+            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                assert(this->hasFailsafeChild(state));
+                if(state.isOperational(this->mId)) {
+                    this->failsafe(state, queues);
+                    this->childrenDontCare(state, queues);
+                }
+            }
+
+            virtual DFTElementType type() const override {
+                return DFTElementType::PAND;
+            }
+            
+            std::string typestring() const override {
+                return "PAND";
+            }
+        };
+        
+        template<typename ValueType>
+        inline std::ostream& operator<<(std::ostream& os, DFTPand<ValueType> const& gate) {
+             return os << gate.toString();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTPor.h b/src/storage/dft/elements/DFTPor.h
new file mode 100644
index 000000000..1aaa943b0
--- /dev/null
+++ b/src/storage/dft/elements/DFTPor.h
@@ -0,0 +1,36 @@
+#pragma once 
+
+#include "DFTGate.h"
+namespace storm {
+    namespace storage {
+        template<typename ValueType>
+        class DFTPor : public DFTGate<ValueType> {
+        public:
+            DFTPor(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
+                    DFTGate<ValueType>(id, name, children)
+            {}
+
+            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                 assert(false);
+            }
+
+            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                assert(false);
+            }
+
+            virtual DFTElementType type() const override {
+                return DFTElementType::POR;
+            }
+            
+            std::string  typestring() const override {
+                return "POR";
+            }
+        };
+
+        template<typename ValueType>
+        inline std::ostream& operator<<(std::ostream& os, DFTPor<ValueType> const& gate) {
+             return os << gate.toString();
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTRestriction.h b/src/storage/dft/elements/DFTRestriction.h
index 70163a6e6..f0fef5845 100644
--- a/src/storage/dft/elements/DFTRestriction.h
+++ b/src/storage/dft/elements/DFTRestriction.h
@@ -1,7 +1,6 @@
 #pragma once
 
-#include "../DFTElements.h"
-
+#include "DFTElement.h"
 namespace storm {
     namespace storage {
         template<typename ValueType>
diff --git a/src/storage/dft/elements/DFTSpare.h b/src/storage/dft/elements/DFTSpare.h
new file mode 100644
index 000000000..dd3689311
--- /dev/null
+++ b/src/storage/dft/elements/DFTSpare.h
@@ -0,0 +1,70 @@
+#pragma once 
+
+
+#include "DFTGate.h"
+namespace storm {
+    namespace storage {
+        
+
+        template<typename ValueType>
+        class DFTSpare : public DFTGate<ValueType> {
+
+        public:
+            DFTSpare(size_t id, std::string const& name, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
+                    DFTGate<ValueType>(id, name, children)
+            {}
+            
+            std::string typestring() const override {
+                return "SPARE";
+            }
+
+            virtual DFTElementType type() const override {
+                return DFTElementType::SPARE;
+            }
+
+            bool isSpareGate() const override {
+                return true;
+            }
+            
+            void fail(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                DFTGate<ValueType>::fail(state, queues);
+                state.finalizeUses(this->mId);
+            }
+            
+            void failsafe(DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const {
+                DFTGate<ValueType>::failsafe(state, queues);
+                state.finalizeUses(this->mId);
+            }
+            
+            bool checkDontCareAnymore(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if (DFTGate<ValueType>::checkDontCareAnymore(state, queues)) {
+                    state.finalizeUses(this->mId);
+                    return true;
+                }
+                return false;
+            }
+            
+            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if(state.isOperational(this->mId)) {
+                    size_t uses = state.uses(this->mId);
+                    if(!state.isOperational(uses)) {
+                        bool claimingSuccessful = state.claimNew(this->mId, uses, this->mChildren);
+                        if(!claimingSuccessful) {
+                            this->fail(state, queues);
+                        }
+                    }                  
+                } 
+            }
+
+            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if(state.isOperational(this->mId)) {
+                    if(state.isFailsafe(state.uses(this->mId))) {
+                        this->failsafe(state, queues);
+                        this->childrenDontCare(state, queues);
+                    }
+                }
+            }
+
+        };
+    }
+}
\ No newline at end of file
diff --git a/src/storage/dft/elements/DFTVot.h b/src/storage/dft/elements/DFTVot.h
new file mode 100644
index 000000000..3a3e818d2
--- /dev/null
+++ b/src/storage/dft/elements/DFTVot.h
@@ -0,0 +1,75 @@
+#pragma once 
+namespace storm {
+    namespace storage {
+        
+
+        template<typename ValueType>
+        class DFTVot : public DFTGate<ValueType> {
+
+        private:
+            unsigned mThreshold;
+
+        public:
+            DFTVot(size_t id, std::string const& name, unsigned threshold, std::vector<std::shared_ptr<DFTElement<ValueType>>> const& children = {}) :
+                    DFTGate<ValueType>(id, name, children), mThreshold(threshold)
+            {}
+
+            void checkFails(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                if(state.isOperational(this->mId)) {
+                    unsigned nrFailedChildren = 0;
+                    for(auto const& child : this->mChildren)
+                    {
+                        if(state.hasFailed(child->id())) {
+                            ++nrFailedChildren;
+                            if(nrFailedChildren >= mThreshold) 
+                            {
+                                this->fail(state, queues);
+                                return;
+                            }
+                        }
+                    }
+                  
+                } 
+            }
+
+            void checkFailsafe(storm::storage::DFTState<ValueType>& state, DFTStateSpaceGenerationQueues<ValueType>& queues) const override {
+                assert(this->hasFailsafeChild(state));
+                if(state.isOperational(this->mId)) {
+                    unsigned nrFailsafeChildren = 0;
+                    for(auto const& child : this->mChildren)
+                    {
+                        if(state.isFailsafe(child->id())) {
+                            ++nrFailsafeChildren;
+                            if(nrFailsafeChildren > this->nrChildren() - mThreshold)
+                            {
+                                this->failsafe(state, queues);
+                                this->childrenDontCare(state, queues);
+                                return;
+                            }
+                        }
+                    }
+                }
+            }
+
+            virtual DFTElementType type() const override {
+                return DFTElementType::VOT;
+            }
+            
+            std::string typestring() const override{
+                return "VOT (" + std::to_string(mThreshold) + ")";
+            }
+            
+            virtual bool isTypeEqualTo(DFTElement<ValueType> const& other) const override {
+                if(!DFTElement<ValueType>::isTypeEqualTo(other)) return false;
+                DFTVot<ValueType> const& otherVOT = static_cast<DFTVot<ValueType> const&>(other);
+                return (mThreshold == otherVOT.mThreshold);
+            }
+        };
+
+        template<typename ValueType>
+        inline std::ostream& operator<<(std::ostream& os, DFTVot<ValueType> const& gate) {
+            return os << gate.toString();
+        }
+
+    }
+}
\ No newline at end of file