public bool Read(Stream stream)
        {
            try
            {
                BinaryReader reader = new BinaryReader(stream);

                // read header
                ulong magicNumber = reader.ReadUInt64();
                byte formatVersion = reader.ReadByte();
                byte[] md5hash = reader.ReadBytes(16);
                uint reserved = reader.ReadUInt32();
                uint fileLength = reader.ReadUInt32();
                uint offsetToContent = reader.ReadUInt32();
                uint numContentItems = reader.ReadUInt32();

                // Signing
                CheckSignature(stream, reader, offsetToContent);

                // Construct BinaryReadInfo
                BinaryReadInfo readInfo = new BinaryReadInfo()
                {
                     FormatVersion = formatVersion,
                     IsSigned = isSigned,
                     IsSignatureValid = validSignature,
                     IsCertificateTrusted = certificateTrusted
                };

                var componentDescriptions = new List<ComponentResource>();

                // Load content
                for (uint contentCounter = 0; contentCounter < numContentItems; contentCounter++)
                {
                    var itemType = (BinaryConstants.ContentItemType)reader.ReadUInt16();

                    if (itemType == BinaryConstants.ContentItemType.Resource)
                    {
                        var item = new BinaryResource();
                        item.Read(reader, readInfo);
                        Items.Add(item);
                        Resources.Add(item);
                    }
                    else if (itemType == BinaryConstants.ContentItemType.Component)
                    {
                        var item = new ComponentResource();
                        item.Read(reader, readInfo);
                        Items.Add(item);
                        componentDescriptions.Add(item);
                    }
                    else
                    {
                        // Unknown item type
                        continue;
                    }
                }

                // Process images
                Dictionary<uint, MultiResolutionImage> images = new Dictionary<uint, MultiResolutionImage>();
                foreach(var resource in Resources)
                {
                    if (resource.ResourceType == BinaryResourceType.BitmapImage
                        || resource.ResourceType == BinaryResourceType.JPEGImage
                        || resource.ResourceType == BinaryResourceType.PNGImage
                        || true)
                    {
                        if (!images.ContainsKey(resource.ID))
                            images.Add(resource.ID, new MultiResolutionImage());

                        images[resource.ID].Add(new SingleResolutionImage()
                        {
                            MimeType = BinaryConstants.ResourceMimeTypeToString((uint)resource.ResourceType),
                            Data = resource.Buffer
                        });
                    }
                }

                // Add component descriptions
                foreach(var componentDescription in componentDescriptions)
                {
                    componentDescription.SetIcons(images);
                    ComponentDescriptions.Add(componentDescription.ComponentDescription);
                }

                return true;
            }
            catch (Exception)
            {
                // Invalid binary file
                return false;
            }
        }
        public bool Read(Stream stream)
        {
            try
            {
                BinaryReader reader = new BinaryReader(stream);

                // read header
                ulong  magicNumber     = reader.ReadUInt64();
                byte   formatVersion   = reader.ReadByte();
                byte[] md5hash         = reader.ReadBytes(16);
                uint   reserved        = reader.ReadUInt32();
                uint   fileLength      = reader.ReadUInt32();
                uint   offsetToContent = reader.ReadUInt32();
                uint   numContentItems = reader.ReadUInt32();

                // Signing
                CheckSignature(stream, reader, offsetToContent);

                // Construct BinaryReadInfo
                BinaryReadInfo readInfo = new BinaryReadInfo()
                {
                    FormatVersion        = formatVersion,
                    IsSigned             = isSigned,
                    IsSignatureValid     = validSignature,
                    IsCertificateTrusted = certificateTrusted
                };

                var componentDescriptions = new List <ComponentResource>();

                // Load content
                for (uint contentCounter = 0; contentCounter < numContentItems; contentCounter++)
                {
                    var itemType = (BinaryConstants.ContentItemType)reader.ReadUInt16();

                    if (itemType == BinaryConstants.ContentItemType.Resource)
                    {
                        var item = new BinaryResource();
                        item.Read(reader, readInfo);
                        Items.Add(item);
                        Resources.Add(item);
                    }
                    else if (itemType == BinaryConstants.ContentItemType.Component)
                    {
                        var item = new ComponentResource();
                        item.Read(reader, readInfo);
                        Items.Add(item);
                        componentDescriptions.Add(item);
                    }
                    else
                    {
                        // Unknown item type
                        continue;
                    }
                }

                // Process images
                Dictionary <uint, MultiResolutionImage> images = new Dictionary <uint, MultiResolutionImage>();
                foreach (var resource in Resources)
                {
                    if (resource.ResourceType == BinaryResourceType.BitmapImage ||
                        resource.ResourceType == BinaryResourceType.JPEGImage ||
                        resource.ResourceType == BinaryResourceType.PNGImage ||
                        true)
                    {
                        if (!images.ContainsKey(resource.ID))
                        {
                            images.Add(resource.ID, new MultiResolutionImage());
                        }

                        images[resource.ID].Add(new SingleResolutionImage()
                        {
                            MimeType = BinaryConstants.ResourceMimeTypeToString((uint)resource.ResourceType),
                            Data     = resource.Buffer
                        });
                    }
                }

                // Add component descriptions
                foreach (var componentDescription in componentDescriptions)
                {
                    componentDescription.SetIcons(images);
                    ComponentDescriptions.Add(componentDescription.ComponentDescription);
                }

                return(true);
            }
            catch (Exception)
            {
                // Invalid binary file
                return(false);
            }
        }