// Path: openmrs/api/src/main/java/org/projectbuendia/openmrs/api/Bookmark.java
// public class Bookmark {
//     public final @Nonnull Date minTime;
//     public final @Nullable String minUuid;
// 
//     private static final TimeZone UTC = TimeZone.getTimeZone("Etc/UTC");
//     private static final DateFormat ISO8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
//     static { ISO8601_FORMAT.setTimeZone(UTC);}
//     private static final long REQUEST_BUFFER_WINDOW = 2000;
// 
//     public Bookmark(Date minTime, @Nullable String minUuid) {
//         if (minTime == null) {
//             throw new IllegalArgumentException("minTime cannot be null");
//         }
//         this.minTime = minTime;
//         this.minUuid = minUuid;
//     }
// 
//     @Override public boolean equals(Object obj) {
//         return obj instanceof Bookmark &&
//             Objects.equals(minTime, ((Bookmark) obj).minTime) &&
//             Objects.equals(minUuid, ((Bookmark) obj).minUuid);
//     }
// 
//     public String serialize() {
//         String result = ISO8601_FORMAT.format(minTime);
//         if (minUuid != null) result += "/" + minUuid;
//         return result;
//     }
// 
//     public static Bookmark deserialize(String text) throws ParseException {
//         String[] parts = text.split("/", 2);
//         Date minTime = parse8601(parts[0]);
//         String minUuid = null;
//         if (parts.length == 2 && !parts[1].isEmpty()) {
//             minUuid = parts[1];
//         }
//         return new Bookmark(minTime, minUuid);
//     }
// 
//     /**
//      * Bookmarks from the DAO aren't necessarily directly usable by the client - if the
//      * most recently modified record is close enough to the current time, there's a chance that
//      * records inserted by concurrent requests will never be synchronized. This method clamps a
//      * DAO-provided Bookmark to a few seconds before the request time, to ensure that this edge
//      * case can't occur. Note that in some circumstances, this could mean that a record is fetched
//      * multiple times, which is ok under our synchronisation model.
//      */
//     public static Bookmark clampToBufferedRequestTime(@Nullable Bookmark bookmark, Date requestTime) {
//         if (requestTime == null) {
//             throw new IllegalArgumentException("requestTime cannot be null");
//         }
//         Date earliestAllowableTime = new Date(requestTime.getTime() - REQUEST_BUFFER_WINDOW);
//         if (bookmark == null || earliestAllowableTime.before(bookmark.minTime)) {
//             return new Bookmark(earliestAllowableTime, null);
//         }
//         return bookmark;
//     }
// 
//     private static Date parse8601(String iso8601) throws ParseException {
//         return ISO8601_FORMAT.parse(iso8601);
//     }
// }


import javax.annotation.Nullable;
import java.util.List;
import org.projectbuendia.openmrs.api.Bookmark;
/*
 * Copyright 2015 The Project Buendia Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.  You may obtain a copy
 * of the License at: http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distrib-
 * uted under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.  See the License for
 * specific language governing permissions and limitations under the License.
 */

package org.projectbuendia.openmrs.api.db;



/**
 * A result set that contains a list of results, and possibly a {@link Bookmark}
 * that can be used to fetch the next set of results.
 */
public class SyncPage<T> {
    public final List<T> results;
    @Nullable public final Bookmark bookmark;

// Path: openmrs/api/src/main/java/org/projectbuendia/openmrs/api/Bookmark.java
// public class Bookmark {
//     public final @Nonnull Date minTime;
//     public final @Nullable String minUuid;
// 
//     private static final TimeZone UTC = TimeZone.getTimeZone("Etc/UTC");
//     private static final DateFormat ISO8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
//     static { ISO8601_FORMAT.setTimeZone(UTC);}
//     private static final long REQUEST_BUFFER_WINDOW = 2000;
// 
//     public Bookmark(Date minTime, @Nullable String minUuid) {
//         if (minTime == null) {
//             throw new IllegalArgumentException("minTime cannot be null");
//         }
//         this.minTime = minTime;
//         this.minUuid = minUuid;
//     }
// 
//     @Override public boolean equals(Object obj) {
//         return obj instanceof Bookmark &&
//             Objects.equals(minTime, ((Bookmark) obj).minTime) &&
//             Objects.equals(minUuid, ((Bookmark) obj).minUuid);
//     }
// 
//     public String serialize() {
//         String result = ISO8601_FORMAT.format(minTime);
//         if (minUuid != null) result += "/" + minUuid;
//         return result;
//     }
// 
//     public static Bookmark deserialize(String text) throws ParseException {
//         String[] parts = text.split("/", 2);
//         Date minTime = parse8601(parts[0]);
//         String minUuid = null;
//         if (parts.length == 2 && !parts[1].isEmpty()) {
//             minUuid = parts[1];
//         }
//         return new Bookmark(minTime, minUuid);
//     }
// 
//     /**
//      * Bookmarks from the DAO aren't necessarily directly usable by the client - if the
//      * most recently modified record is close enough to the current time, there's a chance that
//      * records inserted by concurrent requests will never be synchronized. This method clamps a
//      * DAO-provided Bookmark to a few seconds before the request time, to ensure that this edge
//      * case can't occur. Note that in some circumstances, this could mean that a record is fetched
//      * multiple times, which is ok under our synchronisation model.
//      */
//     public static Bookmark clampToBufferedRequestTime(@Nullable Bookmark bookmark, Date requestTime) {
//         if (requestTime == null) {
//             throw new IllegalArgumentException("requestTime cannot be null");
//         }
//         Date earliestAllowableTime = new Date(requestTime.getTime() - REQUEST_BUFFER_WINDOW);
//         if (bookmark == null || earliestAllowableTime.before(bookmark.minTime)) {
//             return new Bookmark(earliestAllowableTime, null);
//         }
//         return bookmark;
//     }
// 
//     private static Date parse8601(String iso8601) throws ParseException {
//         return ISO8601_FORMAT.parse(iso8601);
//     }
// }


// Path: openmrs/api/src/main/java/org/projectbuendia/openmrs/api/db/SyncPage.java
import javax.annotation.Nullable;
import java.util.List;
import org.projectbuendia.openmrs.api.Bookmark;

/*
 * Copyright 2015 The Project Buendia Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.  You may obtain a copy
 * of the License at: http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distrib-
 * uted under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.  See the License for
 * specific language governing permissions and limitations under the License.
 */

package org.projectbuendia.openmrs.api.db;



/**
 * A result set that contains a list of results, and possibly a {@link Bookmark}
 * that can be used to fetch the next set of results.
 */
public class SyncPage<T> {
    public final List<T> results;
    @Nullable public final Bookmark bookmark;

    public SyncPage(List<T> results, @Nullable Bookmark bookmark) {