// Path: src/java/nxt/db/FilteringIterator.java
// public final class FilteringIterator<T> implements Iterator<T>, Iterable<T>, AutoCloseable {
// 
//     public static interface Filter<T> {
//         boolean ok(T t);
//     }
// 
//     private final DbIterator<T> dbIterator;
//     private final Filter<T> filter;
//     private final int from;
//     private final int to;
//     private T next;
//     private boolean hasNext;
//     private boolean iterated;
//     private int count;
// 
//     public FilteringIterator(DbIterator<T> dbIterator, Filter<T> filter) {
//         this(dbIterator, filter, 0, Integer.MAX_VALUE);
//     }
// 
//     public FilteringIterator(DbIterator<T> dbIterator, int from, int to) {
//         this(dbIterator, new Filter<T>() {
//             @Override
//             public boolean ok(T t) {
//                 return true;
//             }
//         }, from, to);
//     }
// 
//     public FilteringIterator(DbIterator<T> dbIterator, Filter<T> filter, int from, int to) {
//         this.dbIterator = dbIterator;
//         this.filter = filter;
//         this.from = from;
//         this.to = to;
//     }
// 
//     @Override
//     public boolean hasNext() {
//         if (hasNext) {
//             return true;
//         }
//         while (dbIterator.hasNext() && count <= to) {
//             next = dbIterator.next();
//             if (filter.ok(next)) {
//                 if (count >= from) {
//                     count += 1;
//                     hasNext = true;
//                     return true;
//                 }
//                 count += 1;
//             }
//         }
//         hasNext = false;
//         return false;
//     }
// 
//     @Override
//     public T next() {
//         if (hasNext) {
//             hasNext = false;
//             return next;
//         }
//         while (dbIterator.hasNext() && count <= to) {
//             next = dbIterator.next();
//             if (filter.ok(next)) {
//                 if (count >= from) {
//                     count += 1;
//                     hasNext = false;
//                     return next;
//                 }
//                 count += 1;
//             }
//         }
//         throw new NoSuchElementException();
//     }
// 
//     @Override
//     public void close() {
//         dbIterator.close();
//     }
// 
//     @Override
//     public void remove() {
//         throw new UnsupportedOperationException();
//     }
// 
//     @Override
//     public Iterator<T> iterator() {
//         if (iterated) {
//             throw new IllegalStateException("Already iterated");
//         }
//         iterated = true;
//         return this;
//     }
// 
// }


import nxt.DigitalGoodsStore;
import nxt.NxtException;
import nxt.db.DbIterator;
import nxt.db.FilteringIterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONStreamAware;
import javax.servlet.http.HttpServletRequest;
package nxt.http;



public final class GetDGSPurchases extends APIServlet.APIRequestHandler {

    static final GetDGSPurchases instance = new GetDGSPurchases();

    private GetDGSPurchases() {
        super(new APITag[] {APITag.DGS}, "seller", "buyer", "firstIndex", "lastIndex", "completed");
    }

    @Override
    JSONStreamAware processRequest(HttpServletRequest req) throws NxtException {

        long sellerId = ParameterParser.getSellerId(req);
        long buyerId = ParameterParser.getBuyerId(req);
        int firstIndex = ParameterParser.getFirstIndex(req);
        int lastIndex = ParameterParser.getLastIndex(req);
        final boolean completed = "true".equalsIgnoreCase(req.getParameter("completed"));


        JSONObject response = new JSONObject();
        JSONArray purchasesJSON = new JSONArray();
        response.put("purchases", purchasesJSON);

        if (sellerId == 0 && buyerId == 0) {
// Path: src/java/nxt/db/FilteringIterator.java
// public final class FilteringIterator<T> implements Iterator<T>, Iterable<T>, AutoCloseable {
// 
//     public static interface Filter<T> {
//         boolean ok(T t);
//     }
// 
//     private final DbIterator<T> dbIterator;
//     private final Filter<T> filter;
//     private final int from;
//     private final int to;
//     private T next;
//     private boolean hasNext;
//     private boolean iterated;
//     private int count;
// 
//     public FilteringIterator(DbIterator<T> dbIterator, Filter<T> filter) {
//         this(dbIterator, filter, 0, Integer.MAX_VALUE);
//     }
// 
//     public FilteringIterator(DbIterator<T> dbIterator, int from, int to) {
//         this(dbIterator, new Filter<T>() {
//             @Override
//             public boolean ok(T t) {
//                 return true;
//             }
//         }, from, to);
//     }
// 
//     public FilteringIterator(DbIterator<T> dbIterator, Filter<T> filter, int from, int to) {
//         this.dbIterator = dbIterator;
//         this.filter = filter;
//         this.from = from;
//         this.to = to;
//     }
// 
//     @Override
//     public boolean hasNext() {
//         if (hasNext) {
//             return true;
//         }
//         while (dbIterator.hasNext() && count <= to) {
//             next = dbIterator.next();
//             if (filter.ok(next)) {
//                 if (count >= from) {
//                     count += 1;
//                     hasNext = true;
//                     return true;
//                 }
//                 count += 1;
//             }
//         }
//         hasNext = false;
//         return false;
//     }
// 
//     @Override
//     public T next() {
//         if (hasNext) {
//             hasNext = false;
//             return next;
//         }
//         while (dbIterator.hasNext() && count <= to) {
//             next = dbIterator.next();
//             if (filter.ok(next)) {
//                 if (count >= from) {
//                     count += 1;
//                     hasNext = false;
//                     return next;
//                 }
//                 count += 1;
//             }
//         }
//         throw new NoSuchElementException();
//     }
// 
//     @Override
//     public void close() {
//         dbIterator.close();
//     }
// 
//     @Override
//     public void remove() {
//         throw new UnsupportedOperationException();
//     }
// 
//     @Override
//     public Iterator<T> iterator() {
//         if (iterated) {
//             throw new IllegalStateException("Already iterated");
//         }
//         iterated = true;
//         return this;
//     }
// 
// }


// Path: src/java/nxt/http/GetDGSPurchases.java
import nxt.DigitalGoodsStore;
import nxt.NxtException;
import nxt.db.DbIterator;
import nxt.db.FilteringIterator;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONStreamAware;
import javax.servlet.http.HttpServletRequest;

package nxt.http;



public final class GetDGSPurchases extends APIServlet.APIRequestHandler {

    static final GetDGSPurchases instance = new GetDGSPurchases();

    private GetDGSPurchases() {
        super(new APITag[] {APITag.DGS}, "seller", "buyer", "firstIndex", "lastIndex", "completed");
    }

    @Override
    JSONStreamAware processRequest(HttpServletRequest req) throws NxtException {

        long sellerId = ParameterParser.getSellerId(req);
        long buyerId = ParameterParser.getBuyerId(req);
        int firstIndex = ParameterParser.getFirstIndex(req);
        int lastIndex = ParameterParser.getLastIndex(req);
        final boolean completed = "true".equalsIgnoreCase(req.getParameter("completed"));


        JSONObject response = new JSONObject();
        JSONArray purchasesJSON = new JSONArray();
        response.put("purchases", purchasesJSON);

        if (sellerId == 0 && buyerId == 0) {
            try (FilteringIterator<DigitalGoodsStore.Purchase> purchaseIterator = new FilteringIterator<>(DigitalGoodsStore.getAllPurchases(0, -1),