diff --git a/go.mod b/go.mod
index 3fc5dbd477f12ea2df332810bad1d193bbc8205e..015e2823f021a6c53041edfe4e00aa49616055e8 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/golang/protobuf v1.3.2 // indirect
 	github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51
 	github.com/gorilla/websocket v1.4.1
-	github.com/iotaledger/hive.go v0.0.0-20191205213014-6bee840fa69a
+	github.com/iotaledger/hive.go v0.0.0-20191208004610-567900b261bd
 	github.com/iotaledger/iota.go v1.0.0-beta.9
 	github.com/kr/text v0.1.0
 	github.com/labstack/echo v3.3.10+incompatible
diff --git a/go.sum b/go.sum
index 6a2724a85c9dc8576ebcdb169a10efee47df2e2d..21013aaa10a237c3ee55af178ab8f640c205cbfb 100644
--- a/go.sum
+++ b/go.sum
@@ -96,6 +96,10 @@ github.com/iotaledger/hive.go v0.0.0-20191205211001-eafba1daa31e h1:7F9mSTDfFwMl
 github.com/iotaledger/hive.go v0.0.0-20191205211001-eafba1daa31e/go.mod h1:7iqun29a1x0lymTrn0UJ3Z/yy0sUzUpoOZ1OYMrYN20=
 github.com/iotaledger/hive.go v0.0.0-20191205213014-6bee840fa69a h1:mI4GR5wcI5G6vjumuI2KH9r0mf5me3i6mWhDMtkKR04=
 github.com/iotaledger/hive.go v0.0.0-20191205213014-6bee840fa69a/go.mod h1:7iqun29a1x0lymTrn0UJ3Z/yy0sUzUpoOZ1OYMrYN20=
+github.com/iotaledger/hive.go v0.0.0-20191206001944-418a9127c1eb h1:iMYyaySL2gEjOcPRzWZYCn4+vXkanq1b9Pr9fKSzdrI=
+github.com/iotaledger/hive.go v0.0.0-20191206001944-418a9127c1eb/go.mod h1:7iqun29a1x0lymTrn0UJ3Z/yy0sUzUpoOZ1OYMrYN20=
+github.com/iotaledger/hive.go v0.0.0-20191208004610-567900b261bd h1:hh8iusLOBylWNHeJNiZv6atCbO7vzjCLlg53pNAMkFk=
+github.com/iotaledger/hive.go v0.0.0-20191208004610-567900b261bd/go.mod h1:7iqun29a1x0lymTrn0UJ3Z/yy0sUzUpoOZ1OYMrYN20=
 github.com/iotaledger/iota.go v1.0.0-beta.7 h1:OaUNahPvOdQz2nKcgeAfcUdxlEDlEV3xwLIkwzZ1B/U=
 github.com/iotaledger/iota.go v1.0.0-beta.7/go.mod h1:dMps6iMVU1pf5NDYNKIw4tRsPeC8W3ZWjOvYHOO1PMg=
 github.com/iotaledger/iota.go v1.0.0-beta.9 h1:c654s9pkdhMBkABUvWg+6k91MEBbdtmZXP1xDfQpajg=
