diff --git a/alib2abstraction/src/abstraction/PackingAbstraction.cpp b/alib2abstraction/src/abstraction/PackingAbstraction.cpp
index 7a83d4d881922e9b236dc3ddb8afd455c27ca8d4..faf135e2d5cd97a77733e1b3f74829ce0ea60c9f 100644
--- a/alib2abstraction/src/abstraction/PackingAbstraction.cpp
+++ b/alib2abstraction/src/abstraction/PackingAbstraction.cpp
@@ -5,35 +5,25 @@ template class abstraction::PackingAbstraction < 3 >;
 
 namespace abstraction {
 
-PackingAbstractionImpl::LazyValue::LazyValue ( std::unique_ptr < abstraction::OperationAbstraction > ref ) : m_lifeReference ( std::move ( ref ) ) {
+PackingAbstractionImpl::PackingAbstractionImpl ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions ) {
+	std::transform ( abstractions.begin ( ), abstractions.end ( ), std::back_inserter ( m_abstractions ),
+		[ ] ( std::unique_ptr < abstraction::OperationAbstraction > & abstraction ) { return std::make_pair ( std::move ( abstraction ), std::vector < ConnectionSource > { } ); }
+	);
 }
 
-std::unique_ptr < abstraction::Value > PackingAbstractionImpl::LazyValue::asValue ( bool, bool ) {
-	throw std::domain_error ( "Feature not available on lazy value" );
-}
-
-ext::type_index PackingAbstractionImpl::LazyValue::getTypeIndex ( ) const {
-	return this->getLifeReference( )->getReturnTypeIndex ( );
-}
+std::shared_ptr < abstraction::Value > PackingAbstractionImpl::recursiveEval ( size_t id, std::vector < std::shared_ptr < abstraction::Value > > & cache ) {
+	for ( ConnectionSource connection : m_abstractions [ id ].second ) {
+		if ( ! cache [ connection.sourceId ] )
+			cache [ connection.sourceId ] = recursiveEval ( connection.sourceId, cache );
 
-abstraction::TypeQualifiers::TypeQualifierSet PackingAbstractionImpl::LazyValue::getTypeQualifiers ( ) const {
-	return this->getLifeReference ( )->getReturnTypeQualifiers ( );
-}
-
-std::shared_ptr < abstraction::Value > PackingAbstractionImpl::LazyValue::getProxyAbstraction ( ) {
-	if ( cache == nullptr )
-		cache = this->getLifeReference ( )->eval ( );
-	return cache;
-}
+		m_abstractions [ id ].first->attachInput ( cache [ connection.sourceId ], connection.paramPosition );
+	}
 
-const std::unique_ptr < abstraction::OperationAbstraction > & PackingAbstractionImpl::LazyValue::getLifeReference ( ) const {
-	return m_lifeReference;
+	return m_abstractions [ id ].first->eval ( );
 }
 
-bool PackingAbstractionImpl::LazyValue::isTemporary ( ) const {
-	if ( cache == nullptr )
-		throw std::domain_error ( "Feature not available on unevaluated value" );
-	return cache->isTemporary ( );
+void PackingAbstractionImpl::setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) {
+	m_abstractions [ targetId ].second.push_back ( ConnectionSource { sourceId, paramPosition } );
 }
 
 } /* namespace abstraction */
diff --git a/alib2abstraction/src/abstraction/PackingAbstraction.hpp b/alib2abstraction/src/abstraction/PackingAbstraction.hpp
index 0f13e4c97e3afed7de109ffb9a85f0931e667bd7..0165c4d0d1066326953ebbd73e41ea0c65fdf122 100644
--- a/alib2abstraction/src/abstraction/PackingAbstraction.hpp
+++ b/alib2abstraction/src/abstraction/PackingAbstraction.hpp
@@ -10,53 +10,27 @@ namespace abstraction {
 
 class PackingAbstractionImpl : public OperationAbstraction {
 protected:
-	class LazyValue : public Value {
-		std::shared_ptr < Value > cache;
-		std::unique_ptr < abstraction::OperationAbstraction > m_lifeReference;
-
-	public:
-		explicit LazyValue ( std::unique_ptr < abstraction::OperationAbstraction > ref );
-
-		std::unique_ptr < abstraction::Value > asValue ( bool move, bool isTemporary ) override;
-
-		ext::type_index getTypeIndex ( ) const override;
-
-		abstraction::TypeQualifiers::TypeQualifierSet getTypeQualifiers ( ) const override;
-
-		std::shared_ptr < abstraction::Value > getProxyAbstraction ( ) override;
-
-		const std::unique_ptr < abstraction::OperationAbstraction > & getLifeReference ( ) const;
-
-		bool isTemporary ( ) const override;
-	};
-
 	struct ConnectionTarget {
 		size_t targetId;
 		size_t paramPosition;
 	};
 
-private:
-	ext::vector < std::shared_ptr < LazyValue > > m_abstractions;
+	struct ConnectionSource {
+		size_t sourceId;
+		size_t paramPosition;
+	};
 
-public:
-	explicit PackingAbstractionImpl ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions ) {
-		std::transform ( abstractions.begin ( ), abstractions.end ( ), std::back_inserter ( m_abstractions ), [ ] ( std::unique_ptr < abstraction::OperationAbstraction > & abstraction ) { return std::make_shared < LazyValue > ( std::move ( abstraction ) ); } );
-	}
+	ext::vector < std::pair < std::unique_ptr < abstraction::OperationAbstraction >, std::vector < ConnectionSource > > > m_abstractions;
 
-	void setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) {
-		m_abstractions [ targetId ]->getLifeReference ( )->attachInput ( m_abstractions [ sourceId ], paramPosition );
-	}
+public:
+	explicit PackingAbstractionImpl ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions );
 
