private void PushChanges() throws Exception {
    BookmarkCollection updates = Bookmark.GetBookmarksForServerUpdate(getContextSource());
    BookmarkCollection deletes = Bookmark.GetBookmarksForServerDelete(this.getContextSource());
    if (updates.size() == 0 && deletes.size() == 0) return;

    // et...
    EntityType et = EntityType.GetEntityType(Bookmark.class);

    // get the server ones...
    BookmarksService service = new BookmarksService();
    BookmarkCollection fromServer = service.GetAll();

    // walk the locally updated items…
    for (Bookmark local : updates) {
      // find it in our server set...
      Bookmark toUpdate = null;
      for (Bookmark server : fromServer) {
        if (local.getOrdinal() == server.getOrdinal()) {
          toUpdate = server;
          break;
        }
      }

      // did we have one to change?
      if (toUpdate != null) {
        // walk the fields...
        int serverId = 0;
        for (EntityField field : et.getFields()) {
          if (!(field.getIsKey()))
            toUpdate.SetValue(field, local.GetValue(field), SetReason.UserSet);
          else serverId = toUpdate.getBookmarkId();
        }

        // send that up...
        service.PushUpdate(this.getContextSource(), toUpdate, serverId);
      } else {
        // we need to insert it...
        service.PushInsert(this.getContextSource(), local);
      }
    }

    // what about ones to delete?
    for (Bookmark local : deletes) {
      // find a matching ordinal on the server...
      for (Bookmark server : fromServer) {
        if (local.getOrdinal() == server.getOrdinal())
          service.PushDelete(this.getContextSource(), server, server.getBookmarkId());
      }
    }
  }
  public BookmarkCollection GetAll() throws Exception {
    EntityType et = EntityType.GetEntityType(Bookmark.class);

    // run...
    String url = GetServiceUrl(et);
    Document doc = HttpHelper.DownloadXml(url, GetDownloadSettings());

    // load...
    return (BookmarkCollection) LoadEntities(doc, et);
  }
  public void DoSync(IContextSource source) throws Exception {
    _contextSource = source;
    _database = new DatabaseHelper(source);

    // make sure we have a table...
    _entityType = EntityType.GetEntityType(Bookmark.class);
    _database.EnsureTableExists(_entityType);

    // push changes, then get the latest...
    PushChanges();
    GetLatest();
  }