////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Writes a ushort patch value to a stream. </summary>
        ///
        /// <param name="target">	    The target stream. </param>
        /// <param name="writeAddress">	The address to write to. </param>
        /// <param name="data">		    The data to write. </param>
        ///
        /// <returns>	true if it succeeds, false if it fails. </returns>
        private bool WriteUInt16(MemoryStream target
                                 , long writeAddress
                                 , PatchDefinition.Data data)
        {
            if ((writeAddress + 2) >= target.Length)
            {
                OnErrorOccurred("Failed to write patch data ({0}) as the data would write beyond the end of the file. Inform the developers of this.", data.ID);
                return(false);
            }

            // Try and parse the hex string
            ushort parsedValue;

            if (!Utilities.Parse.TryParseHex(data.Value, out parsedValue))
            {
                OnErrorOccurred("Failed to parse value ({0}). Inform the developers of this.", data.ID);
                return(false);
            }

            // Swap the value's endianness if required
            if (data.SwapEndian)
            {
                ushort endianSwapped = 0;

                endianSwapped |= (ushort)((parsedValue & 0xff00) >> 8);
                endianSwapped |= (ushort)((parsedValue & 0x00ff) << 8);

                parsedValue = endianSwapped;
            }

            // Write the value to the stream
            target.Seek(writeAddress, SeekOrigin.Begin);
            target.Write(BitConverter.GetBytes(parsedValue), 0, 2);
            return(true);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Writes a string patch value to a stream. </summary>
        ///
        /// <param name="target">	    The target stream. </param>
        /// <param name="writeAddress">	The address to write to. </param>
        /// <param name="data">		    The data to write. </param>
        ///
        /// <returns>	true if it succeeds, false if it fails. </returns>
        private bool WriteString(Stream target
                                 , long writeAddress
                                 , PatchDefinition.Data data)
        {
            // Default write length to the length of the string if zero
            int writeLength = data.Length;

            if (writeLength == 0)
            {
                writeLength = data.Value.Length;
            }

            // Check we are not writing out of bounds
            if ((writeAddress + writeLength) >= target.Length)
            {
                OnErrorOccurred("Failed to write patch data ({0}) as the data would write beyond the end of the file. Inform the developers of this.", data.ID);
                return(false);
            }

            // Write the strings bytes as ASCII
            var bytes = Encoding.ASCII.GetBytes(data.Value);

            target.Seek(writeAddress, SeekOrigin.Begin);
            target.Write(bytes, 0, writeLength);

            // If necessary, write a null character to terminate the string
            if (data.WriteNull)
            {
                target.WriteByte(0);
            }

            return(true);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Writes a byte array patch value to a stream. </summary>
        ///
        /// <param name="target">	    The target stream. </param>
        /// <param name="writeAddress">	The address to write to. </param>
        /// <param name="data">		    The data to write. </param>
        ///
        /// <returns>	true if it succeeds, false if it fails. </returns>
        private bool WriteBytes(Stream target
                                , long writeAddress
                                , PatchDefinition.Data data)
        {
            // Check the strings length is a multiple of two
            if (data.Value.Length % 2 != 0)
            {
                OnErrorOccurred("The length of a hex byte string ({0}) in the file patcher is odd. Inform the developers.", data.ID);
                return(false);
            }

            // Create the byte array
            byte[] bytes = null;
            try
            {
                // Convert every two characters into a byte
                bytes = Enumerable.Range(0, data.Value.Length)
                        .Where(index => (index % 2) == 0)
                        .Select(index => Convert.ToByte(data.Value.Substring(index, 2), 16))
                        .ToArray();
            }
            catch (Exception)
            {
                OnErrorOccurred("Failed to parse a byte array ({0}). Inform the developers of this.", data.ID);
                return(false);
            }

            // Default the write length to the array length if zero
            int writeLength = data.Length;

            if (writeLength == 0)
            {
                writeLength = bytes.Length;
            }

            if ((writeAddress + writeLength) >= target.Length)
            {
                OnErrorOccurred("Failed to write patch data ({0}) as the data would write beyond the end of the file. Inform the developers of this.", data.ID);
                return(false);
            }

            // Write the byte array to the stream
            target.Seek(writeAddress, SeekOrigin.Begin);
            target.Write(bytes, 0, writeLength);
            return(true);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Writes patch data to a stream. </summary>
        ///
        /// <param name="output">       The output stream. </param>
        /// <param name="address">      The write address. </param>
        /// <param name="imageBase">	The image base address. </param>
        /// <param name="data">			The data to write. </param>
        ///
        /// <returns>	true if it succeeds, false if it fails. </returns>
        private bool WriteData(MemoryStream output, uint address, int imageBase, PatchDefinition.Data data)
        {
            // Calculate the byte address and move to it
            long writeAddress = address - imageBase;

            if (writeAddress >= output.Length)
            {
                OnErrorOccurred("Failed to write patch data ({0}) as the pointer is beyond the end of the file. Inform the developers of this.", data.ID);
                return(false);
            }
            output.Seek(writeAddress, SeekOrigin.Begin);

            bool success = false;

            switch (data.Type)
            {
            case PatchDefinition.ValueType.String:
                success = WriteString(output, writeAddress, data);
                break;

            case PatchDefinition.ValueType.UInteger32:
                success = WriteUInt32(output, writeAddress, data);
                break;

            case PatchDefinition.ValueType.UInteger16:
                success = WriteUInt16(output, writeAddress, data);
                break;

            case PatchDefinition.ValueType.Byte:
                success = WriteByte(output, writeAddress, data);
                break;

            case PatchDefinition.ValueType.Bytes:
                success = WriteBytes(output, writeAddress, data);
                break;
            }

            return(success);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>	Writes a byte patch value to a stream. </summary>
        ///
        /// <param name="target">	    The target stream. </param>
        /// <param name="writeAddress">	The address to write to. </param>
        /// <param name="data">		    The data to write. </param>
        ///
        /// <returns>	true if it succeeds, false if it fails. </returns>
        private bool WriteByte(MemoryStream target
                               , long writeAddress
                               , PatchDefinition.Data data)
        {
            if ((writeAddress + 1) >= target.Length)
            {
                OnErrorOccurred("Failed to write patch data ({0}) as the data would write beyond the end of the file. Inform the developers of this.", data.ID);
                return(false);
            }

            // Try and parse the hex string
            byte parsedValue;

            if (!Utilities.Parse.TryParseHex(data.Value, out parsedValue))
            {
                OnErrorOccurred("Failed to parse value ({0}). Inform the developers of this.", data.ID);
                return(false);
            }

            // Write the value to the stream
            target.Seek(writeAddress, SeekOrigin.Begin);
            target.WriteByte(parsedValue);
            return(true);
        }