-	void clearInnerConnection ( size_t targetId, size_t paramPosition ) {
-		m_abstractions [ targetId ]->getLifeReference ( )->detachInput ( paramPosition );
-	}
+	std::shared_ptr < abstraction::Value > recursiveEval ( size_t id, std::vector < std::shared_ptr < abstraction::Value > > & cache );
 
-	bool inputsAttached ( ) const override {
-		return std::all_of ( m_abstractions.begin ( ), m_abstractions.end ( ), [ ] ( const std::shared_ptr < LazyValue > & operation ) { return operation->getLifeReference ( )->inputsAttached ( ); } );
-	}
+	void setInnerConnection ( size_t sourceId, size_t targetId, size_t paramPosition );
 
 protected:
-	const ext::vector < std::shared_ptr < LazyValue > > & getAbstractions ( ) const {
+	const ext::vector < std::pair < std::unique_ptr < abstraction::OperationAbstraction >, std::vector < ConnectionSource > > > & getAbstractions ( ) const {
 		return m_abstractions;
 	}
 
@@ -64,12 +38,12 @@ protected:
 
 template < size_t NumberOfParams >
 class PackingAbstraction : public PackingAbstractionImpl {
-	ext::array < ext::vector < ConnectionTarget >, NumberOfParams > m_connections;
+	ext::array < std::pair < ext::vector < ConnectionTarget >, std::shared_ptr < abstraction::Value > >, NumberOfParams > m_connections;
 	size_t m_resultId;
 
 public:
 	void setOuterConnection ( size_t sourceId, size_t targetId, size_t paramPosition ) {
-		m_connections [ sourceId ].push_back ( ConnectionTarget { targetId, paramPosition } );
+		m_connections [ sourceId ].first.push_back ( ConnectionTarget { targetId, paramPosition } );
 	}
 
 	PackingAbstraction ( ext::vector < std::unique_ptr < abstraction::OperationAbstraction > > abstractions, size_t resultId ) : PackingAbstractionImpl ( std::move ( abstractions ) ), m_resultId ( resultId ) {
@@ -78,17 +52,28 @@ public:
 private:
 	void attachInput ( const std::shared_ptr < abstraction::Value > & input, size_t index ) override {
 		try {
-			for ( const ConnectionTarget & target : m_connections [ index ] )
-				getAbstractions ( ) [ target.targetId ]->getLifeReference ( )->attachInput ( input, target.paramPosition );
+			for ( const ConnectionTarget & target : m_connections [ index ].first )
+				getAbstractions ( ) [ target.targetId ].first->attachInput ( input, target.paramPosition );
 		} catch ( ... ) {
 			this->detachInput ( index );
 			throw;
 		}
+		m_connections [ index ].second = input;
 	}
 
 	void detachInput ( size_t index ) override {
-		for ( const ConnectionTarget & target : m_connections [ index ] )
-			getAbstractions ( ) [ target.targetId ]->getLifeReference ( )->detachInput ( target.paramPosition );
+		for ( const ConnectionTarget & target : m_connections [ index ].first )
+			getAbstractions ( ) [ target.targetId ].first->detachInput ( target.paramPosition );
+
+		m_connections [ index ].second = nullptr;
+	}
+
+	bool inputsAttached ( ) const override {
+		// Note: it is up to the designer of the inner connections among packed abstraction to make sure once the outter connections are set the execution does not fail due to unattached inputs.
+
+		return std::all_of ( m_connections.begin ( ), m_connections.end ( ), [ ] ( const std::pair < ext::vector < ConnectionTarget >, std::shared_ptr < abstraction::Value > > & connection ) {
+			return static_cast < bool > ( connection.second );
+		} );
 	}
 
 public:
@@ -96,7 +81,8 @@ public:
 		if ( ! inputsAttached ( ) )
 			return nullptr;
 
-		return getAbstractions ( ) [ m_resultId ]->getProxyAbstraction ( );
+		std::vector < std::shared_ptr < abstraction::Value > > cache ( m_abstractions.size ( ) );
+		return recursiveEval ( m_resultId, cache );
 	}
 
 	size_t numberOfParams ( ) const override {
@@ -104,19 +90,19 @@ public:
 	}
 
 	ext::type_index getParamTypeIndex ( size_t index ) const override {
-		return getAbstractions ( ) [ m_connections.at ( index ) [ 0 ].targetId ]->getLifeReference ( )->getParamTypeIndex ( m_connections.at ( index ) [ 0 ].paramPosition );
+		return getAbstractions ( ) [ m_connections.at ( index ).first [ 0 ].targetId ].first->getParamTypeIndex ( m_connections.at ( index ).first [ 0 ].paramPosition );
 	}
 
 	abstraction::TypeQualifiers::TypeQualifierSet getParamTypeQualifiers ( size_t index ) const override {
-		return getAbstractions ( ) [ m_connections.at ( index ) [ 0 ].targetId ]->getLifeReference ( )->getParamTypeQualifiers ( m_connections.at ( index ) [ 0 ].paramPosition );
+		return getAbstractions ( ) [ m_connections.at ( index ).first [ 0 ].targetId ].first->getParamTypeQualifiers ( m_connections.at ( index ).first [ 0 ].paramPosition );
 	}
 
 	ext::type_index getReturnTypeIndex ( ) const override {
-		return getAbstractions ( ) [ m_resultId ]->getLifeReference ( )->getReturnTypeIndex ( );
+		return getAbstractions ( ) [ m_resultId ].first->getReturnTypeIndex ( );
 	}
 
 	abstraction::TypeQualifiers::TypeQualifierSet getReturnTypeQualifiers ( ) const override {
-		return getAbstractions ( ) [ m_resultId ]->getLifeReference ( )->getReturnTypeQualifiers ( );
+		return getAbstractions ( ) [ m_resultId ].first->getReturnTypeQualifiers ( );
 	}
 
 };