JDK-8188051-branch October 20 ABDA updates JDK-8188051-branch
authorlancea
Sat, 20 Oct 2018 08:17:38 -0400
branchJDK-8188051-branch
changeset 56997 c9cbac2979fb
parent 56832 4f7713e6a308
child 56998 8eb32e5b1a9f
JDK-8188051-branch October 20 ABDA updates
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaDataSourceProperty.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaSessionProperty.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayRowCountOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceProperty.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Examples.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/MultiOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OutOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowCountOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowPublisherOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/PrimitiveOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Result.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowCountOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowPublisherOperation.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Session.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SessionProperty.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ShardingKey.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlBlob.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlClob.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlStruct.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Submission.java
src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/TransactionCompletion.java
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaDataSourceProperty.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaDataSourceProperty.java	Sat Oct 20 08:17:38 2018 -0400
@@ -60,18 +60,31 @@
   }
   
   @Override
+  /**
+   * {@inheritDoc}
+   */
   public Class<?> range() {
     return range;
   }
 
   @Override
+  /**
+   * {@inheritDoc}
+   */
   public Object defaultValue() {
     return defaultValue;
   }
 
   @Override
+  /**
+   * {@inheritDoc}
+   */
   public boolean isSensitive() {
     return isSensitive;
   }
   
