private SyncMovie toSyncMovie(Movie tmmMovie, boolean watched) {
    SyncMovie movie = null;

    MovieIds ids = new MovieIds();
    if (!tmmMovie.getIdAsString(Constants.IMDBID).isEmpty()) {
      ids.imdb = tmmMovie.getIdAsString(Constants.IMDBID);
    }
    if (tmmMovie.getIdAsInt(Constants.TMDBID) != 0) {
      ids.tmdb = tmmMovie.getIdAsInt(Constants.TMDBID);
    }
    if (tmmMovie.getIdAsInt(Constants.TRAKTID) != 0) {
      ids.trakt = tmmMovie.getIdAsInt(Constants.TRAKTID);
    }

    // we have to decide what we send; trakt behaves differenty when sending data to
    // sync collection and sync history.
    if (watched) {
      // sync history
      if (tmmMovie.isWatched() && tmmMovie.getLastWatched() == null) {
        // watched in tmm and not in trakt -> sync
        movie = new SyncMovie().id(ids).watchedAt(new DateTime(tmmMovie.getLastWatched()));
      }
    } else {
      // sync collection
      movie = new SyncMovie().id(ids).collectedAt(new DateTime(tmmMovie.getDateAdded()));
    }

    return movie;
  }
  /**
   * Syncs Trakt.tv collection (specified movies)<br>
   * Gets all Trakt movies from collection, matches them to ours, and sends ONLY the new ones back
   * to Trakt
   */
  public void syncTraktMovieCollection(List<Movie> moviesInTmm) {
    if (!isEnabled()) {
      return;
    }

    // create a local copy of the list
    List<Movie> tmmMovies = new ArrayList<Movie>(moviesInTmm);
    // *****************************************************************************
    // 1) get diff of TMM <-> Trakt collection
    // *****************************************************************************
    LOGGER.info("got " + tmmMovies.size() + " movies for Trakt.tv collection sync");

    // get ALL Trakt movies in collection
    List<BaseMovie> traktMovies = new ArrayList<BaseMovie>();

    try {
      traktMovies = TRAKT.sync().collectionMovies(Extended.DEFAULT_MIN);
      // Extended.DEFAULT adds url, poster, fanart, banner, genres
      // Extended.MAX adds certs, runtime, and other stuff (useful for scraper!)
    } catch (RetrofitError e) {
      handleRetrofitError(e);
      return;
    } catch (UnauthorizedException e) {
      // not authorized - maybe access token revoked - relogin
      if (this.Login()) {
        // ok, it worked, lets try once again :)
        try {
          traktMovies = TRAKT.sync().collectionMovies(Extended.DEFAULT_MIN);
        } catch (UnauthorizedException e1) {
          return;
        }
      } else {
        handleRetrofitError((RetrofitError) e.getCause());
        return;
      }
    }
    LOGGER.info("You have " + traktMovies.size() + " movies in your Trakt.tv collection");

    // loop over all movies on trakt
    for (BaseMovie traktMovie : traktMovies) {
      // loop over TMM movies, and check if IMDBID match
      for (int i = tmmMovies.size() - 1; i >= 0; i--) {
        Movie tmmMovie = tmmMovies.get(i);

        if (matches(tmmMovie, traktMovie.movie.ids)) {
          // we have a movie match

          // update missing IDs (we get them for free :)
          boolean dirty = updateIDs(tmmMovie, traktMovie.movie.ids);

          if (traktMovie.collected_at != null
              && !(traktMovie.collected_at.toDate().equals(tmmMovie.getDateAdded()))) {
            // always set from trakt, if not matched (Trakt = master)
            LOGGER.trace(
                "Marking movie '"
                    + tmmMovie.getTitle()
                    + "' as collected on "
                    + traktMovie.collected_at.toDate()
                    + " (was "
                    + tmmMovie.getDateAddedAsString()
                    + ")");
            tmmMovie.setDateAdded(traktMovie.collected_at.toDate());
            dirty = true;
          }

          if (dirty) {
            tmmMovie.saveToDb();
          }

          // remove it from our list (no need to add)
          tmmMovies.remove(i);
        }
      }
    }

    if (tmmMovies.size() == 0) {
      LOGGER.info("Already up-to-date - no need to add anything :)");
      return;
    }

    // *****************************************************************************
    // 2) add remaining TMM movies to Trakt collection
    // *****************************************************************************
    LOGGER.debug("prepare " + tmmMovies.size() + " movies for Trakt.tv collection sync");

    List<SyncMovie> movies = new ArrayList<SyncMovie>();
    int nosync = 0;
    for (Movie tmmMovie : tmmMovies) {
      if (tmmMovie.getIdAsInt(Constants.TRAKTID) != 0
          || !tmmMovie.getIdAsString(Constants.IMDBID).isEmpty()
          || tmmMovie.getIdAsInt(Constants.TMDBID) != 0) {
        movies.add(toSyncMovie(tmmMovie, false));
      } else {
        // do not add to Trakt if we do not have at least one ID
        nosync++;
        continue;
      }
    }
    if (nosync > 0) {
      LOGGER.debug("skipping " + nosync + " movies, because they have not been scraped yet!");
    }

    if (movies.size() == 0) {
      LOGGER.info("no new movies for Trakt collection sync found.");
      return;
    }

    try {
      LOGGER.info("Adding " + movies.size() + " movies to Trakt.tv collection");
      SyncItems items = new SyncItems().movies(movies);
      response = TRAKT.sync().addItemsToCollection(items);
      LOGGER.info("Trakt add-to-library status:");
      printStatus(response);
    } catch (RetrofitError e) {
      handleRetrofitError(e);
      return;
    } catch (UnauthorizedException e) {
      handleRetrofitError((RetrofitError) e.getCause());
      return;
    }
  }