/// <summary>
        /// Create a OS9 module file object.
        /// </summary>
        /// <param name="fileinfo">Directory information for this file, or <value>null</value> if no directory information is available.</param>
        /// <param name="filedata">Raw file data, including headers and payload.</param>
        /// <param name="validate">If cleared, an invalid module file can be created, i.e. header and file checksum values are not validated.</param>
        internal OS9ModuleFile(OS9FileInfo fileinfo, byte[] filedata, bool validate = true) : base(fileinfo)
        {
            if (filedata == null)
            {
                throw new ArgumentNullException("filedata");
            }
            var filename = fileinfo == null ? null : fileinfo.Name;

            if (filedata.Length < StandardModuleHeaderSize)
            {
                throw new InvalidFileException(filename, String.Format("A module file must contain a {0} byte header.  This file is only {1} bytes long.", StandardModuleHeaderSize, filedata.Length));
            }
            if (filedata[0] != 0x87 || filedata[1] != 0xcd)
            {
                throw new InvalidFileException(filename, "Module file header does not contain valid sync sequence.");
            }

            data = (byte[])filedata.Clone();

            if (ModuleSize > data.Length)
            {
                throw new InvalidFileException(filename, String.Format("The module header specifies a module size of {0} bytes but the file is only {1} bytes.", ModuleSize, data.Length));
            }

            int nameoffset = (data[4] << 8) | data[5];

            if (nameoffset > data.Length)
            {
                throw new InvalidFileException(filename, "Module filename offset is outside the file data.");
            }
            ModuleName = OS9Utils.ParseString(data, nameoffset);

            if (validate)
            {
                if (HeaderParity != CalculateHeaderParity(data, StandardModuleHeaderSize - 1))
                {
                    throw new InvalidFileException(filename, "Header parity error");
                }
                if (ModuleCRC != CalculateModuleCRC(data, ModuleSize - 3))
                {
                    throw new InvalidFileException(filename, "Invalid module CRC");
                }
            }
        }