CAY-2814 Select query iterator() and batchIterator() methods return incorrect results
 - cleanup code for QueryResponse
diff --git a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
index deafacf..e55d21c 100644
--- a/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
+++ b/cayenne-commitlog/src/main/java/org/apache/cayenne/commitlog/DeletedDiffProcessor.java
@@ -62,7 +62,7 @@
 		QueryResponse result = channel.onQuery(null, query);
 
 		@SuppressWarnings("unchecked")
-		List<DataRow> rows = result.firstList();
+		List<DataRow> rows = (List<DataRow>)result.firstList();
 
 		if (rows.isEmpty()) {
 			LOGGER.warn("No DB snapshot for object to be deleted, no changes will be recorded. ID: " + id);
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java
index 4c4c282..c8fb01b 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/QueryResponse.java
@@ -66,27 +66,35 @@
     /**
      * Returns whether current iteration result is a list or an update count.
      */
-    boolean isList();
+    default boolean isList() {
+        return false;
+    }
 
     /**
      * Returns whether current response  is an iterator
      *
      * @since 5.0
      */
-    boolean isIterator();
+    default boolean isIterator() {
+        return false;
+    }
 
     /**
      * Returns a List under the current iterator position. Use {@link #isList()} to check
      * the result type before calling this method.
      */
-    List<?> currentList();
+    default List<?> currentList() {
+        return null;
+    }
 
     /**
      * Returns a current iterator.
      *
      * @since 5.0
      */
-    ResultIterator<?> currentIterator();
+    default ResultIterator<?> currentIterator() {
+        return null;
+    }
 
     /**
      * Returns an update count under the current iterator position. Returned value is an
@@ -94,7 +102,9 @@
      * an int[1]. Use {@link #isList()} to check the result type before calling this
      * method.
      */
-    int[] currentUpdateCount();
+    default int[] currentUpdateCount() {
+        return null;
+    }
 
     /**
      * Rewinds response iterator to the next result, returning true if it is available.
@@ -111,8 +121,9 @@
      * null if the query has no lists. Note that this method resets current iterator to an
      * undefined state.
      */
-    @SuppressWarnings("rawtypes")
-    List firstList();
+    default List<?> firstList() {
+        return null;
+    }
 
     /**
      * A utility method for quickly retrieving the Iterator in the response. Returns
@@ -120,12 +131,15 @@
      *
      * @since 5.0
      */
-    @SuppressWarnings("rawtypes")
-    ResultIterator firstIterator();
+    default ResultIterator<?> firstIterator() {
+        return null;
+    }
 
     /**
      * A utility method for quickly retrieving the first update count from the response.
      * Note that this method resets current iterator to an undefined state.
      */
-    int[] firstUpdateCount();
+    default int[] firstUpdateCount() {
+        return null;
+    }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java
index 0182333..d1b42c1 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/GenericResponse.java
@@ -28,12 +28,12 @@
 
 /**
  * A simple serializable implementation of QueryResponse.
- * 
+ *
  * @since 1.2
  */
 public class GenericResponse implements QueryResponse, Serializable {
 
-    protected List results;
+    protected List<Object> results;
 
     protected transient int currentIndex;
 
@@ -41,37 +41,39 @@
      * Creates an empty BaseResponse.
      */
     public GenericResponse() {
-        results = new ArrayList();
+        results = new ArrayList<>();
     }
 
     /**
      * Creates a BaseResponse with a single result list.
      */
-    public GenericResponse(List list) {
-        results = new ArrayList(1);
+    public GenericResponse(List<?> list) {
+        results = new ArrayList<>(1);
         addResultList(list);
     }
 
     /**
      * Creates a response that it a shallow copy of another response.
      */
+    @SuppressWarnings("unused")
     public GenericResponse(QueryResponse response) {
-
-        results = new ArrayList(response.size());
+        results = new ArrayList<>(response.size());
 
         response.reset();
         while (response.next()) {
             if (response.isList()) {
                 addResultList(response.currentList());
-            }
-            else {
+            } else if (response.isIterator()) {
+                addResultIterator(response.currentIterator());
+            } else {
                 addBatchUpdateCount(response.currentUpdateCount());
             }
         }
     }
 
-    public List firstList() {
-        for (reset(); next();) {
+    @Override
+    public List<?> firstList() {
+        for (reset(); next(); ) {
             if (isList()) {
                 return currentList();
             }
@@ -81,12 +83,19 @@
     }
 
     @Override
-    public ResultIterator firstIterator() {
+    public ResultIterator<?> firstIterator() {
+        for (reset(); next(); ) {
+            if (isIterator()) {
+                return currentIterator();
+            }
+        }
+
         return null;
     }
 
+    @Override
     public int[] firstUpdateCount() {
-        for (reset(); next();) {
+        for (reset(); next(); ) {
             if (!isList()) {
                 return currentUpdateCount();
             }
@@ -95,37 +104,43 @@
         return null;
     }
 
-    public List currentList() {
-        return (List) results.get(currentIndex - 1);
+    @Override
+    public List<?> currentList() {
+        return (List<?>) results.get(currentIndex - 1);
     }
 
     @Override
-    public ResultIterator currentIterator() {
-        return null;
+    public ResultIterator<?> currentIterator() {
+        return (ResultIterator<?>) results.get(currentIndex - 1);
     }
 
+    @Override
     public int[] currentUpdateCount() {
         return (int[]) results.get(currentIndex - 1);
     }
 
+    @Override
     public boolean isList() {
         return results.get(currentIndex - 1) instanceof List;
     }
 
     @Override
     public boolean isIterator() {
-        return false;
+        return results.get(currentIndex - 1) instanceof ResultIterator;
     }
 
+    @Override
     public boolean next() {
         return ++currentIndex <= results.size();
     }
 
+    @Override
     public void reset() {
         // use a zero-based index, not -1, as this will simplify serialization handling
         currentIndex = 0;
     }
 
+    @Override
     public int size() {
         return results.size();
     }
@@ -138,20 +153,25 @@
     }
 
     public void addBatchUpdateCount(int[] resultCount) {
-
         if (resultCount != null) {
             results.add(resultCount);
         }
     }
 
     public void addUpdateCount(int resultCount) {
-        results.add(new int[] {
-            resultCount
-        });
+        results.add(new int[]{resultCount});
     }
 
-    public void addResultList(List list) {
-        this.results.add(list);
+    public void addResultList(List<?> list) {
+        results.add(list);
+    }
+
+    /**
+     * @param iterator to add as a result
+     * @since 5.0
+     */
+    public void addResultIterator(ResultIterator<?> iterator) {
+        results.add(iterator);
     }
 
     /**
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java
index 961af91..72e9913 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/IteratedQueryResponse.java
@@ -21,20 +21,19 @@
 
 import org.apache.cayenne.ResultIterator;
 
-import java.util.List;
-
 /**
  * Implementation of QueryResponse for iterated query.
  *
  * @since 5.0
  */
 public class IteratedQueryResponse extends GenericResponse {
-    private ResultIterator iterator;
-    public IteratedQueryResponse(ResultIterator iterator) {
+    private ResultIterator<?> iterator;
+
+    public IteratedQueryResponse(ResultIterator<?> iterator) {
         this.iterator = iterator;
     }
 
-    public void setIterator(ResultIterator iterator) {
+    public void setIterator(ResultIterator<?> iterator) {
         this.iterator = iterator;
     }
 
@@ -44,47 +43,23 @@
     }
 
     @Override
-    public boolean isList() {
-        return false;
-    }
-
-    @Override
     public boolean isIterator() {
         return true;
     }
 
     @Override
-    public List<?> currentList() {
-        return null;
-    }
-
-    @Override
-    public ResultIterator currentIterator() {
+    public ResultIterator<?> currentIterator() {
         return iterator;
     }
 
     @Override
-    public int[] currentUpdateCount() {
-        return new int[0];
-    }
-
-    @Override
     public boolean next() {
         return false;
     }
 
     @Override
-    public List firstList() {
-        return null;
-    }
-
-    @Override
     public ResultIterator<?> firstIterator() {
         return iterator;
     }
 
-    @Override
-    public int[] firstUpdateCount() {
-        return new int[0];
-    }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java b/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java
index 30f8783..13f2f7a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/util/ListResponse.java
@@ -25,7 +25,6 @@
 import java.util.List;
 
 import org.apache.cayenne.QueryResponse;
-import org.apache.cayenne.ResultIterator;
 
 /**
  * A QueryResponse optimized to hold a single object or data row list.
@@ -34,7 +33,7 @@
  */
 public class ListResponse implements QueryResponse, Serializable {
 
-    protected List objectList;
+    protected List<?> objectList;
 
     protected transient int currentIndex;
 
@@ -42,14 +41,14 @@
      * Creates an empty response.
      */
     public ListResponse() {
-        this.objectList = new ArrayList(1);
+        this.objectList = new ArrayList<>(1);
     }
 
     public ListResponse(Object object) {
         this.objectList = Collections.singletonList(object);
     }
 
-    public ListResponse(List objectList) {
+    public ListResponse(List<?> objectList) {
         this.objectList = objectList;
     }
 
@@ -65,12 +64,7 @@
         return true;
     }
 
-    @Override
-    public boolean isIterator() {
-        return false;
-    }
-
-    public List currentList() {
+    public List<?> currentList() {
         if (currentIndex != 1) {
             throw new IndexOutOfBoundsException("Past iteration end: " + currentIndex);
         }
@@ -78,11 +72,6 @@
         return objectList;
     }
 
-    @Override
-    public ResultIterator<?> currentIterator() {
-        return null;
-    }
-
     public int[] currentUpdateCount() {
         throw new IllegalStateException("Current object is not an update count");
     }
@@ -96,16 +85,8 @@
         currentIndex = 0;
     }
 
-    public List firstList() {
+    public List<?> firstList() {
         return objectList;
     }
 
-    @Override
-    public ResultIterator firstIterator() {
-        return null;
-    }
-
-    public int[] firstUpdateCount() {
-        return new int[0];
-    }
 }