/// <summary>
        /// Refreshes the service data and returns a collection of objects detailing how the service data was changed.
        /// </summary>
        /// <param name="progress">The object used to report refresh progress.</param>
        /// <returns>A collection of objects detailing how the service data was changed</returns>
        public IReadOnlyCollection <ProteinDictionaryChange> Refresh(IProgress <ProgressInfo> progress)
        {
            IReadOnlyCollection <ProteinDictionaryChange> dictionaryChanges;

            using (var stream = new MemoryStream())
            {
                Logger.Info("Downloading new project data from Stanford...");
                _downloader.Download(stream, progress);
                stream.Position = 0;

                var serializer    = new ProjectSummaryJsonDeserializer();
                var newDictionary = ProteinDictionary.CreateFromExisting(_dictionary, serializer.Deserialize(stream));
                dictionaryChanges = newDictionary.Changes;
                _dictionary       = newDictionary;
            }

            foreach (var info in dictionaryChanges.Where(info => info.Result != ProteinDictionaryChangeResult.NoChange))
            {
                Logger.Info(info.ToString());
            }

            var now = DateTime.UtcNow;

            foreach (var key in _projectsNotFound.Keys.ToList())
            {
                if (_dictionary.ContainsKey(key))
                {
                    _projectsNotFound.Remove(key);
                }
                else
                {
                    _projectsNotFound[key] = now;
                }
            }
            _lastRefreshTime = now;

            Write();
            return(dictionaryChanges);
        }