// Path: app/src/main/java/com/lambdasoup/quickfit/model/DayOfWeek.java
// public enum DayOfWeek implements Parcelable {
//     MONDAY(Calendar.MONDAY, R.string.monday),
//     TUESDAY(Calendar.TUESDAY, R.string.tuesday),
//     WEDNESDAY(Calendar.WEDNESDAY, R.string.wednesday),
//     THURSDAY(Calendar.THURSDAY, R.string.thursday),
//     FRIDAY(Calendar.FRIDAY, R.string.friday),
//     SATURDAY(Calendar.SATURDAY, R.string.saturday),
//     SUNDAY(Calendar.SUNDAY, R.string.sunday);
// 
//     public final int calendarConst;
//     public final int fullNameResId;
// 
//     DayOfWeek(int calendarConst, @StringRes int fullNameResId) {
//         this.calendarConst = calendarConst;
//         this.fullNameResId = fullNameResId;
//     }
// 
//     @NonNull
//     public static DayOfWeek[] getWeek() {
//         return getWeek(Calendar.getInstance());
//     }
// 
//     @NonNull
//     protected static DayOfWeek[] getWeek(Calendar calendar) {
//         int firstDay = calendar.getFirstDayOfWeek();
//         DayOfWeek[] week = new DayOfWeek[7];
//         for (int i = 0; i < 7; i++) {
//             int calendarConst = firstDay + i;
//             if (calendarConst > 7) {
//                 calendarConst -= 7;
//             }
//             week[i] = getByCalendarConst(calendarConst);
//         }
//         return week;
//     }
// 
//     public static DayOfWeek getByCalendarConst(int calendarConst) {
//         switch (calendarConst) {
//             case Calendar.MONDAY:
//                 return MONDAY;
//             case Calendar.TUESDAY:
//                 return TUESDAY;
//             case Calendar.WEDNESDAY:
//                 return WEDNESDAY;
//             case Calendar.THURSDAY:
//                 return THURSDAY;
//             case Calendar.FRIDAY:
//                 return FRIDAY;
//             case Calendar.SATURDAY:
//                 return SATURDAY;
//             case Calendar.SUNDAY:
//                 return SUNDAY;
//             default:
//                 throw new IllegalArgumentException("Not a java.util.Calendar weekday constant: " + calendarConst);
//         }
//     }
// 
//     // GENERATED START
//     // by parcelable AndroidStudio plugin
// 
//     @Override
//     public int describeContents() {
//         return 0;
//     }
// 
//     @Override
//     public void writeToParcel(final Parcel dest, final int flags) {
//         dest.writeString(name());
//     }
// 
//     public static final Creator<DayOfWeek> CREATOR = new Creator<DayOfWeek>() {
//         @Override
//         public DayOfWeek createFromParcel(final Parcel source) {
//             return DayOfWeek.valueOf(source.readString());
//         }
// 
//         @Override
//         public DayOfWeek[] newArray(final int size) {
//             return new DayOfWeek[size];
//         }
//     };
// 
//     // GENERATED END
// }
// 
// Path: app/src/main/java/com/lambdasoup/quickfit/util/Lists.java
// public class Lists {
//     private Lists() {
//         // do not instantiate
//     }
// 
// 
//     @NonNull
//     public static <S, T> List<T> map(@NonNull  List<S> source, @NonNull Function<S, T> transformation) {
//         return new AbstractList<T>() {
//             @Override
//             public T get(int location) {
//                 return transformation.apply(source.get(location));
//             }
// 
//             @Override
//             public int size() {
//                 return source.size();
//             }
//         };
//     }
// 
//     /**
//      * Assumes that list is ordered according to ordering. If not, results
//      * are undefined.
//      * Finds index i, such that list.get(j) for all j < i is less than item
//      * according to ordering, and list.get(j) for all j>= i is at least item
//      * according to ordering. In other words, the left-most possible insertion
//      * point for item that keeps list ordered is found.
//      */
//     public static <T> int bisectLeft(@NonNull List<T> list, @NonNull Comparator<T> ordering, @NonNull T item) {
//         int low = 0;
//         int high = list.size();
//         int mid;
// 
//         while (low < high) {
//             mid = (low + high) / 2;
//             if (ordering.compare(item, list.get(mid)) <= 0) {
//                 high = mid;
//             } else {
//                 low = mid + 1;
//             }
//         }
//         return low;
//     }
// }


