private static void CheckForResourceDescriptionsUpdate()
        {
            if (ItsTimeToUpdate())
            {
                lock (_updateLock)
                {
                    if (ItsTimeToUpdate())
                    {
                        _updating = true;

                        var futureResources = Resource.Load().ToArray();

                        Resource[] currentResources = null;
                        lock (_cacheLock)
                        {
                            currentResources = _cachedResources;
                            _futureResources = futureResources;
                        }

                        //var unchangedResourceNames = futureResources.Intersect(currentResources).Select(r => r.ResourceName);
                        //var affectedControllerUrls = futureResources.Where(r => uncha

                        var affectedControllerUrls =
                            futureResources
                            .Select(r => r.Controller.Url).Distinct()
                            .Union(currentResources
                                   .Select(r => r.Controller.Url).Distinct());

                        if (String.Join("\r\n", futureResources.OrderBy(r => r.ResourceName).Select(r => r.Json)) ==
                            String.Join("\r\n", currentResources.OrderBy(r => r.ResourceName).Select(r => r.Json)))
                        {
                            affectedControllerUrls = new string[0];
                        }

                        if (_updateKeys.Any())
                        {
                            // todo : Log.Warn
                            _updateKeys = new HashSet <string>();
                        }

                        foreach (string url in affectedControllerUrls) // _updateKeys not threadsafe => not in parallel
                        {
                            string updateKey = url;                    // todo : generate dumping key

                            _updateKeys.Add(updateKey);

                            var farm = new ControllerFarmServiceClient();
                            farm.Endpoint.Address = new EndpointAddress(url);
                            farm.InnerChannel.OperationTimeout = TimeSpan.FromSeconds(5);

                            try
                            {
                                farm.ReloadAllResources(updateKey);
                                farm.Close();
                            }
                            catch (Exception e)
                            {
                                farm.Abort();
                                // todo: log exception

                                _updateKeys.Remove(updateKey);
                            }
                        }

                        if (!_updateKeys.Any())
                        {
                            _updating       = false;
                            _lastUpdateTime = DateTime.Now;
                        }
                    }
                }
            }
        }
        private static void CheckForResourceDescriptionsUpdate()
        {
            if (ItsTimeToUpdate())
            {
                lock (_updateLock)
                {
                    if (ItsTimeToUpdate())
                    {
                        _updating = true;

                        var futureResources = Resource.Load().ToArray();

                        Resource[] currentResources = null;
                        lock (_cacheLock)
                        {
                            currentResources = _cachedResources;
                            _futureResources = futureResources;
                        }

                        //var unchangedResourceNames = futureResources.Intersect(currentResources).Select(r => r.ResourceName);
                        //var affectedControllerUrls = futureResources.Where(r => uncha

                        var affectedControllerUrls =
                            futureResources
                                .Select(r => r.Controller.Url).Distinct()
                            .Union(currentResources
                                .Select(r => r.Controller.Url).Distinct());

                        if (String.Join("\r\n",  futureResources.OrderBy(r => r.ResourceName).Select(r => r.Json)) ==
                            String.Join("\r\n", currentResources.OrderBy(r => r.ResourceName).Select(r => r.Json)))
                            affectedControllerUrls = new string[0];

                        if (_updateKeys.Any())
                        {
                            // todo : Log.Warn
                            _updateKeys = new HashSet<string>();
                        }

                        foreach (string url in affectedControllerUrls) // _updateKeys not threadsafe => not in parallel
                        {
                            string updateKey = url; // todo : generate dumping key

                            _updateKeys.Add(updateKey);

                            var farm = new ControllerFarmServiceClient();
                            farm.Endpoint.Address = new EndpointAddress(url);
                            farm.InnerChannel.OperationTimeout = TimeSpan.FromSeconds(5);

                            try
                            {
                                farm.ReloadAllResources(updateKey);
                                farm.Close();
                            }
                            catch (Exception e)
                            {
                                farm.Abort();
                                // todo: log exception

                                _updateKeys.Remove(updateKey);
                            }
                        }

                        if (!_updateKeys.Any())
                        {
                            _updating = false;
                            _lastUpdateTime = DateTime.Now;
                        }
                    }
                }
            }
        }