private void ConvertBytesToMessage(byte[] header, byte[] data, int pos)
        {
            if (header == null || header.Length == 0)
            {
                header = data;
            }

            Version = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 0, 2));

            if (Version != _version)
            {
                // TODO: incompatible version
                throw new Exception("Incompatible version");
            }

            int size = header[2];

            if (size > 0)
            {
                Id   = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos += size;
            }

            size = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 3, 5));
            if (size > 0)
            {
                Tag  = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos += size;
            }

            size = header[5];
            if (size > 0)
            {
                GroupId = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos    += size;
            }

            size = header[6];
            if (size > 0)
            {
                SequenceNumber = ByteUtils.BytesToInteger(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos           += size;
            }

            size = header[7];
            if (size > 0)
            {
                SequenceTotal = ByteUtils.BytesToInteger(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos          += size;
            }

            size = header[8];
            if (size > 0)
            {
                Priority = (sbyte)data[pos];
                pos     += size;
            }

            size = header[9];
            if (size > 0)
            {
                Timestamp = ByteUtils.BytesToLong(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos      += size;
            }

            size = header[10];
            if (size > 0)
            {
                Publisher = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos      += size;
            }

            size = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 11, 13));
            if (size > 0)
            {
                AuthId = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos   += size;
            }

            size = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 13, 15));
            if (size > 0)
            {
                AuthGroup = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos      += size;
            }

            size = header[15];
            if (size > 0)
            {
                ChainPosition = ByteUtils.BytesToLong(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos          += size;
            }

            size = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 16, 18));
            if (size > 0)
            {
                Hash = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos += size;
            }

            size = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 18, 20));
            if (size > 0)
            {
                PreviousHash = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos         += size;
            }

            size = ByteUtils.BytesToShort(ByteUtils.CopyOfRange(header, 20, 22));
            if (size > 0)
            {
                Nonce = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos  += size;
            }

            size = header[22];
            if (size > 0)
            {
                DifficultyTarget = ByteUtils.BytesToInteger(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos += size;
            }

            size = header[23];
            if (size > 0)
            {
                InfoType = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos     += size;
            }

            size = header[24];
            if (size > 0)
            {
                InfoFormat = StringUtils.NewString(ByteUtils.CopyOfRange(data, pos, pos + size));
                pos       += size;
            }

            size = ByteUtils.BytesToInteger(ByteUtils.CopyOfRange(header, 25, 29));
            if (size > 0)
            {
                ContextData = ByteUtils.CopyOfRange(data, pos, pos + size);
                pos        += size;
            }

            size = ByteUtils.BytesToInteger(ByteUtils.CopyOfRange(header, 29, 33));
            if (size > 0)
            {
                ContentData = ByteUtils.CopyOfRange(data, pos, pos + size);
            }
        }