import com.lambdasoup.quickfit.model.DayOfWeek;
import com.lambdasoup.quickfit.util.Lists;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
                    refreshPositions();
                    callback.onMoved(oldPosition, newPosition);
                }
            }
        }

        List<Long> leavingIds = new ArrayList<>();
        //noinspection Convert2streamapi
        for (Long oldId : positionForId.keySet()) {
            if (!newIds.contains(oldId)) {
                leavingIds.add(oldId);
            }
        }
        for (Long leavingId : leavingIds) {
            dataset.remove(getPositionForId(leavingId));
            int oldPosition = getPositionForId(leavingId);
            callback.onRemoved(oldPosition);
            refreshPositions();
        }

        releaseWriteLock();

    }

    private int getPositionForId(long id) {
        Integer pos = positionForId.get(id);
        return pos == null ? POSITION_INVALID : pos;
    }

    private int findPositionFor(ScheduleItem item) {
// Path: app/src/main/java/com/lambdasoup/quickfit/model/DayOfWeek.java
// public enum DayOfWeek implements Parcelable {
//     MONDAY(Calendar.MONDAY, R.string.monday),
//     TUESDAY(Calendar.TUESDAY, R.string.tuesday),
//     WEDNESDAY(Calendar.WEDNESDAY, R.string.wednesday),
//     THURSDAY(Calendar.THURSDAY, R.string.thursday),
//     FRIDAY(Calendar.FRIDAY, R.string.friday),
//     SATURDAY(Calendar.SATURDAY, R.string.saturday),
//     SUNDAY(Calendar.SUNDAY, R.string.sunday);
// 
//     public final int calendarConst;
//     public final int fullNameResId;
// 
//     DayOfWeek(int calendarConst, @StringRes int fullNameResId) {
//         this.calendarConst = calendarConst;
//         this.fullNameResId = fullNameResId;
//     }
// 
//     @NonNull
//     public static DayOfWeek[] getWeek() {
//         return getWeek(Calendar.getInstance());
//     }
// 
//     @NonNull
//     protected static DayOfWeek[] getWeek(Calendar calendar) {
//         int firstDay = calendar.getFirstDayOfWeek();
//         DayOfWeek[] week = new DayOfWeek[7];
//         for (int i = 0; i < 7; i++) {
//             int calendarConst = firstDay + i;
//             if (calendarConst > 7) {
//                 calendarConst -= 7;
//             }
//             week[i] = getByCalendarConst(calendarConst);
//         }
//         return week;
//     }
// 
//     public static DayOfWeek getByCalendarConst(int calendarConst) {
//         switch (calendarConst) {
//             case Calendar.MONDAY:
//                 return MONDAY;
//             case Calendar.TUESDAY:
//                 return TUESDAY;
//             case Calendar.WEDNESDAY:
//                 return WEDNESDAY;
//             case Calendar.THURSDAY:
//                 return THURSDAY;
//             case Calendar.FRIDAY:
//                 return FRIDAY;
//             case Calendar.SATURDAY:
//                 return SATURDAY;
//             case Calendar.SUNDAY:
//                 return SUNDAY;
//             default:
//                 throw new IllegalArgumentException("Not a java.util.Calendar weekday constant: " + calendarConst);
//         }
//     }
// 
//     // GENERATED START
//     // by parcelable AndroidStudio plugin
// 
//     @Override
//     public int describeContents() {
//         return 0;
//     }
// 
//     @Override
//     public void writeToParcel(final Parcel dest, final int flags) {
//         dest.writeString(name());
//     }
// 
//     public static final Creator<DayOfWeek> CREATOR = new Creator<DayOfWeek>() {
//         @Override
//         public DayOfWeek createFromParcel(final Parcel source) {
//             return DayOfWeek.valueOf(source.readString());
//         }
// 
//         @Override
//         public DayOfWeek[] newArray(final int size) {
//             return new DayOfWeek[size];
//         }
//     };
// 
//     // GENERATED END
// }
// 
// Path: app/src/main/java/com/lambdasoup/quickfit/util/Lists.java
// public class Lists {
//     private Lists() {
//         // do not instantiate
//     }
// 
// 
//     @NonNull
//     public static <S, T> List<T> map(@NonNull  List<S> source, @NonNull Function<S, T> transformation) {
//         return new AbstractList<T>() {
//             @Override
//             public T get(int location) {
//                 return transformation.apply(source.get(location));
//             }
// 
//             @Override
//             public int size() {
//                 return source.size();
//             }
//         };
//     }
// 
//     /**
//      * Assumes that list is ordered according to ordering. If not, results
//      * are undefined.
//      * Finds index i, such that list.get(j) for all j < i is less than item
//      * according to ordering, and list.get(j) for all j>= i is at least item
//      * according to ordering. In other words, the left-most possible insertion
//      * point for item that keeps list ordered is found.
//      */
//     public static <T> int bisectLeft(@NonNull List<T> list, @NonNull Comparator<T> ordering, @NonNull T item) {
//         int low = 0;
//         int high = list.size();
//         int mid;
// 
//         while (low < high) {
//             mid = (low + high) / 2;
//             if (ordering.compare(item, list.get(mid)) <= 0) {
//                 high = mid;
//             } else {
//                 low = mid + 1;
//             }
//         }
//         return low;
//     }
// }


// Path: app/src/main/java/com/lambdasoup/quickfit/viewmodel/ScheduleList.java
import com.lambdasoup.quickfit.model.DayOfWeek;
import com.lambdasoup.quickfit.util.Lists;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

                    refreshPositions();
                    callback.onMoved(oldPosition, newPosition);
                }
            }
        }

        List<Long> leavingIds = new ArrayList<>();
        //noinspection Convert2streamapi
        for (Long oldId : positionForId.keySet()) {
            if (!newIds.contains(oldId)) {
                leavingIds.add(oldId);
            }
        }
        for (Long leavingId : leavingIds) {
            dataset.remove(getPositionForId(leavingId));
            int oldPosition = getPositionForId(leavingId);
            callback.onRemoved(oldPosition);
            refreshPositions();
        }

        releaseWriteLock();

    }

    private int getPositionForId(long id) {
        Integer pos = positionForId.get(id);
        return pos == null ? POSITION_INVALID : pos;
    }

    private int findPositionFor(ScheduleItem item) {
        return Lists.bisectLeft(dataset, ordering, item);