/// <summary>
        /// Add data to the image archive
        /// </summary>
        /// <param name="Key"></param>
        /// <param name="Bytes"></param>
        public void Add(string Key, byte[] Bytes)
        {
            lock (this)
            {
                if (this.archiveIndexKey.ContainsKey(Key))
                {
                    throw new Exception("Key already exists: " + Key);
                }
                MD5Checksum       md5 = MD5Checksum.Generate(Bytes);
                ImageArchiveEntry entry;

                if (this.archiveIndexMD5.ContainsKey(md5))
                {
                    ImageArchiveEntry oldiae = this.archiveIndexMD5[md5];
                    entry = new ImageArchiveEntry
                    {
                        Key = Key,
                        BytePositionStart = oldiae.BytePositionStart,
                        Size = oldiae.Size,
                        MD5  = md5
                    };
                }
                else
                {
                    entry = new ImageArchiveEntry
                    {
                        Key = Key,
                        BytePositionStart = this.archiveFile.Position,
                        Size = Bytes.Length,
                        MD5  = md5
                    };
                    //Add the entry to the MD5 index.
                    this.archiveIndexMD5.Add(md5, entry);
                    //Add to memorystream
                    this.archiveFile.Write(Bytes, 0, Bytes.Length);
                }
                //Add to key index
                this.archiveIndexKey.Add(Key, entry);
            }
        }
        /// <summary>
        /// Remove the specific key from index.
        /// </summary>
        /// <param name="Key"></param>
        public void Remove(string Key)
        {
            lock (this)
            {
                if (!this.archiveIndexKey.ContainsKey(Key))
                {
                    throw new Exception("Key not found: " + Key);
                }

                ImageArchiveEntry removedEntry = this.archiveIndexKey[Key];
                this.archiveIndexKey.Remove(Key);
                //Browse through each ImageArchiveEntry we have, to find out if we can remove this image from the stream.
                bool removeStream = true;
                foreach (KeyValuePair <string, ImageArchiveEntry> kvp in this.archiveIndexKey)
                {
                    if (kvp.Value.MD5 == removedEntry.MD5)
                    {
                        removeStream = false;
                        //Replace representation in MD5 index
                        this.archiveIndexMD5[removedEntry.MD5] = kvp.Value;
                        break;
                    }
                }

                //If we can remove the stream
                if (removeStream)
                {
                    //Adjust position mapping of entries after removed entry, but only if the removed entry isn't the last entry.
                    if ((removedEntry.BytePositionStart + removedEntry.Size) == this.archiveFile.Length)
                    {
                        foreach (KeyValuePair <string, ImageArchiveEntry> kvp in this.archiveIndexKey)
                        {
                            if (kvp.Value.BytePositionStart > removedEntry.BytePositionStart)
                            {
                                kvp.Value.BytePositionStart -= removedEntry.Size;
                            }
                        }
                    }

                    //Remove this part of the stream.
                    MemoryStream ms = new MemoryStream();
                    byte[]       buffer;
                    //Part before removed entry.
                    if (removedEntry.BytePositionStart > 0)
                    {
                        buffer = new byte[removedEntry.BytePositionStart];
                        this.archiveFile.Read(buffer, 0, (int)removedEntry.BytePositionStart);
                        ms.Write(buffer, 0, buffer.Length);
                    }

                    //Part after removed entry.
                    if ((removedEntry.BytePositionStart + removedEntry.Size) <= this.archiveFile.Length)
                    {
                        int startpos = (int)removedEntry.BytePositionStart + removedEntry.Size;
                        int length   = (int)this.archiveFile.Length - startpos;
                        buffer = new byte[length];
                        this.archiveFile.Read(buffer, startpos, length);
                        ms.Write(buffer, 0, buffer.Length);
                    }
                }
            }
        }