+  @Override
+  public boolean validate(Object value) {
+    return validator.apply(value);
+  }
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaSessionProperty.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaSessionProperty.java	Sat Oct 20 08:17:38 2018 -0400
@@ -139,21 +139,33 @@
     this.isSensitive = isSensitive;
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public Class<?> range() {
     return range;
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public boolean validate(Object value) {
     return validator.apply(value);
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public Object defaultValue() {
     return defaultValue;
   }
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public boolean isSensitive() {
     return isSensitive;
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/AdbaType.java	Sat Oct 20 08:17:38 2018 -0400
@@ -207,38 +207,33 @@
     
   private static final String STANDARD_VENDOR = "jdk.incubator.sql2";
 
-  protected final Class javaType;
+  protected final Class<?> javaType;
   
-  AdbaType(Class type) {
+  AdbaType(Class<?> type) {
     javaType = type;
   }
   
-    /**
-     *{@inheritDoc }
-     * @return The name of this {@code SQLType}.
-     */
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public String getName() {
     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
   }
 
-    /**
-     * Returns the name of the vendor that supports this data type.
-     * @return  The name of the vendor for this data type which is
-     * the package name containing this type.
-     */
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public String getVendor() {
     return STANDARD_VENDOR;
   }
 
-    /**
-     * Returns the vendor specific type number for the data type.
-     * @return  An Integer representing the data type. For {@code ABDAType},
-     * the value will be the same value as in {@code Types} for the data type.
-     */
+  /**
+   * {@inheritDoc}
+   */
   @Override
-  public <T> Class<T> getJavaType() {
+  public Class<?> getJavaType() {
     return javaType;
   }
   
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayRowCountOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ArrayRowCountOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -182,9 +182,19 @@
   */
   public <A, S extends T> ArrayRowCountOperation<T> collect(Collector<? super Result.RowCount, A, S> c);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ArrayRowCountOperation}
+   */
   @Override
   public ArrayRowCountOperation<T> onError(Consumer<Throwable> handler);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ArrayRowCountOperation}
+   */
   @Override
   public ArrayRowCountOperation<T> timeout(Duration minTime);
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSource.java	Sat Oct 20 08:17:38 2018 -0400
@@ -52,7 +52,8 @@
      * Specify a property and its value for the built {@link DataSource}.
      *
      * @param p {@link DataSourceProperty} to set. Not {@code null}.
-     * @param v value for the property
+     * @param v value for the property. If v is {@link Cloneable} it is cloned, 
+     * otherwise it is retained.
      * @return this {@link Builder}
      * @throws IllegalArgumentException if {@code p.validate(v)} does not return
      * true, if this method has already been called with the property
@@ -100,7 +101,8 @@
      * for a particular {@link Session} via {@link Session.Builder#property}.
      *
      * @param property the {@link SessionProperty} to be set. May not be {@code null}.
-     * @param value the value to be set for {@code property}
+     * @param value the value to be set for {@code property}. If value is 
+     * {@link Cloneable} it is cloned otherwise it is retained
      * @return this {@link Builder}
      * @throws IllegalArgumentException if {@code property.validate(value)} does not
      * return {@code true}. If it throws an {@link Exception} that {@link Exception} is the cause. Or if
@@ -119,7 +121,8 @@
      *
      * @param property the {@link SessionProperty} to set. May not be
      * {@code null}.
-     * @param value the value to set as the default for {@code property}
+     * @param value the value to set as the default for {@code property}. If 
+     * value is {@link Cloneable} it is cloned otherwise it is retained
      * @return this {@link Builder}
      * @throws IllegalArgumentException if {@code property.validate(value)} does
      * not return {@code true}. If it throws an {@link Exception} that
@@ -254,6 +257,9 @@
     return new LinkedList<>();
   }
   
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public void close();
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceFactory.java	Sat Oct 20 08:17:38 2018 -0400
@@ -41,14 +41,14 @@
    * Uses SPI to find a {@link DataSourceFactory} with the requested name or
    * {@code null} if one is not found.
    *
-   * @param <T>
+
    * @param name the name of the class that implements the factory
    * @return a {@link DataSourceFactory} for {@code name} or {@code null} if one
    * is not found
    */
-  public static <T extends DataSourceFactory> T newFactory(String name) {
+  public static DataSourceFactory newFactory(String name) {
     if (name == null) throw new IllegalArgumentException("DataSourceFactory name is null");
-    return (T)ServiceLoader
+    return ServiceLoader
             .load(DataSourceFactory.class)
             .stream()
             .filter(p -> p.type().getName().equals(name))
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceProperty.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/DataSourceProperty.java	Sat Oct 20 08:17:38 2018 -0400
@@ -24,16 +24,17 @@
  */
 package jdk.incubator.sql2;
 
+import java.io.Serializable;
+
 /**
  * An attribute of a {@link DataSource} that can be configured to influence its
- * behavior. Implementors of this interface define the properties of
  * {@link DataSource}s. The {@link DataSource.Builder#property} method is used
  * to set the values of {@link DataSource} properties.
  *
  * Implementations must be thread safe.
  *
  */
-public interface DataSourceProperty {
+public interface DataSourceProperty extends Serializable {
 
   /**
    * Return the name of this {@link DataSourceProperty}.
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Examples.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Examples.java	Sat Oct 20 08:17:38 2018 -0400
@@ -22,19 +22,15 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.incubator.sql2;
 
-import java.io.DataInputStream;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionStage;
 import java.util.concurrent.Flow;
-import java.util.concurrent.ForkJoinPool;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.Flow.Subscriber;
+import java.util.concurrent.Flow.Subscription;
 import java.util.stream.Collector;
 import java.util.stream.Collectors;
 
@@ -43,9 +39,8 @@
  * demonstrate the best way to use each feature, just one way.
  */
 public class Examples {
-  
+
   // DataSourceFactory
-
   public DataSource getDataSource() {
     return DataSourceFactory.newFactory("oracle.database.adba")
             .builder()
@@ -54,54 +49,48 @@
             .password("tiger")
             .build();
   }
-  
+
   // RowCountOperation
-  
-  public void insertItem(DataSource ds, Item item) {
-    try (Session session = ds.getSession()) {
-      session.rowCountOperation("insert into tab values (:id, :name, :answer)")
-              .set("id", item.id(), AdbaType.NUMERIC)
-              .set("name", item.name(), AdbaType.VARCHAR)
-              .set("answer", item.answer(), AdbaType.NUMERIC)
-              .submit();
-    }
+  public void insertItem(Session session, Item item) {
+    session.rowCountOperation("insert into tab values (:id, :name, :answer)")
+            .set("id", item.id(), AdbaType.NUMERIC)
+            .set("name", item.name(), AdbaType.VARCHAR)
+            .set("answer", item.answer(), AdbaType.NUMERIC)
+            .submit();
   }
-  
+
   // RowOperation
-  
   public void idsForAnswer(DataSource ds, List<Integer> result, int correctAnswer) {
     try (Session session = ds.getSession()) {
       session.<List<Integer>>rowOperation("select id, name, answer from tab where answer = :target")
               .set("target", correctAnswer, AdbaType.NUMERIC)
-              .collect(() -> result, 
-                       (list, row) -> list.add(row.at("id").get(Integer.class)) )
+              .collect(() -> result,
+                       (list, row) -> list.add(row.at("id").get(Integer.class)))
               .submit();
     }
   }
-  
+
   // RowOperation
-  
   public CompletionStage<List<Item>> itemsForAnswer(DataSource ds, int answer) {
     try (Session session = ds.getSession()) {
       return session.<List<Item>>rowOperation("select id, name, answer from tab where answer = :target")
               .set("target", 42, AdbaType.NUMERIC)
-              .collect(Collectors.mapping( 
-                       row -> new Item(row.at("id").get(Integer.class),
-                                       row.at("name").get(String.class),
-                                       row.at("answer").get(Integer.class) ),
-                       Collectors.toList() ))
+              .collect(Collectors.mapping(
+                      row -> new Item(row.at("id").get(Integer.class),
+                                      row.at("name").get(String.class),
+                                      row.at("answer").get(Integer.class)),
+                      Collectors.toList()))
               .submit()
               .getCompletionStage();
     }
   }
-  
+
   // Independent OperationGroup
-
   public void insertItemsIndependent(DataSource ds, List<Item> list) {
     String sql = "insert into tab values (:id, :name, :answer)";
-    try (Session session = ds.getSession()) {
-      OperationGroup group = session.operationGroup()
-              .independent();
+    try (Session session = ds.getSession();
+      OperationGroup<Void, Void> group = 
+        session.<Void, Void>operationGroup().independent()) {
       for (Item elem : list) {
         group.rowCountOperation(sql)
                 .set("id", elem.id)
@@ -109,109 +98,105 @@
                 .set("answer", elem.answer)
                 .submit()
                 .getCompletionStage()
-                .exceptionally( t -> {
+                .exceptionally(t -> {
                   System.out.println(elem.id);
                   return null;
                 });
       }
       group.submit();
-      
     }
   }
-  
+
   // Held OperationGroup
-  
   public void insertItemsHold(DataSource ds, List<Item> list) {
     String sql = "insert into tabone values (:id, :name, :answer)";
-    try (Session session = ds.getSession()) {
-      OperationGroup group = session.operationGroup()
-              .independent();
-      group.submitHoldingForMoreMembers();
+    try (Session session = ds.getSession();
+      OperationGroup<Void, Void> group = 
+        session.<Void, Void>operationGroup().independent()) {
+      
+      // Submit the group before any member is submitted. Each member 
+      // operation executes immediately upon submission.
+      group.submit();
       for (Item elem : list) {
         group.rowCountOperation(sql)
                 .set("elem_", elem)
                 .submit()
                 .getCompletionStage()
-                .exceptionally( t -> {
+                .exceptionally(t -> {
                   System.out.println(elem.id);
                   return null;
                 });
       }
-      group.releaseProhibitingMoreMembers();
     }
   }
-  
+
   // Parallel, Independent OperationGroup
-  
   public void updateListParallel(List<Item> list, DataSource ds) {
     String query = "select id from tab where answer = :answer";
     String update = "update tab set name = :name where id = :id";
-    try (Session session = ds.getSession()) {
+    try (Session session = ds.getSession();
       OperationGroup<Object, Object> group = session.operationGroup()
               .independent()
-              .parallel();
-      group.submitHoldingForMoreMembers();
+              .parallel()) {
+      group.submit();
       for (Item elem : list) {
         CompletionStage<Integer> idPromise = group.<List<Integer>>rowOperation(query)
                 .set("answer", elem.answer, AdbaType.NUMERIC)
-                .collect( Collector.of(
+                .collect(Collector.of(
                         () -> new ArrayList<>(),
-                        (l, row) -> l.add( row.at("id").get(Integer.class) ),
-                        (l, r) -> l ))
+                        (l, row) -> l.add(row.at("id").get(Integer.class)),
+                        (l, r) -> l))
                 .submit()
                 .getCompletionStage()
-                .thenApply( l -> l.get(0) );
+                .thenApply(l -> l.get(0));
         group.rowCountOperation(update)
                 .set("id", idPromise)
                 .set("name", "the ultimate question")
                 .submit()
                 .getCompletionStage()
-                .exceptionally( t -> {
+                .exceptionally(t -> {
                   System.out.println(elem.id);
                   return null;
                 });
       }
-      group.releaseProhibitingMoreMembers();
     }
   }
-  
+
   // TransactionCompletion
-  
   public void transaction(DataSource ds) {
     try (Session session = ds.getSession(t -> System.out.println("ERROR: " + t.toString()))) {
       TransactionCompletion trans = session.transactionCompletion();
       CompletionStage<Integer> idPromise = session.<Integer>rowOperation("select empno, ename from emp where ename = :1 for update")
               .set("1", "CLARK", AdbaType.VARCHAR)
               .collect(Collectors.collectingAndThen(
-                                        Collectors.mapping(r -> r.at("empno").get(Integer.class), 
-                                                           Collectors.toList()), 
-                                        l -> l.get(0)))
-              .onError( t -> trans.setRollbackOnly() )
+                      Collectors.mapping(r -> r.at("empno").get(Integer.class),
+                                         Collectors.toList()),
+                      l -> l.get(0)))
+              .onError(t -> trans.setRollbackOnly())
               .submit()
               .getCompletionStage();
       session.<Long>rowCountOperation("update emp set deptno = :1 where empno = :2")
               .set("1", 50, AdbaType.INTEGER)
               .set("2", idPromise, AdbaType.INTEGER)
-              .apply(c -> { 
+              .apply(c -> {
                 if (c.getCount() != 1L) {
                   trans.setRollbackOnly();
                   throw new RuntimeException("updated wrong number of rows");
                 }
                 return c.getCount();
               })
-              .onError(t -> trans.setRollbackOnly() )
+              .onError(t -> trans.setRollbackOnly())
               .submit();
-          //    .getCompletionStage()
-          //    .exceptionally( t -> { trans.setRollbackOnly(); return null; } ) // incorrect
+      //    .getCompletionStage()
+      //    .exceptionally( t -> { trans.setRollbackOnly(); return null; } ) // incorrect
       session.catchErrors();
       session.commitMaybeRollback(trans);
-    }    
+    }
   }
-  
+
   // RowPublisherOperation
-  
   public CompletionStage<List<String>> rowSubscriber(DataSource ds) {
-    
+
     String sql = "select empno, ename from emp";
     CompletableFuture<List<String>> result = new CompletableFuture<>();
 
@@ -248,7 +233,7 @@
       }
 
     };
-    
+
     try (Session session = ds.getSession()) {
       return session.<List<String>>rowPublisherOperation(sql)
               .subscribe(subscriber, result)
@@ -256,42 +241,39 @@
               .getCompletionStage();
     }
   }
-  
+
   // ArrayRowCountOperation
-  
-  public CompletionStage<Long> arrayInsert(DataSource ds, 
-                                           List<Integer> ids, 
-                                           List<String> names, 
+  public CompletionStage<Long> arrayInsert(DataSource ds,
+                                           List<Integer> ids,
+                                           List<String> names,
                                            List<Integer> answers) {
     String sql = "insert into tab values (?, ?, ?)";
     try (Session session = ds.getSession()) {
       return session.<Long>arrayRowCountOperation(sql)
-          .collect(Collectors.summingLong( c -> c.getCount() ))
-          .set("1",ids, AdbaType.INTEGER)
-          .set("2", names, AdbaType.VARCHAR)
-          .set("3", answers, AdbaType.INTEGER)
-          .submit()
-          .getCompletionStage();
+              .collect(Collectors.summingLong(c -> c.getCount()))
+              .set("1", ids, AdbaType.INTEGER)
+              .set("2", names, AdbaType.VARCHAR)
+              .set("3", answers, AdbaType.INTEGER)
+              .submit()
+              .getCompletionStage();
     }
   }
-  
+
   // ArrayRowCountOperation -- transposed
-  
   public CompletionStage<Long> transposedArrayInsert(DataSource ds, List<Item> items) {
     String sql = "insert into tab values (?, ?, ?)";
     try (Session session = ds.getSession()) {
       return session.<Long>arrayRowCountOperation(sql)
-          .collect(Collectors.summingLong( c -> c.getCount() ))
-          .set("1", items.stream().map(Item::id).collect(Collectors.toList()), AdbaType.INTEGER)
-          .set("2", items.stream().map(Item::name).collect(Collectors.toList()), AdbaType.VARCHAR)
-          .set("3", items.stream().map(Item::answer).collect(Collectors.toList()), AdbaType.INTEGER)
-          .submit()
-          .getCompletionStage();
+              .collect(Collectors.summingLong(c -> c.getCount()))
+              .set("1", items.stream().map(Item::id).collect(Collectors.toList()), AdbaType.INTEGER)
+              .set("2", items.stream().map(Item::name).collect(Collectors.toList()), AdbaType.VARCHAR)
+              .set("3", items.stream().map(Item::answer).collect(Collectors.toList()), AdbaType.INTEGER)
+              .submit()
+              .getCompletionStage();
     }
   }
-  
+
   // OutOperation
-  
   public CompletionStage<Item> getItem(DataSource ds, int id) {
     String sql = "call item_for_id(:id, :name, :answer)";
     try (Session session = ds.getSession()) {
@@ -299,63 +281,99 @@
               .set("id", id, AdbaType.INTEGER)
               .outParameter("name", AdbaType.VARCHAR)
               .outParameter("answer", AdbaType.INTEGER)
-              .apply( out -> new Item(id, 
-                                      out.at("name").get(String.class), 
-                                      out.at("answer").get(Integer.class)) )
+              .apply(out -> new Item(id,
+                                     out.at("name").get(String.class),
+                                     out.at("answer").get(Integer.class)))
               .submit()
               .getCompletionStage();
     }
   }
-  
+
   // MultiOperation
-  
   // LocalOperation
-  
   // Control Operation Submission Rate
-    
-  public CompletionStage<Long> insertRecords(DataSource ds, DataInputStream in) {
-    String insert = "insert into tab values (@record)";
-    try (Session session = ds.getSession()) {
-      OperationGroup<Long, Long> group = session.<Long, Long>operationGroup()
+  public class RecordSubscriber implements Subscriber<byte[]> {
+
+    private final Session session;
+    private OperationGroup<Long, Long> group;
+
+    public RecordSubscriber(DataSource ds) {
+      session = ds.getSession();
+    }
+
+    @Override
+    public void onSubscribe(Subscription subscription) {
+      group = session.<Long, Long>operationGroup()
               .independent()
               .collect(Collectors.summingLong(c -> c));
-      group.submitHoldingForMoreMembers();
-      Semaphore demand = new Semaphore(0);
-      session.requestHook( n -> demand.release((int)n) );
-      while (in.available() > 0) {
-        demand.acquire(1); // user thread blocked by Semaphore, not by ADBA
-        group.<Long>rowCountOperation(insert)
-                    .set("record", in.readUTF(), AdbaType.VARCHAR)
-                    .apply(c -> c.getCount())
-                    .submit();
-      }
-      return group.releaseProhibitingMoreMembers()
-                  .getCompletionStage();
+      group.submit();
+      session.requestHook(subscription::request);
+    }
+
+    @Override
+    public void onNext(byte[] item) {
+      String insert = "insert into tab values (@record)";
+      group.<Long>rowCountOperation(insert)
+              .set("record", item, AdbaType.VARBINARY)
+              .apply(c -> c.getCount())
+              .submit();
     }
-    catch (IOException | InterruptedException ex) { 
-      throw new SqlException(ex);
+
+    @Override
+    public void onError(Throwable t) {
+      group.close();
+      session.close();
+    }
+
+    @Override
+    public void onComplete() {
+      group.close();
+      session.close();
     }
   }
-  
+
   // Controlling Session creation rate
-  
-  public void ingest(DataInputStream in) throws Exception {
-    DataSourceFactory factory = DataSourceFactory.newFactory("com.oracle.adbaoverjdbc.DataSourceFactory");
-    Semaphore demand = new Semaphore(0);
-    DataSource ds = factory.builder()
-            .requestHook( n -> demand.release((int)n) )
-            .build();
-    AtomicLong total = new AtomicLong(0L);
-    do {
-      demand.acquire(1);
-      insertRecords(ds, in).thenAccept(total::addAndGet);
-    } while (true);
+  public class ItemSubscriber implements Subscriber<Item> {
+
+    private final DataSourceFactory factory;
+    private DataSource ds;
+
+    public ItemSubscriber(DataSourceFactory f) {
+      factory = f;
+    }
+
+    @Override
+    public void onSubscribe(Subscription subscription) {
+      ds = factory.builder()
+              .url("//host.oracle.com:5521/example")
+              .username("scott")
+              .password("tiger")
+              .requestHook(subscription::request)
+              .build();
+    }
+
+    @Override
+    public void onNext(Item item) {
+      try (Session s = ds.getSession()) {
+        insertItem(s, item);
+      }
+    }
+
+    @Override
+    public void onError(Throwable t) {
+      ds.close();
+    }
+
+    @Override
+    public void onComplete() {
+      ds.close();
+    }
   }
-  
+
   // SessionProperty
   public enum ExampleSessionProperty implements SessionProperty {
     LANGUAGE;
-    
+
     private static final String DEFAULT_VALUE = "AMERICAN_AMERICA";
 
     @Override
@@ -375,14 +393,14 @@
 
     @Override
     public boolean configureOperation(OperationGroup<?, ?> group, Object value) {
-      group.operation("ALTER SESSION SET NLS_LANG = " 
-                      + group.enquoteIdentifier((String)value, false))
+      group.operation("ALTER SESSION SET NLS_LANG = "
+              + group.enquoteIdentifier((String) value, false))
               .submit();
       return true;
     }
-    
+
   }
-  
+
   public DataSource getDataSource(DataSourceFactory factory) {
     return factory.builder()
             .registerSessionProperty(ExampleSessionProperty.LANGUAGE)
@@ -390,32 +408,38 @@
             // or .sessionProperty(ExampleSessionProperty.LANGUAGE, "FRENCHCANADIAN_CANADA")
             .build();
   }
-  
+
   public Session getSession(DataSource ds) {
     return ds.builder()
             .property(ExampleSessionProperty.LANGUAGE, "FRENCH_FRANCE")
             .build()
             .attach();
   }
-  
+
   // Sharding
-  
   // TransactionOutcome
-  
   // Column navigation
-  
-  private class Name { Name(String ... args) {} }
-  private class Address { Address(String ... args) {} }
-  
+  private class Name {
+
+    Name(String... args) {
+    }
+  }
+
+  private class Address {
+
+    Address(String... args) {
+    }
+  }
+
   private Name getName(Result.Column col) {
     return new Name(
-      col.get(String.class), // title
-      col.next().get(String.class), // given name
-      col.next().get(String.class), // middle initial
-      col.next().get(String.class), // family name
-      col.next().get(String.class)); // suffix
+            col.get(String.class), // title
+            col.next().get(String.class), // given name
+            col.next().get(String.class), // middle initial
+            col.next().get(String.class), // family name
+            col.next().get(String.class)); // suffix
   }
-  
+
   private Address getAddress(Result.Column col) {
     List<String> a = new ArrayList<>();
     for (Result.Column c : col.slice(6)) {
@@ -423,6 +447,8 @@
     }
     return new Address(a.toArray(new String[0]));
   }
+
+  @SuppressWarnings("unused")
   public void columNavigation(Result.RowColumn column) {
     Name fullName = getName(column.at("name_title"));
     Address streetAddress = getAddress(column.at("street_address_line1"));
@@ -431,29 +457,28 @@
       System.out.println("trailing column " + c.get(String.class));
     }
   }
-  
-  // Error handling
 
-  
+  // Error handling
   static public class Item {
+
     public int id;
     public String name;
     public int answer;
-    
+
     public Item(int i, String n, int a) {
-      id =i;
+      id = i;
       name = n;
       answer = a;
     }
-    
+
     public int id() {
       return id;
     }
-    
+
     public String name() {
       return name;
     }
-    
+
     public int answer() {
       return answer;
     }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/LocalOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -54,9 +54,19 @@
    */
   public LocalOperation<T> onExecution(Callable<T> action);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code LocalOperation}
+   */
   @Override
   public LocalOperation<T> onError(Consumer<Throwable> handler);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code LocalOperation}
+   */
   @Override
   public LocalOperation<T> timeout(Duration minTime);
   
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/MultiOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/MultiOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -33,14 +33,18 @@
 /**
  * A multi-operation is an {@link Operation} that returns one or more results in
  * addition to the out result defined by the {@link Operation}. Each result is
- * processed by an Operation. The Operations can be created by calling
- * rowOperation, rowProcessorOperation, or countOperation if the kind of results
- * is known. These results are processed in the order the Operations are
- * submitted. Any results not processed by an explicit Operation is processed by
- * calling the appropriate handler specified by onRows or onCount. If any result
- * is an error that error is processed by calling the handler specified by
- * onError. If the appropriate handler is not specified that result is ignored,
- * including errors.
+ * processed by an {@link Operation}. The {@link Operation}s can be created by
+ * calling
+ * {@link MultiOperation#rowOperation}, {@link MultiOperation#rowProcessorOperation},
+ * or {@link MultiOperation#rowCountOperation} if the kind of results is known.
+ * These results are processed in the order the {@link Operation}s are
+ * submitted. Any results not processed by an explicit {@link Operation} is
+ * processed by calling the appropriate handler specified by
+ * {@link MultiOperation#onRows} or {@link MultiOperation#onCount}. If any
+ * result is an error that error is processed by calling the handler specified
+ * by {@link Operation#onError} of the corresponding {@link Operation}. If the
+ * appropriate handler is not specified that result is ignored, including
+ * errors.
  *
  * ISSUE: Should this have a collector?
  *
@@ -52,9 +56,9 @@
    * Returns a {@link RowOperation} to process a row sequence result. The
    * {@link Operation}s are executed in the order they are submitted. If a
    * result is of the wrong type for the next submitted {@link Operation} the
-   * {@link MultiOperation} is completed with {@link IllegalStateException}.
+   * {@code MultiOperation} is completed with {@link IllegalStateException}.
    *
-   * @return a {@link RowOperation} that is part of this {@link MultiOperation}
+   * @return a {@link RowOperation} that is part of this {@code MultiOperation}
    */
   public RowOperation<T> rowOperation();
 
@@ -62,21 +66,21 @@
    * Returns a {@link RowPublisherOperation} to process a row sequence result.
    * The {@link Operation}s are executed in the order they are submitted. If a
    * result is of the wrong type for the next submitted {@link Operation} the
-   * {@link MultiOperation} is completed with {@link IllegalStateException}.
+   * {@code MultiOperation} is completed with {@link IllegalStateException}.
    *
    * @return a {@link RowPublisherOperation} that is part of this
-   * {@link MultiOperation}
+   * {@code MultiOperation}
    */
-  public RowPublisherOperation<T> rowProcessorOperation();
+  public RowPublisherOperation<T> rowPublisherOperation();
 
   /**
    * Returns a {@link RowCountOperation} to process a count result. The
    * {@link Operation}s are executed in the order they are submitted. If a
    * result is of the wrong type for the next submitted Operation the
-   * {@link MultiOperation} is completed with {@link IllegalStateException}.
+   * {@code MultiOperation} is completed with {@link IllegalStateException}.
    *
    * @return a {@link RowCountOperation} that is part of this
-   * {@link MultiOperation}
+   * {@code MultiOperation}
    */
   public RowCountOperation<T> rowCountOperation();
 
@@ -95,7 +99,7 @@
    * If this method is not called any trailing count results are ignored.
    *
    * @param handler not null
-   * @return this MultiOperation
+   * @return this {@code MultiOperation}
    * @throws IllegalStateException if this method was called previously
    */
   public MultiOperation<T> onCount(BiConsumer<Integer, RowCountOperation<T>> handler);
@@ -118,7 +122,7 @@
    * called.
    *
    * @param handler
-   * @return This MultiOperation
+   * @return This {@code MultiOperation}
    * @throws IllegalStateException if this method was called previously
    */
   public MultiOperation<T> onRows(BiConsumer<Integer, RowOperation<T>> handler);
@@ -128,13 +132,13 @@
    * is called for each error that occurs. When called the first argument is the
    * number of results, including errors, that preceeded the current error. The
    * second argument is a {@link Throwable} corresponding to the error. When the
-   * handler returns processing of the MultiOperation results continues. Only
+   * handler returns processing of the {@code MultiOperation} results continues. Only
    * one onError method may be called.
    *
    * @param handler a BiConsumer that handles an error
-   * @return this MultiOperation
-   * @throws IllegalStateException if this method or 
-   * {@link MultiOperation#onError(java.util.function.Consumer)} was called 
+   * @return this {@code MultiOperation}
+   * @throws IllegalStateException if this method or
+   * {@link MultiOperation#onError(java.util.function.Consumer)} was called
    * previously
    */
   public MultiOperation<T> onError(BiConsumer<Integer, Throwable> handler);
@@ -145,30 +149,66 @@
    * returns any individual results, even if any or all of those results are
    * errors, this handler is not called.
    *
-   * @param handler
-   * @return
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
    */
   @Override
   public MultiOperation<T> onError(Consumer<Throwable> handler);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> apply(Function<Result.OutColumn, ? extends T> processor);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> outParameter(String id, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> set(String id, Object value, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> set(String id, Object value);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> set(String id, CompletionStage<?> source, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> set(String id, CompletionStage<?> source);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code MultiOperation}
+   */
   @Override
   public MultiOperation<T> timeout(Duration minTime);
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Operation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -29,61 +29,63 @@
 
 /**
  * A description of some work to be done by the database and how to process the
- * database output. An {@link Operation} is created by an
+ * database output. An {@code Operation} is created by an
  * {@link OperationGroup}, configured and submitted. If not submitted it is not
  * executed. If submitted it is possibly executed according to the attributes of
  * the {@link OperationGroup} that created it.
- * 
+ *
  * <p>
- * If execution of the work results in an error, the Operation is completed
- * exceptionally. The {@link Throwable} that completes the Operation is
- * implementation dependent. It is recommended that an implementation use
- * SqlException in the event of database problems. Other {@link Throwable}s such
- * as {@link java.io.IOException}, {@link NullPointerException}, etc can be used
- * as appropriate. An implementation should not wrap a useful exception in a
+ * If execution of the work results in an error, the {@code Operation} is
+ * completed exceptionally. The {@link Throwable} that completes the
+ * {@code Operation} is implementation dependent. It is recommended that an
+ * implementation use {@link SqlException} in the event of database problems.
+ * Other {@link Throwable}s such as
+ * {@link java.io.IOException}, {@link NullPointerException}, etc can be used as
+ * appropriate. An implementation should not wrap a useful exception in a
  * {@link SqlException} unless that provides valuable additional information. An
  * implementation should use whatever {@link Throwable} best facilitates
  * appropriate error handling.</p>
- * 
+ *
  * <p>
- * An Operation is not required to be thread safe. In general a single user
- * thread will configure and submit an Operation. Once an Operation is submitted
- * it is immutable. {@link OperationGroup} is an exception and is thread safe.</p>
+ * An {@code Operation} is not required to be thread safe. In general a single
+ * user thread will configure and submit an Operation. Once an {@code Operation}
+ * is submitted it is immutable. {@link OperationGroup} is an exception and is
+ * thread safe.</p>
  *
- * @param <T> the type of the result of the {@link Operation}
+ * @param <T> the type of the result of the {@code Operation}
  */
 public interface Operation<T> extends PrimitiveOperation<T> {
-  
+
   /**
-   * Provides an error handler for this {@link Operation}. If execution of this
-   * {@link Operation} results in an error, before the Operation is completed,
-   * the handler is called with the {@link Throwable} as the argument. The type
-   * of the {@link Throwable} is implementation dependent.
-   * 
+   * Provides an error handler for this {@code Operation}. If execution of this
+   * {@code Operation} results in an error, before the {@code Operation} is
+   * completed, the handler is called with the {@link Throwable} as the
+   * argument. The type of the {@link Throwable} is implementation dependent.
+   *
    * @param handler
-   * @return this {@link Operation}
+   * @return this {@code Operation}
    * @throws IllegalStateException if this method is called more than once on
-   * this operation
+   * this {@code Operation}
    */
   public Operation<T> onError(Consumer<Throwable> handler);
-  
+
   /**
-   * The minimum time before this {@link Operation} might be canceled
-   * automatically. The default value is forever. The time is
-   * counted from the beginning of Operation execution. The Operation will not
-   * be canceled before {@code minTime} after the beginning of execution.
-   * Some time at least {@code minTime} after the beginning of execution,
-   * an attempt will be made to cancel the {@link Operation} if it has not yet
-   * completed. Implementations are encouraged to attempt to cancel within a
-   * reasonable time, though what is reasonable is implementation dependent.
+   * The minimum time before this {@code Operation} might be canceled
+   * automatically. The default value is forever. The time is counted from the
+   * beginning of Operation execution. The Operation will not be canceled before
+   * {@code minTime} after the beginning of execution. Some time at least
+   * {@code minTime} after the beginning of execution, an attempt will be made
+   * to cancel the {@code Operation} if it has not yet completed.
+   * Implementations are encouraged to attempt to cancel within a reasonable
+   * time, though what is reasonable is implementation dependent.
    *
    * @param minTime minimum time to wait before attempting to cancel
-   * @return this Operation
-   * @throws IllegalArgumentException if minTime &lt;= {@link java.time.Duration#ZERO}
+   * @return this {@code Operation}
+   * @throws IllegalArgumentException if minTime &lt;=
+   * {@link java.time.Duration#ZERO}
    * @throws IllegalStateException if this method is called more than once on
-   * this operation
+   * this {@code Operation}
    */
   public Operation<T> timeout(Duration minTime);
 
-
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OperationGroup.java	Sat Oct 20 08:17:38 2018 -0400
@@ -35,119 +35,157 @@
  * <p>
  * A set of {@link Operation}s that share certain properties, are managed as a
  * unit, and are executed as a unit. The {@link Operation}s created by an
- * {@link OperationGroup} and submitted are the member {@link Operation}s of
- * that {@link OperationGroup}. An {@link OperationGroup} is not a transaction
+ * {@code OperationGroup} and submitted are the member {@link Operation}s of
+ * that {@code OperationGroup}. An {@code OperationGroup} is not a transaction
  * and is not related to a transaction in any way.</p>
  *
  * <p>
- * An {@link OperationGroup} conceptually has a collection of member
- * {@link Operation}s. When an {@link OperationGroup} is submitted it is placed
- * in the collection of the {@link OperationGroup} of which it is a member. The
- * member {@link OperationGroup} is executed according to the attributes of the
- * {@link OperationGroup} of which it is a member. The member {@link Operation}s
- * of an {@link OperationGroup} are executed according to the attributes of that
- * {@link OperationGroup}.</p>
+ * An {@link OperationGroup} provides conditional execution, control of error
+ * response, and control of execution order.</p>
+ *
+ * <p>
+ * Execution of one or more {@link Operation}s may depend on the result of a
+ * previous {@link Operation}. Depending on the result of that previous
+ * {@link Operation} some other {@link Operation}s perhaps should not be
+ * executed. For example consider an account withdrawal. If the amount to
+ * withdraw exceeds the account balance the withdrawal {@link Operation}s should
+ * not be executed and an overdraft {@link Operation} should be executed
+ * instead. It would be possible for the user thread to wait for the balance
+ * check {@link Operation} but that would block. Better would be to use the
+ * {@link java.util.concurrent.CompletionStage} of the balance check
+ * {@link Operation} and submit the appropriate {@link Operation} in a
+ * subsequent stage. But this is a common pattern and it is better still to
+ * encapsulate that pattern, which conditional {@link OperationGroup} does.</p>
+ *
+ * <p>
+ * Not all {@link Operation}s need to be executed in the order submitted. The
+ * most common example is a mass insert. The order in which the records are
+ * inserted doesn’t matter. A parallel {@link OperationGroup} gives the
+ * implementation the freedom to execute the {@link Operation}s in any order. If
+ * some of the {@link Operation}s have
+ * {@link java.util.concurrent.CompletionStage} parameters this can be
+ * especially valuable.</p>
+ *
+ * <p>
+ * {@link OperationGroup} also allows control of error response. By default if
+ * one {@link Operation} fails all subsequent {@link Operation}s are skipped.
+ * That’s not always right. Consider the mass insert case. Just because one
+ * insert fails doesn’t mean they should all fail. An independent
+ * {@link OperationGroup} does this; the failure of one {@link Operation} has no
+ * impact on the execution of the rest.</p>
  *
  * <p>
- * How an {@link OperationGroup} is executed depends on its attributes.</p>
+ * As an {@link OperationGroup} is an {@link Operation} it must be submitted
+ * before its member {@link Operation}s are executed. Submitting an {@link OperationGroup}
+ * allows its member {@link Operation}s to be executed but does not prohibit more
+ * member {@link Operation}s from being submitted. Member {@link Operation}s may be 
+ * submitted before and after the containing {@link OperationGroup} is submitted.</p>
  *
  * <p>
- * If an {@link OperationGroup} has a condition and the value of that condition
- * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below.
- * If it is {@link Boolean#FALSE} then the {@link OperationGroup} is completed
- * with the value null. If the condition completed exceptionally then the
- * {@link OperationGroup} is completed exceptionally with a
- * {@link SqlSkippedException} that has that exception as its cause.</p>
+ * The result of an {@link OperationGroup} depends on the results of its member
+ * {@link Operation}s. Therefore an {@link OperationGroup} must know when all
+ * member {@link Operation}s have been submitted. It cannot generate a
+ * result until all member {@link Operation}s are completed. Since member {@link Operation}s can be
+ * submitted after the {@link OperationGroup} has been submitted (see previous
+ * paragraph) submitting the containing {@link OperationGroup} is not sufficient to mark that all member
+ * {@link Operation}s have been submitted. Calling {@link OperationGroup#close} signals
+ * that all member Operations have been submitted. After close is called, no
+ * more member Operations may be submitted and the OperationGroup will complete 
+ * when all member Operations are complete.</p>
  * 
  * <p>
- * If the {@link OperationGroup} is sequential the member {@link Operation}s are
+ * An {@code OperationGroup} conceptually has a collection of member
+ * {@link Operation}s. When an {@code OperationGroup} is submitted it is placed
+ * in the collection of the {@code OperationGroup} of which it is a member. The
+ * member {@code OperationGroup} is executed according to the attributes of the
+ * {@code OperationGroup} of which it is a member. The member {@link Operation}s
+ * of an {@code OperationGroup} are executed according to the attributes of that
+ * {@code OperationGroup}.</p>
+ *
+ * <p>
+ * How an {@code OperationGroup} is executed depends on its attributes.</p>
+ *
+ * <p>
+ * If an {@code OperationGroup} has a condition and the value of that condition
+ * is {@link Boolean#TRUE} then execute the member {@link Operation}s as below.
+ * If it is {@link Boolean#FALSE} then the {@code OperationGroup} is completed
+ * with the value null. If the condition completed exceptionally then the
+ * {@code OperationGroup} is completed exceptionally with a
+ * {@link SqlSkippedException} that has that exception as its cause.</p>
+ *
+ * <p>
+ * If the {@code OperationGroup} is sequential the member {@link Operation}s are
  * executed in the order they were submitted. If it is parallel, they may be
  * executed in any order including simultaneously.</p>
  *
  * <p>
- * If an {@link OperationGroup} is dependent and a member {@link Operation}
+ * If an {@code OperationGroup} is dependent and a member {@link Operation}
  * completes exceptionally the remaining member {@link Operation}s in the
  * collection are completed exceptionally with a {@link SqlSkippedException}
- * that has the initial {@link Exception} as its cause and the {@link OperationGroup}
- * is completed exceptionally with the initial {@link Exception}. A member
- * {@link Operation} in-flight may either complete normally or be completed
- * exceptionally but must complete one way or the other. [NOTE: Too strong?]</p>
+ * that has the initial {@link Exception} as its cause and the
+ * {@code OperationGroup} is completed exceptionally with the initial
+ * {@link Exception}. A member {@link Operation} in-flight may either complete
+ * normally or be completed exceptionally but must complete one way or the
+ * other. [NOTE: Too strong?]</p>
  *
  * <p>
- * After a call to {@link OperationGroup#submitHoldingForMoreMembers} the
- * {@link OperationGroup} is submitted and held. After a call to 
- * {@link OperationGroup#releaseProhibitingMoreMembers} the {@link OperationGroup} 
- * is no longer held and is still submitted. Holding permits member {@link Operation}s
- * to be executed at the same time additional member {@link Operation}s are
- * submitted. Collecting the member {@link Operation}s' results does not begin
- * until the {@link OperationGroup} is no longer held.</p>
- * 
- * <p>
- * If an {@link OperationGroup} is held additional member {@link Operation}s may
- * be submitted. If an {@link OperationGroup} is not held, no additional member 
- * {@link Operation}s  may be submitted after the {@link OperationGroup} is 
- * submitted. If an {@link OperationGroup} is held it will be completed only after 
- * it is released or if conditional and the condition is not {@link Boolean#TRUE}. 
- * If a {@link OperationGroup} is dependent, held, one of its member
- * {@link Operation}s completed exceptionally, and its queue is empty then the
- * {@link OperationGroup} is released.</p>
+ * The result of this {@code OperationGroup} is the result of collecting the
+ * results of its member {@link Operation}s. If the {@code OperationGroup} is
+ * dependent and one of its member {@link Operation}s completes exceptionally,
+ * the {@code OperationGroup} is completed exceptionally.</p>
  *
  * <p>
- * The result of this {@link OperationGroup} is the result of collecting the
- * results of its member {@link Operation}s. If the {@link OperationGroup} is 
- * dependent and one of its member {@link Operation}s completes exceptionally,
- * the {@link OperationGroup} is completed exceptionally.</p>
- * 
- * <p>
  * An implementation of this class must be thread safe as result and error
- * handlers running asynchronously may be accessing an {@link OperationGroup} in
+ * handlers running asynchronously may be accessing an {@code OperationGroup} in
  * parallel with each other and with a user thread.</p>
-
+ *
 * <p>
- * ISSUE: Currently no way to create a nested {@link OperationGroup}. That is an
- * intentional limitation but may be a simplification we can live with. Or not.</p>
+ * ISSUE: Currently no way to create a nested {@code OperationGroup}. That is an
+ * intentional limitation but may be a simplification we can live with. Or
+ * not.</p>
  *
  * @param <S> The type of the result of the member {@link Operation}s
  * @param <T> The type of the collected results the member {@link Operation}s
  */
-public interface OperationGroup<S, T> extends Operation<T> {
+public interface OperationGroup<S, T> extends Operation<T>, AutoCloseable {
 
   /**
-   * Mark this {@link OperationGroup} as parallel. If this method is not called
-   * the {@link OperationGroup} is sequential. If an {@link OperationGroup} is
+   * Mark this {@code OperationGroup} as parallel. If this method is not called
+   * the {@code OperationGroup} is sequential. If an {@code OperationGroup} is
    * parallel, member {@link Operation}s may be executed in any order including
-   * in parallel. If an {@link OperationGroup} is sequential, the default,
+   * in parallel. If an {@code OperationGroup} is sequential, the default,
    * member {@link Operation}s are executed strictly in the order they are
    * submitted.
    *
-   * Note: There is no covariant override of this method in {@link Session}
-   * as there is only a small likelihood of needing it.
+   * Note: There is no covariant override of this method in {@link Session} as
+   * there is only a small likelihood of needing it.
    *
-   * @return this {@link OperationGroup}
-   * @throws IllegalStateException if this {@link OperationGroup} has been
+   * @return this {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} has been
    * submitted, any member {@link Operation}s have been created, or this method
    * has been called previously
    */
   public OperationGroup<S, T> parallel();
 
   /**
-   * Mark this {@link OperationGroup} as independent. If this method is not
-   * called the {@link OperationGroup} is dependent, the default. If an
-   * {@link OperationGroup} is independent then failure of one member
+   * Mark this {@code OperationGroup} as independent. If this method is not
+   * called the {@code OperationGroup} is dependent, the default. If an
+   * {@code OperationGroup} is independent then failure of one member
    * {@link Operation} does not affect the execution of other member
-   * {@link Operation}s. If an {@link OperationGroup} is dependent then failure
+   * {@link Operation}s. If an {@code OperationGroup} is dependent then failure
    * of one member {@link Operation} will cause all member {@link Operation}s
    * remaining in the queue to be completed exceptionally with a
    * {@link SqlSkippedException} with the cause set to the original exception.
    *
-   * The result of this {@link OperationGroup}'s execution is the result of collecting the
-   * results of the member {@link Operation}s that complete normally. 
+   * The result of this {@code OperationGroup}'s execution is the result of
+   * collecting the results of the member {@link Operation}s that complete
+   * normally.
    *
-   * Note: There is no covariant override of this method in {@link Session}
-   * as there is only a small likelihood of needing it.
+   * Note: There is no covariant override of this method in {@link Session} as
+   * there is only a small likelihood of needing it.
    *
-   * @return this {@link OperationGroup}
-   * @throws IllegalStateException if this {@link OperationGroup} has been 
+   * @return this {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} has been
    * submitted, any member {@link Operation}s have been created, or this method
    * has been called previously
    */
@@ -155,83 +193,41 @@
 
   /**
    * Define a condition that determines whether the member {@link Operation}s of
-   * this {@link OperationGroup} are executed or not. If and when this
-   * {@link OperationGroup} is executed then if the condition argument is
+   * this {@code OperationGroup} are executed or not. If and when this
+   * {@code OperationGroup} is executed then if the condition argument is
    * completed with {@link Boolean#TRUE} the member {@link Operation}s are
    * executed. If {@link Boolean#FALSE} or if it is completed exceptionally the
    * member {@link Operation}s are not executed but are removed from the queue.
    * After all member {@link Operation}s have been removed from the queue this
-   * {@link OperationGroup} is completed with {@code null}.
+   * {@code OperationGroup} is completed with {@code null}.
    *
-   * Note: There is no covariant override of this method in Session as there
-   * is only a small likelihood of needing it.
+   * Note: There is no covariant override of this method in Session as there is
+   * only a small likelihood of needing it.
    *
    * ISSUE: Should the member Operations be skipped or otherwise completed
    * exceptionally?
    *
    * @param condition a {@link CompletionStage} the value of which determines
-   * whether this {@link OperationGroup} is executed or not
+   * whether this {@code OperationGroup} is executed or not
    * @return this OperationGroup
-   * @throws IllegalStateException if this {@link OperationGroup} has been
+   * @throws IllegalStateException if this {@code OperationGroup} has been
    * submitted, any member {@link Operation}s have been created, or this method
    * has been called previously
    */
   public OperationGroup<S, T> conditional(CompletionStage<Boolean> condition);
 
   /**
-   * Mark this {@link OperationGroup} as submitted and held. It can be executed but cannot be
-   * completed. A {@link OperationGroup} that is held remains in the queue even
-   * if all of its current member {@link Operation}s have completed. So long as
-   * the {@link OperationGroup} is held new member {@link Operation}s can be
-   * submitted. A {@link OperationGroup} that is held must be released before it
-   * can be completed and removed from the queue.
-   * 
-   * If the {@link OperationGroup} is dependent and one of its member {@link Operation}s
-   * completes exceptionally and its queue is empty the {@link OperationGroup}
-   * is completed.
-   *
-   * Note: There is no covariant override of this method in Session as there
-   * is only a small likelihood of needing it.
-   *
-   * ISSUE: Need a better name.
-   *
-   * @return a Submission for this OperationGroup
-   * @throws IllegalStateException if this {@link OperationGroup} has been
-   * submitted
-   */
-  public Submission<T> submitHoldingForMoreMembers();
-
-  /**
-   * Allow this {@link OperationGroup} to be completed and removed from the
-   * queue once all of its member {@link Operation}s have been completed. After
-   * this method is called no additional member {@link Operation}s can be
-   * submitted. Once all member {@link Operation}s have been removed from the
-   * queue this {@link OperationGroup} will be completed and removed from the
-   * queue.
-   *
-   * Note: There is no covariant override of this method in Session as there
-   * is only a small likelihood of needing it.
-   *
-   * ISSUE: Need a better name.
-   *
-   * @return the same Submission that was returned by {@link OperationGroup#submitHoldingForMoreMembers}
-   * @throws IllegalStateException if this {@link OperationGroup} has been
-   * completed or is not held.
-   */
-  public Submission<T> releaseProhibitingMoreMembers();
-
-  /**
    * Provides a {@link Collector} to reduce the results of the member
-   * {@link Operation}s. The result of this {@link OperationGroup} is the result
+   * {@link Operation}s. The result of this {@code OperationGroup} is the result
    * of calling finisher on the final accumulated result.If the
    * {@link Collector} is {@link Collector.Characteristics#UNORDERED} the member
    * {@link Operation} results may be accumulated out of order.If the
    * {@link Collector} is {@link Collector.Characteristics#CONCURRENT} then the
    * member {@link Operation} results may be split into subsets that are reduced
-   * separately and then combined. If this {@link OperationGroup} is sequential,
+   * separately and then combined. If this {@code OperationGroup} is sequential,
    * the characteristics of the {@link Collector} only affect how the results of
    * the member {@link Operation}s are collected; the member {@link Operation}s
-   * are executed sequentially regardless. If this {@link OperationGroup} is
+   * are executed sequentially regardless. If this {@code OperationGroup} is
    * parallel the characteristics of the {@link Collector} may influence the
    * execution order of the member {@link Operation}s.
    *
@@ -241,10 +237,10 @@
    * @param c the Collector. Not null.
    * @return This OperationGroup
    * @throws IllegalStateException if called more than once or if this
-   * {@link OperationGroup} has been submitted
+   * {@code OperationGroup} has been submitted
    */
   public OperationGroup<S, T> collect(Collector<S, ?, T> c);
-  
+
   /**
    * Return a new member {@link PrimitiveOperation} that is never skipped.
    * Skipping of member {@link Operation}s stops with a catchOperation and the
@@ -253,19 +249,17 @@
    * exceptionally, it has no error handler or timeout.
    *
    * @return an {@link PrimitiveOperation} that is never skipped;
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held or if the {@link OperationGroup} is parallel or
-   * independent.
+   * @throws IllegalStateException if this {@code OperationGroup} is closed
+   * or if this {@code OperationGroup} is parallel or independent.
    */
   public PrimitiveOperation<S> catchOperation();
-  
+
   /**
    * Creates and submits a catch Operation. Convenience method.
    *
    * @return this OperationGroup
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held or if the {@link OperationGroup} is parallel or
-   * independent.
+   * @throws IllegalStateException if this {@code OperationGroup} is closed
+   * or if this {@code OperationGroup} is parallel or independent.
    */
   public default OperationGroup<S, T> catchErrors() {
     catchOperation().submit();
@@ -287,9 +281,8 @@
    * @param <R> the result type of the returned {@link ArrayRowCountOperation}
    * @param sql SQL to be executed. Must return an update count.
    * @return a new {@link ArrayRowCountOperation} that is a member of this
-   * {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> ArrayRowCountOperation<R> arrayRowCountOperation(String sql);
 
@@ -298,120 +291,113 @@
    *
    * @param <R> the result type of the returned {@link RowCountOperation}
    * @param sql SQL to be executed. Must return an update count.
-   * @return an new {@link ParameterizedRowCountOperation} that is a member of this
-   * {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * @return an new {@link ParameterizedRowCountOperation} that is a member of
+   * this {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> ParameterizedRowCountOperation<R> rowCountOperation(String sql);
 
   /**
    * Return a new {@link Operation} for a SQL that doesn't return any result,
    * for example DDL. The result of this Operation is always null.
-   * 
+   *
    * The result of the returned Operation must be Void but specifying that here
    * causes problems.
    *
    * @param sql SQL for the {@link Operation}.
    * @return a new {@link Operation} that is a member of this
-   * {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public Operation<S> operation(String sql);
 
   /**
-   * Return a new {@link OutOperation} that is a member {@link Operation} of this 
-   * {@link OperationGroup}. The SQL must return a set of zero or more out 
+   * Return a new {@link OutOperation} that is a member {@link Operation} of
+   * this {@code OperationGroup}. The SQL must return a set of zero or more out
    * parameters or function results.
    *
    * @param <R> the result type of the returned {@link OutOperation}
    * @param sql SQL for the {@link Operation}. Must return zero or more out
    * parameters or function results.
    * @return a new {@link OutOperation} that is a member of this
-   * {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> OutOperation<R> outOperation(String sql);
 
   /**
-   * Return a new {@link ParameterizedRowOperation} that is a member 
-   * {@link Operation} of this {@link OperationGroup}.
+   * Return a new {@link ParameterizedRowOperation} that is a member
+   * {@link Operation} of this {@code OperationGroup}.
    *
    * @param <R> the type of the result of the returned
    * {@link ParameterizedRowOperation}
    * @param sql SQL for the {@link Operation}. Must return a row sequence.
    * @return a new {@link ParameterizedRowOperation} that is a member of this
-   * {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> ParameterizedRowOperation<R> rowOperation(String sql);
 
   /**
    * Return a new {@link ParameterizedRowPublisherOperation} that is a member
-   * {@link Operation} of this {@link OperationGroup}.
+   * {@link Operation} of this {@code OperationGroup}.
    *
    * @param <R> the type of the result of the returned
    * {@link ParameterizedRowPublisherOperation}
    * @param sql SQL for the {@link Operation}. Must return a row sequence.
    * @return a new {@link ParameterizedRowPublisherOperation} that is a member
-   * of this {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * of this {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> ParameterizedRowPublisherOperation<R> rowPublisherOperation(String sql);
 
   /**
-   * Return a new {@link MultiOperation} that is a member 
-   * {@link Operation} of this {@link OperationGroup}.
+   * Return a new {@link MultiOperation} that is a member {@link Operation} of
+   * this {@code OperationGroup}.
    *
-   * @param <R> the type of the result of the returned
-   * {@link MultiOperation}
+   * @param <R> the type of the result of the returned {@link MultiOperation}
    * @param sql SQL for the {@link Operation}
    * @return a new {@link MultiOperation} that is a member of this
-   * {@link OperationGroup}
-   * @throws IllegalStateException if the {@link OperationGroup} has been
-   * submitted and is not held
+   * {@code OperationGroup}
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> MultiOperation<R> multiOperation(String sql);
 
   /**
    * Return a new {@link Operation} that ends the database transaction. This
-   * {@link Operation} is a member of the {@link OperationGroup}. The
+   * {@link Operation} is a member of the {@code OperationGroup}. The
    * transaction is ended with a commit unless the {@link TransactionCompletion}
    * has been {@link TransactionCompletion#setRollbackOnly} in which case the
    * transaction is ended with a rollback.
-   * 
+   *
    * <p>
    * An endTransaction Operation may be skipped. To insure that it will not be
    * skipped it should immediately follow a catch Operation. All end transaction
    * convenience methods do so.</p>
    *
-   * The type argument {@link S} of the containing {@link OperationGroup} must
+   * The type argument {@link S} of the containing {@code OperationGroup} must
    * be a supertype of {@link TransactionOutcome}.
    *
-   * @param trans the TransactionCompletion that determines whether the Operation does a 
- database commit or a database rollback.
+   * @param trans the TransactionCompletion that determines whether the
+   * Operation does a database commit or a database rollback.
    * @return an {@link Operation} that will end the database transaction.
-   * @throws IllegalStateException if this {@link OperationGroup} has been
-   * submitted and is not held or is parallel.
+   * @throws IllegalStateException if this {@code OperationGroup} is closed
+   * or is parallel.
    */
   public Operation<TransactionOutcome> endTransactionOperation(TransactionCompletion trans);
 
   /**
    * Convenience method that creates and submits a endTransaction
    * {@link Operation} that commits by default but can be set to rollback by
-   * calling {@link TransactionCompletion#setRollbackOnly}. The endTransaction Operation
-   * is never skipped.
+   * calling {@link TransactionCompletion#setRollbackOnly}. The endTransaction
+   * Operation is never skipped.
    *
-   * @param trans the TransactionCompletion that determines whether the {@link Operation} is a
-   * database commit or a database rollback.
-   * @return a {@link CompletionStage} that is completed with the outcome of the 
+   * @param trans the TransactionCompletion that determines whether the
+   * {@link Operation} is a database commit or a database rollback.
+   * @return a {@link CompletionStage} that is completed with the outcome of the
    * transaction
-   * @throws IllegalStateException if this {@link OperationGroup} has been
-   * submitted and is not held or is parallel.
+   * @throws IllegalStateException if this {@code OperationGroup} is closed
+   * or is parallel.
    */
   public default CompletionStage<TransactionOutcome> commitMaybeRollback(TransactionCompletion trans) {
     catchErrors();
@@ -419,23 +405,22 @@
   }
 
   /**
-   * Return a new {@link LocalOperation} that is a member {@link Operation} of 
-   * this {@link OperationGroup}.
+   * Return a new {@link LocalOperation} that is a member {@link Operation} of
+   * this {@code OperationGroup}.
    *
    * @param <R> value type of the returned local {@link Operation}
    * @return a LocalOperation
-   * @throws IllegalStateException if this {@link OperationGroup} has been submitted and
-   * is not held
+   * @throws IllegalStateException if this {@code OperationGroup} is closed.
    */
   public <R extends S> LocalOperation<R> localOperation();
 
   /**
    * Supply a {@link Logger} for the implementation of this
-   * {@link OperationGroup} to use to log significant events. Exactly what
+   * {@code OperationGroup} to use to log significant events. Exactly what
    * events are logged, at what Level the events are logged and with what
    * parameters is implementation dependent. All member {@link Operation}s of
-   * this {@link OperationGroup} will use the same {@link Logger} except a
-   * member {@link OperationGroup} that is supplied with a different
+   * this {@code OperationGroup} will use the same {@link Logger} except a
+   * member {@code OperationGroup} that is supplied with a different
    * {@link Logger} uses that {@link Logger}.
    *
    * Supplying a {@link Logger} configured with a
@@ -446,7 +431,7 @@
    * error will be logged.
    *
    * Implementation Note: Implementations are encouraged to log the creation of
-   * this {@link OperationGroup} set to {@link java.util.logging.Level#INFO},
+   * this {@code OperationGroup} set to {@link java.util.logging.Level#INFO},
    * the creation of member {@link Operation}s at the
    * {@link java.util.logging.Level#CONFIG} level, and execution of member
    * {@link Operation}s at the {@link java.util.logging.Level#FINE} level.
@@ -458,7 +443,7 @@
    * {@link java.util.logging.Level#SEVERE} Level.
    *
    * @param logger used by the implementation to log significant events
-   * @return this {@link OperationGroup}
+   * @return this {@code OperationGroup}
    */
   public OperationGroup<S, T> logger(Logger logger);
 
@@ -484,7 +469,7 @@
    * </table>
    * </blockquote>
    *
-   * @implNote JDBC driver implementations may need to provide their own
+   * @implNote ADBA driver implementations may need to provide their own
    * implementation of this method in order to meet the requirements of the
    * underlying datasource.
    * @param val a character string. Not null
@@ -594,7 +579,7 @@
    * as a quoted identifier
    * @return A simple SQL identifier or a delimited identifier. Not null
    * @throws NullPointerException if identifier is {@code null}
-   * @throws IllegalArgumentException if {@code identifier} can not be converted 
+   * @throws IllegalArgumentException if {@code identifier} can not be converted
    * to a valid identifier
    */
   default String enquoteIdentifier(String identifier, boolean alwaysQuote) {
@@ -723,11 +708,34 @@
     return "N'" + val.replace("'", "''") + "'";
   }
 
-    // Covariant overrides
+  /**
+   * Allow this {@code OperationGroup} to be completed and removed from the
+   * queue once all of its member {@link Operation}s have been completed. After
+   * this method is called no additional member {@link Operation}s can be
+   * submitted. Once all member {@link Operation}s have been removed from the
+   * queue this {@code OperationGroup} will be completed and removed from the
+   * queue.
+   * 
+   * {@inheritDoc}
+   */
+  @Override
+  public void close();
+
+  // Covariant overrides
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code OperationGroup}
+   */
   @Override
   public OperationGroup<S, T> timeout(Duration minTime);
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code OperationGroup}
+   */
   @Override
   public OperationGroup<S, T> onError(Consumer<Throwable> handler);
-  
+
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OutOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/OutOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -44,10 +44,10 @@
    * 
    * @param id the parameter identifier
    * @param type the SQL type of the value of the parameter
-   * @return this {@link OutOperation}
+   * @return this {@code OutOperation}
    * @throws IllegalArgumentException if id is not a parameter marker in the SQL
    * @throws IllegalStateException if this method has been called previously on
-   * this {@link Operation} with the same id or this {@link OutOperation} has been submitted
+   * this {@link Operation} with the same id or this {@code OutOperation} has been submitted
    */
   public OutOperation<T> outParameter(String id, SqlType type);
   
@@ -55,8 +55,8 @@
    * Provide a processor that will handle the result of executing the SQL.
    * 
    * @param processor the {@link Function} that will be called to process the result of
-   * this {@link OutOperation}
-   * @return this {@link OutOperation}
+   * this {@code OutOperation}
+   * @return this {@code OutOperation}
    * @throws IllegalStateException if this method has been called previously on
    * this {@link Operation} or this {@link Operation} has been submitted.
    */
@@ -64,21 +64,51 @@
 
   // Covariant overrides
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code OutOperation}
+   */
   @Override
   public OutOperation<T> onError(Consumer<Throwable> handler);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code OutOperation}
+   */
   @Override
   public OutOperation<T> set(String id, Object value);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code OutOperation}
+   */
   @Override
   public OutOperation<T> set(String id, Object value, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code OutOperation}
+   */
   @Override
   public OutOperation<T> set(String id, CompletionStage<?> source);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code OutOperation}
+   */
   @Override
   public OutOperation<T> set(String id, CompletionStage<?> source, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code OutOperation}
+  */
   @Override
   public OutOperation<T> timeout(Duration minTime);
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -38,7 +38,7 @@
  * 
  * A SQL structured type passed as an argument to a set method must be created
  * by the same {@link Session} that the created the
- * {@link ParameterizedOperation}. If not {@link IllegalArgumentException} is
+ * {@code ParameterizedOperation}. If not {@link IllegalArgumentException} is
  * thrown. A SQL structured type is one of
  * {@link SqlArray}, {@link SqlBlob}, {@link SqlClob}, {@link SqlRef} or
  * {@link SqlStruct}. This limitation holds recursively for all components of
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowCountOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowCountOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -31,7 +31,7 @@
 import java.util.function.Function;
 
 /**
- * A {@link ParameterizedRowCountOperation} is a {@link ParameterizedOperation} that returns a count.
+ * A {@code ParameterizedRowCountOperation} is a {@link ParameterizedOperation} that returns a count.
  *
  * @param <T> the type of the result of this {@link Operation}
  */
@@ -56,24 +56,59 @@
   
   // Covariant overrides
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   public ParameterizedRowCountOperation<T> onError(Consumer<Throwable> handler);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   ParameterizedRowCountOperation<T> apply(Function<Result.RowCount, ? extends T> processor);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   public ParameterizedRowCountOperation<T> set(String id, Object value);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   public ParameterizedRowCountOperation<T> set(String id, Object value, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   public ParameterizedRowCountOperation<T> set(String id, CompletionStage<?> source);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   public ParameterizedRowCountOperation<T> set(String id, CompletionStage<?> source, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowCountOperation}
+   */
   @Override
   public ParameterizedRowCountOperation<T> timeout(Duration minTime);
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -39,27 +39,67 @@
 
   // Covariant overrides
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> onError(Consumer<Throwable> handler);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> fetchSize(long rows) throws IllegalArgumentException;
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public <A, S extends T> ParameterizedRowOperation<T> collect(Collector<? super Result.RowColumn, A, S> c);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> set(String id, Object value, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> set(String id, CompletionStage<?> source, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> set(String id, CompletionStage<?> source);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> set(String id, Object value);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowOperation}
+   */
   @Override
   public ParameterizedRowOperation<T> timeout(Duration minTime);
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowPublisherOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ParameterizedRowPublisherOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -41,25 +41,60 @@
 
   // Covariant overrides
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> subscribe(Flow.Subscriber<? super Result.RowColumn> subscriber,
                                                           CompletionStage<? extends T> result);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> set(String id, Object value, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> set(String id, CompletionStage<?> source, SqlType type);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> set(String id, CompletionStage<?> source);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> set(String id, Object value);
 
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> onError(Consumer<Throwable> handler);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code ParameterizedRowPublisherOperation}
+   */
   @Override
   public ParameterizedRowPublisherOperation<T> timeout(Duration minTime);
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/PrimitiveOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/PrimitiveOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -30,7 +30,7 @@
  * 
  * References in JavaDoc to the "collection of Operations" and "member
  * Operations" should be understood to include PrimitiveOperations. The
- * distinction between {@link Operation} and {@link PrimitiveOperation} in the
+ * distinction between {@link Operation} and {@code PrimitiveOperation} in the
  * API is strictly followed as it enables the compiler to catch a significant
  * class of errors. The two types are not distinguished in the JavaDoc as making 
  * such a distinction would not add clarity.
@@ -41,16 +41,16 @@
 public interface PrimitiveOperation<T> {
 
   /**
-   * Add this {@link PrimitiveOperation} to the tail of the {@link Operation}
+   * Add this {@code PrimitiveOperation} to the tail of the {@link Operation}
    * collection of the {@link Session} that created this
-   * {@link PrimitiveOperation}. A {@link PrimitiveOperation} can be submitted
-   * only once. Once a {@link PrimitiveOperation} is submitted it is immutable.
-   * Any attempt to modify a submitted {@link PrimitiveOperation} will throw
+   * {@code PrimitiveOperation}. A {@code PrimitiveOperation} can be submitted
+   * only once. Once a {@code PrimitiveOperation} is submitted it is immutable.
+   * Any attempt to modify a submitted {@code PrimitiveOperation} will throw
    * {@link IllegalStateException}.
    *
-   * @return a {@link Submission} for this {@link PrimitiveOperation}
+   * @return a {@link Submission} for this {@code PrimitiveOperation}
    * @throws IllegalStateException if this method is called more than once on
-   * this {@link PrimitiveOperation}
+   * this {@code PrimitiveOperation}
    */
   Submission<T> submit();
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Result.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Result.java	Sat Oct 20 08:17:38 2018 -0400
@@ -37,7 +37,7 @@
 public interface Result {
 
   /**
-   * A {@link Result} that is just a number of rows modified, a {@link Long}.
+   * A {@code Result} that is just a number of rows modified, a {@link Long}.
    *
    * Note: It is certainly true that this is not needed; {@link Long} could be
    * used instead. Seems like there might be a documentational advantage to
@@ -56,10 +56,21 @@
   /**
    * A mutable handle to one value of an ordered sequence of columns of a row or
    * of out parameters. Columns have a 1-based index and optionally an
-   * identifier. Identifiers are not guaranteed to be unique. Only {@code clone}
-   * and {@code slice} create new instances. All other methods return this
-   * instance (modifying it if necessary) including {@code forEach},
-   * {@code next}, and {@code iterator}.
+   * identifier. Identifiers are not guaranteed to be unique.
+   * <br>
+   * A newly created Column is initially positioned on the first column of 
+   * it's sequence. The position is modified by calls to {@link #at(int)}, 
+   * {@link #at(String)}, {@link #next()}, or {@link #next(int)}. 
+   * The methods {@link #clone()}, {@link #slice(int)}, 
+   * {@link #forEach(Consumer)}, and {@link #iterator()} create new instances. 
+   * All other methods return this instance (modifying it if necessary) 
+   * including {@link #next()}, and {@link #forEachRemaining(Consumer)}.
+   * <br>
+   * In cases where the result of an operation has no columns, an instance of
+   * this class may represent an empty sequence of columns. Instances 
+   * associated to the empty sequence return 0 from calls to {@link #index()} 
+   * and {@link #absoluteIndex()}. It is illegal to modify the position or 
+   * accesses any attribute of a column if the sequence is empty.   
    */
   public interface Column extends Result, Iterable<Column>, Iterator<Column>, Cloneable {
 
@@ -69,6 +80,7 @@
      * @param <T>
      * @param type
      * @return the value of this {@link Column}
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public <T> T get(Class<T> type);
 
@@ -78,6 +90,7 @@
      *
      * @param <T>
      * @return the value of this {@link Column}
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public default <T> T get() {
       return get(javaType());
@@ -87,22 +100,30 @@
      * Return the identifier of this {@link Column}. May be null.
      *
      * @return the identifier of this {@link Column}. May be null
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public String identifier();
 
     /**
-     * Return the 1-based index of this {@link Column}. The returned value is
-     * relative to the slice if this {@link Column} is the result of a call to
-     * {@code slice()}. {@code
-     * col.slice(n).index() == 1}.
-     *
+     * Return the 1-based index of this {@link Column}. If the column 
+     * sequence is empty, the return value is 0.
+     * <br>
+     * The returned value is relative to the slice if this {@link Column} is 
+     * the result of a call to {@link #slice(int)}. 
+     * <br>
+     * {@code col.slice(n).index() == 1}.
+     * <br>
+     * {@code col.slice(n).next().index() == 2}.
+     *  
      * @return the index of this {@link Column}
      */
     public int index();
 
     /**
      * Return the 1-based index of this {@link Column} relative to the original
-     * sequence of values.
+     * sequence of values. If the column sequence is empty, the return value 
+     * is 0.
+     * <br>
      * {@code col.absoluteIndex() == col.slice(n).absoluteIndex()}.
      *
      * @return the absolute 1-based index of this {@link Column}
@@ -113,6 +134,7 @@
      * Return the SQL type of the value of this {@link Column}.
      *
      * @return the SQL type of this value
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public SqlType sqlType();
 
@@ -123,6 +145,7 @@
      * @param <T>
      * @return a {@link Class} that best represents the value of this
      * {@link Column}
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public <T>Class<T> javaType();
 
@@ -132,6 +155,7 @@
      * @return
      * @throws UnsupportedOperationException if the length of the current value
      * is undefined
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public long length();
 
@@ -158,18 +182,20 @@
      * @param id an identifier. Not null
      * @return this {@link Column}
      * @throws NoSuchElementException if id does not identify exactly one value
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public Column at(String id);
 
     /**
      * Modify this {@link Column} to point to the value at {@code index}. The
-     * first value is at index 1. Negative numbers count back from the last
+     * first value is at index 1. Negative numbers count back from the last 
      * value. The last value is at index -1.
      *
      * @param index a new index
      * @return this {@link Column}
-     * @throws NoSuchElementException if {@code index > length} or
-     * {@code index < -length}
+     * @throws NoSuchElementException if {@code index > length}, 
+     * {@code index < -length}, or {@code index == 0}
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public Column at(int index);
 
@@ -177,15 +203,20 @@
      * Modify this {@link Column} to point to the value at the current index +
      * {@code offset}. If {@code offset} is 0 this is a noop. If {@code offset}
      * is negative the new index is less than the current index. If the new
-     * index would be less than 1 or greater than length this {@link Column} is
-     * not modified and {@link IllegalArgumentException} is thrown.
+     * index would be less than 1 or greater than the sequence length this 
+     * {@link Column} is not modified and {@link IllegalArgumentException} is 
+     * thrown.
      *
      * @param offset an increment to the current index
      * @return this {@link Column}
      * @throws NoSuchElementException if the new index would be less than 1 or
-     * greater than {@code length}
+     * greater than the sequence length.
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public default Column next(int offset) {
+      if (index() == 0) {
+        throw new IllegalStateException();
+      }
       int newIndex = index() + offset;
       if (offset > numberOfValuesRemaining() || newIndex < 1) {
         throw new NoSuchElementException();
@@ -199,16 +230,20 @@
      * consists of {@code numValues} number of values. If {@code numValues} is
      * positive the values are the value of this column and its successors. If
      * {@code numValues} is negative the values are the predecessors of this
-     * column not including this {@link Column}. The order of the values of the
-     * new {@link Column} is the same as the order of the values of this
-     * {@link Column}. The returned {@link Column} points to the first value of
-     * the slice. This {@link Column} is not modified.
+     * column not including this {@link Column}.
+     * <br> 
+     * The returned {@link Column} is positioned on the first value of the 
+     * slice.
+     * <br>
+     * The order of the values of the new {@link Column} is the same as the 
+     * order of the values of this {@link Column}. This {@link Column} 
+     * is not modified.
      *
      * @param numValues the number of columns to include in the slice
      * @return a new {@link Column}.
      * @throws NoSuchElementException if the current index plus
-     * {@code numValues} is greater than the number of values of this
-     * {@link Column} or less than 1
+     * {@code numValues} is greater than the sequence length or less than 1
+     * @throws IllegalStateException if the column sequence is empty.
      */
     public Column slice(int numValues);
 
@@ -225,30 +260,66 @@
      *
      * @return this {@link Column}
      * @throws NoSuchElementException if the new index would be greater than
-     * {@code length}
+     * the sequence length.
+     * @throws IllegalStateException if the column sequence is empty.
      */
-    @Override
     public default Column next() {
       return next(1);
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public default boolean hasNext() {
       return numberOfValuesRemaining() > 0;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public default void forEach(Consumer<? super Column> action) {
-      do {
-        action.accept(this);
-        if (!hasNext()) break;
-        next();
-      } while (true);
+      if (index() == 0) {
+        return;
+      }
+      action.accept(this.clone());
+      while (hasNext()) {
+        action.accept(next().clone());
+      }
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public default Column iterator() {
-      return this.clone();
+    public default Iterator<Column> iterator() {
+      return new Iterator<Column>() {
+        Column next = Column.this.index() == 0 ? null : Column.this.clone();
+  
+        @Override
+        public boolean hasNext() {
+          return next != null;
+        }
+  
+        @Override
+        public Column next() {
+          if (!hasNext()) {
+            throw new NoSuchElementException();
+          }
+          
+          Column prev = next.clone();
+          
+          if (next.hasNext()) {
+            next.next();
+          }
+          else {
+            next = null;
+          }
+          
+          return prev;
+        }
+      };
     }
 
     /**
@@ -264,9 +335,12 @@
      *
      * @return a {@link java.util.Spliterator}
      */
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public default Spliterator<Column> spliterator() {
-      List list = new ArrayList<>(numberOfValuesRemaining());
+      List<Column> list = new ArrayList<>(numberOfValuesRemaining());
       this.clone().forEach(c -> list.add(c.slice(1)));
       return java.util.Spliterators.spliterator(list.toArray(), numberOfValuesRemaining());
     }
@@ -294,7 +368,7 @@
      * @return the count of rows in the row sequence preceeding this
      * {@link RowColumn}
      * @throws IllegalStateException if the call that was passed this
-     * {@link Result} has ended
+     * {@code Result} has ended
      */
     public long rowNumber();
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowCountOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowCountOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -41,14 +41,24 @@
    * 
    * @param function processes the count produced by executing this
    * {@link Operation} and returns the result
-   * @return this {@link RowCountOperation}
+   * @return this {@code RowCountOperation}
    * @throws IllegalStateException if this method has been called previously
    */
   public RowCountOperation<T> apply(Function<Result.RowCount, ? extends T> function);
 
+  /**
+   * {@inheritDoc} 
+   * 
+   * @return this {@code RowCountOperation}
+   */
   @Override
   public RowCountOperation<T> onError(Consumer<Throwable> handler);
 
+  /**
+   * {@inheritDoc} 
+   * 
+   * @return this {@code RowCountOperation}
+   */
   @Override
   public RowCountOperation<T> timeout(Duration minTime);
   
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -22,7 +22,6 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.incubator.sql2;
 
 import java.util.function.BiConsumer;
@@ -31,8 +30,8 @@
 import java.util.stream.Collector;
 
 /**
- * A {@link RowOperation} is a database operation that returns a row sequence.
- * 
+ * A {@code RowOperation} is a database operation that returns a row sequence.
+ *
  * @param <T> the type of the result of this {@link Operation}
  */
 public interface RowOperation<T> extends Operation<T> {
@@ -40,48 +39,54 @@
   /**
    * A hint to the implementation of how many rows to fetch in each database
    * access. Implementations are free to ignore it.
-   * 
+   *
    * @param rows suggested number of rows to fetch per access
-   * @return this {@link RowOperation}
+   * @return this {@code RowOperation}
    * @throws IllegalArgumentException if row &lt; 1
    * @throws IllegalStateException if this method had been called previously or
-   * this Operation has been submitted.
+   * this {@link Operation} has been submitted.
    */
   public RowOperation<T> fetchSize(long rows) throws IllegalArgumentException;
-  
+
   /**
    * Provides a {@link Collector} to reduce the sequence of rows.The result of
    * the {@link Operation} is the result of calling finisher on the final
    * accumulated result. If the {@link Collector} is
    * {@link Collector.Characteristics#UNORDERED} rows may be accumulated out of
    * order. If the {@link Collector} is
-   * {@link Collector.Characteristics#CONCURRENT} then the sequence of rows may be
-   * split into subsequences that are reduced separately and then combined.
+   * {@link Collector.Characteristics#CONCURRENT} then the sequence of rows may
+   * be split into subsequences that are reduced separately and then combined.
    *
    * @param <A> the type of the accumulator
    * @param <S> the type of the final result
-   * @param c the Collector. Not null. 
-   * @return This RowOperation
+   * @param c the Collector. Not {@code null}.
+   * @return This {@code RowOperation}
    * @throws IllegalStateException if this method had been called previously or
-   * this Operation has been submitted.
-  */
+   * this {@link Operation} has been submitted.
+   */
   public <A, S extends T> RowOperation<T> collect(Collector<? super Result.RowColumn, A, S> c);
-  
+
   /**
-   * Convenience method to collect the rows when the accumulated result is the 
+   * Convenience method to collect the rows when the accumulated result is the
    * final result.
-   * 
+   *
    * @param <S> the type of the accumulated result
    * @param supplier supplies the accumulated result
-   * @param accumulator accumulates each RowColumn into the accumulated result
-   * @return this RowOperation
+   * @param accumulator accumulates each {@link Result.RowColumn} into the
+   * accumulated result
+   * @return this {@code RowOperation}
    */
   public default <S extends T> RowOperation<T> collect(Supplier<S> supplier,
-                                 BiConsumer<S, Result.RowColumn> accumulator) {
+                                                       BiConsumer<S, Result.RowColumn> accumulator) {
     return collect(Collector.of(supplier, accumulator, (l, r) -> l));
   }
 
+  /**
+   * {@inheritDoc}
+   *
+   * @return this {@code RowOperation}
+   */
   @Override
   public RowOperation<T> onError(Consumer<Throwable> handler);
-  
+
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowPublisherOperation.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/RowPublisherOperation.java	Sat Oct 20 08:17:38 2018 -0400
@@ -1,7 +1,26 @@
 /*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
+ * Copyright (c)  2018, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ * 
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 package jdk.incubator.sql2;
 
@@ -13,8 +32,8 @@
 public interface RowPublisherOperation<T> extends Operation<T> {
 
   /**
-   * * DRAFT Subscribe to the stream of Rows returned by this Operation. The
-   * result of this Operation is the value of the {@code result} parameter.
+   * Subscribe to the stream of rows returned by this {@link Operation}. The
+   *  value of the {@code result} parameter is the result of this {@link Operation}.
    *
    * @param subscriber Not null.
    * @param result Not null.
@@ -24,9 +43,19 @@
                                             CompletionStage<? extends T> result);
   // Covariant overrides
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code RowPublisherOperation}
+   */
   @Override
   public RowPublisherOperation<T> onError(Consumer<Throwable> handler);
   
+  /**
+   * {@inheritDoc}
+   * 
+   * @return this {@code RowPublisherOperation}
+   */
   @Override
   public RowPublisherOperation<T> timeout(Duration minTime);
   
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Session.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Session.java	Sat Oct 20 08:17:38 2018 -0400
@@ -31,163 +31,136 @@
 import java.util.function.LongConsumer;
 
 /**
- * A {@link Session} is an abstraction of a SQL database and
- * a group of {@link Operation}s to be executed by that SQL database. No method
- * on {@link Session} or any of its dependent objects ({@link RowOperation}
- * etc) blocks. Any method that might block must execute any potentially blocking
+ * A {@code Session} is an abstraction of a SQL database and a group of
+ * {@link Operation}s to be executed by that SQL database. No method on
+ * {@code Session} or any of its dependent objects ({@link RowOperation} etc)
+ * blocks. Any method that might block must execute any potentially blocking
  * action in a thread other than the calling thread.
- * 
+ *
  * <p>
- * A {@link Session} is independent of any particular data source. Any data 
+ * A {@code Session} is independent of any particular data source. Any data
  * source that meets the specifications set by the {@link Session.Builder} can
- * be used to execute the {@link Operation}s submitted to the {@link Session}.
- * An application is expected to create, use, and close {@link Session}s as 
- * needed. An application should hold a {@link Session} only when required by
+ * be used to execute the {@link Operation}s submitted to the {@code Session}.
+ * An application is expected to create, use, and close {@code Session}s as
+ * needed. An application should hold a {@code Session} only when required by
  * data source semantics. An implementation should cache and reused data source
- * resources as appropriate. {@link Session}s should not be cached.
+ * resources as appropriate. {@code Session}s should not be cached.
  *
  * <p>
  * An implementation of this type must be thread safe as result and error
- * handlers running asynchronously may be accessing a {@link Session} in
- * parallel with each other and with a user thread. {@link Session}s are not
- * required to support multiplexed use; a single {@link Session} should be
- * used for only one unit of work at a time. Executing independent units of work
- * on a single {@link Session} in parallel will most likely lead to
- * unpredictable outcomes. As a rule of thumb only one user thread should access
- * a {@link Session} at a time. Such a user thread should execute a complete
- * unit of work before another user thread accesses the {@link Session}. An
- * implementation may support parallel multiplexed use, but it is not required.</p>
+ * handlers running asynchronously may be accessing a {@code Session} in
+ * parallel with each other and with a user thread. {@code Session}s are not
+ * required to support multiplexed use; a single {@code Session} should be used
+ * for only one unit of work at a time. Executing independent units of work on a
+ * single {@code Session} in parallel will most likely lead to unpredictable
+ * outcomes. As a rule of thumb only one user thread should access a
+ * {@code Session} at a time. Such a user thread should execute a complete unit
+ * of work before another user thread accesses the {@code Session}. An
+ * implementation may support parallel multiplexed use, but it is not
+ * required.</p>
  *
  * <p>
- * All methods inherited from OperationGroup throw IllegalStateException if the
- * the {@link Session} is not active.</p>
+ * All methods inherited from {@link OperationGroup} throw
+ * {@link IllegalStateException} if the the {@code Session} is closed.</p>
  */
 public interface Session extends AutoCloseable, OperationGroup<Object, Object> {
 
   /**
-   * Identifies the operational state of a {@link Session}.
+   * Identifies the operational state of a {@code Session}.
    */
-  public enum Lifecycle {
-    /**
-     * unattached. When a attach {@link Operation} is completed successfully
-     * -&gt; {@link OPEN}. If {@link deactivate} is called -&gt;
-     * {@link NEW_INACTIVE}. If {@link abort} is called -&gt; {@link ABORTING}.
-     * No {@link Operation}s other than attach and close will be performed. A
- Session in this state is both 'open' and 'active'.
-     */
-    NEW,
-    /**
-     * Unattached and inactive. Any queued attach or close {@link Operation}
-     * is performed. No work can be submitted. If the {@link activate} method is
-     * called -&gt; {@link NEW}. If a attach {@link Operation} completes -&gt;
-     * {@link INACTIVE}. If a close {@link Operation} is executed -&gt;
-     * {@link CLOSING}. If {@link abort} is called -&gt; {@link ABORTING}. A
- Session in this state is 'open'.
-     */
-    NEW_INACTIVE,
-    /**
-     * fully operational. Work is queued and performed. If {@link deactivate} is
-     * called -&gt; {@link INACTIVE}. If a close {@link Operation} is executed
-     * -&gt; {@link CLOSING}. If {@link abort} is called -&gt; {@link ABORTING}.
- A Session in this state is both 'open' and 'active'.
-     */
-    OPEN,
-    /**
-     * Not available for new work. Queued work is performed. No work can be
-     * submitted. If the {@link activate} method is called -&gt; {@link OPEN}.
-     * If a close {@link Operation} is executed -&gt; {@link CLOSING}. If
-     * {@link abort} is called -&gt; {@link ABORTING}. A {@link Session} in
-     * this state is 'open'.
-     */
-    INACTIVE,
-    /**
-     * Work in progress is completed but no additional work is started or
-     * queued. Attempting to queue work throws {@link IllegalStateException}.
-     * When the currently executing {@link Operation}s are completed -&gt;
-     * {@link CLOSED}. All other queued Operations are completed exceptionally
- with SqlSkippedException. A Session in this state is 'closed'.
-     */
-    CLOSING,
-    /**
-     * Work is neither queued nor performed. The currently executing
-     * {@link Operation}s, if any, are terminated, exceptionally if necessary.
-     * Any queued {@link Operation}s are terminated exceptionally with
-     * {@link SqlSkippedException}. Attempting to queue work throws
-     * {@link IllegalStateException}. When the queue is empty -&lt;
-     * {@link CLOSED}. A Session in this state is 'closed'.
-     */
-    ABORTING,
-    /**
-     * Work is neither queued nor performed. Attempting to queue work throws
-     * {@link IllegalStateException}. A Session in this state is 'closed'.
-     */
-    CLOSED;
-    
-    static {
-      NEW.init(true, true, NEW, NEW_INACTIVE, OPEN, ABORTING, CLOSING, CLOSED);
-      NEW_INACTIVE.init(true, false, NEW, NEW_INACTIVE, INACTIVE, ABORTING, CLOSING, CLOSED);
-      OPEN.init(true, true, OPEN, INACTIVE, OPEN, ABORTING, CLOSING, CLOSED);
-      INACTIVE.init(true, false, OPEN, INACTIVE, INACTIVE, ABORTING, INACTIVE, INACTIVE);
-      CLOSING.init(false, true, CLOSING, CLOSING, CLOSING, ABORTING, CLOSING, CLOSED);
-      ABORTING.init(false, true, ABORTING, ABORTING, ABORTING, ABORTING, ABORTING, CLOSED);
-      CLOSED.init(false, true, CLOSED, CLOSED, CLOSED, CLOSED, CLOSED, CLOSED);
-    }
-    
-    private boolean isOpen;
-    private boolean isActive;
-    private Lifecycle onActivate;
-    private Lifecycle onDeactivate;
-    private Lifecycle onAttach;
-    private Lifecycle onAbort;
-    private Lifecycle onClose;
-    private Lifecycle onClosed;
-    
-    private void init(boolean io, boolean ia, Lifecycle ac, Lifecycle da, Lifecycle cn, Lifecycle ab, Lifecycle cl, Lifecycle cd) {
-      isOpen = io;
-      isActive = ia;
-      onActivate = ac;
-      onDeactivate = da;
-      onAttach = cn;
-      onAbort = ab;
-      onClose = cl;
-      onClosed = cd;
-    }
-    public boolean isOpen() {
-      return isOpen;
-    }
-    
-    public boolean isActive() {
-      return isActive;
-    }
-    
-    public Lifecycle activate() {
-      return onActivate;
-    }
-    
-    public Lifecycle deactivate() {
-      return onDeactivate;
-    }
-    
-    public Lifecycle attach() {
-      return onAttach;
-    }
-    
-    public Lifecycle abort() {
-      return onAbort;
-    }
-    
-    public Lifecycle close() {
-      return onClose;
-    }
-    
-    public Lifecycle closed() {
-      return onClosed;
-    }
-  
-  }
+ public enum Lifecycle {
+   /**
+    * A newly created Session is in this state. When a attach {@link Operation}
+    * is completed successfully -&gt; {@link ATTACHED}. If {@link Session#abort}
+    * is called -&gt; {@link ABORTING}. No {@link Operation}s other than attach
+    * and close will be performed. A {@code Session} in this state is 'open'.
+    */
+   NEW,
+   /**
+    * fully operational. Work is queued and performed. If a close
+    * {@link Operation} is submitted -&gt; {@link CLOSING}. If
+    * {@link Session#abort} is called -&gt; {@link ABORTING}. A {@code Session}
+    * in this state is 'open' and 'working'.
+    */
+   ATTACHED,
+   /**
+    * Work in progress is completed but no additional work can be submitted. 
+    * Attempting to queue work throws {@link IllegalStateException}.
+    * When the close {@link Operation} is completed -&gt;
+    * {@link CLOSED}. A {@code Session} in this state is 'closed' and 'working'.
+    */
+   CLOSING,
+   /**
+    * Work is neither queued nor performed. The currently executing
+    * {@link Operation}s, if any, are terminated immediately. Any queued
+    * {@link Operation}s are removed from the queue. Attempting to queue work
+    * throws {@link IllegalStateException}. When the queue is empty -&lt;
+    * {@link CLOSED}. A {@code Session} in this state is 'closed'.
+    */
+   ABORTING,
+   /**
+    * Work is neither queued nor performed. Attempting to queue work throws
+    * {@link IllegalStateException}. A Session in this state is 'closed'.
+    */
+   CLOSED;
+
+   static {
+     NEW.init(false, false, ATTACHED, CLOSING, ABORTING, CLOSED);
+     ATTACHED.init(false, true, ATTACHED, CLOSING, ABORTING, CLOSED);
+     CLOSING.init(true, true, CLOSING, CLOSING, ABORTING, CLOSED);
+     ABORTING.init(true, false, ABORTING, ABORTING, ABORTING, CLOSED);
+     CLOSED.init(true, false, CLOSED, CLOSED, CLOSED, CLOSED);
+   }
+
+   private boolean isClosed;
+   private boolean isWorking;
+   private Lifecycle onAttach;
+   private Lifecycle onClose;
+   private Lifecycle onAbort;
+   private Lifecycle onClosed;
+
+   private void init(boolean isClosed,
+                     boolean isWorking,
+                     Lifecycle onAttach, 
+                     Lifecycle onClose, 
+                     Lifecycle onAbort, 
+                     Lifecycle onClosed) {
+     this.isClosed = isClosed;
+     this.isWorking = isWorking;
+     this.onAttach = onAttach;
+     this.onClose = onClose;
+     this.onAbort = onAbort;
+     this.onClosed = onClosed;
+   }
+
+   public boolean isClosed() {
+     return isClosed;
+   }
+
+   public boolean isWorking() {
+     return isWorking;
+   }
+
+   public Lifecycle attach() {
+     return onAttach;
+   }
+
+   public Lifecycle close() {
+     return onClose;
+   }
+
+   public Lifecycle abort() {
+     return onAbort;
+   }
+
+   public Lifecycle closed() {
+     return onClosed;
+   }
+
+ }
 
   /**
-   * Specifiers for how much effort to put into validating a {@link Session}.
+   * Specifiers for how much effort to put into validating a {@code Session}.
    * The amount of effort put into checking should be non-decreasing from NONE
    * (least effort) to COMPLETE (most effort). Exactly what is checked is
    * implementation dependent. For example, a memory resident database driver
@@ -197,7 +170,7 @@
    */
   public enum Validation {
     /**
-     * isValid fails only if the {@link Session} is closed.
+     * isValid fails only if the {@code Session} is closed.
      */
     NONE,
     /**
@@ -229,13 +202,12 @@
 
     /**
      * If this {@link java.util.EventListener} is registered with a
-     * {@link Session} this method is called whenever that
-     * {@link Session}'s lifecycle changes. Note that the lifecycle may have
-     * changed again by the time this method is called so the
-     * {@link Session}'s current lifecycle may be different from the value of
-     * {@code current}.
+     * {@code Session} this method is called whenever that {@code Session}'s
+     * lifecycle changes. Note that the lifecycle may have changed again by the
+     * time this method is called so the {@code Session}'s current lifecycle may
+     * be different from the value of {@code current}.
      *
-     * @param session the {@link Session}
+     * @param session the {@code Session}
      * @param previous the previous value of the lifecycle
      * @param current the new value of the lifecycle
      */
@@ -243,61 +215,59 @@
   }
 
   /**
-   * A {@link Session} builder. A {@link Session} is initially in the
-   * {@link Session.Lifecycle#NEW} lifecycle state. It transitions to the
-   * {@link Session.Lifecycle#OPEN} lifecycle state when fully initialized or
-   * to {@link Session.Lifecycle#CLOSED} if initialization fails.
+   * A {@code Session} builder. A {@code Session} is initially in the
+   * {@link Session.Lifecycle#NEW} lifecycle state. It transitions to 
+   * {@link Session.Lifecycle#CLOSED} if initialization fails.
    *
    */
   public interface Builder {
 
     /**
-     * Specify a property and its value for the built {@link Session}.
+     * Specify a property and its value for the built {@code Session}.
      *
      * @param p {@link SessionProperty} to set. Not {@code null}.
-     * @param v value for the property
+     * @param v value for the property. If v is {@link Cloneable} it is cloned
+     * otherwise it is retained.
      * @return this {@link Builder}
      * @throws IllegalArgumentException if {@code p.validate(v)} does not return
-     * true, if this method has already been called with the property
-     * {@code p}, or the implementation does not support the {@link SessionProperty}.
+     * true, if this method has already been called with the property {@code p},
+     * or the implementation does not support the {@link SessionProperty}.
      */
     public Builder property(SessionProperty p, Object v);
 
     /**
-     * Return a {@link Session} with the attributes specified. Note that the
-     * {@link Session} may not be attached to a server. Call one of the
-     * {@link attach} convenience methods to attach the {@link Session} to
-     * a server. The lifecycle of the new {@link Session} is
+     * Return a {@code Session} with the attributes specified. Note that the
+     * {@code Session} may not be attached to a server. Call one of the
+     * {@link attach} convenience methods to attach the {@code Session} to a
+     * server. The lifecycle of the new {@code Session} is
      * {@link Lifecycle#NEW}.
- 
- This method cannot block. If the DataSource is unable to support a new
- Session when this method is called, this method throws SqlException.
- Note that the implementation does not have to allocate scarce resources to
- the new {@link Session} when this method is called so limiting the
-     * number of {@link Session}s is not required to limit the use of
-     * scarce resources. It may be appropriate to limit the number of 
-     * {@link Session}s for other reasons, but that is implementation dependent.
      *
-     * @return a {@link Session}
+     * This method cannot block. If the DataSource is unable to support a new
+     * Session when this method is called, this method throws SqlException. Note
+     * that the implementation does not have to allocate scarce resources to the
+     * new {@code Session} when this method is called so limiting the number of
+     * {@code Session}s is not required to limit the use of scarce resources. It
+     * may be appropriate to limit the number of {@code Session}s for other
+     * reasons, but that is implementation dependent.
+     *
+     * @return a {@code Session}
      * @throws IllegalStateException if this method has already been called or
- if the implementation cannot create a Session with the specified
- {@link SessionProperty}s.
+     * if the implementation cannot create a Session with the specified
+     * {@link SessionProperty}s.
      * @throws IllegalStateException if the {@link DataSource} that created this
      * {@link Builder} is closed
-     * @throws SqlException if creating a {@link Session} would exceed some
+     * @throws SqlException if creating a {@code Session} would exceed some
      * limit
      */
     public Session build();
   }
 
   /**
-   * Returns an {@link Operation} that attaches this {@link Session} to a
-   * data source. If the Operation completes successfully and the lifecycle is
-   * {@link Lifecycle#NEW} -&gt; {@link Lifecycle#OPEN}. If lifecycle is
-   * {@link Lifecycle#NEW_INACTIVE} -&gt; {@link Lifecycle#INACTIVE}. If the
+   * Returns an {@link Operation} that attaches this {@code Session} to a data
+   * source. If the Operation completes successfully and the lifecycle is
+   * {@link Lifecycle#NEW} -&gt; {@link Lifecycle#ATTACHED}. If the
    * {@link Operation} completes exceptionally the lifecycle -&gt;
-   * {@link Lifecycle#CLOSED}. The lifecycle must be {@link Lifecycle#NEW} or
-   * {@link Lifecycle#NEW_INACTIVE} when the {@link Operation} is executed.
+   * {@link Lifecycle#CLOSED}. The lifecycle must be {@link Lifecycle#NEW}  when the {@link Operation} is executed.
    * Otherwise the {@link Operation} will complete exceptionally with
    * {@link SqlException}.
    *
@@ -306,9 +276,9 @@
    * {@link attach()}. Unless there is a specific need, do not call this method
    * directly.
    *
-   * @return an {@link Operation} that attaches this {@link Session} to a
+   * @return an {@link Operation} that attaches this {@code Session} to a
    * server.
-   * @throws IllegalStateException if this {@link Session} is in a lifecycle
+   * @throws IllegalStateException if this {@code Session} is in a lifecycle
    * state other than {@link Lifecycle#NEW}.
    */
   public Operation<Void> attachOperation();
@@ -317,22 +287,22 @@
    * Convenience method that supports the fluent style of the builder needed by
    * try with resources.
    *
-   * Note: A {@link Session} is an {@link OperationGroup} and so has some
+   * Note: A {@code Session} is an {@link OperationGroup} and so has some
    * advanced features that most users do not need. Management of these features
    * is encapsulated in this method and the corresponding {@link close()}
    * convenience method. The vast majority of users should just use these
    * methods and not worry about the advanced features. The convenience methods
    * do the right thing for the overwhelming majority of use cases. A tiny
    * number of users might want to take advantage of the advanced features that
-   * {@link OperationGroup} brings to {@link Session} and so would call
+   * {@link OperationGroup} brings to {@code Session} and so would call
    * {@link attachOperation} directly.
    *
    * @return this Session
-   * @throws IllegalStateException if this {@link Session} is in a lifecycle
+   * @throws IllegalStateException if this {@code Session} is in a lifecycle
    * state other than {@link Lifecycle#NEW}.
    */
   public default Session attach() {
-    this.submitHoldingForMoreMembers();
+    this.submit();
     this.attachOperation()
             .submit();
     return this;
@@ -344,16 +314,19 @@
    *
    * @param onError an Exception handler that is called if the attach
    * {@link Operation} completes exceptionally.
-   * @return this {@link Session}
-   * @throws IllegalStateException if this {@link Session} is in a lifecycle
+   * @return this {@code Session}
+   * @throws IllegalStateException if this {@code Session} is in a lifecycle
    * state other than {@link Lifecycle#NEW}.
    */
   public default Session attach(Consumer<Throwable> onError) {
-    this.submitHoldingForMoreMembers();
+    this.submit();
     this.attachOperation()
             .submit()
             .getCompletionStage()
-            .exceptionally(t -> { onError.accept(t); return null; } );
+            .exceptionally(t -> {
+              onError.accept(t);
+              return null;
+            });
     return this;
   }
 
@@ -361,34 +334,34 @@
    * Returns an {@link Operation} that verifies that the resources are available
    * and operational. Successful completion of that {@link Operation} implies
    * that at some point between the beginning and end of the {@link Operation}
- the Session was working properly to the extent specified by {@code depth}.
-   * There is no guarantee that the {@link Session} is still working after 
-   * completion. If the {@link Session} is not valid the Operation completes
+   * the Session was working properly to the extent specified by {@code depth}.
+   * There is no guarantee that the {@code Session} is still working after
+   * completion. If the {@code Session} is not valid the Operation completes
    * exceptionally.
    *
    * @param depth how completely to check that resources are available and
    * operational. Not {@code null}.
-   * @return an {@link Operation} that will validate this {@link Session}
-   * @throws IllegalStateException if this Session is not active
+   * @return an {@link Operation} that will validate this {@code Session}
+   * @throws IllegalStateException if this Session is closed.
    */
   public Operation<Void> validationOperation(Validation depth);
 
   /**
-   * Convenience method to validate a {@link Session}.
+   * Convenience method to validate a {@code Session}.
    *
    * @param depth how completely to check that resources are available and
    * operational. Not {@code null}.
    * @param minTime how long to wait. If 0, wait forever
    * @param onError called if validation fails or times out. May be
    * {@code null}.
-   * @return this {@link Session}
+   * @return this {@code Session}
    * @throws IllegalArgumentException if {@code milliseconds} &lt; 0 or
    * {@code depth} is {@code null}.
-   * @throws IllegalStateException if this Session is not active
+   * @throws IllegalStateException if this Session is closed.
    */
   public default Session validate(Validation depth,
-          Duration minTime,
-          Consumer<Throwable> onError) {
+                                  Duration minTime,
+                                  Consumer<Throwable> onError) {
     this.validationOperation(depth)
             .timeout(minTime)
             .onError(onError)
@@ -397,87 +370,93 @@
   }
 
   /**
-   * Create an {@link Operation} to close this {@link Session}. When the
-   * {@link Operation} is executed, if this {@link Session} is open -&gt;
-   * {@link Lifecycle#CLOSING}. If this {@link Session} is closed executing
-   * the returned {@link Operation} is a no-op. When the queue is empty and all
+   * Create an {@link Operation} to close this {@code Session}. When the
+   * {@link Operation} is submitted, if this {@code Session} is not closed -&gt;
+   * {@link Lifecycle#CLOSING}. If this {@code Session} is closed executing the
+   * returned {@link Operation} is a no-op. When the queue is empty and all
    * resources released -&gt; {@link Lifecycle#CLOSED}.
    *
-   * A close {@link Operation} is never skipped. Even when the
-   * {@link Session} is dependent, the default, and an {@link Operation}
-   * completes exceptionally, a close {@link Operation} is still executed. If
-   * the {@link Session} is parallel, a close {@link Operation} is not
-   * executed so long as there are other {@link Operation}s or the
-   * {@link Session} is held for more {@link Operation}s.
+   * A close {@link Operation} is never skipped. Even when the {@code Session}
+   * is dependent, the default, and an {@link Operation} completes
+   * exceptionally, a close {@link Operation} is still executed. If the
+   * {@code Session} is parallel, a close {@link Operation} is not executed so
+   * long as there are other {@link Operation}s or the {@code Session} is held
+   * for more {@link Operation}s.
    *
    * Note: It is highly recommended to use try with resources or the
    * {@link close()} convenience method. Unless there is a specific need, do not
    * call this method directly.
    *
-   * @return an {@link Operation} that will close this {@link Session}.
-   * @throws IllegalStateException if the Session is not active
+   * @return an {@link Operation} that will close this {@code Session}.
+   * @throws IllegalStateException if the Session is closed.
    */
   public Operation<Void> closeOperation();
 
   /**
-   * Create and submit an {@link Operation} to close this {@link Session}.
+   * Create and submit an {@link Operation} to close this {@code Session}.
    * Convenience method.
    *
-   * Note: A {@link Session} is an {@link OperationGroup} and so has some
+   * Note: A {@code Session} is an {@link OperationGroup} and so has some
    * advanced features; that most users do not need. Management of these
    * features is encapsulated in this method and the corresponding
-   * {@link attach()} convenience method. The vast majority of users should
-   * just use these methods and not worry about the advanced features. The
+   * {@link attach()} convenience method. The vast majority of users should just
+   * use these methods and not worry about the advanced features. The
    * convenience methods do the right thing for the overwhelming majority of use
    * cases. A tiny number of user might want to take advantage of the advanced
-   * features that {@link OperationGroup} brings to {@link Session} and so
-   * would call {@link closeOperation} directly.
+   * features that {@link OperationGroup} brings to {@code Session} and so would
+   * call {@link closeOperation} directly.
    *
-   * @throws IllegalStateException if the Session is not active
+   * @throws IllegalStateException if the Session is closed.
+   */
+  /**
+   * {@inheritDoc}
    */
   @Override
   public default void close() {
     this.closeOperation()
             .submit();
-    this.releaseProhibitingMoreMembers();
+    // submitting a close Operation must satisfy the requirements of
+    // OperationGroup.close()
   }
 
   /**
-   * Create a new {@link OperationGroup} for this {@link Session}.
+   * Create a new {@link OperationGroup} for this {@code Session}.
    *
    * @param <S> the result type of the member {@link Operation}s of the returned
    * {@link OperationGroup}
    * @param <T> the result type of the collected results of the member
    * {@link Operation}s
    * @return a new {@link OperationGroup}.
-   * @throws IllegalStateException if this Session is not active
+   * @throws IllegalStateException if this Session is closed.
    */
   public <S, T> OperationGroup<S, T> operationGroup();
 
   /**
-   * Returns a new {@link TransactionCompletion} that can be used as an argument to an
-   * endTransaction Operation.
+   * Returns a new {@link TransactionCompletion} that can be used as an argument
+   * to an endTransaction Operation.
    *
    * It is most likely an error to call this within an error handler, or any
    * handler as it is very likely that when the handler is executed the next
-   * submitted endTransaction {@link Operation} will have been created with a 
- different TransactionCompletion.
- 
- ISSUE: Should this be moved to OperationGroup?
+   * submitted endTransaction {@link Operation} will have been created with a
+   * different TransactionCompletion.
+   *
+   * ISSUE: Should this be moved to OperationGroup?
    *
    * @return a new {@link TransactionCompletion}. Not null.
-   * @throws IllegalStateException if this Session is not active
+   * @throws IllegalStateException if this Session is closed.
    */
   public TransactionCompletion transactionCompletion();
-  
+
   /**
-   * Unconditionally perform a transaction rollback. Create an endTransaction 
-   * {@link Operation}, set it to rollback only, and submit it. The endTransaction
-   * is never skipped. Convenience method. To execute a commit call 
+   * Unconditionally perform a transaction rollback. Create an endTransaction
+   * {@link Operation}, set it to rollback only, and submit it. The
+   * endTransaction is never skipped. Convenience method. To execute a commit
+   * call
    * {@link OperationGroup#commitMaybeRollback(jdk.incubator.sql2.TransactionCompletion)}.
    *
    * @return this {@link OperationGroup}
-   * @see OperationGroup#commitMaybeRollback(jdk.incubator.sql2.TransactionCompletion) 
+   * @see
+   * OperationGroup#commitMaybeRollback(jdk.incubator.sql2.TransactionCompletion)
    */
   public default CompletionStage<TransactionOutcome> rollback() {
     TransactionCompletion t = transactionCompletion();
@@ -488,16 +467,16 @@
 
   /**
    * Register a listener that will be called whenever there is a change in the
-   * lifecycle of this {@link Session}.If the listener is already registered
- this is a no-op. ISSUE: Should lifecycleListener be a SessionProperty so that it is 
- always reestablished on Session.activate?
+   * lifecycle of this {@code Session}.If the listener is already registered
+   * this is a no-op. ISSUE: Should lifecycleListener be a SessionProperty so
+   * that it is always reestablished on Session.activate?
    *
    * @param listener Not {@code null}.
    * @return this Session
-   * @throws IllegalStateException if this Session is not active
+   * @throws IllegalStateException if this Session is not open
    */
   public Session registerLifecycleListener(SessionLifecycleListener listener);
-  
+
   /**
    * Removes a listener that was registered by calling
    * registerLifecycleListener.Sometime after this method is called the listener
@@ -506,113 +485,71 @@
    *
    * @param listener Not {@code null}.
    * @return this Session
-   * @throws IllegalStateException if this Session is not active
    */
   public Session deregisterLifecycleListener(SessionLifecycleListener listener);
 
   /**
-   * Return the current lifecycle of this {@link Session}. 
+   * Return the current lifecycle of this {@code Session}.
    *
-   * @return the current lifecycle of this {@link Session}.
+   * @return the current lifecycle of this {@code Session}.
    */
   public Lifecycle getSessionLifecycle();
 
   /**
-   * Terminate this {@link Session}. If lifecycle is
-   * {@link Lifecycle#NEW}, {@link Lifecycle#OPEN}, {@link Lifecycle#INACTIVE}
+   * Terminate this {@code Session}. If lifecycle is
+   * {@link Lifecycle#NEW}, {@link Lifecycle#ATTACHED}
    * or {@link Lifecycle#CLOSING} -&gt; {@link Lifecycle#ABORTING} If lifecycle
    * is {@link Lifecycle#ABORTING} or {@link Lifecycle#CLOSED} this is a no-op.
    * If an {@link Operation} is currently executing, terminate it immediately.
    * Remove all remaining {@link Operation}s from the queue. {@link Operation}s
    * are not skipped. They are just removed from the queue.
    *
-   * @return this {@link Session}
+   * @return this {@code Session}
    */
   public Session abort();
 
   /**
-   * Return the set of properties configured on this {@link Session}
-   * excepting any sensitive properties. Neither the key nor the value for
-   * sensitive properties are included in the result. Properties (other than
-   * sensitive properties) that have default values are included even when not
-   * explicitly set. Properties that have no default value and are not set
-   * explicitly are not included.
+   * Return the set of properties configured on this {@code Session} excepting
+   * any sensitive properties. Neither the key nor the value for sensitive
+   * properties are included in the result. Properties (other than sensitive
+   * properties) that have default values are included even when not explicitly
+   * set. Properties that have no default value and are not set explicitly
+   * either by the {@link DataSource} or the {@link Session.Builder} are not
+   * included.
    *
    * @return a {@link Map} of property, value. Not modifiable. May be retained.
    * Not {@code null}.
-   * @throws IllegalStateException if this Session is not active
+   * @throws IllegalStateException if this Session is not open
    */
   public Map<SessionProperty, Object> getProperties();
-  
+
   /**
    *
-   * @return a {@link ShardingKey.Builder} for this {@link Session}
-   * @throws IllegalStateException if this Session is not active
+   * @return a {@link ShardingKey.Builder} for this {@code Session}
+   * @throws IllegalStateException if this Session is not open
    */
   public ShardingKey.Builder shardingKeyBuilder();
 
   /**
-   * Provide a method that this {@link Session} will call to control the rate
-   * of {@link Operation} submission. This {@link Session} will call
-   * {@code request} with a positive argument when the {@link Session} is
-   * able to accept more {@link Operation} submissions. The difference between
-   * the sum of all arguments passed to {@code request} and the number of
+   * Provide a method that this {@code Session} will call to control the rate of
+   * {@link Operation} submission. This {@code Session} will call
+   * {@code request} with a positive argument when the {@code Session} is able
+   * to accept more {@link Operation} submissions. The difference between the
+   * sum of all arguments passed to {@code request} and the number of
    * {@link Operation}s submitted after this method is called is the
    * <i>demand</i>. The demand must always be non-negative. If an
    * {@link Operation} is submitted that would make the demand negative the call
    * to {@link Operation#submit} throws {@link IllegalStateException}. Prior to
-   * a call to {@code requestHook}, the demand is defined to be infinite.
-   * After a call to {@code requestHook}, the demand is defined to be
-   * zero and is subsequently computed as described previously.
-   * {@link Operation}s submitted prior to the call to {@code requestHook} do
-   * not affect the demand.
+   * a call to {@code requestHook}, the demand is defined to be infinite. After
+   * a call to {@code requestHook}, the demand is defined to be zero and is
+   * subsequently computed as described previously. {@link Operation}s submitted
+   * prior to the call to {@code requestHook} do not affect the demand.
    *
    * @param request accepts calls to increase the demand. Not null.
-   * @return this {@link Session}
+   * @return this {@code Session}
    * @throws IllegalStateException if this method has been called previously or
-   * this {@link Session} is not active.
+   * this {@code Session} is not open.
    */
   public Session requestHook(LongConsumer request);
 
-  /**
-   * Make this {@link Session} ready for use. A newly created
-   * {@link Session} is active. Calling this method on a {@link Session}
-   * that is active is a no-op. If the lifecycle is {@link Lifecycle#INACTIVE}
-   * -&gt; {@link Lifecycle#OPEN}. If the lifecycle is
-   * {@link Lifecycle#NEW_INACTIVE} -&gt; {@link Lifecycle#NEW}.
-   *
-   * @return this {@link Session}
-   * @throws IllegalStateException if this {@link Session} is closed.
-   */
-  public Session activate();
-
-  /**
-   * Makes this {@link Session} inactive. After a call to this method
-   * previously submitted Operations will be executed normally. If the lifecycle
-   * is {@link Lifecycle#NEW} -&gt; {@link Lifecycle#NEW_INACTIVE}. if the
-   * lifecycle is {@link Lifecycle#OPEN} -&gt; {@link Lifecycle#INACTIVE}. If
-   * the lifecycle is {@link Lifecycle#INACTIVE} or
-   * {@link Lifecycle#NEW_INACTIVE} this method is a no-op. After calling this
-   * method or calling any method other than {@link deactivate}, {@link activate},
-   * {@link abort}, or {@link getSessionLifecycle} will throw
-   * {@link IllegalStateException}. Data source state not specified
-   * by {@link Session.Builder} may not be preserved.
-   * 
-   * <p>
-   * In general {@link Session}s should not be pooled as the implementation
-   * should cache and reuse the data source resources that back {@link Session}s
-   * as appropriate, not cache the {@link Session}s themselves. 
-   * However, any {@link Session} pool is required by default to
-   * call {@code deactivate} when putting a {@link Session} into the pool. The
-   * pool is required by default to call {@code activate} when removing a
-   * {@link Session} from the pool for use. A pool may have an optional mode where
-   * it does not call {@code deactivate}/{@code activate} as required above. The
-   * behavior of the pool and {@link Session}s cached in the pool in such a
-   * mode is entirely implementation dependent.</p>
-   * 
-   * @return this {@link Session}
-   * @throws IllegalStateException if this {@link Session} is closed
-   */
-  public Session deactivate();
-  
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SessionProperty.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SessionProperty.java	Sat Oct 20 08:17:38 2018 -0400
@@ -22,41 +22,43 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+package jdk.incubator.sql2;
 
-package jdk.incubator.sql2;
+import java.io.Serializable;
 
 /**
  * An attribute of a {@link Session} that can be configured to influence its
- * behavior. Implementors of this interface define the properties of
- * {@link Session}s. The {@link Session.Builder#property} method is used to set the values
- * of {@link Session} properties.
- * 
+ * behavior. implementers of this interface define the properties of
+ * {@link Session}s. The {@link Session.Builder#property} method is used to set
+ * the values of {@link Session} properties.
+ *
  * Implementations must be thread safe.
- * 
+ *
  */
-public interface SessionProperty {
+public interface SessionProperty extends Serializable {
 
   /**
-   * Return the name of this {@link SessionProperty}.
-   * 
-   * @return the name of this {@link SessionProperty}
+   * Return the name of this {@code SessionProperty}.
+   *
+   * @return the name of this {@code SessionProperty}
    */
   public String name();
 
   /**
-   * Return the type of the value of this {@link SessionProperty}. Any value
-   * set for this property must be assignable to this type.
+   * Return the type of the value of this {@code SessionProperty}. Any value set
+   * for this property must be assignable to this type.
    *
-   * @return the type of the values of this {@link SessionProperty}
+   * @return the type of the values of this {@code SessionProperty}
    */
   public Class<?> range();
 
   /**
-   * Determine whether a value is valid for this {@link SessionProperty}. Returns
-   * {@code true} if {@code value} is valid and {@code false} otherwise.
-   * 
-   * @param value a value for this {@link SessionProperty}
-   * @return {@code true} iff {@code value} is valid for this {@link SessionProperty}
+   * Determine whether a value is valid for this {@code SessionProperty}.
+   * Returns {@code true} if {@code value} is valid and {@code false} otherwise.
+   *
+   * @param value a value for this {@code SessionProperty}
+   * @return {@code true} iff {@code value} is valid for this
+   * {@code SessionProperty}
    */
   public default boolean validate(Object value) {
     return (value == null && this.range() == Void.class) || this.range().isInstance(value);
@@ -65,15 +67,15 @@
   /**
    * Return the value for this property to use if no other value is set. For
    * this to have any meaning for a user defined property the property must be
-   * registered with the {@link DataSource} by calling 
-   * {@link DataSource.Builder#registerSessionProperty}. 
+   * registered with the {@link DataSource} by calling
+   * {@link DataSource.Builder#registerSessionProperty}.
    *
    * @return the default value or {@code null} if there is no default value
    */
   public Object defaultValue();
 
   /**
-   * Returns true if this {@link SessionProperty} contains sensitive information
+   * Returns true if this {@code SessionProperty} contains sensitive information
    * such as a password or encryption key.
    *
    * @return true iff this is sensitive
@@ -85,15 +87,16 @@
    * {@link Session} to have the specified property value. Returns {@code true}
    * if any {@link Operation}s were submitted. {@code false} otherwise.
    *
-   * Called by {@link Session.Builder#build()} to configure a {@link Session} as
-   * specified in the {@link Session.Builder#property} method. SessionProperties
-   * known to the implementation may return {@code false} and rely on the
-   * implementation to do the right thing.
+   * Potentially called when an attach {@link Operation} is executed to
+   * configure a {@link Session} as specified in the
+   * {@link Session.Builder#property} method. SessionProperties known to the
+   * implementation may return {@code false} and rely on the implementation to
+   * do the right thing.
    *
    * @param group an {@link OperationGroup} which will be the container of the
    * submitted {@link Operation}s, if any
-   * @param value the value to which the property is to be set. May be null if
-   * {@link range()} is {@link Void}.
+   * @param value the value to which the property is to be set. May be
+   * {@code null} if {@link range()} is {@link Void}.
    * @return true if any {@link Operation}s were submitted, false otherwise
    * @throws IllegalStateException if it is not possible to configure the
    * {@link Session} as specified.
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ShardingKey.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/ShardingKey.java	Sat Oct 20 08:17:38 2018 -0400
@@ -25,13 +25,13 @@
 package jdk.incubator.sql2;
 
 /**
- * Interface used to indicate that this object represents a Sharding Key. A
- * {@link ShardingKey} instance is only guaranteed to be compatible with the
- * data source instance that it was derived from. A {@link ShardingKey} is
+ * Interface used to indicate that this object represents a sharding key. A
+ * {@code ShardingKey} instance is only guaranteed to be compatible with the
+ * data source instance that it was derived from. A {@code ShardingKey} is
  * created using {@link Builder}.
  * <p>
  * The following example illustrates the use of {@link Builder} to create a
- * {@link ShardingKey}:
+ * {@code ShardingKey}:
  * <pre>
  * {@code
  *
@@ -44,11 +44,11 @@
  * </pre>
  * <p>
  *
- * A {@link ShardingKey} is used for specifying a
+ * A {@code ShardingKey} is used for specifying a
  * {@link AdbaSessionProperty#SHARDING_KEY} or a
  * {@link AdbaSessionProperty#SHARDING_GROUP_KEY}. Databases that support
- * composite Sharding may use a * to specify a additional level of partitioning
- * within to specify a additional level of partitioning within the Shard.
+ * composite sharding may use a * to specify a additional level of partitioning
+ * within to specify a additional level of partitioning within the shard.
  * <p>
  * The following example illustrates the use of {@link Builder} to create a
  * {@link AdbaSessionProperty#SHARDING_GROUP_KEY} for an eastern region with
@@ -59,10 +59,10 @@
  *
  *     DataSource ds = new MyDataSource();
  *     ShardingKey superShardingKey = ds.shardingKeyBuilder()
- *                           .subkey("EASTERN_REGION", JDBCType.VARCHAR)
+ *                           .subkey("EASTERN_REGION", AdbaType.VARCHAR)
  *                           .build();
  *     ShardingKey shardingKey = ds.shardingKeyBuilder()
- *                           .subkey("PITTSBURGH_BRANCH", JDBCType.VARCHAR)
+ *                           .subkey("PITTSBURGH_BRANCH", AdbaType.VARCHAR)
  *                           .build();
  *     Session con = ds.builder()
  *                           .property(SHARDING_GROUP_KEY, superShardingKey)
@@ -75,11 +75,11 @@
 
   /**
    * A builder created from a {@link DataSource} or object, used to create a
-   * {@link ShardingKey} with sub-keys of supported data types. Implementations
+   * {@code ShardingKey} with sub-keys of supported data types. Implementations
    * must support JDBCType.VARCHAR and may also support additional data types.
    * <p>
-   * The following example illustrates the use of {@link Builder} to create a
-   * {@link ShardingKey}:
+   * The following example illustrates the use of {@code Builder} to create a
+   * {@code ShardingKey}:
    * <pre>
    * {@code
    *
@@ -100,7 +100,7 @@
      * Key.
      *
      * @param subkey contains the object that needs to be part of shard sub key
-     * @param subkeyType sub-key data type of type java.sql.SQLType
+     * @param subkeyType sub-key data type of type {@link SqlType}
      * @return this builder object
      */
     public Builder subkey(Object subkey, SqlType subkeyType);
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlBlob.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlBlob.java	Sat Oct 20 08:17:38 2018 -0400
@@ -35,94 +35,97 @@
 
   /**
    * Return an {@link Operation} that will release the temporary resources
-   * associated with this {@link SqlBlob}.
+   * associated with this {@code SqlBlob}.
    *
    * @return an {@link Operation} that will release the temporary resources
-   * associated with this {@link SqlBlob}.
+   * associated with this {@code SqlBlob}.
    */
   public Operation<Void> closeOperation();
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public default void close() {
     this.closeOperation().submit();
   }
 
   /**
-   * Return a {@link Operation} that fetches the position of this {@link SqlBlob}.
+   * Return a {@link Operation} that fetches the position of this {@code SqlBlob}.
    * The position is 1-based. Position 0 is immediately before the first byte in
-   * the {@link SqlBlob}. Position 1 is the first byte in the {@link SqlBlob}, etc.
-   * Position {@link length()} is the last byte in the {@link SqlBlob}.
+   * the {@code SqlBlob}. Position 1 is the first byte in the {@code SqlBlob}, etc.
+   * Position {@link length()} is the last byte in the {@code SqlBlob}.
    *
    * Position is between 0 and length + 1.
    *
-   * @return a {@link Operation} that returns the position of this {@link SqlBlob}
+   * @return a {@link Operation} that returns the position of this {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public Operation<Long> getPositionOperation();
 
   /**
-   * Get the position of this {@link SqlBlob}. The position is 1-based. Position 0
-   * is immediately before the first byte in the {@link SqlBlob}. Position 1 is the
-   * first byte in the {@link SqlBlob}, etc. Position {@link length()} is the last
-   * byte in the {@link SqlBlob}.
+   * Get the position of this {@code SqlBlob}. The position is 1-based. Position 0
+   * is immediately before the first byte in the {@code SqlBlob}. Position 1 is the
+   * first byte in the {@code SqlBlob}, etc. Position {@link length()} is the last
+   * byte in the {@code SqlBlob}.
    *
    * Position is between 0 and length + 1.
    *
    * ISSUE: Should position be 1-based as SQL seems to do or 0-based as Java
    * does?
    *
-   * @return a future which value is the 1-based position of this {@link SqlBlob}
+   * @return a future which value is the 1-based position of this {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public default CompletionStage<Long> getPosition() {
     return getPositionOperation().submit().getCompletionStage();
   }
 
   /**
-   * Return a {@link Operation} that fetches the length of this {@link SqlBlob}.
+   * Return a {@link Operation} that fetches the length of this {@code SqlBlob}.
    *
-   * @return a {@link Operation} that returns the length of this {@link SqlBlob}
+   * @return a {@link Operation} that returns the length of this {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public Operation<Long> lengthOperation();
 
   /**
-   * Get the length of this {@link SqlBlob}.
+   * Get the length of this {@code SqlBlob}.
    *
-   * @return a future which value is the number of bytes in this {@link SqlBlob}
+   * @return a future which value is the number of bytes in this {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public default CompletionStage<Long> length() {
     return lengthOperation().submit().getCompletionStage();
   }
 
   /**
-   * Return a {@link Operation} that sets the position of this {@link SqlBlob}. If
-   * offset exceeds the length of this {@link SqlBlob} set position to the length +
-   * 1 of this {@link SqlBlob}, ie one past the last byte.
+   * Return a {@link Operation} that sets the position of this {@code SqlBlob}. If
+   * offset exceeds the length of this {@code SqlBlob} set position to the length +
+   * 1 of this {@code SqlBlob}, ie one past the last byte.
    *
    * @param offset a non-negative number
-   * @return a {@link Operation} that sets the position of this {@link SqlBlob}
+   * @return a {@link Operation} that sets the position of this {@code SqlBlob}
    * @throws IllegalArgumentException if {@code offset} is less than 0
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public Operation<Long> setPositionOperation(long offset);
 
   /**
-   * Set the position of this {@link SqlBlob}. If offset exceeds the length of this
-   * {@link SqlBlob} set position to the length + 1 of this {@link SqlBlob}, ie one
+   * Set the position of this {@code SqlBlob}. If offset exceeds the length of this
+   * {@code SqlBlob} set position to the length + 1 of this {@code SqlBlob}, ie one
    * past the last byte.
    *
    * @param offset the 1-based position to set
-   * @return this {@link SqlBlob}
+   * @return this {@code SqlBlob}
    * @throws IllegalArgumentException if offset is less than 0
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public default SqlBlob setPosition(long offset) {
     setPositionOperation(offset).submit();
@@ -134,14 +137,14 @@
    * occurrence of the target after the position. If there is no such occurrence
    * set the position to 0.
    *
-   * @param target a {@link SqlBlob} created by the same {@link Session}
+   * @param target a {@code SqlBlob} created by the same {@link Session}
    * containing the byte sequence to search for
    * @return a {@link Operation} that locates {@code target} in this
-   * {@link SqlBlob}
+   * {@code SqlBlob}
    * @throws IllegalArgumentException if {@code target} was created by some
    * other {@link Session}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public Operation<Long> locateOperation(SqlBlob target);
 
@@ -150,11 +153,11 @@
    * after the position. If there is no such occurrence set the position to 0.
    *
    * @param target the byte sequence to search for
-   * @return this {@link SqlBlob}
+   * @return this {@code SqlBlob}
    * @throws IllegalArgumentException if {@code target} was created by some
    * other {@link Session}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed
+   * {@code SqlBlob} is closed
    */
   public default SqlBlob locate(SqlBlob target) {
     locateOperation(target).submit();
@@ -168,9 +171,9 @@
    *
    * @param target the byte sequence to search for. Not {@code null}. Captured.
    * @return a {@link Operation} that locates {@code target} in this
-   * {@link SqlBlob}
+   * {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public Operation<Long> locateOperation(byte[] target);
 
@@ -179,9 +182,9 @@
    * after the position. If there is no such occurrence set the position to 0.
    *
    * @param target the byte sequence to search for
-   * @return this {@link SqlBlob}
+   * @return this {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public default SqlBlob locate(byte[] target) {
     locateOperation(target).submit();
@@ -189,25 +192,25 @@
   }
 
   /**
-   * Return a {@link Operation} that truncates this {@link SqlBlob} so that the
-   * current position is the end of the {@link SqlBlob}. If the position is N, then
+   * Return a {@link Operation} that truncates this {@code SqlBlob} so that the
+   * current position is the end of the {@code SqlBlob}. If the position is N, then
    * after {@link trim()} the length is N - 1. The position is still N. This
    * will fail if position is 0.
    *
-   * @return a {@link Operation} that trims the length of this {@link SqlBlob}
+   * @return a {@link Operation} that trims the length of this {@code SqlBlob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed or position is 0.
+   * {@code SqlBlob} is closed or position is 0.
    */
   public Operation<Long> trimOperation();
 
   /**
-   * Truncate this {@link SqlBlob} so that the current position is the end of the
-   * {@link SqlBlob}. If the position is N, then after {@link trim()} the length is
+   * Truncate this {@code SqlBlob} so that the current position is the end of the
+   * {@code SqlBlob}. If the position is N, then after {@link trim()} the length is
    * N - 1. The position is still N. This will fail if position is 0.
    *
    * @return this SqlBlob
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed or position is 0.
+   * {@code SqlBlob} is closed or position is 0.
    */
   public default SqlBlob trim() {
     trimOperation().submit();
@@ -216,7 +219,7 @@
 
   /**
    * Return a {@link java.nio.channels.Channel} that can be used to read bytes from the
-   * {@link SqlBlob} beginning at the position. Reading bytes from the returned
+   * {@code SqlBlob} beginning at the position. Reading bytes from the returned
    * {@link java.nio.channels.Channel} advances the position.
    *
    * Each call to a read method that fetches bytes from the server creates and
@@ -232,8 +235,8 @@
 
   /**
    * Return a {@link java.nio.channels.Channel} that can be used to write bytes
-   * to this {@link SqlBlob} beginning at the position. Bytes written overwrite
-   * bytes already in the {@link SqlBlob}. Writing bytes to the returned
+   * to this {@code SqlBlob} beginning at the position. Bytes written overwrite
+   * bytes already in the {@code SqlBlob}. Writing bytes to the returned
    * {@link java.nio.channels.Channel} advances the position.
    *
    * Each call to a write method that flushes bytes to the server creates and
@@ -249,7 +252,7 @@
    * @return a writable byte {@link java.nio.channels.Channel} beginning at the
    * position.
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlBlob} is closed.
+   * {@code SqlBlob} is closed.
    */
   public AsynchronousByteChannel getWriteChannel();
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlClob.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlClob.java	Sat Oct 20 08:17:38 2018 -0400
@@ -36,94 +36,97 @@
 
   /**
    * Return an {@link Operation} that will release the temporary resources
-   * associated with this {@link SqlClob}.
+   * associated with this {@code SqlClob}.
    *
    * @return an {@link Operation} that will release the temporary resources
-   * associated with this {@link SqlClob}.
+   * associated with this {@code SqlClob}.
    */
   public Operation<Void> closeOperation();
 
+  /**
+   * {@inheritDoc}
+   */
   @Override
   public default void close() {
     this.closeOperation().submit();
   }
 
   /**
-   * Return a {@link Operation} that fetches the position of this {@link SqlClob}.
-   * Position 0 is immediately before the first char in the {@link SqlClob}.
-   * Position 1 is the first char in the {@link SqlClob}, etc. Position
-   * {@link length()} is the last char in the {@link SqlClob}.
+   * Return a {@link Operation} that fetches the position of this {@code SqlClob}.
+   * Position 0 is immediately before the first char in the {@code SqlClob}.
+   * Position 1 is the first char in the {@code SqlClob}, etc. Position
+   * {@link length()} is the last char in the {@code SqlClob}.
    *
    * Position is between 0 and length + 1.
    *
-   * @return an {@link Operation} that returns the position of this {@link SqlClob}
+   * @return an {@link Operation} that returns the position of this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.;
+   * {@code SqlClob} is closed.;
    */
   public Operation<Long> getPositionOperation();
 
   /**
-   * Get the position of this {@link SqlClob}. Position 0 is immediately before the
-   * first char in the {@link SqlClob}. Position 1 is the first char in the
-   * {@link SqlClob}, etc. Position {@link length()} is the last char in the SqlClob.
+   * Get the position of this {@code SqlClob}. Position 0 is immediately before the
+   * first char in the {@code SqlClob}. Position 1 is the first char in the
+   * {@code SqlClob}, etc. Position {@link length()} is the last char in the SqlClob.
 
  Position is between 0 and length + 1.
 
  ISSUE: Should position be 1-based as SQL seems to do or 0-based as Java
  does?
    *
-   * @return a future which value is the position of this {@link SqlClob}
+   * @return a future which value is the position of this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public default CompletionStage<Long> getPosition() {
     return getPositionOperation().submit().getCompletionStage();
   }
 
   /**
-   * Return a {@link Operation} that fetches the length of this {@link SqlClob}.
+   * Return a {@link Operation} that fetches the length of this {@code SqlClob}.
    *
-   * @return a {@link Operation} that returns the length of this {@link SqlClob}
+   * @return a {@link Operation} that returns the length of this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public Operation<Long> lengthOperation();
 
   /**
-   * Get the length of this {@link SqlClob}.
+   * Get the length of this {@code SqlClob}.
    *
    * @return a {@link java.util.concurrent.Future} which value is the number of
-   * chars in this {@link SqlClob}
+   * chars in this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public default CompletionStage<Long> length() {
     return lengthOperation().submit().getCompletionStage();
   }
 
   /**
-   * Return an {@link Operation} that sets the position of this {@link SqlClob}. If
-   * {@code offset} exceeds the length of this {@link SqlClob} set position to the
-   * length + 1 of this {@link SqlClob}, ie one past the last char.
+   * Return an {@link Operation} that sets the position of this {@code SqlClob}. If
+   * {@code offset} exceeds the length of this {@code SqlClob} set position to the
+   * length + 1 of this {@code SqlClob}, ie one past the last char.
    *
    * @param offset a non-negative number
-   * @return a {@link Operation} that sets the position of this {@link SqlClob}
+   * @return a {@link Operation} that sets the position of this {@code SqlClob}
    * @throws IllegalArgumentException if {@code offset} is less than 0
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public Operation<Long> setPositionOperation(long offset);
 
   /**
-   * Set the position of this {@link SqlClob}. If {@code offset} exceeds the length
-   * of this {@link SqlClob} set position to the length + 1 of this {@link SqlClob},
+   * Set the position of this {@code SqlClob}. If {@code offset} exceeds the length
+   * of this {@code SqlClob} set position to the length + 1 of this {@code SqlClob},
    * ie one past the last char.
    *
    * @param offset the 1-based position to set
-   * @return this {@link SqlClob}
+   * @return this {@code SqlClob}
    * @throws IllegalArgumentException if {@code offset} is less than 0
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public default SqlClob setPosition(long offset) {
     setPositionOperation(offset).submit();
@@ -135,14 +138,14 @@
    * next occurrence of the target after the position. If there is no such
    * occurrence set the position to 0.
    *
-   * @param target a {@link SqlClob} created by the same {@link Session}
+   * @param target a {@code SqlClob} created by the same {@link Session}
    * containing the char sequence to search for
    * @return an {@link Operation} that locates {@code target} in this
-   * {@link SqlClob}
+   * {@code SqlClob}
    * @throws IllegalArgumentException if {@code target} was created by some
    * other {@link Session}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public Operation<Long> locateOperation(SqlClob target);
 
@@ -151,11 +154,11 @@
    * after the position. If there is no such occurrence set the position to 0.
    *
    * @param target the char sequence to search for
-   * @return this {@link SqlClob}
+   * @return this {@code SqlClob}
    * @throws IllegalArgumentException if {@code target} was created by some
    * other {@link Session}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed
+   * {@code SqlClob} is closed
    */
   public default SqlClob locate(SqlClob target) {
     locateOperation(target).submit();
@@ -169,9 +172,9 @@
    *
    * @param target the char sequence to search for. Not {@code null}. Captured.
    * @return an {@link Operation} that locates {@code target} in this
-   * {@link SqlClob}
+   * {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public Operation<Long> locateOperation(CharSequence target);
 
@@ -180,9 +183,9 @@
    * after the position. If there is no such occurrence set the position to 0.
    *
    * @param target the char sequence to search for
-   * @return this {@link SqlClob}
+   * @return this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed.
+   * {@code SqlClob} is closed.
    */
   public default SqlClob locate(CharSequence target) {
     locateOperation(target).submit();
@@ -190,25 +193,25 @@
   }
 
   /**
-   * Return an {@link Operation} that truncates this {@link SqlClob} so that the
-   * current position is the end of the {@link SqlClob}. If the position is N, then
+   * Return an {@link Operation} that truncates this {@code SqlClob} so that the
+   * current position is the end of the {@code SqlClob}. If the position is N, then
    * after trim() the length is N - 1. The position is still N. This will fail
    * if position is 0.
    *
-   * @return an {@link Operation} that trims the length of this {@link SqlClob}
+   * @return an {@link Operation} that trims the length of this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed or position is 0.
+   * {@code SqlClob} is closed or position is 0.
    */
   public Operation<Long> trimOperation();
 
   /**
-   * Truncate this {@link SqlClob} so that the current position is the end of the
-   * {@link SqlClob}. If the position is N, then after {@link trim()} the length is
+   * Truncate this {@code SqlClob} so that the current position is the end of the
+   * {@code SqlClob}. If the position is N, then after {@link trim()} the length is
    * N - 1. The position is still N. This will fail if position is 0.
    *
-   * @return this {@link SqlClob}
+   * @return this {@code SqlClob}
    * @throws IllegalStateException if the {@link Session} that created this
-   * {@link SqlClob} is closed or position is 0.
+   * {@code SqlClob} is closed or position is 0.
    */
   public default SqlClob trim() {
     trimOperation().submit();
@@ -216,7 +219,7 @@
   }
 
   /**
-   * Returns a {@link Reader} for the characters in this {@link SqlClob}.
+   * Returns a {@link Reader} for the characters in this {@code SqlClob}.
    * Characters are read starting at the current position. Each character read
    * advances the position by one.
    *
@@ -230,7 +233,7 @@
   public Reader getReader();
 
   /**
-   * Returns a Writer for this {@link SqlClob}. Characters are written starting at
+   * Returns a Writer for this {@code SqlClob}. Characters are written starting at
    * the current position. Each character written advances the position by one.
    *
    * ISSUE: There is no character analog to
@@ -238,7 +241,7 @@
    * construct a {@link java.io.Writer} from an
    * {@link java.nio.channels.AsynchronousByteChannel} however.
    *
-   * @return a Writer for the characters of this SqlClob
+   * @return a {@link java.io.Writer} for the characters of this {@code SqlClob}
    */
   public Writer getWriter();
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlException.java	Sat Oct 20 08:17:38 2018 -0400
@@ -25,24 +25,21 @@
 package jdk.incubator.sql2;
 
 /**
- * <P>
  * An exception that provides information on a database access error or other
  * errors.
  *
  * <P>
- * Each <code>SqlException</code> provides several kinds of information:
+ * Each {@code SqlException} provides several kinds of information:
  * <UL>
  * <LI> a string describing the error. This is used as the Java Exception
- * message, available via the method <code>getMesasge</code>.
+ * message, available via the method {@link getMessage}.
  * <LI> a "SQLstate" string, which follows either the XOPEN SQLstate conventions
  * or the SQL:2003 conventions. The values of the SQLState string are described
- * in the appropriate spec. The <code>DatabaseMetaData</code> method
- * <code>getSQLStateType</code> can be used to discover whether the driver
- * returns the XOPEN type or the SQL:2003 type.
+ * in the appropriate spec.
  * <LI> an integer error code that is specific to each vendor. Normally this
  * will be the actual error code returned by the underlying database.
- * <LI> the causal relationship, if any for this <code>SqlException</code>.
- * <LI> the SQL string that was executing when the error occurred.
+ * <LI> the causal relationship, if any for this {@code SqlException}.
+ * <LI> the SQL string that was executing when the error occurred. May be {@code null}.
  * <LI> the position in the SQL string where the error was detected.
  * </UL>
  */
@@ -101,7 +98,7 @@
   // Methods
   
   /**
-   * Retrieves the SqlState for this <code>SqlException</code> object.
+   * Retrieves the SqlState for this {@code SqlException} object.
    *
    * @return the SQLState value
    */
@@ -111,7 +108,7 @@
 
   /**
    * Retrieves the vendor-specific exception code for this
-   * <code>SqlException</code> object.
+   * {@code SqlException} object.
    *
    * @return the vendor's error code
    */
@@ -123,7 +120,7 @@
    * Get the position.
    *
    * @return the index of the first character in sql where an error is detected.
-   * Zero based.
+   * Zero based. {@code -1} if the position is not defined or unknown.
    */
   public int getPosition() {
     return position;
@@ -132,7 +129,7 @@
   /**
    * Get the sql.
    *
-   * @return the SQL string sent to the database
+   * @return the SQL string sent to the database. May be {@code null}.
    */
   public String getSqlString() {
     return sqlString;
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlSkippedException.java	Sat Oct 20 08:17:38 2018 -0400
@@ -22,20 +22,21 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.incubator.sql2;
 
 /**
- * A {@link SqlException} that is used to complete an {@link Operation} when that {@link Operation} is
- * skipped. If an {@link Operation} is skipped the {@link Operation} is removed from the head of
- * the queue, no work is sent to the database and the {@link java.util.concurrent.CompletionStage} of that
- * {@link Operation} is completed exceptionally with a {@link SqlSkippedException}. The cause of
- * the {@link SqlSkippedException} is the {@link Throwable} that caused the {@link Operation} to be
- * skipped, if any.
+ * A {@link SqlException} that is used to complete an {@link Operation} when
+ * that {@link Operation} is skipped. If an {@link Operation} is skipped the
+ * {@link Operation} is removed from the head of the queue, no work is sent to
+ * the database and the {@link java.util.concurrent.CompletionStage} of that
+ * {@link Operation} is completed exceptionally with a
+ * {@code SqlSkippedException}. The cause of the {@code SqlSkippedException} is
+ * the {@link Throwable} that caused the {@link Operation} to be skipped, if
+ * any.
  *
  */
 public class SqlSkippedException extends SqlException {
-  
+
   private static final long serialVersionUID = 1L;
 
   /**
@@ -50,7 +51,7 @@
   public SqlSkippedException(String message, Throwable cause, String sqlState, int vendorCode, String sql, int position) {
     super(message, cause, sqlState, vendorCode, sql, position);
   }
-  
+
   /**
    *
    * @param cause
@@ -58,7 +59,7 @@
   public SqlSkippedException(SqlException cause) {
     super(cause.getMessage(), cause, cause.getSqlState(), cause.getVendorCode(), cause.getSqlString(), cause.getPosition());
   }
-  
+
   /**
    *
    * @param cause
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlStruct.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlStruct.java	Sat Oct 20 08:17:38 2018 -0400
@@ -76,8 +76,8 @@
      *
      * Implementations may choose to directly access a field named with the same
      * identifier or a constructor or static factory method where all of the
-     * formal parameters are named by &#64;Field annotations in the applied
-     * &#64;SqlStruct.
+     * formal parameters are named by Field annotations in the applied
+     * SqlStruct.
      *
      * @return a Java identifier
      */
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/SqlType.java	Sat Oct 20 08:17:38 2018 -0400
@@ -49,5 +49,5 @@
    * 
    * @return a Java type that best represents values of this SQL type
    */
-  public <T> Class<T> getJavaType();
+  public Class<?> getJavaType();
 }
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Submission.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/Submission.java	Sat Oct 20 08:17:38 2018 -0400
@@ -41,7 +41,7 @@
  * cancel. Neither of these is trivial.
  *
  * @param <T> The type of the result of the {@link Operation} that created this
- * {@link Submission}
+ * {@code Submission}
  */
 public interface Submission<T> {
 
--- a/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/TransactionCompletion.java	Thu Jul 12 15:23:13 2018 -0400
+++ b/src/jdk.incubator.adba/share/classes/jdk/incubator/sql2/TransactionCompletion.java	Sat Oct 20 08:17:38 2018 -0400
@@ -25,48 +25,50 @@
 package jdk.incubator.sql2;
 
 /**
- * A mutable object that controls whether a transactionCompletion Operation sends
- * a database commit or a database rollback to the server. A transactionCompletion
- * Operation is created with a TransactionCompletion. By default a transactionCompletion
- * Operation requests that the database end the transaction with a commit.
- * If {@link TransactionCompletion#setRollbackOnly} is called on the TransactionCompletion used to create
- the Operation prior to the Operation being executed, the Operation will
- request that the database end the transaction with a rollback.
- 
- Example:
-
- <pre>
+ * A mutable object that controls whether a transactionCompletion
+ * {@link Operation} sends a database commit or a database rollback to the
+ * server. A transactionCompletion {@link Operation} is created with a
+ * {@code TransactionCompletion}. By default a transactionCompletion
+ * {@link Operation} requests that the database end the transaction with a
+ * commit. If {@link TransactionCompletion#setRollbackOnly} is called on the
+ * {@code TransactionCompletion} used to create the Operation prior to the
+ * Operation being executed, the Operation will request that the database end
+ * the transaction with a rollback.
+ *
+ * Example:
+ *
+ * <pre>
  * {@code
-   TransactionCompletion t = session.transactionCompletion();
-   session.countOperation(updateSql)
-       .resultProcessor( count -> { if (count > 1) t.setRollbackOnly(); } )
-       .submit();
-   session.commitMaybeRollback(t);
- }</pre>
-
- A TransactionCompletion can not be used to create more than one endTransaction 
- Operation.
- 
- A TransactionCompletion is thread safe.
- 
- ISSUE: The name is terrible. Please suggest a better alternative, TransactionLatch?
+ * TransactionCompletion t = session.transactionCompletion();
+ * session.countOperation(updateSql)
+ * .resultProcessor( count -> { if (count > 1) t.setRollbackOnly(); } )
+ * .submit();
+ * session.commitMaybeRollback(t);
+ * }</pre>
+ *
+ * A {@code TransactionCompletion} can not be used to create more than one
+ * endTransaction {@link Operation}.
+ *
+ * A {@code TransactionCompletion} is thread safe.
+ *
  */
 public interface TransactionCompletion {
 
   /**
-   * Causes an endTransactionOperation created with this TransactionCompletion that is executed
-   * subsequent to this call to perform a rollback. If this method is not called
-   * prior to Operation execution the Operation will perform a commit.
+   * Causes an endTransaction {@link Operation} created with this
+   * {@code TransactionCompletion} that is executed subsequent to this call to
+   * perform a rollback. If this method is not called prior to {@link Operation}
+   * execution the {@link Operation} will perform a commit.
    *
-   * @return true if the call succeeded. False if the call did not succeed in
- setting the TransactionCompletion rollback only because the endTransaction
- Operation had already been executed.
+   * @return {@code true} if the call succeeded. {@code false} if the call did
+   * not succeed in setting the TransactionCompletion rollback only because the
+   * endTransaction Operation had already been executed.
    */
   public boolean setRollbackOnly();
 
   /**
    * Returns {@code true} iff the {@link setRollbackOnly} method has been called
- on this TransactionCompletion
+   * on this TransactionCompletion
    *
    * @return {@code true} if {@link setRollbackOnly} has been called.
    */