/// <summary>
        ///     Generates the bytes.
        /// </summary>
        /// <returns>System.Byte[].</returns>
        internal override byte[] GenerateBytes()
        {
            byte flags = 0;

            if (Properties.IsSupplyMutable)
            {
                flags += 1;
            }

            if (Properties.IsTransferable)
            {
                flags += 2;
            }

            if (Properties.IsLevyMutable)
            {
                flags += 4;
            }

            var builder = new FlatBufferBuilder(1);


            IList <KeyValuePair <MosaicPropertyId, ulong> > propertyList = new List <KeyValuePair <MosaicPropertyId, ulong> >();

            var duration = Properties.Duration;

            if (duration > 0)
            {
                propertyList.Add(new KeyValuePair <MosaicPropertyId, ulong>(MosaicPropertyId.DURATION, duration));
            }

            var mosaicProperties = new Offset <MosaicProperty> [propertyList.Count];

            for (var index = 0; index < propertyList.Count; index++)
            {
                KeyValuePair <MosaicPropertyId, ulong> mp = propertyList[index];
                var valueOffset = MosaicProperty.CreateValueVector(builder, mp.Value.ToUInt8Array());
                MosaicProperty.StartMosaicProperty(builder);
                MosaicProperty.AddMosaicPropertyId(builder, mp.Key.GetValueInByte());
                MosaicProperty.AddValue(builder, valueOffset);
                mosaicProperties[index] = MosaicProperty.EndMosaicProperty(builder);
            }



            // create vectors
            var signatureVector = MosaicDefinitionTransactionBuffer.CreateSignatureVector(builder, new byte[64]);
            var signerVector    = MosaicDefinitionTransactionBuffer.CreateSignerVector(builder, GetSigner());
            var feeVector       = MosaicDefinitionTransactionBuffer.CreateMaxFeeVector(builder, MaxFee?.ToUInt8Array());
            var deadlineVector  =
                MosaicDefinitionTransactionBuffer.CreateDeadlineVector(builder, Deadline.Ticks.ToUInt8Array());
            var mosaicIdVector =
                MosaicDefinitionTransactionBuffer.CreateMosaicIdVector(builder, MosaicId.Id.ToUInt8Array());
            var optionalPropertiesVector =
                MosaicDefinitionTransactionBuffer.CreateOptionalPropertiesVector(builder, mosaicProperties);

            // create version
            var version = (uint)GetTxVersionSerialization();

            // header + nonce + id + numOptProp + flags + divisibility + (id + value)*numOptProp
            var totalSize = GetSerializedSize(); //HEADER_SIZE + 4 + 8 + 1 + 1 + 1 + (1 + 8) * mosaicProperties.Length;

            // add vectors to buffer
            MosaicDefinitionTransactionBuffer.StartMosaicDefinitionTransactionBuffer(builder);
            MosaicDefinitionTransactionBuffer.AddSize(builder, (uint)totalSize);
            MosaicDefinitionTransactionBuffer.AddSignature(builder, signatureVector);
            MosaicDefinitionTransactionBuffer.AddSigner(builder, signerVector);
            MosaicDefinitionTransactionBuffer.AddVersion(builder, (uint)version);
            MosaicDefinitionTransactionBuffer.AddType(builder, TransactionType.GetValue());
            MosaicDefinitionTransactionBuffer.AddMaxFee(builder, feeVector);
            MosaicDefinitionTransactionBuffer.AddDeadline(builder, deadlineVector);

            MosaicDefinitionTransactionBuffer.AddMosaicNonce(builder, BitConverter.ToUInt32(MosaicNonce.Nonce, 0));
            MosaicDefinitionTransactionBuffer.AddMosaicId(builder, mosaicIdVector);
            MosaicDefinitionTransactionBuffer.AddNumOptionalProperties(builder, (byte)mosaicProperties.Length);
            MosaicDefinitionTransactionBuffer.AddFlags(builder, flags);
            MosaicDefinitionTransactionBuffer.AddDivisibility(builder, (byte)Properties.Divisibility);
            MosaicDefinitionTransactionBuffer.AddOptionalProperties(builder, optionalPropertiesVector);


            // Calculate size
            var codedMosaicDefinition = MosaicDefinitionTransactionBuffer.EndMosaicDefinitionTransactionBuffer(builder);

            builder.Finish(codedMosaicDefinition.Value);

            // validate size
            var output = new MosaicDefinitionTransactionSchema().Serialize(builder.SizedByteArray());

            if (output.Length != totalSize)
            {
                throw new SerializationException("Serialized form has incorrect length");
            }

            return(output);
        }