// including modifying the shared game state
        public void ToHigherLayer(byte[] buffer, long offset, long size, Action <byte[]> otherwise)
        {
            foreach (byte[] frame in _framingProtocol.FromLowLayerToHere(buffer.Skip((int)offset).Take((int)size).ToArray()))
            {
                // string rawString = Encoding.UTF8.GetString(buffer, (int)offset, (int)size);
                string rawString = Encoding.UTF8.GetString(frame);
                Console.WriteLine(rawString);
                try
                {
                    // RemoteInstruction instruction = JsonSerializer.Deserialize<RemoteInstruction>(rawString);
                    RemoteInstruction instruction = JsonSerializer.Deserialize <RemoteInstruction>(frame);
                    switch (instruction.Type)
                    {
                    case RemoteInstructionType.ChessChange:
                        // _gameState.Board.AddChessChange((ChessChange)instruction);
                        _gameState.AddChessChange(JsonSerializer.Deserialize <ChessChange>(frame));
                        break;

                    case RemoteInstructionType.ChessMove:
                        // _gameState.Board.AddChessMove((ChessMove)instruction);
                        _gameState.AddChessMove(JsonSerializer.Deserialize <ChessMove>(frame));
                        break;

                    case RemoteInstructionType.UndoChessBoard:
                        _gameState.UndoHistory();
                        break;

                    case RemoteInstructionType.RedoChessBoard:
                        _gameState.RedoHistory();
                        break;

                    default:
                        otherwise?.Invoke(frame);
                        break;
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }