void PerformUnitSyncOperation(WorkItem workItem)
        {
            Trace.TraceInformation("PerformUnitSyncOperation");
            VerifyUnitSync();

            if (unitSync == null)
            {
                Trace.TraceError("Skipping file after unitsync loading errors: {0}", workItem.CacheItem.ShortPath);
                CacheMarkFailedUnitSync(workItem.CacheItem.ShortPath);
                return;
            }

            var info = GetUnitSyncData(workItem.CacheItem.FileName);
            UnInitUnitsync();

            if (info != null)
            {
                workItem.CacheItem.InternalName = info.Name;
                workItem.CacheItem.ResourceType = info.ResourceType;

                CacheItemAdd(workItem.CacheItem);

                var args = new CancelEventArgs<ResourceInfo>(info);
                UploadUnitsyncData.Invoke(this,args);
                if (args.Cancel) return;

                var serializedData = MetaDataCache.SerializeAndCompressMetaData(info);

                var map = info as Map;
                object userState = null;
                try
                {
                    var creator = new TorrentCreator();
                    creator.Path = GetFullPath(workItem);
                    var ms = new MemoryStream();
                    creator.Create(ms);

                    byte[] minimap = null;
                    byte[] metalMap = null;
                    byte[] heightMap = null;
                    if (map != null)
                    {
                        minimap = map.Minimap.ToBytes(ImageSize);
                        metalMap = map.Metalmap.ToBytes(ImageSize);
                        heightMap = map.Heightmap.ToBytes(ImageSize);
                        userState = new MapRegisteredEventArgs(info.Name, map, minimap, metalMap, heightMap, serializedData);
                    }
                    var mod = info as Mod;
                    if (mod != null) userState = new KeyValuePair<Mod, byte[]>(mod, serializedData);

                    Trace.TraceInformation("uploading {0} to server", info.Name);
                    Task.Factory.StartNew(() => {
                        ReturnValue e;
                        try {
                             e = service.RegisterResource(PlasmaServiceVersion, springPaths.SpringVersion, workItem.CacheItem.Md5.ToString(),
                                workItem.CacheItem.Length, info.ResourceType, workItem.CacheItem.FileName, info.Name,
                                serializedData, info.Dependencies, minimap, metalMap, heightMap,
                                ms.ToArray());
                        } catch (Exception ex) {
                            Trace.TraceError("Error uploading data to server: {0}", ex);
                            return;
                        } finally {
                            Interlocked.Decrement(ref itemsSending);
                        }
                        
                        if (e != ReturnValue.Ok)
                        {
                            Trace.TraceWarning("Resource registering failed: {0}", e);
                            return;
                        }
                        var mapArgs = userState as MapRegisteredEventArgs;
                        if (mapArgs != null)
                        {
                            var mapName = mapArgs.MapName;
                            MetaData.SaveMinimap(mapName, mapArgs.Minimap);
                            MetaData.SaveMetalmap(mapName, mapArgs.MetalMap);
                            MetaData.SaveHeightmap(mapName, mapArgs.HeightMap);
                            MetaData.SaveMetadata(mapName, mapArgs.SerializedData);
                            MapRegistered(this, mapArgs);
                        }
                        else if (userState != null)
                        {
                            var kvp = (KeyValuePair<Mod, byte[]>)userState;
                            var modInfo = kvp.Key;
                            var serializedDataRet = kvp.Value;
                            MetaData.SaveMetadata(modInfo.Name, serializedDataRet);
                            ModRegistered(this, new EventArgs<Mod>(mod));
                        }
                    });

                    Interlocked.Increment(ref itemsSending);
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error registering new resource {0}: {1}", workItem.CacheItem.ShortPath, e);
                }
            }
            else
            {
                Trace.TraceError("Could not unitsync file {0}", workItem.CacheItem.ShortPath);
                CacheMarkFailedUnitSync(workItem.CacheItem.ShortPath);
            }
            return;
        }
        void PerformUnitSyncOperation(WorkItem workItem)
        {
            Trace.TraceInformation("PerformUnitSyncOperation");
            VerifyUnitSync();

            if (unitSync == null)
            {
                Trace.TraceError("Skipping file after unitsync loading errors: {0}", workItem.CacheItem.ShortPath);
                CacheMarkFailedUnitSync(workItem.CacheItem.ShortPath);
                return;
            }

            var info = GetUnitSyncData(workItem.CacheItem.FileName);

            UnInitUnitsync();

            if (info != null)
            {
                workItem.CacheItem.InternalName = info.Name;
                workItem.CacheItem.ResourceType = info is Map ? ResourceType.Map : ResourceType.Mod;

                CacheItemAdd(workItem.CacheItem);

                var args = new CancelEventArgs <IResourceInfo>(info);
                UploadUnitsyncData.Invoke(this, args);
                if (args.Cancel)
                {
                    return;
                }

                var serializedData = MetaDataCache.SerializeAndCompressMetaData(info);

                var    map       = info as Map;
                object userState = null;
                try
                {
                    var creator = new TorrentCreator();
                    creator.Path = GetFullPath(workItem);
                    var ms = new MemoryStream();
                    creator.Create(ms);

                    byte[] minimap   = null;
                    byte[] metalMap  = null;
                    byte[] heightMap = null;
                    if (map != null)
                    {
                        minimap   = map.Minimap.ToBytes(ImageSize);
                        metalMap  = map.Metalmap.ToBytes(ImageSize);
                        heightMap = map.Heightmap.ToBytes(ImageSize);
                        userState = new MapRegisteredEventArgs(info.Name, map, minimap, metalMap, heightMap, serializedData);
                    }
                    var mod = info as Mod;
                    if (mod != null)
                    {
                        userState = new KeyValuePair <Mod, byte[]>(mod, serializedData);
                    }

                    Trace.TraceInformation("uploading {0} to server", info.Name);
                    Task.Factory.StartNew(() => {
                        ReturnValue e;
                        try {
                            e = service.RegisterResource(PlasmaServiceVersion, springPaths.SpringVersion, workItem.CacheItem.Md5.ToString(),
                                                         workItem.CacheItem.Length, info is Map ? ResourceType.Map : ResourceType.Mod, workItem.CacheItem.FileName, info.Name,
                                                         serializedData, mod != null ? mod.Dependencies.ToList() : null, minimap, metalMap, heightMap,
                                                         ms.ToArray());
                        } catch (Exception ex) {
                            Trace.TraceError("Error uploading data to server: {0}", ex);
                            return;
                        } finally {
                            Interlocked.Decrement(ref itemsSending);
                        }

                        if (e != ReturnValue.Ok)
                        {
                            Trace.TraceWarning("Resource registering failed: {0}", e);
                            return;
                        }
                        var mapArgs = userState as MapRegisteredEventArgs;
                        if (mapArgs != null)
                        {
                            var mapName = mapArgs.MapName;
                            MetaData.SaveMinimap(mapName, mapArgs.Minimap);
                            MetaData.SaveMetalmap(mapName, mapArgs.MetalMap);
                            MetaData.SaveHeightmap(mapName, mapArgs.HeightMap);
                            MetaData.SaveMetadata(mapName, mapArgs.SerializedData);
                            MapRegistered(this, mapArgs);
                        }
                        else
                        {
                            var kvp               = (KeyValuePair <Mod, byte[]>)userState;
                            var modInfo           = kvp.Key;
                            var serializedDataRet = kvp.Value;
                            MetaData.SaveMetadata(modInfo.Name, serializedDataRet);
                            ModRegistered(this, new EventArgs <Mod>(mod));
                        }
                    });

                    Interlocked.Increment(ref itemsSending);
                }
                catch (Exception e)
                {
                    Trace.TraceError("Error registering new resource {0}: {1}", workItem.CacheItem.ShortPath, e);
                }
            }
            else
            {
                Trace.TraceError("Could not unitsync file {0}", workItem.CacheItem.ShortPath);
                CacheMarkFailedUnitSync(workItem.CacheItem.ShortPath);
            }
            return;
        }