public async void SynchronizeBookmarks(Book book) { if (!CanSync()) { return; } var bookmarkService = IocManager.Container.Resolve <IBookmarkService>(); var data = await _cloudStorageService.LoadJson <DateTime?>(this.PathGenerator(book.ID, BookmarksLastChangeNode)); if (!data.HasValue || !book.BookmarksSyncLastChange.HasValue || book.BookmarksSyncLastChange.Value < data.Value) { var cloudBookmarks = await _cloudStorageService.LoadJsonList <Model.Sync.Bookmark>(this.PathGenerator(book.ID, BookmarksNode)); var deviceBookmarks = await bookmarkService.LoadBookmarksByBookID(book.ID); var change = false; foreach (var cloudBookmark in cloudBookmarks) { var deviceBookmark = deviceBookmarks.FirstOrDefault(o => o.ID == cloudBookmark.ID); if (deviceBookmark == null && !cloudBookmark.Deleted) { deviceBookmark = new Model.Bookshelf.Bookmark { ID = cloudBookmark.ID, BookID = book.ID, Name = cloudBookmark.Name, Position = cloudBookmark.Position, LastChange = DateTime.UtcNow, }; deviceBookmarks.Add(deviceBookmark); change = true; bookmarkService.SaveBookmark(deviceBookmark); } else if (deviceBookmark != null && deviceBookmark.LastChange < cloudBookmark.LastChange) { deviceBookmark.Name = cloudBookmark.Name; deviceBookmark.Deleted = cloudBookmark.Deleted; deviceBookmark.LastChange = DateTime.UtcNow; change = true; bookmarkService.SaveBookmark(deviceBookmark); } } var cloudMissingBookmarks = deviceBookmarks.Select(o => o.ID).Except(cloudBookmarks.Select(o => o.ID)); if (cloudMissingBookmarks.Any()) { change = true; } foreach (var deviceBookmark in deviceBookmarks.Where(o => cloudMissingBookmarks.Contains(o.ID))) { this.SaveBookmark(book.ID, deviceBookmark); } _bookshelfService.SaveBook(book); if (change) { this.SaveBookmarksLastChange(book.ID); } var bookmarks = await bookmarkService.LoadBookmarksByBookID(book.ID); _messageBus.Send(new BookmarksChangedMessage { Bookmarks = bookmarks }); } }