private void RemoveMemory()
    {
        if (memories.Count == 0)
        {
            return;
        }

        MemoryTypes priorMemory = memories.Dequeue();

        if (priorMemory == MemoryTypes.None)
        {
            return;
        }
        else
        {
            switch (priorMemory)
            {
            case MemoryTypes.Pitfall:
                ApplyPitfallMemory(false);
                break;

            case MemoryTypes.PitfallBoost:
                ApplyPitfallMemory(true);
                break;

            case MemoryTypes.Climb:
                ApplyClimbMemory(false);
                break;

            case MemoryTypes.ClimbBoost:
                ApplyClimbMemory(true);
                break;
            }
        }
    }
    /// <summary>
    /// Removes the prior one by default
    /// </summary>
    /// <param name="memoryToAssign"></param>
    /// <param name="remove"></param>
    private void ApplyMemory(MemoryTypes memoryToAssign, bool remove = true)
    {
        // Don't apply same type twice
        if (!memories.Contains(memoryToAssign))
        {
            Debug.Log("Applying memory " + memoryToAssign);

            // Remove prior memory
            if (remove)
            {
                RemoveMemory();
            }

            switch (memoryToAssign)
            {
            case MemoryTypes.Pitfall:
                ApplyPitfallMemory(true);
                break;

            case MemoryTypes.PitfallBoost:
                ApplyPitfallMemory(false);
                break;

            case MemoryTypes.Climb:
                ApplyClimbMemory(true);
                break;

            case MemoryTypes.ClimbBoost:
                ApplyClimbMemory(false);
                break;
            }

            // Update list
            memories.Enqueue(memoryToAssign);

            // Display memory effect in UI
            memoryCanvasController.ChangeMemory(memoryToAssign);
        }
    }
        private Int32 MatchingMemoryType(MemoryTypes mType)
        {
            Int32 res;
            switch (mType)
            {
                case MemoryTypes.Merker:
                    {
                        res = libnodave.daveFlags;
                        break;
                    }
                case MemoryTypes.Input:
                    {
                        res = libnodave.daveInputs;
                        break;
                    }
                case MemoryTypes.Output:
                    {
                        res = libnodave.daveOutputs;
                        break;
                    }
                case MemoryTypes.DataBlock:
                    {
                        res = libnodave.daveDB;
                        break;
                    }
                default:
                    {
                        res = libnodave.daveDB;
                        break;
                    }
            }

            return res;
        }
        public DateTime GetDateTime(MemoryTypes mType, int blockNum, int addressByte)
        {
            CheckStateConnection();

            Byte[] arrayBytes = new Byte[BYTEINDATETIME];
            Int32 errorCode = _daveConnection.readBytes(MatchingMemoryType(mType), blockNum, addressByte, BYTEINDATETIME,
                arrayBytes);
            if (errorCode != 0)
            {
                SendPlcException(errorCode);
            }

            return PlcDataConverter.ByteArrayToDateTime(arrayBytes);
        }
        public float GetFloat(MemoryTypes mType, int blockNum, int addressByte)
        {
            CheckStateConnection();

            Int32 errorCode = _daveConnection.readBytes(MatchingMemoryType(mType), blockNum, addressByte, BYTEINDWORD,
                null);
            if (errorCode != 0)
            {
                SendPlcException(errorCode);
            }

            return _daveConnection.getFloat();
        }
        public uint GetUInt32(MemoryTypes mType, Int32 blockNum, Int32 addressByte)
        {
            CheckStateConnection();

            Int32 errorCode = _daveConnection.readBytes(MatchingMemoryType(mType), blockNum, addressByte, BYTEINDWORD,
                null);
            if (errorCode != 0)
            {
                SendPlcException(errorCode);
            }

            return (uint) _daveConnection.getU32();
        }
        public byte[] GetBytes(MemoryTypes mType, int blockNum, int addressByte, int numOfBytes)
        {
            CheckStateConnection();

            Byte[] arrayBytes = new Byte[numOfBytes];
            Int32 errorCode = _daveConnection.readBytes(MatchingMemoryType(mType), blockNum, addressByte, numOfBytes,
                arrayBytes);
            if (errorCode != 0)
            {
                SendPlcException(errorCode);
            }

            return arrayBytes;
        }
        public Byte GetByte(MemoryTypes mType, Int32 blockNum, Int32 addressByte)
        {
            CheckStateConnection();

            Int32 errorCode = _daveConnection.readBytes(MatchingMemoryType(mType), blockNum, addressByte, BYTE, null);
            if (errorCode != 0)
            {
                SendPlcException(errorCode);
            }

            return (Byte) _daveConnection.getU8();
        }
        public Boolean GetBit(MemoryTypes mType, Int32 blockNum, Int32 addressByte, Int32 addressBit)
        {
            CheckStateConnection();

            Int32 errorCode = _daveConnection.readBytes(MatchingMemoryType(mType), blockNum, addressByte, BYTE, null);
            if (errorCode != 0)
            {
                SendPlcException(errorCode);
            }

            Int32 byteValue = _daveConnection.getU8();
            return PlcDataConverter.GetBitInByte(byteValue, addressBit);
        }