private void AddItemToCache(CachedItem item, CachePoint point)
        {
            if (_items.ContainsKey(item.Magnet.TTH))
            {
                throw new InvalidOperationException("The item is already registered");
            }

            _items.Add(item.Magnet.TTH, item);
            point.AddItem(item);
        }
        public void RegisterCachePoint(string path, long totalFreeSpace)
        {
            var point = new CachePoint
            {
                SystemPath = path,
                TotalSpace = totalFreeSpace
            };

            lock (_syncRoot)
            {
                _points.Add(point);
            }

            foreach (var filePath in Directory.EnumerateFiles(path, "*.bitfield"))
            {
                using (var fs = File.OpenRead(filePath))
                    using (var reader = new BinaryReader(fs))
                    {
                        Magnet magnet;
                        try
                        {
                            magnet = new Magnet
                            {
                                TTH      = reader.ReadString(),
                                FileName = reader.ReadString(),
                                Size     = reader.ReadInt64()
                            };
                        }
                        catch (Exception x)
                        {
                            Logger.Error("Error when loading bitfield: {0}", x.Message);
                            fs.Close();
                            File.Delete(filePath);
                            var dataFile = Path.ChangeExtension(filePath, "");
                            if (File.Exists(dataFile))
                            {
                                File.Delete(dataFile);
                            }
                            continue;
                        }


                        var segmentLength = reader.ReadInt32();
                        var bytesLength   = reader.ReadInt32();
                        var bitarray      = new BitArray(reader.ReadBytes(bytesLength));
                        bitarray.Length = DownloadItem.SegmentsCount(magnet.Size, segmentLength);

                        var item = new CachedItem(magnet, segmentLength, bitarray)
                        {
                            CachePath = Path.Combine(point.SystemPath, magnet.TTH),
                            Created   = new FileInfo(filePath).CreationTime
                        };

                        if (!LazyCacheDownload && bitarray.TrueCount() != bitarray.Count)
                        {
                            Logger.Error("Non-finished item found, removing {0}", item.CachePath);
                            fs.Close();
                            File.Delete(item.BitFileldFilePath);
                            if (File.Exists(item.CachePath))
                            {
                                File.Delete(item.CachePath);
                            }
                            continue;
                        }

                        if (File.Exists(item.CachePath))
                        {
                            lock (_syncRoot)
                            {
                                if (_items.ContainsKey(magnet.TTH))
                                {
                                    Logger.Error("Duplicate cache item found, removing {0}", item.CachePath);
                                    fs.Close();
                                    File.Delete(item.BitFileldFilePath);
                                    if (File.Exists(item.CachePath))
                                    {
                                        File.Delete(item.CachePath);
                                    }
                                }
                                else
                                {
                                    AddItemToCache(item, point);
                                }
                            }
                        }
                        else
                        {
                            fs.Close();
                            File.Delete(item.BitFileldFilePath);
                        }
                    }
            }

            Logger.Info("Cache loaded {0}", Utils.FormatBytes(point.UsedSpace));

            // delete files without bitfields
            foreach (var filePath in Directory.EnumerateFiles(path))
            {
                if (Path.GetExtension(filePath) == ".bitfield")
                {
                    continue;
                }

                var file = Path.GetFileName(filePath);

                if (!_items.ContainsKey(file))
                {
                    Logger.Info("Removing invalid cache file {0}", file);
                    File.Delete(filePath);
                }
            }

            if (!_listening)
            {
                ProxyUploadItem.SegmentDownloaded += HttpUploadItem_HttpSegmentDownloaded;
                ProxyUploadItem.SegmentNeeded     += HttpUploadItem_HttpSegmentNeeded;
                _listening = true;
            }
        }