Source:
public static ReprocessedEvents reprocessEventsBasedOnFeedback(final ImmutableList<TimelineFeedback> timelineFeedbackList, final ImmutableList<Event> algEvents,final ImmutableList<Event> extraEvents, final Integer offsetMillis) { final Map<Long,Event> feedbackEventMapByOriginalTime = getFeedbackEventsInOriginalTimeMap(timelineFeedbackList,offsetMillis); Scorer longScorer = new Scorer<Long>() { @Override public Long getScore(Long o1, Long o2) { return Math.abs(o1-o2); } }; Comparator longComparator = new Comparator<Long>() { @Override public int compare(Long o1, Long o2) { if (o1 < o2) { return -1; } if (o1 > o2) { return 1; } return 0; } }; final BestMatchByTypeMap<Event.Type,Long> typeAndTimeMatcher = new BestMatchByTypeMap<>(longScorer,longComparator); for (final Event event : algEvents) { typeAndTimeMatcher.add(event.getType(),event.getStartTimestamp()); } for (final Event event : extraEvents) { typeAndTimeMatcher.add(event.getType(),event.getStartTimestamp()); } Map<TypeAndTime,Long> timeEventMapper = new HashMap<>(); final Iterator<Long> it = feedbackEventMapByOriginalTime.keySet().iterator(); while (it.hasNext()) { final Long key = it.next(); final Event value = feedbackEventMapByOriginalTime.get(key); final Long newFeedbackTime = value.getStartTimestamp(); Long matchedEventTime = typeAndTimeMatcher.getClosest(value.getType(),key); if (matchedEventTime == null) { continue; } typeAndTimeMatcher.remove(value.getType(),matchedEventTime); timeEventMapper.put(new TypeAndTime(value.getType(),matchedEventTime), newFeedbackTime); } final ImmutableList<Event> newAlgEvents = remap(timeEventMapper,algEvents); final ImmutableList<Event> newExtraEvents = remap(timeEventMapper,extraEvents); return new ReprocessedEvents(newAlgEvents,newExtraEvents); }

Target:
public static ReprocessedEvents reprocessEventsBasedOnFeedback(final ImmutableList<TimelineFeedback> timelineFeedbackList, final ImmutableList<Event> algEvents,final ImmutableList<Event> extraEvents, final Integer offsetMillis) { final Map<Long,Event> feedbackEventMapByOriginalTime = getFeedbackEventsInOriginalTimeMap(timelineFeedbackList,offsetMillis); final Scorer longScorer = new Scorer<Long>() { @Override public Long getScore(Long o1, Long o2) { return Math.abs(o1-o2); } }; final Comparator longComparator = new Comparator<Long>() { @Override public int compare(Long o1, Long o2) { if (o1 < o2) { return -1; } if (o1 > o2) { return 1; } return 0; } }; final BestMatchByTypeMap<Event.Type,Long> typeAndTimeMatcher = new BestMatchByTypeMap<>(longScorer,longComparator); for (final Event event : algEvents) { typeAndTimeMatcher.add(event.getType(),event.getStartTimestamp()); } for (final Event event : extraEvents) { typeAndTimeMatcher.add(event.getType(),event.getStartTimestamp()); } final Map<TypeAndTime,Long> timeEventMapper = new HashMap<>(); final Iterator<Long> it = feedbackEventMapByOriginalTime.keySet().iterator(); while (it.hasNext()) { final Long key = it.next(); final Event value = feedbackEventMapByOriginalTime.get(key); final Long newFeedbackTime = value.getStartTimestamp(); Long matchedEventTime = typeAndTimeMatcher.getClosest(value.getType(),key); if (matchedEventTime == null) { continue; } typeAndTimeMatcher.remove(value.getType(),matchedEventTime); timeEventMapper.put(new TypeAndTime(value.getType(),matchedEventTime), newFeedbackTime); } final ImmutableList<Event> newAlgEvents = remap(timeEventMapper,algEvents); final ImmutableList<Event> newExtraEvents = remap(timeEventMapper,extraEvents); return new ReprocessedEvents(newAlgEvents,newExtraEvents); }