     mutating func sendWindowUpdate(streamID: HTTP2StreamID, windowIncrement: UInt32) -> StateMachineResultWithEffect {
         switch self.state {
         case .prefaceSent(var state):
-            let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
-            self.state = .prefaceSent(state)
-            return result
+            return self.avoidingStateMachineCoW { newState in
+                let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
+                newState = .prefaceSent(state)
+                return result
+            }
 
         case .active(var state):
-            let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
-            self.state = .active(state)
-            return result
+            return self.avoidingStateMachineCoW { newState in
+                let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
+                newState = .active(state)
+                return result
+            }
 
         case .quiescingPrefaceSent(var state):
-            let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
-            self.state = .quiescingPrefaceSent(state)
-            return result
+            return self.avoidingStateMachineCoW { newState in
+                let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
+                newState = .quiescingPrefaceSent(state)
+                return result
+            }
 
         case .locallyQuiesced(var state):
-            let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
-            self.state = .locallyQuiesced(state)
-            return result
+            return self.avoidingStateMachineCoW { newState in
+                let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
+                newState = .locallyQuiesced(state)
+                return result
+            }
 
         case .remotelyQuiesced(var state):
-            let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
-            self.state = .remotelyQuiesced(state)
-            return result
+            return self.avoidingStateMachineCoW { newState in
+                let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
+                newState = .remotelyQuiesced(state)
+                return result
+            }
 
         case .bothQuiescing(var state):
-            let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
-            self.state = .bothQuiescing(state)
-            return result
+            return self.avoidingStateMachineCoW { newState in
+                let result = state.sendWindowUpdate(streamID: streamID, increment: windowIncrement)
+                newState = .bothQuiescing(state)
+                return result
+            }
 
         case .idle, .prefaceReceived, .quiescingPrefaceReceived:
             // We're waiting for the preface.

    mutating func receiveWindowUpdate(streamID: HTTP2StreamID, windowIncrement: UInt32) -> StateMachineResultWithEffect {
        switch self.state {
        case .prefaceReceived(var state):
            let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement)
            self.state = .prefaceReceived(state)
            return result

        case .active(var state):
            let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement)
            self.state = .active(state)
            return result

        case .quiescingPrefaceReceived(var state):
            let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement)
            self.state = .quiescingPrefaceReceived(state)
            return result

        case .locallyQuiesced(var state):
            let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement)
            self.state = .locallyQuiesced(state)
            return result

        case .remotelyQuiesced(var state):
            let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement)
            self.state = .remotelyQuiesced(state)
            return result

        case .bothQuiescing(var state):
            let result = state.receiveWindowUpdate(streamID: streamID, increment: windowIncrement)
            self.state = .bothQuiescing(state)
            return result

        case .idle, .prefaceSent, .quiescingPrefaceSent:
            // We're waiting for the preface.


        case .fullyQuiesced:
            return .init(result: .connectionError(underlyingError: NIOHTTP2Errors.IOOnClosedConnection(), type: .protocolError), effect: nil)

        case .modifying:
            preconditionFailure("Must not be left in modifying state")
        }
    }