diff --git a/packages/ledgerstate/conflict_id.go b/packages/ledgerstate/conflict_id.go
index 0d084ca047931540bac891e7c29ce09b774864a4..fce0559c6d5acfd114a7400f31ed252a933352d9 100644
--- a/packages/ledgerstate/conflict_id.go
+++ b/packages/ledgerstate/conflict_id.go
@@ -9,17 +9,17 @@ import (
 
 type ConflictId [conflictSetIdLength]byte
 
-func NewConflictSetId(conflictBytes ...interface{}) (result ConflictId) {
+func NewConflictId(conflictBytes ...interface{}) (result ConflictId) {
 	switch len(conflictBytes) {
 	case 2:
 		transferHash, ok := conflictBytes[0].(TransferHash)
 		if !ok {
-			panic("expected first parameter of NewConflictSetId to be a TransferHash")
+			panic("expected first parameter of NewConflictId to be a TransferHash")
 		}
 
 		addressHash, ok := conflictBytes[0].(TransferHash)
 		if !ok {
-			panic("expected second parameter of NewConflictSetId to be a AddressHash")
+			panic("expected second parameter of NewConflictId to be a AddressHash")
 		}
 
 		fullConflictSetIdentifier := make([]byte, transferHashLength+addressHashLength)
@@ -29,7 +29,7 @@ func NewConflictSetId(conflictBytes ...interface{}) (result ConflictId) {
 		result = blake2b.Sum256(fullConflictSetIdentifier)
 	case 1:
 	default:
-		panic("invalid parameter count when calling NewConflictSetId")
+		panic("invalid parameter count when calling NewConflictId")
 	}
 
 	return
diff --git a/packages/ledgerstate/ledgerstate.go b/packages/ledgerstate/ledgerstate.go
index 83ff9dc53cdc973fb7a9a532959fa66d4437664a..0af177c674f4ce1fcf7023d91ba981fcbaeb3119 100644
--- a/packages/ledgerstate/ledgerstate.go
+++ b/packages/ledgerstate/ledgerstate.go
@@ -152,9 +152,7 @@ func (ledgerState *LedgerState) BookTransfer(transfer *Transfer) (err error) {
 			return
 		}
 
-		if !targetReality.PersistenceEnabled() {
-			targetReality.Persist()
-		}
+		targetReality.Persist()
 	})
 
 	return
diff --git a/packages/ledgerstate/ledgerstate_test.go b/packages/ledgerstate/ledgerstate_test.go
index fc5efc9e7dfa7b13990ac30e29e74e1364a496de..61ad15e871a030a7192bf777a6dcd84975a2e79b 100644
--- a/packages/ledgerstate/ledgerstate_test.go
+++ b/packages/ledgerstate/ledgerstate_test.go
@@ -233,7 +233,7 @@ func TestAggregateAggregatedRealities(t *testing.T) {
 	multiSpend(ledgerState, 1, aggregatedOutputs0[0], aggregatedOutputs1[0])
 	multiSpend(ledgerState, 1, aggregatedOutputs0[1], aggregatedOutputs2[0])
 
-	time.Sleep(1000 * time.Millisecond)
+	time.Sleep(2000 * time.Millisecond)
 
 	objectstorage.WaitForWritesToFlush()
 
@@ -247,7 +247,7 @@ func TestAggregateAggregatedRealities(t *testing.T) {
 
 	multiSpend(ledgerState, 2, outputs0[0], outputs1[0])
 
-	time.Sleep(1000 * time.Millisecond)
+	time.Sleep(2000 * time.Millisecond)
 
 	objectstorage.WaitForWritesToFlush()
 
diff --git a/packages/ledgerstate/outputs.png b/packages/ledgerstate/outputs.png
index 6f2378aae6fd63d8cc32cebf1de4b0d53e3657d6..b746b5ce8c27e57e55376cd41b8a903a8c5fb5c6 100644
Binary files a/packages/ledgerstate/outputs.png and b/packages/ledgerstate/outputs.png differ
diff --git a/packages/ledgerstate/outputs1.png b/packages/ledgerstate/outputs1.png
index 78638b4ac0d547722553ecba91080eb482cfdfac..fbb292ef06d60e9e6ddf1bf269990516a389fcb7 100644
Binary files a/packages/ledgerstate/outputs1.png and b/packages/ledgerstate/outputs1.png differ
diff --git a/packages/ledgerstate/outputs2.png b/packages/ledgerstate/outputs2.png
index 4e5fb6fc2eb50722536f8cebf3237379c06830c8..60319a10e56e7846b93dd8889d864649f4514ba3 100644
Binary files a/packages/ledgerstate/outputs2.png and b/packages/ledgerstate/outputs2.png differ
diff --git a/packages/ledgerstate/realities2.png b/packages/ledgerstate/realities2.png
index a6fb2ce1c43c24eb3059ea3a8c840a5b846fa769..08f4b00d7bd979f5503fbfcbc0c2a62e636ab170 100644
Binary files a/packages/ledgerstate/realities2.png and b/packages/ledgerstate/realities2.png differ
diff --git a/packages/ledgerstate/reality.go b/packages/ledgerstate/reality.go
index afbbcb50b59c0b9b33fa60bfe47f174b1781b6d3..b163d718083c2985e0dbf50a3e4180cc2212e6f5 100644
--- a/packages/ledgerstate/reality.go
+++ b/packages/ledgerstate/reality.go
@@ -4,9 +4,9 @@ import (
 	"sync"
 	"sync/atomic"
 
-	"github.com/iotaledger/goshimmer/packages/errors"
 	"github.com/iotaledger/goshimmer/packages/stringify"
 
+	"github.com/iotaledger/goshimmer/packages/errors"
 	"github.com/iotaledger/hive.go/objectstorage"
 )
 
@@ -72,19 +72,69 @@ func (reality *Reality) AddParentReality(realityId RealityId) {
 	}
 }
 
+// Utility function that replaces the parent of a reality.
+// Since IO is the most expensive part of the ledger state, we only update the parents and mark the reality as modified
+// if either the oldRealityId exists or the newRealityId does not exist.
+func (reality *Reality) replaceParentReality(oldRealityId RealityId, newRealityId RealityId) {
+	reality.parentRealityIdsMutex.RLock()
+	if _, oldRealityIdExist := reality.parentRealityIds[oldRealityId]; oldRealityIdExist {
+		reality.parentRealityIdsMutex.RUnlock()
+
+		reality.parentRealityIdsMutex.Lock()
+		if _, oldRealityIdExist := reality.parentRealityIds[oldRealityId]; oldRealityIdExist {
+			delete(reality.parentRealityIds, oldRealityId)
+
+			if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist {
+				reality.parentRealityIds[newRealityId] = void
+			}
+
+			reality.SetModified()
+		} else {
+			if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist {
+				reality.parentRealityIds[newRealityId] = void
+
+				reality.SetModified()
+			}
+		}
+		reality.parentRealityIdsMutex.Unlock()
+	} else {
+		if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist {
+			reality.parentRealityIdsMutex.RUnlock()
+
+			reality.parentRealityIdsMutex.Lock()
+			if _, newRealityIdExist := reality.parentRealityIds[newRealityId]; !newRealityIdExist {
+				reality.parentRealityIds[newRealityId] = void
+
+				reality.SetModified()
+			}
+			reality.parentRealityIdsMutex.Unlock()
+		} else {
+			reality.parentRealityIdsMutex.RUnlock()
+		}
+	}
+}
+
 // Returns the amount of TransferOutputs in this Reality.
 func (reality *Reality) GetTransferOutputCount() uint32 {
 	return atomic.LoadUint32(&(reality.transferOutputCount))
 }
 
 // Increases (and returns) the amount of TransferOutputs in this Reality.
-func (reality *Reality) IncreaseTransferOutputCount() uint32 {
-	return atomic.AddUint32(&(reality.transferOutputCount), 1)
+func (reality *Reality) IncreaseTransferOutputCount() (transferOutputCount uint32) {
+	transferOutputCount = atomic.AddUint32(&(reality.transferOutputCount), 1)
+
+	reality.SetModified()
+
+	return
 }
 
 // Decreases (and returns) the amount of TransferOutputs in this Reality.
-func (reality *Reality) DecreaseTransferOutputCount() uint32 {
-	return atomic.AddUint32(&(reality.transferOutputCount), ^uint32(0))
+func (reality *Reality) DecreaseTransferOutputCount() (transferOutputCount uint32) {
+	transferOutputCount = atomic.AddUint32(&(reality.transferOutputCount), ^uint32(0))
+
+	reality.SetModified()
+
+	return
 }
 
 // Returns true, if this reality is an "aggregated reality" that combines multiple other realities.
@@ -136,8 +186,8 @@ func (reality *Reality) GetParentRealities() (parentRealities map[RealityId]*obj
 	return
 }
 
-// Returns a map of all parent realities that are conflicting. Aggregated realities are "transparent". They have to be
-// "released" manually when they are not needed anymore.
+// Returns a map of all parent realities that are not aggregated (aggregated realities are "transparent"). They have to
+// be "released" manually when they are not needed anymore.
 func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorage.CachedObject {
 	if !reality.IsAggregated() {
 		return reality.GetParentRealities()
@@ -150,24 +200,8 @@ func (reality *Reality) GetParentConflictRealities() map[RealityId]*objectstorag
 	}
 }
 
-// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
-func (reality *Reality) collectParentConflictRealities(parentConflictRealities map[RealityId]*objectstorage.CachedObject) {
-	for realityId, cachedParentReality := range reality.GetParentRealities() {
-		parentReality := cachedParentReality.Get().(*Reality)
-
-		if !parentReality.IsAggregated() {
-			parentConflictRealities[realityId] = cachedParentReality
-		} else {
-			parentReality.collectParentConflictRealities(parentConflictRealities)
-
-			cachedParentReality.Release()
-		}
-	}
-}
-
-// [DONE] Returns a map of all ancestor realities (up till the MAIN_REALITY). They have to manually be "released" when
-// they are not needed anymore.
+// Returns a map of all ancestor realities (up till the MAIN_REALITY). They have to manually be "released" when they are
+// not needed anymore.
 func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstorage.CachedObject) {
 	result = make(map[RealityId]*objectstorage.CachedObject, 1)
 
@@ -182,18 +216,25 @@ func (reality *Reality) GetAncestorRealities() (result map[RealityId]*objectstor
 	return
 }
 
-// [DONE] Registers the conflict set in the Reality.
+// Registers the conflict set in the Reality.
 func (reality *Reality) AddConflict(conflictSetId ConflictId) {
-	reality.conflictIdsMutex.Lock()
+	reality.conflictIdsMutex.RLock()
 	if _, exists := reality.conflictIds[conflictSetId]; !exists {
-		reality.conflictIds[conflictSetId] = void
+		reality.conflictIdsMutex.RUnlock()
 
-		reality.SetModified()
+		reality.conflictIdsMutex.Lock()
+		if _, exists := reality.conflictIds[conflictSetId]; !exists {
+			reality.conflictIds[conflictSetId] = void
+
+			reality.SetModified()
+		}
+		reality.conflictIdsMutex.Unlock()
+	} else {
+		reality.conflictIdsMutex.RUnlock()
 	}
-	reality.conflictIdsMutex.Unlock()
 }
 
-// [DONE] Creates a new sub Reality and "stores" it. It has to manually be "released" when it is not needed anymore.
+// Creates a new sub Reality and "stores" it. It has to manually be "released" when it is not needed anymore.
 func (reality *Reality) CreateReality(id RealityId) *objectstorage.CachedObject {
 	newReality := newReality(id, reality.id)
 	newReality.ledgerState = reality.ledgerState
@@ -201,12 +242,34 @@ func (reality *Reality) CreateReality(id RealityId) *objectstorage.CachedObject
 	return reality.ledgerState.realities.Store(newReality)
 }
 
+// Books a transfer into this reality (wrapper for the private bookTransfer function).
 func (reality *Reality) BookTransfer(transfer *Transfer) (err error) {
 	err = reality.bookTransfer(transfer.GetHash(), reality.ledgerState.getTransferInputs(transfer), transfer.GetOutputs())
 
 	return
 }
 
+// Creates a string representation of this Reality.
+func (reality *Reality) String() (result string) {
+	reality.parentRealityIdsMutex.RLock()
+	parentRealities := make([]string, len(reality.parentRealityIds))
+	i := 0
+	for parentRealityId := range reality.parentRealityIds {
+		parentRealities[i] = parentRealityId.String()
+
+		i++
+	}
+	reality.parentRealityIdsMutex.RUnlock()
+
+	result = stringify.Struct("Reality",
+		stringify.StructField("id", reality.GetId().String()),
+		stringify.StructField("parentRealities", parentRealities),
+	)
+
+	return
+}
+
+// Books a transfer into this reality (contains the dispatcher for the actual tasks).
 func (reality *Reality) bookTransfer(transferHash TransferHash, inputs objectstorage.CachedObjects, outputs map[AddressHash][]*ColoredBalance) (err error) {
 	if err = reality.verifyTransfer(inputs, outputs); err != nil {
 		return
@@ -217,31 +280,8 @@ func (reality *Reality) bookTransfer(transferHash TransferHash, inputs objectsto
 		return
 	}
 
-	if len(conflicts) >= 1 {
-		targetRealityId := transferHash.ToRealityId()
-
-		reality.CreateReality(targetRealityId).Consume(func(object objectstorage.StorableObject) {
-			targetReality := object.(*Reality)
-
-			for _, cachedConflictSet := range conflicts {
-				conflictSet := cachedConflictSet.Get().(*Conflict)
-
-				conflictSet.AddReality(targetRealityId)
-				targetReality.AddConflict(conflictSet.GetId())
-			}
-
-			for addressHash, coloredBalances := range outputs {
-				if err = targetReality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...)); err != nil {
-					return
-				}
-			}
-		})
-	} else {
-		for addressHash, coloredBalances := range outputs {
-			if err = reality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...)); err != nil {
-				return
-			}
-		}
+	if err = reality.createTransferOutputs(transferHash, outputs, conflicts); err != nil {
+		return
 	}
 
 	conflicts.Release()
@@ -250,7 +290,7 @@ func (reality *Reality) bookTransfer(transferHash TransferHash, inputs objectsto
 	return
 }
 
-// Verifies the transfer and checks if it is valid (spends existing funds + the net balance is 0).
+// Internal utility function that verifies the transfer and checks if it is valid (inputs exist + the net balance is 0).
 func (reality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, outputs map[AddressHash][]*ColoredBalance) error {
 	totalColoredBalances := make(map[Color]uint64)
 
@@ -289,7 +329,8 @@ func (reality *Reality) verifyTransfer(inputs []*objectstorage.CachedObject, out
 	return nil
 }
 
-// Marks the consumed inputs as spent and returns the corresponding Conflict if the inputs have been consumed before.
+// Internal utility function that marks the consumed inputs as spent and returns the corresponding conflicts if the
+// inputs have been consumed before.
 func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transferHash TransferHash, outputs map[AddressHash][]*ColoredBalance) (conflicts objectstorage.CachedObjects, err error) {
 	conflicts = make(objectstorage.CachedObjects, 0)
 
@@ -301,7 +342,7 @@ func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transf
 
 			return
 		} else if consumersToElevate != nil {
-			if conflict, conflictErr := reality.retrieveConflictForConflictingInput(consumedInput, consumersToElevate); conflictErr != nil {
+			if conflict, conflictErr := reality.processConflictingInput(consumedInput, consumersToElevate); conflictErr != nil {
 				err = conflictErr
 
 				return
@@ -314,18 +355,73 @@ func (reality *Reality) consumeInputs(inputs objectstorage.CachedObjects, transf
 	return
 }
 
-func (reality *Reality) retrieveConflictForConflictingInput(input *TransferOutput, consumersToElevate map[TransferHash][]AddressHash) (conflict *objectstorage.CachedObject, err error) {
-	conflictSetId := NewConflictSetId(input.GetTransferHash(), input.GetAddressHash())
+// Private utility function that creates the transfer outputs in the ledger.
+//
+// If the inputs have been used before and we consequently have a non-empty list of conflicts, we first create a new
+// reality for the inputs and then book the transfer outputs into the correct reality.
+func (reality *Reality) createTransferOutputs(transferHash TransferHash, outputs map[AddressHash][]*ColoredBalance, conflicts objectstorage.CachedObjects) (err error) {
+	if len(conflicts) >= 1 {
+		targetRealityId := transferHash.ToRealityId()
+
+		reality.CreateReality(targetRealityId).Consume(func(object objectstorage.StorableObject) {
+			targetReality := object.(*Reality)
+
+			for _, cachedConflictSet := range conflicts {
+				conflictSet := cachedConflictSet.Get().(*Conflict)
+
+				conflictSet.AddReality(targetRealityId)
+				targetReality.AddConflict(conflictSet.GetId())
+			}
+
+			for addressHash, coloredBalances := range outputs {
+				if err = targetReality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...)); err != nil {
+					return
+				}
+			}
+		})
+	} else {
+		for addressHash, coloredBalances := range outputs {
+			if err = reality.bookTransferOutput(NewTransferOutput(reality.ledgerState, emptyRealityId, transferHash, addressHash, coloredBalances...)); err != nil {
+				return
+			}
+		}
+	}
+
+	return
+}
+
+// Utility function that collects all non-aggregated parent realities. It is used by GetParentConflictRealities and
+// prevents us from having to allocate multiple maps during recursion.
+func (reality *Reality) collectParentConflictRealities(parentConflictRealities map[RealityId]*objectstorage.CachedObject) {
+	for realityId, cachedParentReality := range reality.GetParentRealities() {
+		parentReality := cachedParentReality.Get().(*Reality)
+
+		if !parentReality.IsAggregated() {
+			parentConflictRealities[realityId] = cachedParentReality
+		} else {
+			parentReality.collectParentConflictRealities(parentConflictRealities)
+
+			cachedParentReality.Release()
+		}
+	}
+}
+
+// Utility function that processes a conflicting input by retrieving the corresponding conflict.
+// If there is a non-empty list of consumers to elevate, we elevate them.
+func (reality *Reality) processConflictingInput(input *TransferOutput, consumersToElevate map[TransferHash][]AddressHash) (conflict *objectstorage.CachedObject, err error) {
+	conflictId := NewConflictId(input.GetTransferHash(), input.GetAddressHash())
 
 	if len(consumersToElevate) >= 1 {
-		newConflict := newConflictSet(conflictSetId)
+		newConflict := newConflictSet(conflictId)
 		newConflict.ledgerState = reality.ledgerState
 
 		conflict = reality.ledgerState.conflictSets.Store(newConflict)
 
-		err = reality.createRealityForConsumerOfConflictingInput(consumersToElevate, conflict.Get().(*Conflict))
+		err = reality.createRealityForPreviouslyUnconflictingConsumers(consumersToElevate, conflict.Get().(*Conflict))
 	} else {
-		if conflict, err = reality.ledgerState.conflictSets.Load(conflictSetId[:]); err == nil {
+		if conflict, err = reality.ledgerState.conflictSets.Load(conflictId[:]); err != nil {
+			return
+		} else {
 			conflict.Get().(*Conflict).ledgerState = reality.ledgerState
 		}
 	}
@@ -334,14 +430,13 @@ func (reality *Reality) retrieveConflictForConflictingInput(input *TransferOutpu
 }
 
 // Creates a Reality for the consumers of the conflicting inputs and registers it as part of the corresponding Conflict.
-func (reality *Reality) createRealityForConsumerOfConflictingInput(consumersOfConflictingInput map[TransferHash][]AddressHash, conflict *Conflict) (err error) {
+func (reality *Reality) createRealityForPreviouslyUnconflictingConsumers(consumersOfConflictingInput map[TransferHash][]AddressHash, conflict *Conflict) (err error) {
 	for transferHash, addressHashes := range consumersOfConflictingInput {
-		var elevatedRealityId = transferHash.ToRealityId()
-		var realityIsNew bool
-		var cachedElevatedReality *objectstorage.CachedObject
+		elevatedRealityId := transferHash.ToRealityId()
 
 		// Retrieve the Reality for this Transfer or create one if no Reality exists, yet.
-		if cachedElevatedReality, err = reality.ledgerState.realities.ComputeIfAbsent(elevatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) {
+		var realityIsNew bool
+		if cachedElevatedReality, realityErr := reality.ledgerState.realities.ComputeIfAbsent(elevatedRealityId[:], func(key []byte) (object objectstorage.StorableObject, e error) {
 			newReality := newReality(elevatedRealityId, reality.id)
 			newReality.ledgerState = reality.ledgerState
 
@@ -351,7 +446,9 @@ func (reality *Reality) createRealityForConsumerOfConflictingInput(consumersOfCo
 			realityIsNew = true
 
 			return newReality, nil
-		}); err == nil {
+		}); realityErr != nil {
+			err = realityErr
+		} else {
 			cachedElevatedReality.Consume(func(object objectstorage.StorableObject) {
 				elevatedReality := object.(*Reality)
 
@@ -377,40 +474,39 @@ func (reality *Reality) createRealityForConsumerOfConflictingInput(consumersOfCo
 	return
 }
 
+// Private utility function that elevates a transfer output to the given reality.
 func (reality *Reality) elevateTransferOutput(transferOutputReference *TransferOutputReference, newReality *Reality) (err error) {
-	cachedTransferOutputToElevate := reality.ledgerState.GetTransferOutput(transferOutputReference)
-	if !cachedTransferOutputToElevate.Exists() {
-		return errors.New("could not find TransferOutput to elevate")
-	}
-
-	cachedTransferOutputToElevate.Consume(func(object objectstorage.StorableObject) {
-		transferOutputToElevate := object.(*TransferOutput)
-
-		transferOutputToElevate.SetModified()
+	if cachedTransferOutputToElevate := reality.ledgerState.GetTransferOutput(transferOutputReference); !cachedTransferOutputToElevate.Exists() {
+		err = errors.New("could not find TransferOutput to elevate")
+	} else {
+		cachedTransferOutputToElevate.Consume(func(object objectstorage.StorableObject) {
+			transferOutputToElevate := object.(*TransferOutput)
 
-		if transferOutputToElevate.GetRealityId() == reality.id {
-			err = reality.elevateTransferOutputOfCurrentReality(transferOutputToElevate, newReality)
-		} else {
-			reality.ledgerState.GetReality(transferOutputToElevate.GetRealityId()).Consume(func(nestedReality objectstorage.StorableObject) {
-				err = nestedReality.(*Reality).elevateTransferOutputOfNestedReality(transferOutputToElevate, reality.id, newReality.id)
-			})
-		}
-	})
+			if currentTransferOutputRealityId := transferOutputToElevate.GetRealityId(); currentTransferOutputRealityId == reality.GetId() {
+				err = reality.elevateTransferOutputOfCurrentReality(transferOutputToElevate, newReality)
+			} else if cachedNestedReality := reality.ledgerState.GetReality(currentTransferOutputRealityId); !cachedNestedReality.Exists() {
+				err = errors.New("could not find nested reality to elevate TransferOutput")
+			} else {
+				cachedNestedReality.Consume(func(nestedReality objectstorage.StorableObject) {
+					err = nestedReality.(*Reality).elevateTransferOutputOfNestedReality(transferOutputToElevate, reality.GetId(), newReality.GetId())
+				})
+			}
+		})
+	}
 
 	return
 }
 
+// Private utility function that elevates the transfer output from the current reality to the new reality.
 func (reality *Reality) elevateTransferOutputOfCurrentReality(transferOutput *TransferOutput, newReality *Reality) (err error) {
-	if err = newReality.bookTransferOutput(transferOutput); err != nil {
-		return
-	}
-
-	for transferHash, addresses := range transferOutput.GetConsumers() {
-		for _, addressHash := range addresses {
-			if elevateErr := reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), newReality); elevateErr != nil {
-				err = elevateErr
+	if err = newReality.bookTransferOutput(transferOutput); err == nil {
+		for transferHash, addresses := range transferOutput.GetConsumers() {
+			for _, addressHash := range addresses {
+				if elevateErr := reality.elevateTransferOutput(NewTransferOutputReference(transferHash, addressHash), newReality); elevateErr != nil {
+					err = elevateErr
 
-				return
+					return
+				}
 			}
 		}
 	}
@@ -418,24 +514,19 @@ func (reality *Reality) elevateTransferOutputOfCurrentReality(transferOutput *Tr
 	return
 }
 
+// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
 func (reality *Reality) elevateTransferOutputOfNestedReality(transferOutput *TransferOutput, oldParentRealityId RealityId, newParentRealityId RealityId) (err error) {
 	if !reality.IsAggregated() {
-		reality.parentRealityIdsMutex.Lock()
-		reality.parentRealityIds.Remove(oldParentRealityId).Add(newParentRealityId)
-		reality.parentRealityIdsMutex.Unlock()
+		reality.replaceParentReality(oldParentRealityId, newParentRealityId)
+	} else {
+		reality.ledgerState.AggregateRealities(reality.GetParentRealityIds().Remove(oldParentRealityId).Add(newParentRealityId).ToList()...).Consume(func(newAggregatedReality objectstorage.StorableObject) {
+			newAggregatedReality.Persist()
 
-		return
+			err = reality.elevateTransferOutputOfCurrentReality(transferOutput, newAggregatedReality.(*Reality))
+		})
 	}
 
-	newParentRealities := reality.GetParentRealityIds().Remove(oldParentRealityId).Add(newParentRealityId).ToList()
-
-	reality.ledgerState.AggregateRealities(newParentRealities...).Consume(func(object objectstorage.StorableObject) {
-		object.Persist()
-		object.SetModified()
-
-		err = reality.elevateTransferOutputOfCurrentReality(transferOutput, object.(*Reality))
-	})
-
 	return
 }
 
@@ -464,7 +555,7 @@ func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err
 			reality.ledgerState.GetReality(transferOutputRealityId).Consume(func(object objectstorage.StorableObject) {
 				// decrease transferOutputCount and remove reality if it is empty
 				if object.(*Reality).DecreaseTransferOutputCount() == 0 {
-					//reality.ledgerState.realities.Delete(transferOutputRealityId[:])
+					// delete reality if empty
 				}
 			})
 
@@ -483,24 +574,3 @@ func (reality *Reality) bookTransferOutput(transferOutput *TransferOutput) (err
 
 	return
 }
-
-func (reality *Reality) String() (result string) {
-	reality.parentRealityIdsMutex.RLock()
-
-	parentRealities := make([]string, len(reality.parentRealityIds))
-	i := 0
-	for parentRealityId := range reality.parentRealityIds {
-		parentRealities[i] = parentRealityId.String()
-
-		i++
-	}
-
-	result = stringify.Struct("Reality",
-		stringify.StructField("id", reality.id.String()),
-		stringify.StructField("parentRealities", parentRealities),
-	)
-
-	reality.parentRealityIdsMutex.RUnlock()
-
-	return
-}
diff --git a/packages/ledgerstate/transfer_output.go b/packages/ledgerstate/transfer_output.go
index a783ef161ff7857872f8c592bf7439f14d4f2cbb..b0a99c3125ebc9e549bbc2c7bf6689f792bced86 100644
--- a/packages/ledgerstate/transfer_output.go
+++ b/packages/ledgerstate/transfer_output.go
@@ -57,9 +57,20 @@ func (transferOutput *TransferOutput) GetAddressHash() (addressHash AddressHash)
 }
 
 func (transferOutput *TransferOutput) SetRealityId(realityId RealityId) {
-	transferOutput.realityIdMutex.Lock()
-	transferOutput.realityId = realityId
-	transferOutput.realityIdMutex.Unlock()
+	transferOutput.realityIdMutex.RLock()
+	if transferOutput.realityId != realityId {
+		transferOutput.realityIdMutex.RUnlock()
+
+		transferOutput.realityIdMutex.Lock()
+		if transferOutput.realityId != realityId {
+			transferOutput.realityId = realityId
+
+			transferOutput.SetModified()
+		}
+		transferOutput.realityIdMutex.Unlock()
+	} else {
+		transferOutput.realityIdMutex.RUnlock()
+	}
 }
 
 func (transferOutput *TransferOutput) GetBalances() []*ColoredBalance {